/* ==========================================================================
   Grawlix Labs — homepage

   THESIS      A studio page that reads like a document, not a dashboard. It
               refuses the dark-SaaS arrangement of glass cards floating on a
               gradient: everything sits on a ruled sheet, in plates with
               registration marks, annotated in the margin.
   OWN-WORLD   Near-black ground under a faint drafting grid. Phosphor green
               (#7cffb2) as the only signal colour, teal and violet held back
               for one plate each. Condensed engineered display lettering over
               a warm serif reading voice, with every piece of interface chrome
               in condensed mono. Square plates, hairline rules, corner ticks.
   STORY       You build websites, the intelligence in them, and the machinery
               under both — and the page proves you sweat detail by being made
               of detail.
   MOTION      One orchestrated arrival out of black, then one continuous
               seam drawn down the page by the scroll itself. The three
               specimens resolve from photograph into working diagram as they
               enter. Everything is response, not decoration, and every bit of
               it has a complete static fallback.
   ========================================================================== */

:root{
  /* Ground */
  --void:      #05070a;
  --void-2:    #080a0f;
  --plate:     #0a0d12;
  --plate-2:   #0d1117;

  /* Ink — contrast on --plate: ink 15.9:1, ink-2 8.7:1, ink-3 5.8:1 */
  --ink:       #e6efe9;
  --ink-2:     #a2b0aa;
  --ink-3:     #84918c;

  /* Signal */
  --green:     #7cffb2;
  --green-2:   #2fe08e;
  --green-3:   #3f9e72;   /* 5.9:1 — recessed but legible */
  --teal:      #3ad6d0;
  --violet:    #9578ff;

  /* Rules */
  --rule:      rgba(124,255,178,.16);
  --rule-2:    rgba(230,239,233,.09);
  --rule-3:    rgba(230,239,233,.05);

  --display: "Big Shoulders Display", "Oswald", "Arial Narrow", sans-serif;
  --wide:    "Anybody", "Archivo", "Helvetica Neue", sans-serif;
  --read:    "Literata", Georgia, "Times New Roman", serif;
  --mono:    "Martian Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --shell: min(1200px, calc(100vw - 2.5rem));
  --gutter: clamp(1.25rem, 4vw, 3rem);
  --ease: cubic-bezier(.22,.61,.36,1);
}

*,*::before,*::after{ box-sizing:border-box }

html{ background:var(--void); scroll-behavior:smooth; -webkit-text-size-adjust:100% }

body{
  margin:0;
  background:var(--void);
  color:var(--ink);
  font-family:var(--read);
  font-size:clamp(1rem,.95rem + .22vw,1.08rem);
  font-variation-settings:"opsz" 16;
  line-height:1.72;
  overflow-x:hidden;
  -webkit-font-smoothing:antialiased;
}

img{ max-width:100%; height:auto; display:block }
.shell{ width:var(--shell); margin-inline:auto }

/* ── Type ──────────────────────────────────────────────────────────────── */

h1,h2,h3{
  margin:0;
  font-family:var(--display);
  font-weight:600;
  line-height:.94;
  letter-spacing:.002em;
  text-wrap:balance;
}
h1{ font-size:clamp(3.1rem,1.5rem + 6.6vw,7.4rem) }
h2{ font-size:clamp(2.5rem,1.4rem + 4.4vw,4.8rem) }
h3{ font-size:clamp(1.85rem,1.4rem + 1.5vw,2.5rem); line-height:1 }

h1 em,h2 em{
  display:block;
  font-style:normal;
  color:var(--green);
  text-shadow:0 0 48px rgba(124,255,178,.2);
}

p{ margin:0 0 1.2em; text-wrap:pretty }
p:last-child{ margin-bottom:0 }

/* Headlines arrive a word at a time from behind their own baseline. The
   padding/margin pair gives descenders room inside the clip. */
[data-split]{ text-wrap:initial }
[data-split] .w{
  display:inline-block; overflow:hidden; vertical-align:bottom;
  padding-bottom:.09em; margin-bottom:-.09em;
}
[data-split] .w > i{
  display:inline-block; font-style:inherit;
  transform:translateY(108%);
  transition:transform .95s var(--ease);
  transition-delay:calc(var(--i,0) * 52ms);
}
[data-split].is-lifted .w > i{ transform:none }

a{ color:var(--green); text-decoration-color:rgba(124,255,178,.32); text-underline-offset:3px }
a:hover{ text-decoration-color:var(--green) }

/* Mono is the voice of every label, control, and readout on the page. */
.eyebrow,.plate-index,.plate-tag,.readout dt,.spec span,.procedure .step,
.field label,.intake-head,.intake-note,.colophon-meta,.masthead-nav,
.wordmark-type small,.btn,.note-list{
  font-family:var(--mono);
  font-weight:400;
  font-feature-settings:"liga" 0;
}

