/* ============================================================================
   KNOWING — knowing.css
   Direction: PRESS. The language of the print floor.

   Layers, in order:
     1. Fonts
     2. Tokens
     3. Base + reset
     4. Cursor
     5. Primitives (mark, wordmark, mono, rules)
     6. Reveal
     7. Sections: nav, hero, positioning, work, products, process, board, footer
     8. Reduced motion
   ============================================================================ */

/* ---------------------------------------------------------------- 1. FONTS */
/* Self-hosted latin subsets. No third-party request, no font flash. */
@font-face{
  font-family:'Archivo';
  font-style:normal;
  font-weight:400 600;
  font-stretch:100%;
  font-display:swap;
  src:url('../fonts/archivo-latin-var.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
    U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'Martian Mono';
  font-style:normal;
  font-weight:300 500;
  font-stretch:100%;
  font-display:swap;
  src:url('../fonts/martianmono-latin-var.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
    U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

/* --------------------------------------------------------------- 2. TOKENS */
:root{
  /* Surface */
  --ink:        #0B0D0E;
  --ink-raised: #121517;
  --ink-sunken: #070809;

  /* Text. Contrast against --ink is noted; AA body text needs 4.5:1.
     --grey is BELOW that and is for rules and decoration, never body copy. */
  --paper:      #EDEDEA;   /* 17.6:1 */
  --grey-2:     #8A9296;   /*  6.2:1  — secondary text */
  --grey:       #6E7679;   /*  4.2:1  — decorative / large only */
  --grey-dim:   #454B4E;   /*  1.9:1  — marks and hairlines only */

  /* TWO BLUES, TWO JOBS — they must not compete.
     Cyan is ATTENTION: focus rings, hovers, numbers, anything that must be seen.
     Signal is ATMOSPHERE: washes, tints, surfaces, selection, depth.
     Signal is 2.9:1 on ink and therefore NEVER carries text. */
  --cyan:        #0090C6;  /*  5.4:1 — safe for text */
  --signal:      #35617A;  /*  2.9:1 — surfaces only */
  --signal-deep: #274C61;
  --signal-pale: #D6E1E7;

  --signal-wash: rgba(53,97,122,.10);
  --signal-tint: rgba(53,97,122,.16);
  --signal-line: rgba(53,97,122,.34);

  --line:       rgba(237,237,234,.13);
  --line-soft:  rgba(237,237,234,.07);
  --line-strong:rgba(237,237,234,.26);

  /* Status — desaturated, for the Board panel */
  --moss:       #6E8A76;
  --ochre:      #A98F52;

  /* Type */
  --font-core:  'Archivo',system-ui,-apple-system,sans-serif;
  --font-mono:  'Martian Mono',ui-monospace,SFMono-Regular,monospace;

  --size-xl:    clamp(46px,10.6vw,124px);
  --size-l:     clamp(30px,5.4vw,62px);
  --size-m:     clamp(25px,3.2vw,42px);
  --size-head:  clamp(21px,2.4vw,28px);
  --size-body-l:17px;
  --size-body:  15px;
  --size-small: 13px;
  --size-micro: 10px;

  --ls-xl:      -.03em;
  --ls-l:       -.028em;
  --ls-m:       -.024em;
  --ls-head:    -.018em;
  --ls-micro:   .14em;

  /* Layout */
  --page-max:   1320px;
  --margin:     clamp(20px,5vw,56px);

  /* Motion */
  --ease:       cubic-bezier(.2,.6,.2,1);
  --ease-out:   cubic-bezier(.16,1,.3,1);
  --dur-fast:   200ms;
  --dur-base:   320ms;
  --dur-slow:   600ms;
  --dur-reveal: 900ms;
  --stagger:    90ms;   /* one step of the grid cascade — legible from ~60ms, theatrical past ~150ms */

  /* Image grading defaults — overridden per data-img-key */
  --img-sat:.78; --img-con:1.06; --img-bri:.92;
  --img-grain:.10; --img-vig:.30;
  --img-wash:var(--signal-wash);   /* harbour blue sits in every shadow */
  --img-floor:#0A0C0D;

  --grain:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* Grading keys.
   low   — box shots already sitting on dark grounds
   macro — tight texture: foil, deboss, paper grain
   high  — shots on PALE grounds; pulled down so they don't blow out on ink */
[data-img-key="low"]  {--img-sat:.78;--img-con:1.06;--img-bri:.92;--img-grain:.10;--img-vig:.30}
[data-img-key="macro"]{--img-sat:.70;--img-con:1.10;--img-bri:.88;--img-grain:.13;--img-vig:.36}
[data-img-key="high"] {--img-sat:.76;--img-con:1.04;--img-bri:.84;--img-grain:.08;--img-vig:.34}

/* ----------------------------------------------------------- 3. BASE/RESET */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
body{
  margin:0;
  background:var(--ink);
  color:var(--paper);
  font-family:var(--font-core);
  font-weight:400;
  font-size:var(--size-body);
  line-height:1.62;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  overflow-x:hidden;
}
img{display:block;max-width:100%;height:auto}
a{color:inherit;text-decoration:none}
h1,h2,h3,h4,p,dl,dd,figure{margin:0}
ul{list-style:none;margin:0;padding:0}
button{font:inherit;color:inherit;background:none;border:0;padding:0}

:focus-visible{outline:2px solid var(--cyan);outline-offset:3px}
::selection{background:var(--signal);color:var(--paper)}

.skip{
  position:absolute;left:-9999px;top:0;z-index:100;
  background:var(--paper);color:var(--ink);padding:12px 18px;
  font-family:var(--font-mono);font-size:var(--size-micro);letter-spacing:var(--ls-micro);
  text-transform:uppercase;
}
.skip:focus{left:8px;top:8px}

/* Faint press grid, page-wide, ruled in signal rather than neutral grey —
   the blue reads as a plate guide. Masked so it fades out down the page. */
body::before{
  content:"";position:fixed;inset:0;pointer-events:none;z-index:0;
  background-image:
    linear-gradient(to right,rgba(53,97,122,.16) 1px,transparent 1px),
    linear-gradient(to bottom,rgba(53,97,122,.16) 1px,transparent 1px);
  background-size:96px 96px;
  -webkit-mask-image:radial-gradient(140% 100% at 50% 0%,#000 26%,transparent 74%);
  mask-image:radial-gradient(140% 100% at 50% 0%,#000 26%,transparent 74%);
}
.wrap{position:relative;z-index:1}

/* --------------------------------------------------------------- 4. CURSOR */
/* Default system cursor. A custom registration-mark cursor was built and
   removed — it read as a crosshair and fought the page. Nothing to see here. */

/* ----------------------------------------------------------- 5. PRIMITIVES */
.mono{
  font-family:var(--font-mono);font-weight:400;font-size:var(--size-micro);
  letter-spacing:var(--ls-micro);text-transform:uppercase;color:var(--grey-2);
}
.mono--dim{color:var(--grey)}
.mono--cyan{color:var(--cyan)}

/* Registration mark. Circle r=42 (spans 18–102), cross 10→110: the arms
   overhang by 8 units, ~9% of the diameter.
   stroke-width is in viewBox units and therefore SCALES with the rendered
   size — smaller marks need a larger number to hold a ~1.2–1.5px stroke. */
.mark{display:block;flex:none;overflow:visible}
.mark circle,.mark path{fill:none;stroke:currentColor}

.wm{
  font-family:var(--font-core);font-weight:600;
  text-transform:uppercase;letter-spacing:var(--ls-m);line-height:.9;
}

.rule{height:1px;background:var(--line);border:0;margin:0}

.shell{max-width:var(--page-max);margin:0 auto;padding-inline:var(--margin)}

/* Section head — numbered and ruled, like a job sheet */
.shead{
  position:relative;
  display:flex;align-items:baseline;gap:18px;flex-wrap:wrap;
  padding:0 var(--margin) 22px;
  border-bottom:1px solid var(--line);
}
/* The rule under a section head is ruled rather than simply present — animating
   furniture that was already there rather than adding decoration.
   scaleX only, so the box stays 1px tall and pixel-crisp at rest; the only
   softness is the leading edge while it draws, which is the point.
   bottom:-1px lands it exactly on the (now transparent) border, so there is no
   1px difference between the .js and no-JS paths.
   Deliberately NOT extended to any other hairline — drawing every rule turns a
   print floor into a light show. */
.js .shead{border-bottom-color:transparent}
.js .shead::after{
  content:"";position:absolute;left:0;right:0;bottom:-1px;height:1px;
  background:var(--line);
  transform:scaleX(0);transform-origin:left center;
  transition:transform var(--dur-slow) var(--ease-out) 120ms;
}
.js .shead.is-in::after{transform:scaleX(1)}
.shead h2{font-family:var(--font-mono);font-size:var(--size-small);font-weight:500;
  letter-spacing:.13em;text-transform:uppercase}
.shead .count{margin-left:auto}

/* --------------------------------------------------------------- 6. REVEAL */
/* Hidden state applies only under .js, which an inline head script sets, so a
   failed script leaves a fully readable page rather than a blank one. */
/* --i is written by knowing.js — the element's position within the batch that
   crossed the threshold together, NOT a running count down the page.
   --lead is the delay that buys, and because custom properties inherit,
   anything nested inside a revealing block sequences off the same clock
   (see the docket cascade). */
.js [data-reveal]{
  --lead:calc(var(--i,0) * var(--stagger));
  opacity:0;transform:translateY(12px);
  transition:opacity var(--dur-reveal) var(--ease),transform var(--dur-reveal) var(--ease);
  transition-delay:var(--lead);   /* must stay AFTER the shorthand, which resets delay to 0 */
}
.js [data-reveal].is-in{opacity:1;transform:none}

/* ------------------------------------------------------------------ 7. NAV */
.nav{
  position:sticky;top:0;z-index:30;
  display:flex;align-items:center;justify-content:space-between;gap:24px;
  padding:16px var(--margin);
  border-bottom:1px solid var(--line);
  background:rgba(11,13,14,.82);
  backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
}
.nav__lockup{display:flex;align-items:center;gap:9px}
.nav__lockup .mark{width:19px;height:19px;color:var(--paper)}
.nav__lockup .wm{font-size:19px;letter-spacing:var(--ls-head)}
.nav__links{display:flex;gap:clamp(14px,3vw,34px)}
.nav__links a{
  font-family:var(--font-mono);font-size:var(--size-micro);letter-spacing:.13em;
  text-transform:uppercase;color:var(--grey-2);
  padding-bottom:3px;border-bottom:1px solid transparent;
  transition:color var(--dur-fast) var(--ease),border-color var(--dur-fast) var(--ease);
}
.nav__links a:hover{color:var(--paper);border-bottom-color:var(--cyan)}

.nav__toggle{display:none;align-items:center;gap:8px;
  font-family:var(--font-mono);font-size:var(--size-micro);letter-spacing:.13em;
  text-transform:uppercase;color:var(--grey-2)}
.nav__toggle .bars{display:grid;gap:3px;width:16px}
.nav__toggle .bars i{height:1px;background:currentColor;display:block}

@media (max-width:760px){
  .nav__toggle{display:flex}
  .nav__links{
    position:absolute;left:0;right:0;top:100%;
    flex-direction:column;gap:0;
    background:var(--ink-raised);border-bottom:1px solid var(--line);
    max-height:0;overflow:hidden;
    transition:max-height var(--dur-base) var(--ease);
  }
  .nav__links a{padding:15px var(--margin);border-bottom:1px solid var(--line-soft)}
  .nav[data-open="true"] .nav__links{max-height:60vh}
}

/* ----------------------------------------------------------------- 7. HERO */
.hero{
  position:relative;
  min-height:clamp(560px,88vh,940px);
  display:grid;place-items:center;
  padding:80px var(--margin);
}
.crop{position:absolute;width:26px;height:26px;color:var(--grey-dim)}
.crop::before,.crop::after{content:"";position:absolute;background:currentColor}
.crop::before{width:1px;height:100%}
.crop::after{height:1px;width:100%}
.crop--tl{top:22px;left:22px}
.crop--tr{top:22px;right:22px}   .crop--tr::before{right:0} .crop--tr::after{right:0}
.crop--bl{bottom:22px;left:22px} .crop--bl::before{bottom:0} .crop--bl::after{bottom:0}
.crop--br{bottom:22px;right:22px}
.crop--br::before{right:0;bottom:0} .crop--br::after{right:0;bottom:0}
@media (max-width:640px){
  .crop{width:16px;height:16px}
  .crop--tl,.crop--tr{top:12px} .crop--bl,.crop--br{bottom:12px}
  .crop--tl,.crop--bl{left:12px} .crop--tr,.crop--br{right:12px}
}

.hero__lockup{
  display:flex;flex-direction:column;align-items:center;gap:26px;
  animation:rise 1100ms var(--ease) both;
}
.hero__lockup .mark{width:clamp(46px,6.5vw,74px);height:clamp(46px,6.5vw,74px);color:var(--paper)}
.hero__lockup .wm{font-size:var(--size-xl);letter-spacing:var(--ls-xl)}

@keyframes rise{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}

.hero__strip{
  position:absolute;left:var(--margin);bottom:34px;
  display:flex;align-items:center;gap:14px;
  animation:rise 1100ms 400ms var(--ease) both;
}
.bars{display:flex;gap:2px}
.bars i{width:19px;height:9px;display:block}
.hero__meta{position:absolute;right:var(--margin);bottom:34px;
  animation:rise 1100ms 400ms var(--ease) both}
@media (max-width:760px){
  .hero__strip,.hero__meta{position:static;margin-top:32px;justify-content:center;text-align:center}
  .hero__strip{justify-content:center}
}

/* ---------------------------------------------------------- 7. POSITIONING */
.position{
  padding:clamp(80px,14vh,160px) var(--margin);
  border-top:1px solid var(--line);
  text-align:center;
}
.position p{margin:0 auto;max-width:19ch;font-size:var(--size-l);
  letter-spacing:var(--ls-l);line-height:1.08}

/* ----------------------------------------------------------------- 7. WORK */
.work{padding-top:clamp(64px,10vh,110px)}

/* Two-up contact sheet. Same gap:1px-on-a-line-background trick as
   .product-grid, so Work reads as its sibling.
   minmax(440px,1fr) gives two ~603px columns at 1440 and collapses to one at
   ~881px with no media query.
   align-items:stretch is LOAD-BEARING, not cosmetic: paired cards must share a
   row height so they cross the observer threshold on the same frame. If they
   don't, the stagger in knowing.js silently stops working. */
/* Sits inside .shell, which supplies the container and the page margin. The
   grid must NOT carry its own padding — its background paints the hairline
   gutters, so padding would flood the margin strip with --line.
   The Work head is contained to match; leave the other sections' heads
   full-bleed, since their grids are full-bleed too. */
.work .shead{max-width:var(--page-max);margin-inline:auto}
.work__grid{
  display:grid;gap:1px;background:var(--line);
  /* 440 is load-bearing: inside the 1208px content box, 3x440 (1320) does not
     fit, so auto-fit settles on two ~604px columns. Drop it to 400 and three
     fit — which shrinks the plates too far and, per the motion design, makes
     the docket cascade untenable. Collapses to one column below ~993px. */
  /* min(440px,100%) is required, not decorative: a bare minmax(440px,1fr)
     can never shrink below 440px, so at a 390px viewport the single column
     overflows the page by 70px. The min() clamps the floor to the container
     when the container is the smaller of the two. */
  grid-template-columns:repeat(auto-fit,minmax(min(440px,100%),1fr));
  align-items:stretch;
  border-block:1px solid var(--line);
}
/* Tablet portrait. Left to auto-fit, the grid stays single-column until ~993px,
   which puts the page back over 7,000px at 768 — the exact problem this
   redesign exists to solve. minmax(0,1fr) stops the min-content floor from
   blowing the columns back out. */
@media (min-width:680px) and (max-width:992px){
  .work__grid{grid-template-columns:repeat(2,minmax(0,1fr))}
}

.plate-row{background:var(--ink);display:flex;flex-direction:column}

.plate{position:relative;overflow:hidden;background:var(--img-floor)}
.plate img{
  width:100%;aspect-ratio:4/3;object-fit:cover;
  filter:saturate(var(--img-sat)) contrast(var(--img-con)) brightness(var(--img-bri));
  /* The EXIT. Slow release is the half that should be slow — this used to be
     --dur-reveal (900ms), which left the image drifting for most of a second
     after the pointer had already gone. */
  transition:transform var(--dur-slow) var(--ease);
}

/* The registration mark, briefly stamped into the corner of the sheet — which
   is what a press does. No z-index needed: <picture> is unpositioned, so paint
   order runs img → ::before (wash+vignette) → .plate__reg → ::after (grain).
   The mark therefore sits above the vignette and takes the grain: on the
   sheet, not on the screen. */
.plate__reg{
  position:absolute;top:16px;left:16px;pointer-events:none;
  color:var(--cyan);opacity:0;
  transition:opacity var(--dur-fast) var(--ease);
  filter:drop-shadow(0 1px 4px rgba(0,0,0,.55));  /* holds on the pale-ground keys */
}
.plate__reg .mark{width:16px;height:16px}

/* Gated so a touch tap can't leave the hover state stuck on. */
@media (hover:hover){
  .plate-row:hover .plate__reg{opacity:1}
  .plate-row:hover .plate img{
    transform:scale(1.02);                                 /* was 1.014 — the plate shrank */
    transition:transform var(--dur-base) var(--ease-out);  /* the ENTRANCE: fast in */
  }
}
.plate-row:focus-within .plate__reg{opacity:1}
.plate::before{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:
    radial-gradient(122% 92% at 50% 44%,transparent 54%,rgba(0,0,0,var(--img-vig)) 100%),
    var(--img-wash);
}
.plate::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  opacity:var(--img-grain);mix-blend-mode:overlay;
  background-image:var(--grain);background-size:160px 160px;
}

.spec{
  padding:clamp(22px,2.6vw,32px);
  display:flex;flex-direction:column;flex:1;
}
.spec__client{font-size:var(--size-head);font-weight:500;
  letter-spacing:var(--ls-head);line-height:1.1;margin-bottom:6px}
.spec__line{color:var(--grey-2);font-size:14px;line-height:1.55;margin-bottom:26px}
.spec dl{margin-top:auto;display:grid;grid-template-columns:auto 1fr;
  border-top:1px solid var(--line)}
.spec dt,.spec dd{
  padding:9px 0;font-size:var(--size-micro);letter-spacing:.11em;text-transform:uppercase;
  font-family:var(--font-mono);border-bottom:1px solid var(--line-soft);
}
.spec dt{color:var(--grey);padding-right:20px}
.spec dd{text-align:right;color:var(--paper);font-weight:300}

/* Docket cascade — the rows arriving in sequence, like a spec sheet coming off
   the printer. Driven entirely by the parent's .is-in: no extra observer, no
   JS, no markup. Amplitude is 2px against the card's 12px — an order of
   magnitude apart, so it reads as texture inside one gesture rather than a
   second rhythm arguing with the first.
   --lead is inherited from the card, so card B's docket starts a beat after
   card A's instead of printing in lockstep with it.
   Last row lands at --lead+740ms; the card settles at --lead+900ms. Spec
   first, picture second — the right order for a company that sells spec. */
.js [data-reveal] .spec dt,
.js [data-reveal] .spec dd{
  opacity:0;transform:translateY(2px);
  transition:opacity var(--dur-base) var(--ease-out),
             transform var(--dur-base) var(--ease-out);
}
.js [data-reveal].is-in .spec dt,
.js [data-reveal].is-in .spec dd{opacity:1;transform:none}

/* dt and dd are different element types, so nth-of-type pairs them into rows.
   Covers both the 4-row and 5-row dockets with no per-project markup. */
.js .spec dt:nth-of-type(1),.js .spec dd:nth-of-type(1){transition-delay:calc(var(--lead,0ms) + 200ms)}
.js .spec dt:nth-of-type(2),.js .spec dd:nth-of-type(2){transition-delay:calc(var(--lead,0ms) + 255ms)}
.js .spec dt:nth-of-type(3),.js .spec dd:nth-of-type(3){transition-delay:calc(var(--lead,0ms) + 310ms)}
.js .spec dt:nth-of-type(4),.js .spec dd:nth-of-type(4){transition-delay:calc(var(--lead,0ms) + 365ms)}
.js .spec dt:nth-of-type(5),.js .spec dd:nth-of-type(5){transition-delay:calc(var(--lead,0ms) + 420ms)}

/* ------------------------------------------------------------- 7. PRODUCTS */
/* Hidden at launch via [data-products="off"] on <html>. See index.html. */
[data-products="off"] #products,
[data-products="off"] [data-nav="products"]{display:none}

.products{padding-top:clamp(64px,10vh,110px)}
.product-grid{
  display:grid;gap:1px;background:var(--line);
  grid-template-columns:repeat(auto-fit,minmax(270px,1fr));
  border-bottom:1px solid var(--line);
}
.card{background:var(--ink);padding:0 0 clamp(22px,3vw,30px);display:flex;flex-direction:column}
.card__shot{position:relative;overflow:hidden;background:var(--img-floor);margin-bottom:22px}
.card__shot img{width:100%;aspect-ratio:4/3;object-fit:cover;
  filter:saturate(var(--img-sat)) contrast(var(--img-con)) brightness(var(--img-bri))}
.card__shot::after{content:"";position:absolute;inset:0;pointer-events:none;
  opacity:var(--img-grain);mix-blend-mode:overlay;
  background-image:var(--grain);background-size:160px 160px}

/* Held slot — for the two SKUs with no photography yet. Honest, not a stand-in.
   Same box metrics as .card__shot so names stay on one line across the row. */
.card__held{
  aspect-ratio:4/3;display:grid;place-items:center;gap:12px;margin-bottom:22px;
  background:linear-gradient(180deg,var(--signal-wash),transparent 70%),var(--ink-raised);
}
.card__held .mark{width:28px;height:28px;color:var(--signal)}

.card__body{padding-inline:clamp(20px,2.6vw,28px);display:flex;flex-direction:column;flex:1}
/* Card scale, not section-head scale — five across leaves ~230px of measure. */
.card__name{font-size:clamp(18px,1.5vw,22px);font-weight:500;letter-spacing:var(--ls-head);
  line-height:1.16;margin-bottom:8px}
.card__spec{color:var(--grey-2);font-size:14px;line-height:1.55;margin-bottom:24px}
.card__foot{margin-top:auto;display:flex;align-items:flex-end;justify-content:space-between;
  gap:16px;border-top:1px solid var(--line);padding-top:16px}
.card__price{font-family:var(--font-mono);font-size:var(--size-body-l);font-weight:400;
  letter-spacing:.02em}
.card__price small{display:block;font-size:var(--size-micro);letter-spacing:var(--ls-micro);
  text-transform:uppercase;color:var(--grey);margin-top:5px}
.card__cta{font-family:var(--font-mono);font-size:var(--size-micro);letter-spacing:.13em;
  text-transform:uppercase;border-bottom:1px solid var(--line);padding-bottom:3px;
  transition:color var(--dur-fast) var(--ease),border-color var(--dur-fast) var(--ease)}
.card__cta:hover{color:var(--paper);border-bottom-color:var(--cyan)}

/* -------------------------------------------------------------- 7. PROCESS */
.process{padding-top:clamp(64px,10vh,110px)}
.steps{
  display:grid;gap:1px;background:var(--line);
  grid-template-columns:repeat(auto-fit,minmax(230px,1fr));
  border-bottom:1px solid var(--line);
}
.step{background:var(--ink);padding:clamp(30px,4.4vw,56px) clamp(22px,2.8vw,34px)}
.step__no{display:block;color:var(--cyan);margin-bottom:clamp(26px,5vh,52px)}
.step__name{font-size:var(--size-m);font-weight:500;letter-spacing:var(--ls-m);
  line-height:1.06;margin-bottom:10px}
.step__note{color:var(--grey-2);font-size:14px;line-height:1.55}

/* ------------------------------------------------------------ 7. THE BOARD */
.board{padding-top:clamp(64px,10vh,110px)}
.board__inner{
  display:grid;gap:clamp(34px,5vw,64px);
  grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr);
  align-items:center;
  padding:clamp(48px,8vh,96px) var(--margin);
  border-bottom:1px solid var(--line);
}
@media (max-width:900px){.board__inner{grid-template-columns:1fr}}
.board__title{font-size:var(--size-l);letter-spacing:var(--ls-l);line-height:1.06;margin-bottom:22px}
.board__copy{color:var(--grey-2);font-size:var(--size-body-l);line-height:1.62;max-width:44ch;
  margin-bottom:32px}
.board__cta{
  display:inline-flex;align-items:center;gap:10px;
  font-family:var(--font-mono);font-size:var(--size-micro);letter-spacing:.13em;
  text-transform:uppercase;padding:13px 20px;border:1px solid var(--line-strong);
  transition:border-color var(--dur-fast) var(--ease),background var(--dur-fast) var(--ease);
}
.board__cta:hover{border-color:var(--signal-line);background:var(--signal-tint)}

/* An abstract representation of the portal, not a screenshot.
   A real Forge capture replaces this when there is one worth showing.
   The panel is the one surface where signal carries a whole plane — it reads
   as a lit workspace rather than another slab of ink. */
.panel{
  background:linear-gradient(180deg,var(--signal-tint),transparent 46%),var(--ink-raised);
  border:1px solid var(--signal-line);overflow:hidden;
}
.panel__bar{display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:13px 18px;border-bottom:1px solid var(--signal-line)}
.panel__dot{width:6px;height:6px;border-radius:50%;background:var(--cyan);flex:none}
.panel table{width:100%;border-collapse:collapse;font-family:var(--font-mono);font-size:10px;
  letter-spacing:.07em}
.panel th{
  text-align:left;padding:11px 18px;color:var(--grey);font-weight:400;
  text-transform:uppercase;letter-spacing:var(--ls-micro);
  border-bottom:1px solid var(--line);
}
.panel td{padding:13px 18px;border-bottom:1px solid var(--line-soft);color:var(--grey-2)}
.panel tr:last-child td{border-bottom:0}
.panel td:first-child{color:var(--paper)}
.panel td:last-child,.panel th:last-child{text-align:right}
.pill{display:inline-block;padding:3px 9px;border:1px solid currentColor;
  font-size:9px;letter-spacing:.1em;text-transform:uppercase}
.pill--run{color:var(--moss)}
.pill--hold{color:var(--ochre)}
.pill--proof{color:var(--cyan)}
@media (max-width:520px){
  .panel th:nth-child(2),.panel td:nth-child(2){display:none}
}

/* --------------------------------------------------------------- 7. FOOTER */
.foot{
  display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;gap:26px;
  padding:clamp(56px,9vh,110px) var(--margin) 42px;
}
.foot__mail{
  display:inline-block;font-size:var(--size-m);letter-spacing:var(--ls-m);
  border-bottom:1px solid var(--line);padding-bottom:5px;
  transition:border-color var(--dur-base) var(--ease);
}
.foot__mail:hover{border-bottom-color:var(--cyan)}
.foot__right{display:flex;align-items:center;gap:14px}
.foot__right .mark{width:22px;height:22px;color:var(--grey-dim)}

/* ------------------------------------------------------- 8. REDUCED MOTION */
/* Durations AND delays. Resetting duration alone is not enough: an animation
   with `both` fill and a surviving delay stays at opacity:0 for the delay and
   then blinks in — worse than the motion it was meant to suppress. That was
   live on .hero__strip / .hero__meta (animation: rise 1100ms 400ms ... both). */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{
    animation-duration:1ms!important;
    animation-iteration-count:1!important;
    animation-delay:0s!important;
    transition-duration:1ms!important;
    transition-delay:0s!important;
  }
}
