/* olimarler.com - "Night Session", a telemetry HUD glowing in a dark
   garage. Dark is the default/primary identity - the toggle below is for
   readers who prefer or need a light surface, not a redesign.

   Type system: Fraunces (display, hero moments only) + Inter (body/UI) +
   JetBrains Mono (data - stat numbers, tags, eyebrow labels). Self-hosted
   variable fonts in public/fonts/, OFL-licensed. */

@font-face {
  font-family: "Fraunces";
  src: url("/fonts/fraunces-variable.woff2") format("woff2");
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("/fonts/inter-variable.woff2") format("woff2");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("/fonts/jetbrains-mono-variable.woff2") format("woff2");
  font-weight: 500 700;
  font-style: normal;
  font-display: swap;
}

:root {
  --bg: #07090d;
  --raised: #10141b;
  --raised-2: #161b24;
  --border: #232a35;
  --text: #eef1f5;
  --dim: #939aa6;
  --faint: #5c6470;
  --cyan: #3fe0cf;
  --cyan-dim: #1d7d73;
  --cyan-tint: rgba(63, 224, 207, 0.09);
  --header-bg: rgba(7, 9, 13, 0.82);
  --radius: 14px;
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-md: 0 8px 28px -8px rgba(0, 0, 0, 0.55);
  --ease: cubic-bezier(0.2, 0.7, 0.3, 1);
  --font-display: "Fraunces", ui-serif, Georgia, serif;
  --font-body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;
}

/* Light theme: same tokens, swapped values - everything downstream is
   themed through these already, so no other rule needs to know a light
   mode exists. A warm off-white rather than pure white, so it reads as a
   considered surface rather than a default. --cyan is deepened here (vs.
   the dark theme's electric #3fe0cf) since it also doubles as link/text
   color, and the bright value fails contrast against a light background. */
:root[data-theme="light"] {
  --bg: #f5f3ee;
  --raised: #ffffff;
  --raised-2: #eeece6;
  --border: #ddd9cf;
  --text: #17181c;
  --dim: #5c5f68;
  --faint: #8d909a;
  --cyan: #0c7a70;
  --cyan-dim: #095e56;
  --cyan-tint: rgba(12, 122, 112, 0.08);
  --header-bg: rgba(245, 243, 238, 0.88);
  --shadow-sm: 0 1px 2px rgba(15, 15, 20, 0.06);
  --shadow-md: 0 8px 24px -8px rgba(15, 15, 20, 0.16);
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

a {
  color: var(--cyan);
  text-decoration: none;
}
a:hover {
  text-decoration: underline;
}

/* A single soft radial glow behind the hero, rather than a persistent
   HUD gridline texture - one deliberate atmospheric touch instead of a
   pattern repeated on every page. */
.grid-surface {
  position: fixed;
  inset: 0;
  z-index: -1;
  background-image: radial-gradient(ellipse 90% 55% at 50% -10%, var(--cyan-tint), transparent 60%);
  pointer-events: none;
}
/* A faint scanline drifting down the page on a slow loop - ambient
   texture, not a gimmick you notice on every scroll. Site-wide (unlike
   the hero waveform, which is homepage-only). transform-only animation on
   a pseudo-element so it stays GPU-composited and cheap on mobile. */
.grid-surface::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: -20vh;
  height: 20vh;
  background: linear-gradient(
    to bottom,
    transparent 0%,
    var(--cyan-tint) 48%,
    var(--cyan-tint) 52%,
    transparent 100%
  );
  opacity: 0.6;
  animation: scanline-sweep 22s linear infinite;
  will-change: transform;
}
@keyframes scanline-sweep {
  from {
    transform: translateY(0);
  }
  to {
    transform: translateY(calc(120vh));
  }
}
@media (prefers-reduced-motion: reduce) {
  .grid-surface::after {
    display: none;
  }
}

header.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 1.35rem 1.5rem;
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  background: var(--header-bg);
  backdrop-filter: blur(10px);
  z-index: 10;
}
.brand {
  flex-shrink: 0;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 0.95rem;
  letter-spacing: 0.01em;
  color: var(--text);
}
.brand .dot {
  color: var(--cyan);
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  /* Lets nav.site-nav actually shrink below its content width instead of
     overflowing the header - a flex child's default min-width is auto
     (its content size), which defeats overflow-x on the nav below it. */
  min-width: 0;
}

.theme-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.1rem;
  height: 2.1rem;
  padding: 0;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--raised);
  color: var(--text);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  flex-shrink: 0;
  transition: border-color 0.2s var(--ease), transform 0.15s var(--ease);
}
.theme-toggle:hover {
  border-color: var(--cyan);
  transform: translateY(-1px);
}