.eyebrow{
  display:flex; align-items:flex-start; gap:.6rem;
  margin:0 0 1.5rem;
  font-size:.64rem; letter-spacing:.16em; text-transform:uppercase;
  color:var(--ink-3);
}
.eyebrow .sect{ color:var(--green-3) }
.pip{
  flex:none; margin-top:.55em;
  width:5px; height:5px; border-radius:50%;
  background:var(--green);
  box-shadow:0 0 0 3px rgba(124,255,178,.12), 0 0 14px var(--green);
  animation:pulse 3.4s var(--ease) infinite;
}
@keyframes pulse{ 0%,100%{opacity:1} 50%{opacity:.3} }

.lede{
  max-width:33em;
  font-size:clamp(1.06rem,1rem + .4vw,1.24rem);
  line-height:1.66;
  color:var(--ink-2);
}

/* Footnote references — the annotation layer, always in the DOM. */
.ref{
  text-decoration:none;
  font-family:var(--mono);
  color:var(--green-3);
  padding-right:.12em;
  transition:color .2s var(--ease);
}
.ref sup{ font-size:.62em; top:-.55em; position:relative }
.ref:hover,.ref:focus-visible{ color:var(--green) }

:focus-visible{ outline:2px solid var(--green); outline-offset:3px; border-radius:1px }
:target{ scroll-margin-top:6rem }

.skip-link{
  position:absolute; left:1rem; top:-4rem; z-index:99;
  padding:.7rem 1.1rem;
  background:var(--green); color:var(--void);
  font-family:var(--mono); font-size:.72rem; text-decoration:none;
  transition:top .2s var(--ease);
}
.skip-link:focus-visible{ top:1rem }

/* ── The sheet: ruled ground everything sits on ────────────────────────── */

/* No tiled blueprint grid here on purpose: the page already carries its
   structure in plate borders, registration ticks, and section rules, and a
   two-axis hairline field would be decoration standing in for those. */
.grain,.scanlines,.ignition{ position:fixed; inset:0; pointer-events:none }
.grain,.scanlines{ z-index:60 }

/* A light the visitor carries. Screen blend so it can only ever add light —
   it never darkens a word. */
.pointer-light{
  position:fixed; left:0; top:0; z-index:59;
  width:44rem; height:44rem; margin:-22rem 0 0 -22rem;
  pointer-events:none;
  background:radial-gradient(closest-side,
    rgba(124,255,178,.11), rgba(58,214,208,.045) 44%, transparent 72%);
  mix-blend-mode:screen;
  opacity:0; transition:opacity .7s var(--ease);
  will-change:transform;
}
.pointer-light.is-on{ opacity:1 }

.grain{
  opacity:.055; mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}
/* Kept light: this sits above everything, so anything heavier stripes the
   primary button and roughens the serif. */
.scanlines{
  opacity:.17;
  background:repeating-linear-gradient(to bottom, rgba(0,0,0,0) 0 2px, rgba(0,0,0,.3) 2px 3px);
}

/* The film lands on black, so this starts black too — only a faint
   afterimage of the CRT's green burning off. Raise the alpha if the
   bridge film's fade ends brighter. */
.ignition{
  z-index:80;
  background:radial-gradient(120% 90% at 50% 55%, rgba(124,255,178,.14), rgba(124,255,178,0) 62%), #000;
  opacity:0;
  transition:opacity 1.15s var(--ease);
}
body.is-booting .ignition{ opacity:1 }
body.is-booting{ overflow:hidden }
body.is-booting main,
body.is-booting .masthead,
body.is-booting .colophon{ opacity:0; transform:translateY(14px) }
main,.masthead,.colophon{
  position:relative; z-index:1;
  opacity:1; transform:none;
  transition:opacity .95s var(--ease) .12s, transform .95s var(--ease) .12s;
}

/* ── The film ───────────────────────────────────────────────────────────
   Sits above everything including the ignition overlay, because while it
   runs it IS the page. Hidden by default so a no-JS visitor never meets it. */

.film{
  position:fixed; inset:0; z-index:90;
  background:#000;
  opacity:0; transition:opacity .9s var(--ease);
}
.film[hidden]{ display:none }
.film.is-on{ opacity:1 }
.film.is-out{ opacity:0; pointer-events:none }

/* The footage already pushes in on the beaker; when it runs out, CSS keeps
   pushing and takes the green to black. No second reel, so no cut to mismatch.
   Values carried over from the previous intro, which was tuned against this
   exact footage. */
.film-reel{
  position:absolute; inset:0;
  width:100%; height:100%;
  object-fit:cover;
  transform:scale(1); transform-origin:50% 50%;
  transition:transform 1.25s cubic-bezier(.2,.7,.2,1), filter 1.25s ease;
}
.film.is-transitioning .film-reel{
  transform:scale(2.55);
  filter:saturate(1.08) brightness(.94);
}

.film-blackout{
  position:absolute; inset:0; z-index:2;
  background:#000; opacity:0; pointer-events:none;
}
.film.is-transitioning .film-blackout{
  animation:film-blackout 1.35s .38s ease-in forwards;
}
@keyframes film-blackout{ from{ opacity:0 } to{ opacity:1 } }

.film-controls{
  position:absolute; left:0; right:0; bottom:clamp(1.5rem,4vh,3rem); z-index:4;
  display:flex; justify-content:center; gap:.75rem;
  padding:0 1.25rem;
}
.film-btn{
  padding:.7rem 1.1rem;
  border:1px solid rgba(230,239,233,.28);
  background:rgba(5,7,10,.5);
  backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);
  color:var(--ink);
  font-family:var(--mono); font-size:.62rem; font-weight:400;
  letter-spacing:.16em; text-transform:uppercase;
  cursor:pointer;
  transition:border-color .25s var(--ease), color .25s var(--ease), background .25s var(--ease);
}
.film-btn:hover{ border-color:var(--green); color:var(--green); background:rgba(5,7,10,.72) }

body.film-running{ overflow:hidden }

/* ── Ticker ────────────────────────────────────────────────────────────── */

.ticker{
  position:relative; z-index:40;
  overflow:hidden;
  padding:.55rem 0;
  background:var(--void-2);
  border-bottom:1px solid var(--rule-2);
}
.ticker-track{ display:flex; width:max-content; animation:ticker 52s linear infinite }
.ticker:hover .ticker-track{ animation-play-state:paused }
/* Same phosphor as the headline's second line, with a much tighter glow —
   the headline's 48px bloom would just smear at this size. */
.ticker-track span{
  display:inline-flex; align-items:center; white-space:nowrap;
  font-family:var(--mono); font-size:.55rem; font-weight:300;
  letter-spacing:.22em; text-transform:uppercase;
  color:var(--green);
  text-shadow:0 0 12px rgba(124,255,178,.28);
}
/* Separators step back so the words lead rather than the punctuation. */
.ticker-track i{ font-style:normal; color:rgba(124,255,178,.38); margin:0 1.5rem }
@keyframes ticker{ to{ transform:translateX(-50%) } }

/* ── The spine ─────────────────────────────────────────────────────────── */

.spine{
  position:absolute; left:0; top:0; z-index:3;
  pointer-events:none; overflow:visible;
}
.spine path,.spine circle{ vector-effect:non-scaling-stroke }
.spine-trunk{
  stroke:var(--green); stroke-width:1; opacity:.42;
  stroke-dasharray:1; stroke-dashoffset:1;
}
.spine-branch path{
  stroke:var(--green); stroke-width:1; opacity:.3;
  stroke-dasharray:1; stroke-dashoffset:1;
  transition:stroke-dashoffset .9s var(--ease);
  transition-delay:calc(var(--i,0) * 90ms);
}
.spine-branch path.is-drawn{ stroke-dashoffset:0 }
.spine-node circle{
  fill:var(--green); stroke:none;
  opacity:0; transform-box:fill-box; transform-origin:center;
  transform:scale(.2);
  transition:opacity .5s var(--ease), transform .5s var(--ease);
  transition-delay:calc(var(--i,0) * 90ms + 260ms);
}
.spine-node circle.is-drawn{ opacity:.85; transform:none }

/* ── Masthead ──────────────────────────────────────────────────────────── */

.masthead{
  position:sticky; top:0; z-index:50;
  display:flex; align-items:center; justify-content:space-between; gap:1.5rem;
  width:var(--shell); margin-inline:auto;
  padding:1.1rem 0;
}
.masthead::before{
  content:""; position:absolute; inset:0 -50vw;
  background:linear-gradient(to bottom, rgba(5,7,10,.94), rgba(5,7,10,.74) 62%, rgba(5,7,10,0));
  backdrop-filter:blur(12px); -webkit-backdrop-filter:blur(12px);
  opacity:0; transition:opacity .35s var(--ease); pointer-events:none;
}
/* The masthead keeps its height when it sticks — only the backdrop and rule
   fade in, so nothing reflows mid-scroll. */
.masthead.is-stuck::before{ opacity:1 }
.masthead > *{ position:relative }

.masthead-rule{
  position:absolute; left:0; right:0; bottom:0; height:1px;
  background:var(--rule-2);
  opacity:0; transition:opacity .35s var(--ease);
}
.masthead.is-stuck .masthead-rule{ opacity:1 }

.wordmark{
  display:inline-flex; align-items:center; gap:.7rem;
  color:var(--ink); text-decoration:none;
}
.wordmark-mark{
  display:grid; place-items:center;
  width:2.1rem; height:2.1rem;
  color:var(--green);
  filter:drop-shadow(0 0 12px rgba(124,255,178,.4));
  transition:filter .4s var(--ease), transform .35s var(--ease);
}
.wordmark-mark svg{ width:100% }
.beaker-liquid{
  opacity:1;
  transform-box:fill-box;
  transform-origin:center bottom;
  animation:beaker-liquid-sway 4.8s ease-in-out infinite;
}
.beaker-bubble{
  transform-box:fill-box;
  transform-origin:center;
  animation:beaker-bubble-rise 3.6s ease-in infinite;
  filter:drop-shadow(0 0 1.5px currentColor);
}
.beaker-bubble.bubble-b{ animation-delay:1.15s }
.beaker-bubble.bubble-c{ animation-delay:2.25s }
@keyframes beaker-liquid-sway{
  0%,100%{ transform:translateX(-1px) skewX(-1deg) }
  50%{ transform:translateX(1px) skewX(1deg) }
}
@keyframes beaker-bubble-rise{
  0%,15%{ opacity:0; transform:translateY(3px) scale(.65) }
  28%{ opacity:.9 }
  78%{ opacity:.35 }
  100%{ opacity:0; transform:translateY(-14px) scale(1.05) }
}
.wordmark:hover .wordmark-mark{ filter:drop-shadow(0 0 22px rgba(124,255,178,.8)) }
.wordmark-mark.is-shaken{ animation:shake .5s var(--ease) }
@keyframes shake{
  0%,100%{ transform:none }
  20%{ transform:translate(-2px,1px) rotate(-5deg) }
  45%{ transform:translate(2px,-1px) rotate(5deg) }
  70%{ transform:translate(-1px,0) rotate(-2deg) }
}
@media (prefers-reduced-motion:reduce){
  .beaker-liquid,.beaker-bubble{ animation:none }
  .wordmark-mark svg animate{ display:none }
}