nav.site-nav {
  display: flex;
  gap: 1.75rem;
  overflow-x: auto;
  flex-wrap: nowrap;
  min-width: 0;
  scrollbar-width: none;
}
nav.site-nav::-webkit-scrollbar {
  display: none;
}
nav.site-nav a {
  color: var(--dim);
  font-weight: 500;
  font-size: 0.86rem;
  letter-spacing: 0.01em;
  white-space: nowrap;
  flex-shrink: 0;
  transition: color 0.2s ease;
}
nav.site-nav a.active,
nav.site-nav a:hover {
  color: var(--cyan);
  text-decoration: none;
}

main {
  max-width: 900px;
  margin: 0 auto;
  padding: 2.5rem 1.5rem 6rem;
}

.hero {
  padding: 4.5rem 0 3rem;
  position: relative;
}
.hero .eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--cyan);
  margin-bottom: 1.5rem;
}
.hero .eyebrow .dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--cyan);
  box-shadow: 0 0 8px var(--cyan);
}
.hero h1 {
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-weight: 460;
  font-size: clamp(2.3rem, 5.6vw, 3.4rem);
  line-height: 1.06;
  margin: 0 0 1.1rem;
  letter-spacing: -0.01em;
  text-wrap: balance;
  max-width: 18ch;
}
.hero p {
  color: var(--dim);
  max-width: 34rem;
  font-size: 1.08rem;
}

/* Homepage-only telemetry trace behind the hero text - two SVG copies of
   the same lap-speed-shaped path placed side by side, scrolled left by
   exactly one copy's width on an infinite loop (the classic seamless-
   marquee technique). Negative z-index keeps it under the hero's normal-
   flow text without needing to wrap the text in its own positioned box. */
.hero-with-waveform {
  position: relative;
  overflow: hidden;
}
.hero-waveform {
  position: absolute;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
}
/* ATLAS-style instrument grid behind the traces - faint vertical
   divisions like the "Grid: 20s" ruling on a real waveform view, plus a
   center reference line. */
.hero-waveform::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    repeating-linear-gradient(to right, var(--border) 0 1px, transparent 1px 90px),
    linear-gradient(to bottom, transparent calc(50% - 1px), var(--border) calc(50% - 1px), var(--border) calc(50% + 1px), transparent calc(50% + 1px));
  opacity: 0.4;
}
/* ATLAS panel header - "Cursor: ..." / "Grid: 20s", lifted straight from
   a real waveform view's top-left readout. */
.hero-readout-labels {
  position: absolute;
  top: 6px;
  left: 0;
  right: 0;
  display: flex;
  justify-content: space-between;
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.02em;
  color: var(--faint);
}
.hero-waveform svg {
  position: absolute;
  inset: 0;
  width: 200%;
  height: 100%;
}
.hero-waveform .trace-speed {
  opacity: 0.3;
  animation: waveform-scroll 16s linear infinite;
}
.hero-waveform .trace-throttle {
  opacity: 0.15;
  animation: waveform-scroll 22s linear infinite;
}
.hero-waveform .trace-brake {
  opacity: 0.12;
  animation: waveform-scroll 19s linear infinite;
}
.hero-waveform .trace-rpm {
  opacity: 0.12;
  animation: waveform-scroll 27s linear infinite;
}
@keyframes waveform-scroll {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(-50%);
  }
}

/* ATLAS-style time ruler along the bottom of the waveform - a mono
   timecode strip scrolling left on its own loop, same seamless-marquee
   technique as the traces above (duplicated track, -50% translate). */
.hero-timeline {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 4px;
  overflow: hidden;
  opacity: 0.5;
}
.hero-timeline-track {
  display: flex;
  width: max-content;
  gap: 90px;
  animation: waveform-scroll 20s linear infinite;
}
.hero-timeline-track span {
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.04em;
  color: var(--faint);
  white-space: nowrap;
}

/* One-off load-in: the solid traces (speed/throttle/rpm) are hand-drawn
   with a real stroke-draw (pathLength normalises stroke-dasharray/offset
   to 0-100 regardless of each curve's true geometry, so this needs no JS
   measurement). The dashed brake trace keeps its dash pattern and instead
   gets a clip-path wipe, since dasharray can't hold two patterns at once.
   A traveling glow "pen" crosses left over all of it, then continues
   across the heading and subtext as they wipe in behind it - the same
   stroke that drew the trace goes on to write the words. Runs once, then
   the traces hand off to their own ambient marquee above. Scoped to the
   homepage hero only (.hero-with-waveform). */