.wordmark-type{ display:flex; flex-direction:column; line-height:1.1 }
.wordmark-type strong{
  font-family:var(--display); font-weight:600;
  font-size:1.42rem; letter-spacing:.005em;
}
.wordmark-type small{
  font-size:.53rem; letter-spacing:.19em;
  text-transform:uppercase; color:var(--ink-3);
}

.masthead-nav{ display:flex; align-items:center; gap:1.9rem }
.masthead-nav a{
  font-size:.66rem; letter-spacing:.13em; text-transform:uppercase;
  color:var(--ink-2); text-decoration:none;
  transition:color .25s var(--ease);
}
.masthead-nav a:hover{ color:var(--ink) }
.masthead-nav .nav-cta{
  padding:.55rem .95rem;
  border:1px solid var(--rule);
  color:var(--green);
  background:rgba(124,255,178,.045);
  transition:background .25s var(--ease), border-color .25s var(--ease);
}
.masthead-nav .nav-cta:hover{
  background:rgba(124,255,178,.1); border-color:rgba(124,255,178,.38);
}

/* ── Buttons ───────────────────────────────────────────────────────────── */

.btn{
  display:inline-flex; align-items:center; justify-content:center;
  padding:.95rem 1.6rem;
  border:1px solid transparent;
  font-size:.7rem; letter-spacing:.14em; text-transform:uppercase;
  text-decoration:none; cursor:pointer;
  transition:transform .25s var(--ease), box-shadow .3s var(--ease),
             background .25s var(--ease), border-color .25s var(--ease), color .25s var(--ease);
}
.btn-primary{
  background:var(--green); color:#03100a;
  box-shadow:0 14px 40px rgba(124,255,178,.13);
}
.btn-primary:hover{
  transform:translateY(-2px);
  box-shadow:0 0 34px rgba(124,255,178,.34), 0 18px 46px rgba(124,255,178,.2);
}
.btn-ghost{ border-color:var(--rule-2); color:var(--ink) }
.btn-ghost:hover{ border-color:rgba(124,255,178,.34); color:var(--green); transform:translateY(-2px) }
.btn-block{ width:100%; margin-top:.6rem }

/* ── Hero ──────────────────────────────────────────────────────────────── */

.hero{
  position:relative;
  display:flex; align-items:center;
  min-height:clamp(620px, 94svh, 1020px);
  padding:7rem 0 6rem;
  margin-top:-5.4rem;
  overflow:hidden;
}
.hero-art{
  position:absolute; inset:0;
  width:100%; height:100%;
  object-fit:cover; object-position:66% 50%;
  opacity:.88;
  z-index:0;
  transition:opacity .9s var(--ease);
}
/* The same photograph, but alive: a shader pushes the seam around under the
   pointer. Only ever initialised on a real pointer at desktop width. Phones
   and reduced-motion keep the plain image above and never load any of it. */
.hero-gl{
  position:absolute; inset:0; z-index:0;
  width:100%; height:100%;
  opacity:0; transition:opacity 1.1s var(--ease);
}
.hero.gl-on .hero-gl{ opacity:.88 }
.hero.gl-on .hero-art{ opacity:0 }
/* The seam is the whole point, so it stays lit on the right while the
   reading column sits on genuinely matte ground. */
.hero::after{
  content:""; position:absolute; inset:0; z-index:1;
  background:
    linear-gradient(to top, var(--void) 0%, rgba(5,7,10,.52) 15%, rgba(5,7,10,.14) 56%, rgba(5,7,10,.5) 100%),
    linear-gradient(to right,
      rgba(5,7,10,.97) 0%, rgba(5,7,10,.93) 24%, rgba(5,7,10,.62) 46%,
      rgba(5,7,10,.16) 66%, rgba(5,7,10,0) 82%);
}
.hero-inner{ position:relative; z-index:2 }

.hero h1{ margin-bottom:2rem }

/* The setup line runs wide and mechanical; the payoff stays condensed and
   leans. Two axes of contrast (width and slant) off one sentence. */
.hero h1 .lead{
  display:block;
  font-family:var(--wide);
  font-variation-settings:"wdth" 122, "wght" 700;
  font-size:.8em;
  line-height:1.04;
  letter-spacing:-.01em;
}
/* Big Shoulders ships no true italic, so this is a measured slant rather than
   whatever oblique each browser would synthesise on its own. */
.hero h1 em{
  margin-top:.14em;
  transform:skewX(-9deg);
  transform-origin:left bottom;
}
.hero .lede{ margin-bottom:2.4rem }

.hero-actions{ display:flex; flex-wrap:wrap; gap:.7rem; margin-bottom:3.4rem }

/* Instrument row — bordered cells, not floating text. */
.readout{
  display:grid; grid-template-columns:repeat(3,1fr);
  margin:0; max-width:56rem;
  border:1px solid var(--rule-2);
  background:rgba(5,7,10,.45);
}
.readout div{ padding:1.05rem 1.15rem; border-left:1px solid var(--rule-3); min-width:0 }
.readout div:first-child{ border-left:0 }
.readout dt{
  font-size:.56rem; letter-spacing:.17em; text-transform:uppercase;
  color:var(--green-3); margin-bottom:.5rem;
}
.readout dd{ margin:0; font-size:.9rem; line-height:1.45; color:var(--ink-2) }

.descend{
  position:absolute; left:50%; bottom:1.9rem; z-index:3;
  transform:translateX(-50%);
  display:grid; place-items:center; width:2.4rem; height:2.4rem;
}
.descend span{
  display:block; width:1px; height:2rem;
  background:linear-gradient(to bottom, rgba(124,255,178,0), var(--green));
  animation:drop 2.8s var(--ease) infinite;
}
@keyframes drop{
  0%{ transform:scaleY(.15); transform-origin:top; opacity:0 }
  40%{ transform:scaleY(1); transform-origin:top; opacity:1 }
  70%{ transform:scaleY(1); transform-origin:bottom; opacity:1 }
  100%{ transform:scaleY(.05); transform-origin:bottom; opacity:0 }
}

/* ── Sections ──────────────────────────────────────────────────────────── */

.craft,.studio,.contact,.notes{ position:relative; padding:clamp(5.5rem,10vw,9.5rem) 0 }
.band{ border-top:1px solid var(--rule-2) }

.section-head{ max-width:46rem; margin-bottom:clamp(3rem,6vw,4.8rem) }
.section-head h2{ margin-bottom:1.6rem }
.section-lede{ max-width:33em; color:var(--ink-2) }

/* ── Plates ────────────────────────────────────────────────────────────── */

.craft-grid{ display:grid; gap:1rem }
@media (min-width:920px){ .craft-grid{ grid-template-columns:repeat(3,1fr) } }

.plate{
  position:relative; isolation:isolate;
  display:flex; flex-direction:column;
  border:1px solid var(--rule-2);
  background:linear-gradient(to bottom, var(--plate-2), var(--plate));
  transition:border-color .4s var(--ease), transform .4s var(--ease);
}
/* Registration ticks at the outer corners — the plate is a mounted object. */
.plate::after{
  content:""; position:absolute; inset:6px; z-index:3; pointer-events:none;
  background:
    linear-gradient(var(--rule) 0 0) 0 0/9px 1px no-repeat,
    linear-gradient(var(--rule) 0 0) 0 0/1px 9px no-repeat,
    linear-gradient(var(--rule) 0 0) 100% 0/9px 1px no-repeat,
    linear-gradient(var(--rule) 0 0) 100% 0/1px 9px no-repeat,
    linear-gradient(var(--rule) 0 0) 0 100%/9px 1px no-repeat,
    linear-gradient(var(--rule) 0 0) 0 100%/1px 9px no-repeat,
    linear-gradient(var(--rule) 0 0) 100% 100%/9px 1px no-repeat,
    linear-gradient(var(--rule) 0 0) 100% 100%/1px 9px no-repeat;
  opacity:.65; transition:opacity .4s var(--ease);
}
.plate::before{
  content:""; position:absolute; inset:0; z-index:2; pointer-events:none; opacity:0;
  background:radial-gradient(22rem 22rem at var(--mx,50%) var(--my,0%),
             rgba(124,255,178,.075), rgba(124,255,178,0) 66%);
  transition:opacity .45s var(--ease);
}
.plate:hover{ border-color:rgba(124,255,178,.26); transform:translateY(-4px) }
.plate:hover::before{ opacity:1 }
.plate:hover::after{ opacity:1 }

.plate-head{
  display:flex; justify-content:space-between; align-items:baseline; gap:1rem;
  padding:.95rem 1.35rem;
  border-bottom:1px solid var(--rule-2);
  font-size:.56rem; letter-spacing:.17em; text-transform:uppercase;
}
.plate-index{ color:var(--green-3) }
.plate-tag{ color:var(--ink-3) }

.plate-art{ position:relative; overflow:hidden; aspect-ratio:4/3 }
.plate-art img{
  width:100%; height:100%; object-fit:cover;
  transition:transform 1.1s var(--ease), opacity .9s var(--ease), filter .9s var(--ease);
}
.plate:hover .plate-art img{ transform:scale(1.04) }
/* Once the plate is in view the specimen recedes and the mechanism it stands
   for draws itself on top. */