.hero-trace-draw {
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
  animation: hero-trace-draw-in 1.9s var(--ease) both;
}
.hero-trace-draw-2 {
  animation-delay: 0.1s;
}
.hero-trace-draw-3 {
  animation-delay: 0.18s;
}
@keyframes hero-trace-draw-in {
  to {
    stroke-dashoffset: 0;
  }
}
.hero-trace-wipe {
  clip-path: inset(0 0 0 100%);
  animation: hero-sweep-in 1.9s var(--ease) 0.05s both;
}
.hero-with-waveform .eyebrow,
.hero-with-waveform h1,
.hero-with-waveform p {
  clip-path: inset(0 0 0 100%);
  animation: hero-sweep-in 0.9s var(--ease) both;
}
.hero-with-waveform .eyebrow {
  animation-delay: 0.2s;
  animation-duration: 0.5s;
}
.hero-with-waveform h1 {
  animation-delay: 0.55s;
}
.hero-with-waveform p {
  animation-delay: 0.95s;
}
@keyframes hero-sweep-in {
  from {
    clip-path: inset(0 0 0 100%);
  }
  to {
    clip-path: inset(0 0 0 0%);
  }
}
.hero-pen {
  position: absolute;
  top: 0;
  bottom: 0;
  right: 0;
  width: 2px;
  background: linear-gradient(to bottom, transparent, var(--cyan) 15%, var(--cyan) 85%, transparent);
  box-shadow: 0 0 18px 5px var(--cyan);
  opacity: 0;
  animation: hero-pen-travel 1.9s var(--ease) both;
}
@keyframes hero-pen-travel {
  0% {
    right: 0%;
    opacity: 0;
  }
  4% {
    opacity: 0.85;
  }
  90% {
    opacity: 0.85;
  }
  100% {
    right: 100%;
    opacity: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .hero-waveform .trace-speed,
  .hero-waveform .trace-throttle,
  .hero-waveform .trace-brake,
  .hero-waveform .trace-rpm,
  .hero-trace-draw,
  .hero-trace-wipe,
  .hero-timeline-track,
  .hero-with-waveform .eyebrow,
  .hero-with-waveform h1,
  .hero-with-waveform p {
    animation: none;
    clip-path: none;
    stroke-dasharray: none;
    stroke-dashoffset: 0;
  }
  .hero-pen {
    display: none;
  }
}

section {
  margin-top: 4rem;
}
section h2 {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 1.5rem;
  margin-bottom: 1.1rem;
  letter-spacing: -0.005em;
}
section h3 {
  font-size: 1rem;
  margin: 1.5rem 0 0.75rem;
}

/* An instrument strip, not a bordered card - hairline rules top and
   bottom, mono numerals, so it reads as data displayed rather than
   another content card competing with the ones below it. */
.readout {
  display: flex;
  flex-wrap: wrap;
  gap: 2.5rem;
  padding: 1.5rem 0;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.readout div {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  color: var(--faint);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.readout strong {
  display: block;
  font-family: var(--font-mono);
  font-size: 1.4rem;
  color: var(--text);
  font-weight: 700;
  margin-top: 0.35rem;
  font-variant-numeric: tabular-nums;
}

/* Scroll-triggered reveal, wired up by home.js on the homepage only.
   Starts already visible so a no-JS visitor (or a browser that never
   fires the observer for some reason) never ends up with hidden content. */
.reveal {
  opacity: 1;
  transform: none;
}
.reveal.js-armed {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.5s ease, transform 0.5s ease;
}
.reveal.js-armed.in-view {
  opacity: 1;
  transform: translateY(0);
}
@media (prefers-reduced-motion: reduce) {
  .reveal.js-armed {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

.card {
  background: linear-gradient(155deg, var(--raised), var(--raised-2));
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.75rem;
  box-shadow: var(--shadow-md);
}

.grid {
  display: grid;
  gap: 1.1rem;
}
.grid.cols-2 {
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}
.grid.cols-3 {
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}

.media-item {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--raised);
  box-shadow: var(--shadow-sm);
}
.media-item img {
  width: 100%;
  height: 160px;
  object-fit: cover;
  display: block;
  background: #000;
}
.media-item .meta {
  padding: 0.65rem 0.8rem;
  font-size: 0.8rem;
  color: var(--dim);
}

.app-card {
  display: block;
  background: var(--raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.5rem;
  color: var(--text);
  box-shadow: var(--shadow-sm);
  transition: transform 0.25s var(--ease), box-shadow 0.25s var(--ease), border-color 0.25s ease;
}
.app-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-md);
  border-color: var(--cyan-dim);
  text-decoration: none;
}
.app-card h3 {
  font-family: var(--font-display);
  font-weight: 600;
  margin: 0 0 0.4rem;
  font-size: 1.08rem;
}
.app-card p {
  color: var(--dim);
  font-size: 0.88rem;
  margin: 0 0 0.75rem;
}

.tag-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}
.tag {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--dim);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.2rem 0.6rem;
}

.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.3rem 0.65rem;
  border-radius: 3px;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--cyan);
  border: 1px solid var(--cyan-dim);
  background: var(--cyan-tint);
}