.plate.is-live .plate-art img{ opacity:.28; filter:saturate(.5) }
/* Only enough falloff to seat the art into the plate body — any heavier and
   the specimens go black. */
.plate-art::after{
  content:""; position:absolute; inset:0;
  background:linear-gradient(to bottom,
    rgba(5,7,10,0) 0%, rgba(5,7,10,.08) 48%, rgba(10,13,18,.78) 100%);
}

/* ── Plate demonstrations ──────────────────────────────────────────────── */

.plate-demo{
  position:absolute; inset:0; z-index:2;
  opacity:0; transition:opacity .7s var(--ease) .25s;
}
.plate.is-live .plate-demo{ opacity:1 }
.plate-demo svg{ width:100%; height:100%; display:block }

/* 01 — structure first, then the finished surface laid into it. */
.demo-web .wire rect{
  fill:none; stroke:var(--green); stroke-width:.7;
  opacity:0; transform:translateY(5px);
  transition:opacity .55s var(--ease), transform .55s var(--ease);
  transition-delay:calc(var(--i) * 95ms + 200ms);
}
.plate.is-live .demo-web .wire rect{ opacity:.6; transform:none }
.demo-web .solid rect{
  fill:var(--green); opacity:0;
  transition:opacity .7s var(--ease);
  transition-delay:calc(var(--i) * 130ms + 1050ms);
}
.plate.is-live .demo-web .solid rect{ opacity:.2 }

/* 02 — something shapeless arrives; structured fields leave. */
.demo-ai{
  display:grid; grid-template-columns:1fr 1.15fr; gap:9%;
  align-content:center; padding:16% 11%;
}
.demo-ai .raw{ display:flex; flex-direction:column; justify-content:center; gap:.42rem }
.demo-ai .raw span{
  display:block; height:4px; border-radius:1px; background:var(--ink-3); opacity:.45;
  transition:opacity .6s var(--ease), transform .6s var(--ease);
  transition-delay:calc(var(--i) * 90ms + 950ms);
}
.demo-ai .raw span:nth-child(1){ width:100% }
.demo-ai .raw span:nth-child(2){ width:78% }
.demo-ai .raw span:nth-child(3){ width:92% }
.demo-ai .raw span:nth-child(4){ width:55% }
.plate.is-live .demo-ai .raw span{ opacity:.1; transform:translateX(-7px) }

.demo-ai .parsed div{ display:grid; gap:.3rem; margin-bottom:.6rem }
.demo-ai .parsed div:last-child{ margin-bottom:0 }
.demo-ai .parsed b{
  font-family:var(--mono); font-weight:400; font-size:.58rem;
  letter-spacing:.16em; text-transform:uppercase; color:var(--green-3);
}
.demo-ai .parsed i{
  display:block; height:3px; background:var(--green); opacity:.55;
  transform:scaleX(0); transform-origin:left;
  transition:transform .6s var(--ease);
  transition-delay:calc(var(--i) * 150ms + 1100ms);
}
.plate.is-live .demo-ai .parsed i{ transform:scaleX(1) }

/* 03 — three inputs, one place they reconcile, two things that come out. */
.demo-sys .link path{
  stroke:var(--green); stroke-width:.8; opacity:.45;
  stroke-dasharray:1; stroke-dashoffset:1;
  transition:stroke-dashoffset .8s var(--ease);
  transition-delay:calc(var(--i) * 140ms + 350ms);
}
.plate.is-live .demo-sys .link path{ stroke-dashoffset:0 }
.demo-sys .node circle{
  fill:var(--green); opacity:0;
  transform-box:fill-box; transform-origin:center; transform:scale(.3);
  transition:opacity .45s var(--ease), transform .45s var(--ease);
  transition-delay:calc(var(--i) * 140ms + 250ms);
}
.plate.is-live .demo-sys .node circle{ opacity:.9; transform:none }
.demo-sys .hub{
  fill:none; stroke:var(--green); stroke-width:1; opacity:0;
  transform-box:fill-box; transform-origin:center;
  transform:rotate(45deg) scale(.35);
  transition:opacity .6s var(--ease) .95s, transform .7s var(--ease) .95s;
}
.plate.is-live .demo-sys .hub{ opacity:.9; transform:rotate(45deg) scale(1) }

.plate-body{
  position:relative; z-index:2; flex:1;
  display:flex; flex-direction:column;
  padding:1.6rem 1.35rem 1.9rem;
}
.plate h3{ margin-bottom:1rem }
.plate p{ color:var(--ink-2); font-size:.95rem; line-height:1.68 }

/* Pinned to the plate floor so the three spec blocks line up. */
.spec{ list-style:none; margin:1.5rem 0 0; padding:1.25rem 0 0; border-top:1px solid var(--rule-3) }
@media (min-width:920px){ .spec{ margin-top:auto } }
.spec li{
  display:grid; grid-template-columns:1.6rem 1fr;
  margin-bottom:.62rem;
  font-family:var(--read);
  font-size:.855rem; line-height:1.5; color:var(--ink-3);
}
.spec li:last-child{ margin-bottom:0 }
.spec span{
  font-size:.56rem; letter-spacing:.1em; text-transform:uppercase;
  color:var(--green-3); padding-top:.32em;
}

/* ── Studio ────────────────────────────────────────────────────────────── */

.studio{
  background:
    radial-gradient(62% 80% at 12% 0%, rgba(58,214,208,.05), transparent 62%),
    radial-gradient(55% 75% at 92% 100%, rgba(149,120,255,.055), transparent 64%),
    var(--void-2);
  border-top:1px solid var(--rule-2);
}
.studio-inner{ display:grid; gap:clamp(2.8rem,5vw,4.5rem) }
@media (min-width:920px){ .studio-inner{ grid-template-columns:1fr 1fr; align-items:start } }
.studio-copy h2{ margin-bottom:1.6rem }
.studio-copy p{ color:var(--ink-2); max-width:33em }

.procedure{ list-style:none; margin:0; padding:0 }
.procedure li{
  display:grid; grid-template-columns:auto 1fr; column-gap:1.15rem;
  padding:1.35rem 0;
  border-top:1px solid var(--rule-3);
}
.procedure li:last-child{ border-bottom:1px solid var(--rule-3) }
.procedure .step{
  grid-row:span 2;
  font-size:.62rem; letter-spacing:.1em; color:var(--green); padding-top:.5em;
}
.procedure strong{
  font-family:var(--display); font-weight:600;
  font-size:1.4rem; line-height:1.05; letter-spacing:.004em;
}
.procedure em{
  font-style:normal; font-size:.875rem; color:var(--ink-3);
  line-height:1.55; margin-top:.35rem;
}

/* ── Contact ───────────────────────────────────────────────────────────── */

.contact-inner{ display:grid; gap:clamp(2.8rem,5vw,4.5rem) }
@media (min-width:920px){ .contact-inner{ grid-template-columns:1fr 1fr; align-items:start } }
.contact-copy h2{ margin-bottom:1.7rem }
.contact-copy p{ color:var(--ink-2); max-width:31em }
.contact-direct{
  margin-top:1.9rem; padding-top:1.5rem;
  border-top:1px solid var(--rule-3);
  font-family:var(--mono); font-size:.68rem;
  letter-spacing:.11em; text-transform:uppercase; color:var(--ink-3);
}

/* Intake reads as a form on a plate: ruled fields, no rounded boxes. */
.intake{
  padding:clamp(1.5rem,3vw,2.1rem);
  border:1px solid var(--rule-2);
  background:linear-gradient(to bottom, var(--plate-2), var(--plate));
}
.intake-head{
  margin:0 0 1.9rem; padding-bottom:.9rem;
  border-bottom:1px solid var(--rule-2);
  font-size:.56rem; letter-spacing:.19em; text-transform:uppercase; color:var(--green-3);
}
.hp{ position:absolute; left:-9999px; width:1px; height:1px; overflow:hidden }

.field{ margin-bottom:1.35rem }
.field-row{ display:grid; gap:1.35rem }
@media (min-width:540px){ .field-row{ grid-template-columns:1fr 1fr } }

.field label{
  display:block; margin-bottom:.5rem;
  font-size:.56rem; letter-spacing:.17em; text-transform:uppercase; color:var(--ink-3);
}
.field input,.field select,.field textarea{
  width:100%; padding:.6rem 0;
  border:0; border-bottom:1px solid var(--rule-2);
  background:transparent;
  color:var(--ink);
  font-family:var(--read); font-size:1rem; line-height:1.5;
  transition:border-color .25s var(--ease);
}
.field textarea{ resize:vertical; min-height:6.5rem }
.field select{
  appearance:none;
  background-image:linear-gradient(45deg,transparent 50%,var(--ink-3) 50%),
                   linear-gradient(135deg,var(--ink-3) 50%,transparent 50%);
  background-position:calc(100% - 11px) 1.15rem, calc(100% - 6px) 1.15rem;
  background-size:5px 5px,5px 5px; background-repeat:no-repeat;
  padding-right:2.2rem;
}
.field select option{ background:var(--plate); color:var(--ink) }
.field input::placeholder,.field textarea::placeholder{ color:var(--ink-3); opacity:.62 }
.field input:focus,.field select:focus,.field textarea:focus{
  border-bottom-color:var(--green); outline:none;
}
.field input:focus-visible,.field select:focus-visible,.field textarea:focus-visible{
  outline:2px solid var(--green); outline-offset:4px;
}

.intake-note{
  margin-top:1.1rem; text-align:center;
  font-size:.55rem; letter-spacing:.13em; text-transform:uppercase; color:var(--ink-3);
}

/* ── Notes ─────────────────────────────────────────────────────────────── */

.notes{
  border-top:1px solid var(--rule-2);
  padding-top:clamp(3rem,6vw,4.5rem);
  padding-bottom:clamp(3rem,6vw,4.5rem);
}
.note-list{
  margin:0; padding-left:1.5rem;
  max-width:52rem;
  font-family:var(--read);
  font-size:.86rem; line-height:1.68; color:var(--ink-3);
}
.note-list li{ margin-bottom:.85rem; padding-left:.4rem }
.note-list li:last-child{ margin-bottom:0 }
.note-list li::marker{ font-family:var(--mono); font-size:.62rem; color:var(--green-3) }
.note-list a{ text-decoration:none; opacity:.55 }
.note-list a:hover{ opacity:1 }
.note-list li:target{ color:var(--ink-2) }
.note-list li:target::marker{ color:var(--green) }