main ul {
  margin: 0;
  padding-left: 1.25rem;
  color: var(--dim);
}
main ul li {
  margin-bottom: 0.5rem;
}

form.contact-form {
  display: grid;
  gap: 1.1rem;
  max-width: 32rem;
}
form.contact-form label {
  font-size: 0.8rem;
  color: var(--dim);
  display: block;
  margin-bottom: 0.35rem;
}
form.contact-form input,
form.contact-form textarea {
  width: 100%;
  padding: 0.7rem 0.85rem;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--raised);
  color: var(--text);
  font-size: 0.94rem;
  font-family: inherit;
  transition: border-color 0.2s ease;
}
form.contact-form input:focus,
form.contact-form textarea:focus {
  outline: 2px solid var(--cyan);
  outline-offset: 1px;
}
.hp-field {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

button,
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.8rem 1.6rem;
  border-radius: 999px;
  border: none;
  background: var(--cyan);
  color: var(--bg);
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.92rem;
  letter-spacing: 0.01em;
  cursor: pointer;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.2) inset, 0 8px 20px -8px var(--cyan);
  transition: transform 0.18s var(--ease), box-shadow 0.18s ease;
  white-space: nowrap;
}
button:hover,
.btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.25) inset, 0 12px 28px -8px var(--cyan);
  text-decoration: none;
}
button:active,
.btn:active {
  transform: translateY(0) scale(0.98);
}
button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
}

.status-line {
  font-size: 0.85rem;
  margin-top: 0.6rem;
  color: var(--dim);
}
.status-line.error {
  color: #ff8f8f;
}
.status-line.ok {
  color: var(--cyan);
}
.muted {
  color: var(--dim);
  font-size: 0.92rem;
}

footer.site-footer {
  border-top: 1px solid var(--border);
  padding: 1.5rem;
  text-align: center;
  color: var(--faint);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.02em;
}

main img {
  max-width: 100%;
  border-radius: var(--radius);
  border: 1px solid var(--border);
}

.photo-grid img {
  width: 100%;
  display: block;
  border-radius: var(--radius);
  border: 1px solid var(--border);
}

/* Architecture flow diagrams on Portfolio detail pages - hand-authored
   inline SVG, themed through currentColor/var(--cyan)/var(--dim) so they
   pick up the light/dark toggle for free. */
.flow-diagram {
  margin: 1.5rem 0;
  color: var(--text);
}
.flow-diagram svg {
  width: 100%;
  height: auto;
  display: block;
}
.flow-diagram svg rect,
.flow-diagram svg polygon {
  transition: stroke 0.15s ease, filter 0.15s ease;
}
.flow-diagram svg rect:hover,
.flow-diagram svg polygon:hover {
  stroke: var(--cyan);
  filter: drop-shadow(0 0 6px var(--cyan-tint));
}
.flow-diagram svg .pulse {
  filter: drop-shadow(0 0 3px currentColor);
}
@media (prefers-reduced-motion: reduce) {
  .flow-diagram svg .pulse {
    display: none;
  }
}
.flow-diagram figcaption {
  margin-top: 0.6rem;
  color: var(--dim);
  font-size: 0.85rem;
}

.no-screenshot-note {
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  padding: 1.1rem 1.3rem;
  color: var(--dim);
  font-size: 0.88rem;
}

table {
  width: 100%;
  min-width: 420px;
  border-collapse: collapse;
  font-size: 0.9rem;
}
th,
td {
  text-align: left;
  padding: 0.5rem 0.6rem;
  border-bottom: 1px solid var(--border);
}
th {
  color: var(--dim);
  font-weight: 600;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
main div:has(> table) {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

@media (max-width: 640px) {
  main {
    padding: 1.75rem 1.25rem 4.5rem;
  }
  .hero {
    padding: 2.75rem 0 2rem;
  }
  section {
    margin-top: 3rem;
  }
  nav.site-nav a {
    font-size: 0.82rem;
  }
}