/* ── Colophon ──────────────────────────────────────────────────────────── */

.colophon{ padding:3rem 0 3.5rem; border-top:1px solid var(--rule-2); background:var(--void-2) }
.colophon-inner{ display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:1.5rem }
.colophon .wordmark-type strong{ font-size:1.2rem }
.colophon-line{ margin:0; flex:1 1 18rem; font-size:.84rem; line-height:1.6; color:var(--ink-3) }
.colophon-meta{
  display:flex; align-items:center; gap:.65rem; margin:0;
  font-size:.6rem; letter-spacing:.1em; color:var(--ink-3);
}
.colophon-secret{
  flex:1 1 100%; margin:.5rem 0 0; padding-top:1.4rem;
  border-top:1px solid var(--rule-3);
  max-width:44em;
  font-size:.82rem; line-height:1.65; color:var(--ink-3);
}
.colophon-secret span{
  font-family:var(--mono); font-size:.72rem;
  color:var(--green); margin-right:.6rem; letter-spacing:.06em;
}
.colophon-secret[hidden]{ display:none }

/* ── Scroll reveal ─────────────────────────────────────────────────────── */

[data-lift]{ opacity:0; transform:translateY(20px); transition:opacity .85s var(--ease), transform .85s var(--ease) }
[data-lift].is-lifted{ opacity:1; transform:none }

/* ── Small screens ─────────────────────────────────────────────────────── */

@media (max-width:720px){
  /* Wider left margin than the old 1.25rem: the spine needs a lane to run in,
     otherwise it reads as a stray line hugging the edge. */
  :root{ --shell:calc(100vw - 3.5rem) }

  /* Both faces need reining in on a narrow column. Measured against the
     longest line, "the thing underneath.", which breaks above 44px at 375. */
  .hero h1{ font-size:clamp(2.2rem, 1.1rem + 5.6vw, 3.4rem) }
  .hero h1 .lead{ font-size:.75em; font-variation-settings:"wdth" 104, "wght" 700 }
  .masthead-nav a:not(.nav-cta){ display:none }
  .hero{ min-height:auto; padding:7.5rem 0 4.5rem }
  /* The column spans the full width here, so the art drops right back and
     the scrim goes flat — copy never sits on texture. */
  .hero-art{ object-position:74% 46%; opacity:.42 }
  .hero::after{
    background:linear-gradient(to top,
      var(--void) 0%, rgba(5,7,10,.8) 22%, rgba(5,7,10,.7) 66%, rgba(5,7,10,.78) 100%);
  }
  .readout{ grid-template-columns:1fr }
  .readout div{ border-left:0; border-top:1px solid var(--rule-3) }
  .readout div:first-child{ border-top:0 }
  .descend{ display:none }
  .colophon-inner{ gap:1.1rem }
}

/* Phones: the masthead is the first thing that runs out of room. */
@media (max-width:460px){
  .wordmark-type small{ display:none }
  .wordmark-type strong{ font-size:1.3rem }
  .masthead-nav .nav-cta{
    padding:.5rem .75rem; font-size:.6rem; letter-spacing:.1em; white-space:nowrap;
  }
  .btn{ padding:.9rem 1.25rem; font-size:.66rem }
  .hero-actions .btn{ flex:1 1 auto; justify-content:center }
}

/* ── Reduced motion ────────────────────────────────────────────────────── */

@media (prefers-reduced-motion:reduce){
  html{ scroll-behavior:auto }
  *,*::before,*::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
  }
  [data-lift]{ opacity:1; transform:none }
  .ignition{ display:none }
  body.is-booting main,
  body.is-booting .masthead,
  body.is-booting .colophon{ opacity:1; transform:none }
  body.is-booting{ overflow:auto }
  .plate:hover,.btn:hover{ transform:none }

  /* Static equivalents, not absences: the words sit where they land, the
     spine is drawn in full, and each specimen shows its finished diagram. */
  [data-split] .w > i{ transform:none }
  .ticker-track{ animation:none }
  .spine-trunk{ stroke-dashoffset:0 !important }
  .spine-branch path{ stroke-dashoffset:0 }
  .spine-node circle{ opacity:.85; transform:none }
  .plate-demo{ opacity:1 }
  .plate.is-live .plate-art img,.plate-art img{ opacity:.28; filter:saturate(.5) }
  .demo-web .wire rect{ opacity:.6; transform:none }
  .demo-web .solid rect{ opacity:.2 }
  .demo-ai .raw span{ opacity:.1 }
  .demo-ai .parsed i{ transform:scaleX(1) }
  .demo-sys .link path{ stroke-dashoffset:0 }
  .demo-sys .node circle{ opacity:.9; transform:none }
  .demo-sys .hub{ opacity:.9; transform:rotate(45deg) }
  .pointer-light,.hero-gl{ display:none }
}
