/* ============================================================
   Distinctive Media — homepage, presentation rhythm
   Layers OVER css/home.css. Scoped to body.deck so the eight
   other pages that share home.css are unaffected.

   Borrowed structure from the client-deck system:
   one idea per band, display type vs tiny wide labels with
   nothing in between, and a built mockup per trade instead of
   a stock screenshot.

   House rules enforced in this file (DESIGN.md):
   · no radii, no shadows — depth is hairlines, panel fills
     and a 3px accent edge (top for stat strips, left for data
     panels)
   · every font-size resolves to the ramp in css/home.css
   · every margin/padding sits on the --s-* step scale below
   · label tracking stays inside the 0.05–0.14em band
   ============================================================ */

body.deck{
  /* --- spacing step scale. nothing in this file is off-scale --- */
  --s-1:4px;  --s-2:8px;   --s-3:12px; --s-4:16px; --s-5:24px;
  --s-6:32px; --s-7:48px;  --s-8:64px; --s-9:96px; --s-10:128px; --s-11:192px;

  /* --- rhythm derived from the scale --- */
  --pad-y:    clamp(var(--s-9), 10vw, var(--s-10)); /* band top/bottom  96→128 */
  --gap-block:clamp(var(--s-7),  5vw, var(--s-8));  /* head → component 48→64  */
  --gap-sub:  var(--s-6);                           /* inside a column  32     */
  --gutter:   clamp(var(--s-6),  4vw, var(--s-8));  /* split gutter     32→64  */

  /* --- label tracking band (DESIGN.md: 0.05–0.14em) --- */
  --tr-label:0.14em;
  --tr-spec:0.1em;

  /* --- one lit-panel fill, reused rather than redrawn --- */
  --lit:linear-gradient(160deg, oklch(0.79 0.128 208 / 0.12), oklch(0.79 0.128 208 / 0.02));

  --sim-paper:#EDE9E1;
  --sim-paper-line:#C9C3B6;
  --sim-ink:#1A1F27;
  --warn: oklch(0.72 0.13 25);
  --ok: oklch(0.78 0.15 155);
}

/* ---------- scroll progress ----------
   The rail and .site-head (css/home.css) are both fixed/sticky at top:0.
   On the same --z-sticky value the header wins purely on DOM order — the
   rail markup precedes <header> — so an 80px translucent blurred bar was
   painting over a 3px rail. One step ABOVE the header, derived from the
   same token so the two can never drift apart: the rail is a 3px hairline
   at the very top edge and is the only thing it covers. It still sits
   under .nav-drop-menu (z-index 60 in css/home.css), which is the one
   deck element that legitimately overlaps the top of the page. */
.dk-progress{
  position:fixed;top:0;left:0;height:3px;width:100%;
  background:var(--miami);transform:scaleX(0);transform-origin:0 50%;
  z-index:calc(var(--z-sticky) + 1);pointer-events:none;
}

/* ---------- section shell ---------- */
.dk{position:relative;padding:var(--pad-y) 0;border-top:1px solid var(--line)}
.dk:first-of-type{border-top:0}
/* css/home.css also declares .faq{padding:clamp(70px,9vw,120px) 0} at (0,1,0),
   which ties with .dk on <section class="dk faq"> and resolves only by link
   order. Win it here on specificity so the band rhythm is deterministic. */
.dk.faq{padding:var(--pad-y) 0}

/* DESIGN.md: "Section grounds use a single large radial wash rather than a
   flat fill." Bands that carry no explicit wash class still get one, so no
   band ever sits on the flat body ground. This one DEEPENS rather than
   raises: .dk-alt already owns the raised read, and a panel-toned wash here
   would drop --faint from 5.35:1 to 5.14:1 on the bands that carry
   .dk-eyebrow and .vh. Going darker moves contrast the right way. */
.dk:not(.dk-alt):not(.dk-wash-cy):not(.dk-wash-hi){
  background:radial-gradient(1200px 700px at 50% -10%, oklch(0.11 0.02 265 / 0.80), transparent 64%);
}

/* every raised ground is one large radial wash, never a flat fill */
.dk-alt,
body.deck .contact{
  background:
    radial-gradient(1200px 720px at 50% -14%, oklch(0.20 0.03 265 / 0.85), transparent 66%),
    var(--night-2);
}
.dk-wash-cy::before,.dk-wash-hi::before{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(1100px 640px at var(--wash-x) var(--wash-y), var(--wash-c), transparent 62%);
}
.dk-wash-cy{--wash-x:12%;--wash-y:104%;--wash-c:var(--miami-wash)}
.dk-wash-hi{--wash-x:84%;--wash-y:-8%;--wash-c:oklch(0.79 0.128 208 / 0.09)}
.dk > .wrap{position:relative}

/* ---------- band prose classes: one class, one rendering ----------
   These three are `<p class="dk-lede rv">` etc., and two element-qualified
   descendant rules used to outrank them at (0,1,1) and repaint them per
   band: `.dk-body p` further down this file, and `.about-body > p`
   (css/home.css:552, 58ch). A bare class is (0,1,0) and lost to both, so
   .dk-note rendered --faint/52ch in #why but --dim/60ch in the three plate
   bands, .dk-lede resolved to three different measures (56ch / 60ch /
   58ch), and .dk-eyebrow's `color:var(--faint)` never applied anywhere.
   Scoping to body.deck lifts them to (0,2,1), which beats both without a
   tie — and this whole file is already body.deck-scoped, so it costs
   nothing. Do not demote these back to a bare class. */

/* register index: numeral in cyan, label quiet. the headline is the
   loud thing on a band, not the label above it.
   max-width:none is load-bearing: a one-line flex label has no measure, and
   .dk-lede / .dk-note each declare their own cap while this one declared
   none — so inside .dk-body it silently inherited the 60ch prose cap and
   rendered a different width than the same label one band up. Declaring the
   absence keeps it identical in every band. */
body.deck .dk-eyebrow{
  display:flex;align-items:baseline;gap:var(--s-3);max-width:none;
  font-family:var(--mono);font-weight:700;font-size:var(--m-label);
  letter-spacing:var(--tr-label);text-transform:uppercase;color:var(--faint);
  margin-bottom:var(--s-5);
}
body.deck .dk-eyebrow i{font-style:normal;font-variant-numeric:tabular-nums;color:var(--miami)}
/* no rule before or after the eyebrow: the label carries it alone */

/* section headline is --t-h1. the hero keeps --t-hero to itself. */
.dk-h{
  font-size:var(--t-h1);line-height:1.02;letter-spacing:-0.03em;
  font-family:var(--disp);font-weight:800;font-stretch:100%;text-wrap:balance;
}
body.deck .dk-lede{font-size:var(--t-lede);color:var(--dim);max-width:56ch;margin-top:var(--s-5);text-wrap:pretty}
/* (0,2,2) so it clears `.dk-body p strong` (0,1,2) as well */
body.deck .dk-lede strong{color:var(--ink);font-weight:600}
body.deck .dk-note{margin-top:var(--s-5);font-size:var(--t-body);color:var(--faint);max-width:52ch;text-wrap:pretty}

/* asymmetric split beats a 50/50 — and the prose keeps the wide side
   whichever way the band is flipped */
.dk-split{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,0.85fr);gap:var(--gutter);align-items:center}
.dk-split.flip{grid-template-columns:minmax(0,0.85fr) minmax(0,1.15fr)}
.dk-split.flip .dk-visual{order:-1}
.dk-visual{min-width:0}
.dk-body p + p{margin-top:var(--s-4)}
/* unclassed running prose only — .dk-lede / .dk-note / .dk-eyebrow are
   lifted above this at (0,2,1) further up the file, on purpose */
.dk-body p{color:var(--dim);max-width:60ch;text-wrap:pretty}
.dk-body p b,.dk-body p strong{color:var(--ink);font-weight:600}
.dk-wh{
  font-family:var(--mono);font-weight:700;font-size:var(--m-spec);
  letter-spacing:var(--tr-spec);text-transform:uppercase;color:var(--ink);
  margin:var(--s-6) 0 var(--s-3);
}

/* ---------- hero ----------
   Not here. The hero is owned end to end by css/home.css (.hero-reg), which
   also carries its own responsive steps and its reduced-motion path. This
   file used to re-style it as `body.deck .hero*`; every one of those rules
   was overridden and contributed nothing to the computed style, so they are
   gone. Do not reintroduce a `body.deck .hero…` rule here — home.css is the
   single owner, and a deck rule would only start a specificity fight again.
--------------------------------------------------------------------------- */

/* ---------- stat strip ----------
   one hairline-divided strip under a single cyan rail, not four
   repeated cards. this is the only grid on the site that reads
   as instrumentation. */
.dk-slabs{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(min(200px,100%),1fr));
  gap:1px;margin-top:var(--gap-block);
  background:var(--line);border:1px solid var(--line);border-top:3px solid var(--miami);
}
.dk-slab{background:var(--panel);padding:var(--s-6) var(--s-5) var(--s-5)}
.dk-slab .n{
  font-family:var(--disp);font-weight:800;font-size:var(--t-stat);
  letter-spacing:-0.03em;line-height:1;font-variant-numeric:tabular-nums;
}
/* unit suffix on a figure. --t-h4 keeps it on the prose ramp instead of the
   old 0.5em, which drifted from 14px to 20px across the --t-stat clamp. */
.dk-slab .n small{font-size:var(--t-h4);color:var(--miami);letter-spacing:0}
.dk-slab .l{margin-top:var(--s-3);font-size:var(--t-body);color:var(--dim);text-wrap:pretty}

/* ---------- versus ----------
   two cells, deliberately unequal: the argument gets the wide side. The
   narrow cell was starving its own prose (38.5ch at 1440), so the split is
   softened and the cell padding capped a step lower to buy measure back. */
.dk-versus{
  display:grid;grid-template-columns:minmax(0,0.95fr) minmax(0,1.05fr);
  gap:1px;margin-top:var(--gap-block);background:var(--line);
}
.dk-vcell{background:var(--night);padding:clamp(var(--s-5),3.2vw,var(--s-6)) var(--s-5);border-top:3px solid transparent}
.dk-vcell .vh{
  font-family:var(--mono);font-weight:700;font-size:var(--m-label);
  letter-spacing:var(--tr-label);text-transform:uppercase;color:var(--faint);margin-bottom:var(--s-4);
}
/* --t-stat, not --t-page: no figure outranks the headline of its own band */
.dk-vcell .vn{
  font-family:var(--disp);font-weight:800;font-size:var(--t-stat);font-stretch:100%;
  line-height:1;letter-spacing:-0.03em;font-variant-numeric:tabular-nums;
}
.dk-vcell .vs{margin-top:var(--s-3);color:var(--dim);font-size:var(--t-body);max-width:52ch;text-wrap:pretty}
/* stat comparison → cyan TOP edge */
.dk-vcell.win{background:var(--lit);border-top-color:var(--miami)}
.dk-vcell.win .vh,.dk-vcell.win .vn{color:var(--miami)}

/* ---------- numbered step rail ---------- */
.dk-rail{margin-top:var(--gap-block);display:grid;gap:var(--s-3)}
.dk-step{
  display:grid;grid-template-columns:var(--s-8) minmax(0,1fr);gap:var(--s-6);align-items:start;
  background:var(--panel);border:1px solid var(--line);padding:var(--s-6);
  position:relative;overflow:hidden;
}
.dk-step::after{
  content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--miami);
  transform:scaleY(0);transform-origin:top;transition:transform .5s var(--ease);
}
.dk-step.lit::after{transform:scaleY(1)}
.dk-step .sn{
  font-family:var(--disp);font-weight:800;font-size:var(--t-stat);line-height:1;
  letter-spacing:-0.03em;color:var(--ink);font-variant-numeric:tabular-nums;
}
.dk-step h3{font-size:var(--t-h4);margin-bottom:var(--s-2);text-wrap:balance}
.dk-step p{color:var(--dim);font-size:var(--t-body);max-width:64ch;text-wrap:pretty}
.dk-step p b{color:var(--ink);font-weight:600}

/* ============================================================
   SIMULATION KIT
   Each trade gets a built mockup, not a screenshot. Same shell,
   different instrument: camera back, press proof, browser.
   Drawn UI inside a device may scale its BOXES down, but never its type:
   live copy inside a mockup is still copy, so every string in here sets
   --m-label or --m-spec. There is no third label size. (The old
   --sim-micro resolved to 9.73px and carried real words.)
   ============================================================ */
.sim{position:relative}
.sim-label{
  font-family:var(--mono);font-weight:700;font-size:var(--m-label);
  letter-spacing:var(--tr-spec);text-transform:uppercase;color:var(--faint);
  margin-bottom:var(--s-3);display:flex;align-items:center;gap:var(--s-2);
}
/* 3px accent edge, not a dot with a glow */
.sim-label::before{content:"";width:3px;height:var(--s-3);background:var(--miami);flex:none}

/* ---- A · camera back ---- */
.dev-cam{
  background:oklch(0.11 0.015 265);border:1px solid var(--line);
  padding:var(--s-3);max-width:min(520px,100%);margin-inline:auto;
}
.cam-bar{
  display:flex;justify-content:space-between;align-items:center;gap:var(--s-3);flex-wrap:wrap;
  font-family:var(--mono);font-weight:700;font-size:var(--m-label);letter-spacing:0.05em;
  color:var(--dim);padding:0 var(--s-1) var(--s-2);font-variant-numeric:tabular-nums;
}
.cam-bar .rec{display:inline-flex;align-items:center;gap:var(--s-2);color:var(--warn)}
.cam-bar .rec::before{content:"";width:8px;height:8px;background:var(--warn)}
.cam-lcd{position:relative;aspect-ratio:3/2;overflow:hidden;background:var(--night-2)}
.cam-lcd img{width:100%;height:100%;object-fit:cover}
.cam-grid{position:absolute;inset:0;pointer-events:none;
  background:
    linear-gradient(to right, transparent 33.2%, oklch(1 0 0 / 0.16) 33.2% 33.4%, transparent 33.4%, transparent 66.5%, oklch(1 0 0 / 0.16) 66.5% 66.7%, transparent 66.7%),
    linear-gradient(to bottom, transparent 33.2%, oklch(1 0 0 / 0.16) 33.2% 33.4%, transparent 33.4%, transparent 66.5%, oklch(1 0 0 / 0.16) 66.5% 66.7%, transparent 66.7%);
}
/* four corner brackets, drawn as gradients so nothing overlaps the frame */
.cam-af{
  position:absolute;width:24%;aspect-ratio:1;left:37%;top:33%;
  --b:1.6px; --len:34%;
  background:
    linear-gradient(var(--miami),var(--miami)) 0 0 / var(--len) var(--b) no-repeat,
    linear-gradient(var(--miami),var(--miami)) 0 0 / var(--b) var(--len) no-repeat,
    linear-gradient(var(--miami),var(--miami)) 100% 0 / var(--len) var(--b) no-repeat,
    linear-gradient(var(--miami),var(--miami)) 100% 0 / var(--b) var(--len) no-repeat,
    linear-gradient(var(--miami),var(--miami)) 0 100% / var(--len) var(--b) no-repeat,
    linear-gradient(var(--miami),var(--miami)) 0 100% / var(--b) var(--len) no-repeat,
    linear-gradient(var(--miami),var(--miami)) 100% 100% / var(--len) var(--b) no-repeat,
    linear-gradient(var(--miami),var(--miami)) 100% 100% / var(--b) var(--len) no-repeat;
}
/* lock reads as heavier brackets, not a halo */
.cam-af.locked{--len:44%;--b:3px}
.cam-hist{display:flex;align-items:flex-end;gap:2px;height:34px;margin-top:var(--s-2);padding:0 var(--s-1)}
.cam-hist i{flex:1;background:oklch(0.4 0.03 250);transform:scaleY(0);transform-origin:bottom;transition:transform .6s var(--ease)}
.cam-hist.on i{transform:scaleY(1)}
.cam-strip{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:var(--s-1);margin-top:var(--s-2);padding:0 var(--s-1) var(--s-1)}
.cam-strip figure{position:relative;aspect-ratio:1;overflow:hidden;background:var(--panel);border:1px solid transparent}
.cam-strip img{width:100%;height:100%;object-fit:cover;opacity:0.55}
.cam-strip .pick{border-color:var(--miami)}
.cam-strip .pick img{opacity:1}
.cam-strip .pick::after{
  content:"SELECT";position:absolute;left:0;right:0;bottom:0;
  background:var(--miami);color:var(--night-2);
  font-family:var(--mono);font-weight:700;font-size:var(--m-label);
  letter-spacing:0.05em;text-align:center;padding:2px 0;
}

/* ---- B · press proof (paper, because it is paper) ---- */
.dev-press{max-width:520px;margin-inline:auto}
.press-sheet{
  position:relative;background:var(--sim-paper);color:var(--sim-ink);
  padding:var(--s-5);
}
/* crop marks, one per corner */
.press-sheet::before,.press-sheet::after,
.press-sheet .cm1,.press-sheet .cm2{
  content:"";position:absolute;width:var(--s-4);height:var(--s-4);border:0 solid var(--sim-ink);opacity:0.55;
}
.press-sheet::before{left:var(--s-2);top:var(--s-2);border-left-width:1px;border-top-width:1px}
.press-sheet::after{right:var(--s-2);top:var(--s-2);border-right-width:1px;border-top-width:1px}
.press-sheet .cm1{left:var(--s-2);bottom:var(--s-2);border-left-width:1px;border-bottom-width:1px}
.press-sheet .cm2{right:var(--s-2);bottom:var(--s-2);border-right-width:1px;border-bottom-width:1px}
.press-art{position:relative;aspect-ratio:4/3;overflow:hidden;background:#fff}
.press-art img{width:100%;height:100%;object-fit:cover}
.press-art .bleed{
  position:absolute;inset:9px;border:1px dashed oklch(0.5 0.14 25 / 0.85);pointer-events:none;
}
.press-art .bleed span{
  position:absolute;right:3px;bottom:3px;padding:2px var(--s-1);
  background:oklch(0.5 0.14 25);color:#fff;
  font-family:var(--mono);font-weight:700;font-size:var(--m-label);letter-spacing:0.05em;
}
.press-bars{display:flex;gap:0;margin-top:var(--s-3);height:14px}
.press-bars i{flex:1}
.press-bars i:nth-child(1){background:#00AEEF}
.press-bars i:nth-child(2){background:#EC008C}
.press-bars i:nth-child(3){background:#FFF200}
.press-bars i:nth-child(4){background:#0F0F0F}
.press-bars i:nth-child(5){background:#7F7F7F}
.press-bars i:nth-child(6){background:#C4C4C4}
/* square register target + crosshairs — a mark, not a rounded corner */
.press-reg{
  position:absolute;right:var(--s-5);top:var(--s-5);width:var(--s-5);height:var(--s-5);
  border:1px solid var(--sim-ink);opacity:0.6;
}
.press-reg::before,.press-reg::after{content:"";position:absolute;background:var(--sim-ink)}
.press-reg::before{left:50%;top:-6px;bottom:-6px;width:1px;transform:translateX(-50%)}
.press-reg::after{top:50%;left:-6px;right:-6px;height:1px;transform:translateY(-50%)}
/* two mono sizes only: tracked label, then value */
.press-title{
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1px;
  margin-top:var(--s-3);background:var(--sim-paper-line);border:1px solid var(--sim-paper-line);
}
.press-title div{background:var(--sim-paper);padding:var(--s-2) var(--s-3)}
.press-title b{
  display:block;font-family:var(--mono);font-weight:700;font-size:var(--m-label);
  letter-spacing:0.05em;text-transform:uppercase;color:#6C6558;
}
.press-title span{display:block;font-family:var(--mono);font-weight:700;font-size:var(--m-spec);letter-spacing:0.05em;margin-top:var(--s-1);font-variant-numeric:tabular-nums}
.press-checks{margin-top:var(--s-4);display:grid;gap:1px;background:var(--line);border:1px solid var(--line)}
.press-checks div{
  background:var(--panel);padding:var(--s-3) var(--s-4);
  display:flex;justify-content:space-between;align-items:baseline;gap:var(--s-3);flex-wrap:wrap;
  font-size:var(--t-body);color:var(--dim);text-wrap:pretty;opacity:0;
}
.press-checks div b{font-family:var(--mono);font-weight:700;color:var(--ok);font-size:var(--m-label);letter-spacing:0.05em;white-space:nowrap}
.press-checks div.flag b{color:var(--warn)}
/* the reduced-motion and scripting:none fallbacks for .press-checks div
   live with the other reveal fallbacks at the foot of this file */

/* ---- C · browser ---- */
.dev-web{
  background:oklch(0.11 0.015 265);border:1px solid var(--line);
  max-width:560px;margin-inline:auto;
}
/* wraps rather than crushes: the viewport buttons are real 16px controls,
   so on a narrow column they drop to a second row instead of squeezing the
   URL field down to a couple of characters. They render at every width —
   the 560px branch used to `display:none` them, which deleted a keyboard-
   reachable control (js/home-deck.js binds click + aria-pressed on it) on
   exactly the phones the band is arguing about. Wrapping is the answer to
   a narrow bar; hiding is not. */
.web-chrome{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s-3);padding:var(--s-2) var(--s-3);border-bottom:1px solid var(--line)}
.web-dots{display:flex;gap:var(--s-1);flex:none}
.web-dots i{width:8px;height:8px;background:var(--line)}
.web-url{
  flex:1 1 140px;min-width:140px;background:var(--night-2);border:1px solid var(--line);
  padding:var(--s-1) var(--s-3);font-family:var(--mono);font-size:var(--m-label);color:var(--dim);
  letter-spacing:0.05em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-wrap:pretty;
}
.web-url b{color:var(--ink);font-weight:600}
.web-vp{display:flex;flex-wrap:wrap;gap:var(--s-1);flex:none}
/* real controls, not drawn chrome: DESIGN.md floors form controls at
   --t-body, so these do not shrink with the rest of the mockup. Tracking
   sits at the 0.05em end of the band to keep three buttons in the bar. */
.web-vp button{
  font:inherit;font-family:var(--mono);font-weight:700;font-size:var(--t-body);letter-spacing:0.05em;
  text-transform:uppercase;padding:var(--s-1) var(--s-2);background:transparent;color:var(--faint);
  border:1px solid var(--line);cursor:pointer;
}
.web-vp button.on{background:var(--miami);color:var(--night-2);border-color:var(--miami)}
.web-vp button:focus-visible{outline:2px solid var(--miami);outline-offset:2px}
.web-view{padding:var(--s-4);display:flex;justify-content:center;background:var(--night-2)}
.web-page{
  width:100%;max-width:100%;transition:max-width .6s var(--ease);
  background:var(--night);border:1px solid var(--line);padding:var(--s-3);
}
.web-page.w-tab{max-width:330px}
.web-page.w-phone{max-width:200px}
.wp-nav{display:flex;justify-content:space-between;align-items:center;gap:var(--s-2);margin-bottom:var(--s-2)}
.wp-nav .wp-logo{font-family:var(--disp);font-weight:800;font-size:var(--m-label);letter-spacing:-0.02em;white-space:nowrap}
.wp-nav .wp-logo em{font-style:normal;color:var(--miami)}
/* below this point the values are wireframe drawing dimensions inside a
   simulated 200–560px viewport, not page spacing — they stay off the
   page step scale on purpose */
.wp-nav .wp-menu{display:flex;gap:var(--s-2);align-items:center}
.wp-nav .wp-menu i{display:block;height:4px;width:26px;background:var(--line)}
.wp-nav .wp-menu b{display:block;height:14px;width:44px;background:var(--miami)}
.web-page.w-phone .wp-menu i{display:none}

.wp-hero{position:relative;aspect-ratio:16/8;overflow:hidden;display:flex;flex-direction:column;justify-content:flex-end;gap:6px;padding:var(--s-3)}
.wp-hero img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.wp-hero::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(75deg, oklch(0.11 0.02 265 / 0.92) 12%, oklch(0.11 0.02 265 / 0.35) 68%, transparent);
}
.wp-hero .l1,.wp-hero .l2,.wp-hero .cta{position:relative;z-index:1}
.wp-hero .l1{height:10px;width:64%;background:oklch(0.92 0.005 220)}
.wp-hero .l2{height:6px;width:44%;background:oklch(0.66 0.02 250)}
.wp-hero .cta{height:16px;width:80px;background:var(--miami);margin-top:var(--s-1)}
.web-page.w-phone .wp-hero{aspect-ratio:4/5}
.web-page.w-phone .wp-hero .l1{width:82%}

.wp-cards{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:6px;margin-top:var(--s-2)}
.wp-cards figure{aspect-ratio:4/3;overflow:hidden;background:var(--panel)}
.wp-cards img{width:100%;height:100%;object-fit:cover}
.web-page.w-phone .wp-cards{grid-template-columns:1fr 1fr}
.web-page.w-phone .wp-cards figure:last-child{display:none}
.web-perf{display:grid;gap:1px;background:var(--line);border-top:1px solid var(--line)}
.web-perf div{
  background:var(--panel);padding:var(--s-3) var(--s-4);
  display:flex;justify-content:space-between;align-items:baseline;gap:var(--s-3);flex-wrap:wrap;
  font-size:var(--t-body);color:var(--dim);text-wrap:pretty;
}
.web-perf b{font-family:var(--disp);font-weight:800;font-size:var(--t-h4);color:var(--ink);font-variant-numeric:tabular-nums}
/* unit suffix — --m-label, not 0.6em, which resolved to an off-ramp 13.2px */
.web-perf .unit{color:var(--miami);font-family:var(--mono);font-weight:700;font-size:var(--m-label);letter-spacing:0.05em}

/* ---------- gallery / who / reviews / about / faq, deck rhythm ---------- */
body.deck .masonry{
  columns:3;column-gap:var(--s-3);margin-top:var(--gap-block);
}
body.deck .masonry figure{break-inside:avoid;margin-bottom:var(--s-3);position:relative;overflow:hidden;background:var(--panel)}
body.deck .masonry img{width:100%;height:auto}
/* This selector is (0,2,2) and outranks `.masonry figcaption` (0,1,1) in
   css/home.css, so the scrim under these nine captions is decided HERE.
   It sets no opacity — the hover-gate lives in css/home.css and is owned
   there — but it does have to hold up once the caption is readable without
   a pointer. A single 0.92→transparent ramp put the TOP of the text line
   at only 0.46 effective alpha, which measured 2.04:1 against --ink over
   the brightest work photo. The scrim is now held near-solid across the
   text box and only feathers out above it: worst case 5.7:1, and no photo
   loses more than the bottom 32px. */
body.deck .masonry figcaption{
  position:absolute;left:0;right:0;bottom:0;padding:var(--s-6) var(--s-4) var(--s-3);
  background:linear-gradient(to top,
    oklch(0.11 0.02 265 / 0.92) 0,
    oklch(0.11 0.02 265 / 0.85) 50%,
    oklch(0.11 0.02 265 / 0) 100%);
  font-family:var(--mono);font-weight:700;font-size:var(--m-label);letter-spacing:0.05em;
  text-transform:uppercase;color:var(--ink);text-wrap:pretty;
}

/* who we work with: an index, not eight more cards. hairline rows,
   no vertical dividers, no fill. */
body.deck .who-wall{
  list-style:none;display:grid;
  grid-template-columns:repeat(auto-fit,minmax(min(420px,100%),1fr));
  column-gap:var(--gutter);row-gap:0;
  margin-top:var(--gap-block);border-top:1px solid var(--line);
}
body.deck .who-wall li{padding:var(--s-5) 0;border-bottom:1px solid var(--line)}
body.deck .who-wall b{
  display:block;font-family:var(--disp);font-weight:700;font-size:var(--t-h4);
  letter-spacing:-0.02em;margin-bottom:var(--s-2);text-wrap:balance;
}
body.deck .who-wall span{font-size:var(--t-body);color:var(--dim);text-wrap:pretty}

/* both columns carry prose, so the split and the gutter are set by the
   44ch measure floor rather than by the 1.2/0.8 look. */
body.deck .rev-grid{display:grid;grid-template-columns:minmax(0,1.04fr) minmax(0,0.96fr);gap:var(--s-6);align-items:start}
/* data panel → cyan LEFT edge */
body.deck .rev-rotator{background:var(--panel);border:1px solid var(--line);border-left:3px solid var(--miami);padding:clamp(var(--s-5),3.4vw,var(--s-6))}
body.deck .rev-stars{color:var(--miami);letter-spacing:var(--tr-label);font-size:var(--t-lede)}
body.deck .rev-rotator blockquote p{font-family:var(--disp);font-weight:700;font-size:var(--t-h3);line-height:1.25;letter-spacing:-0.02em;margin-top:var(--s-4);text-wrap:balance}
/* --dim, not --faint: --faint measures 4.99:1 on --panel, under the 5.3 floor */
body.deck .rev-rotator cite{display:block;margin-top:var(--s-4);font-style:normal;font-size:var(--t-caption);color:var(--dim)}
body.deck .rev-dots{display:flex;gap:var(--s-2);margin-top:var(--s-5)}
body.deck .rev-dots button{position:relative;width:26px;height:3px;background:var(--line);border:0;padding:0;cursor:pointer}
/* WCAG 2.5.8 — the bar stays 26x3, the pointer target is 26x24. A pseudo
   element hit-tests as part of its originating button, so this is a real
   target, not a visual hint. */
body.deck .rev-dots button::before{
  content:"";position:absolute;left:0;right:0;top:50%;height:24px;transform:translateY(-50%);
}
/* css/home.css scales the active dot 1.25x; the deck bar is a bar, so the
   two states differ by colour only and the 26x24 target never moves. */
body.deck .rev-dots button.on{background:var(--miami);transform:none}
body.deck .rev-dots button:focus-visible{outline:2px solid var(--miami);outline-offset:4px}
body.deck .why-list{list-style:none;display:grid;gap:1px;background:var(--line);border:1px solid var(--line);margin-top:var(--gap-sub)}
body.deck .why-list li{background:var(--night);padding:var(--s-5) var(--s-4);font-size:var(--t-body);color:var(--dim);text-wrap:pretty}
body.deck .why-list b{display:block;font-family:var(--mono);font-weight:700;font-size:var(--m-spec);letter-spacing:var(--tr-spec);text-transform:uppercase;color:var(--ink);margin-bottom:var(--s-2)}

body.deck .about-grid{display:grid;grid-template-columns:minmax(0,0.85fr) minmax(0,1.15fr);gap:var(--gutter);align-items:center}
body.deck .about-photo{position:relative;overflow:hidden}
body.deck .about-photo figcaption{
  position:absolute;left:0;bottom:0;right:0;padding:var(--s-6) var(--s-4) var(--s-3);
  background:linear-gradient(to top, oklch(0.11 0.02 265 / 0.9), transparent);
  font-size:var(--m-label);letter-spacing:0.05em;text-transform:uppercase;
  font-family:var(--mono);font-weight:700;color:var(--dim);
}
body.deck .about-facts{list-style:none;display:grid;gap:1px;background:var(--line);border:1px solid var(--line);margin-top:var(--gap-sub)}
body.deck .about-facts li{background:var(--night-2);padding:var(--s-4) var(--s-5);display:flex;justify-content:space-between;gap:var(--s-4);font-size:var(--t-body);color:var(--dim);flex-wrap:wrap;text-wrap:pretty}
body.deck .about-facts b{font-family:var(--mono);font-weight:700;font-size:var(--m-spec);letter-spacing:var(--tr-spec);text-transform:uppercase;color:var(--miami)}

body.deck .faq-cols{display:grid;grid-template-columns:1fr 1fr;gap:0 var(--gutter);margin-top:var(--gap-block)}
body.deck .faq details{border-bottom:1px solid var(--line)}
body.deck .faq summary{
  list-style:none;cursor:pointer;padding:var(--s-5) var(--s-7) var(--s-5) 0;position:relative;
  font-family:var(--disp);font-weight:700;font-size:var(--t-h4);letter-spacing:-0.02em;line-height:1.25;text-wrap:balance;
}
body.deck .faq summary::-webkit-details-marker{display:none}
body.deck .faq summary::after{
  content:"";position:absolute;right:6px;top:50%;width:12px;height:2px;background:var(--miami);
}
body.deck .faq summary::before{
  content:"";position:absolute;right:11px;top:50%;width:2px;height:12px;background:var(--miami);
  transform:translateY(-50%);transition:transform .3s var(--ease);
}
body.deck .faq details[open] summary::before{transform:translateY(-50%) scaleY(0)}
body.deck .faq details p{color:var(--dim);font-size:var(--t-body);padding:0 var(--s-5) var(--s-5) 0;max-width:58ch;text-wrap:pretty}
body.deck .faq summary:focus-visible{outline:2px solid var(--miami);outline-offset:3px}

/* ============================================================
   SERVICE PAGES
   Same rhythm as the homepage, one trade per page.
   ============================================================ */

.dk-page-hero{padding:clamp(var(--s-9),12vw,var(--s-10)) 0 clamp(var(--s-8),7vw,var(--s-9));position:relative}
.dk-crumb{
  font-family:var(--mono);font-weight:700;font-size:var(--m-label);
  letter-spacing:var(--tr-label);text-transform:uppercase;color:var(--faint);margin-bottom:var(--s-5);
}
.dk-crumb a{color:var(--miami)}
.dk-crumb a:hover{text-decoration:underline}
/* subpage h1 is --t-page: below the hero, above every section head */
.dk-page-hero h1{font-size:min(var(--t-page),12vw);line-height:1.0;letter-spacing:-0.03em;max-width:16ch}
.dk-ph-grid{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,0.85fr);gap:var(--gutter);align-items:center}
.dk-ph-ctas{display:flex;gap:var(--s-3);flex-wrap:wrap;margin-top:var(--s-6)}
.dk-ph-media{position:relative;overflow:hidden}
.dk-ph-media img{width:100%;aspect-ratio:4/3.2;object-fit:cover}

/* slabs on service pages carry a source line — every stat is attributable */
/* --dim, not --faint: .dk-slab sits on --panel, where --faint is 4.99:1 */
.dk-slab .src{
  display:block;margin-top:var(--s-3);padding-top:var(--s-3);border-top:1px solid var(--line);
  font-family:var(--mono);font-weight:700;font-size:var(--m-label);
  letter-spacing:0.05em;text-transform:uppercase;color:var(--dim);
}

/* category tiles — a butted contact sheet, no gutters anywhere else */
.dk-cats{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(min(220px,100%),1fr));
  gap:1px;margin-top:var(--gap-block);background:var(--line);border:1px solid var(--line);
}
.dk-cats figure{position:relative;overflow:hidden;background:var(--panel)}
.dk-cats img{width:100%;aspect-ratio:4/3;object-fit:cover}
.dk-cats figcaption{
  position:absolute;left:0;right:0;bottom:0;padding:var(--s-6) var(--s-4) var(--s-3);
  background:linear-gradient(to top, oklch(0.11 0.02 265 / 0.92), transparent);
  font-family:var(--mono);font-weight:700;font-size:var(--m-label);
  letter-spacing:0.05em;text-transform:uppercase;text-wrap:pretty;
}

/* before / after — the one comparison that gets real gutters, so it
   never reads as the same grid as the versus strip */
.dk-ba{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.12fr);gap:var(--gutter);margin-top:var(--gap-block)}
/* identical padding on both cards so the two label baselines register;
   only the fill and the edge colour change */
.dk-ba-card{border-left:3px solid var(--line);padding:clamp(var(--s-5),2.4vw,var(--s-6))}
.dk-ba-card .lbl{font-family:var(--mono);font-weight:700;font-size:var(--m-label);letter-spacing:var(--tr-label);text-transform:uppercase;color:var(--warn)}
.dk-ba-card h3{font-size:var(--t-h3);margin:var(--s-3) 0 var(--s-5)}
.dk-ba-card ul{list-style:none;display:grid;gap:var(--s-3)}
.dk-ba-card li{font-size:var(--t-body);color:var(--dim);padding-left:var(--s-5);position:relative;text-wrap:pretty}
.dk-ba-card li::before{content:"";position:absolute;left:0;top:0.7em;width:9px;height:2px;background:var(--warn)}
.dk-ba-card li b{color:var(--ink);font-weight:600}
/* data panel → cyan LEFT edge */
.dk-ba-card.win{border-left-color:var(--miami);background:var(--lit)}
.dk-ba-card.win .lbl{color:var(--miami)}
.dk-ba-card.win li::before{background:var(--miami)}

/* audit scorecard (consulting) — data panel, cyan left edge */
.dk-audit{background:var(--panel);border:1px solid var(--line);border-left:3px solid var(--miami)}
/* --dim, not --faint: .dk-audit sits on --panel, where --faint is 4.99:1 */
.dk-audit-head{
  display:flex;justify-content:space-between;gap:var(--s-3);padding:var(--s-4) var(--s-5);border-bottom:1px solid var(--line);
  font-family:var(--mono);font-weight:700;font-size:var(--m-label);letter-spacing:0.05em;
  text-transform:uppercase;color:var(--dim);font-variant-numeric:tabular-nums;
}
.dk-audit-head b{color:var(--miami)}
.dk-audit-row{padding:var(--s-5);border-bottom:1px solid var(--line)}
.dk-ar-top{display:flex;justify-content:space-between;align-items:center;gap:var(--s-3);margin-bottom:var(--s-3)}
.dk-ar-top b{font-family:var(--mono);font-weight:700;font-size:var(--m-spec);letter-spacing:0.05em}
.dk-chip{
  font-family:var(--mono);font-weight:700;font-size:var(--m-label);letter-spacing:0.05em;text-transform:uppercase;
  padding:var(--s-1) var(--s-2);background:oklch(0.62 0.13 25 / 0.16);color:var(--warn);border:1px solid oklch(0.62 0.13 25 / 0.45);
  white-space:nowrap;
}
.dk-meter{height:6px;background:var(--night);border:1px solid var(--line)}
.dk-meter i{display:block;height:100%;background:var(--warn);transform:scaleX(0);transform-origin:left;transition:transform .8s var(--ease)}
.dk-audit.lit .dk-meter i{transform:scaleX(1)}
.dk-ar-note{margin-top:var(--s-3);font-size:var(--t-body);color:var(--dim);text-wrap:pretty}
.dk-audit-foot{
  padding:var(--s-4) var(--s-5);font-family:var(--mono);font-weight:700;font-size:var(--m-label);
  letter-spacing:0.05em;text-transform:uppercase;color:var(--miami);
}

/* colour swatches (print) */
.dk-swatches{display:flex;gap:var(--s-2);flex-wrap:wrap;margin-top:var(--gap-sub)}
.dk-swatch{width:120px;border:1px solid var(--line)}
.dk-swatch i{display:block;height:56px}
.dk-swatch span{
  display:block;padding:var(--s-2) var(--s-3);border-top:1px solid var(--line);
  font-family:var(--mono);font-weight:700;font-size:var(--m-label);letter-spacing:0.05em;
  color:var(--dim);line-height:1.6;font-variant-numeric:tabular-nums;
}

/* drag-to-grade comparison (photo) */
.dk-grade{position:relative;aspect-ratio:4/3;overflow:hidden;border:1px solid var(--line);background:var(--night-2)}
.dk-grade img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.dk-grade .raw{filter:saturate(0.24) brightness(1.07) contrast(0.86)}
.dk-grade .graded{clip-path:inset(0 0 0 var(--gr,50%))}
.dk-grade .gline{position:absolute;top:0;bottom:0;left:var(--gr,50%);width:3px;background:var(--miami);pointer-events:none}
.dk-grade .gline::after{
  content:"◂ ▸";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  background:var(--miami);color:var(--night-2);padding:var(--s-2) var(--s-3);white-space:nowrap;
  font-family:var(--disp);font-weight:700;font-size:var(--m-spec);
}
.dk-grade input[type=range]{position:absolute;inset:0;width:100%;height:100%;opacity:0;margin:0;cursor:ew-resize}
.dk-grade input:focus-visible{outline:2px solid var(--miami);outline-offset:-4px;opacity:1}
.dk-gtag{
  position:absolute;top:var(--s-3);font-family:var(--mono);font-weight:700;font-size:var(--m-label);
  letter-spacing:0.05em;padding:var(--s-1) var(--s-2);pointer-events:none;text-transform:uppercase;
}
.dk-gtag.raw{left:var(--s-3);background:oklch(0.16 0.025 265 / 0.86);color:var(--dim);border:1px solid var(--line)}
.dk-gtag.graded{right:var(--s-3);background:var(--miami);color:var(--night-2)}

/* price tiers — butted comparison, featured marked by a cyan left edge */
.dk-tiers{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(250px,100%),1fr));gap:1px;margin-top:var(--gap-block);background:var(--line)}
.dk-tier{background:var(--night);padding:clamp(var(--s-5),3.2vw,var(--s-7));border-left:3px solid transparent}
.dk-alt .dk-tier{background:var(--night-2)}
.dk-tier .td{
  font-family:var(--mono);font-weight:700;font-size:var(--m-label);
  letter-spacing:var(--tr-label);text-transform:uppercase;color:var(--faint);
}
.dk-tier .price{
  font-family:var(--disp);font-weight:800;font-size:var(--t-stat);font-stretch:100%;
  line-height:1;letter-spacing:-0.03em;margin:var(--s-3) 0 var(--s-5);font-variant-numeric:tabular-nums;
}
.dk-tier ul{list-style:none;display:grid;gap:var(--s-3)}
.dk-tier li{font-size:var(--t-body);color:var(--dim);padding-left:var(--s-5);position:relative;text-wrap:pretty}
.dk-tier li::before{content:"";position:absolute;left:0;top:0.7em;width:9px;height:2px;background:var(--miami)}
.dk-tier.feat{background:var(--lit);border-left-color:var(--miami)}
.dk-tier.feat .td,.dk-tier.feat .price{color:var(--miami)}

/* numbered sources, cited inline with sup links. --t-caption keeps the
   marker on the prose ramp; 0.62em drifted with whatever it was nested in. */
.dk-fn{font-size:var(--t-caption);vertical-align:super;line-height:0}
.dk-fn a{color:var(--miami)}
.dk-fn a:hover{text-decoration:underline}
.dk-sources{background:var(--night-2);border-top:1px solid var(--line);padding:clamp(var(--s-7),6vw,var(--s-9)) 0}
.dk-sources h2{font-size:var(--t-h3);margin-bottom:var(--s-5)}
.dk-sources ol{padding-left:var(--s-5);display:grid;gap:var(--s-3);max-width:64ch}
.dk-sources li{font-size:var(--t-body);color:var(--dim);text-wrap:pretty}
.dk-sources li:target{color:var(--ink)}
.dk-sources li:target::marker{color:var(--miami)}

/* closing band shared by every page — pulled onto the same band rhythm
   as .dk so the contact block stops being the one off-scale section */
/* .dk-close is the closing <section class="contact dk-close"> on the five
   service pages; index.html's contact band does not carry it. Its heading
   is a plain <h2> on all five, so the old `.dk-close .dk-h{max-width:18ch}`
   matched nothing on any page that loads this file and is gone. */
.dk-close{border-top:1px solid var(--line)}
body.deck .contact{padding:var(--pad-y) 0}
body.deck .contact-grid{gap:var(--gutter)}
body.deck .contact-copy > p:not(.contact-meta){font-size:var(--t-lede);margin:var(--s-5) 0 var(--s-6);max-width:52ch}
body.deck .contact-ctas{gap:var(--s-3)}
body.deck .contact-copy > p.contact-meta{margin-top:var(--s-6);font-size:var(--t-body);line-height:1.6;max-width:52ch}

/* ---------- reveal ----------
   .rv is the only rule on the site that hides live copy, so every path that
   can leave it hidden has to be closed below: reduced motion, JS disabled,
   and (in js/home.js) a failed GSAP CDN. */
.rv{opacity:0;transform:translateY(30px)}

/* ---------- no scripting at all ----------
   The GSAP fallback in js/home.js is itself JavaScript, so it cannot help
   here. This block is the only thing standing between a JS-off visitor and
   eleven empty bands: it lands every JS-driven element on its END state.
   `scripting` is a UA-evaluated media feature — a browser that does not
   know it simply never matches this block, so nothing leaks into the
   normal path where JS is running. */
@media (scripting: none){
  .rv{opacity:1;transform:none}
  .press-checks div{opacity:1}
  .dk-step::after{transform:scaleY(1)}
  .cam-hist i{transform:scaleY(1)}
  .dk-meter i{transform:scaleX(1)}
  .cam-af{--len:44%;--b:3px}
}

@media (prefers-reduced-motion: reduce){
  .rv{opacity:1 !important;transform:none !important}
  .press-checks div{opacity:1}
  .dk-step::after{transform:scaleY(1)}
  .cam-hist i{transform:scaleY(1)}
  .dk-meter i{transform:scaleX(1)}
  /* every transition declared in this file … */
  .dk-step::after,
  .cam-hist i,
  .dk-meter i,
  .web-page,
  body.deck .faq summary::before{transition:none}
  /* … and every transition css/home.css puts on a deck element. These live
     in the other stylesheet, so they are neutralised from here by the
     body.deck prefix rather than by editing that file.
     `.masonry figcaption` is listed for its transition ONLY. Its visibility
     — the opacity gate that used to make the nine work-wall captions
     hover-only — is owned by css/home.css and is deliberately not touched
     from here, in either direction. Nothing in this file sets opacity on
     that element, so this block cannot re-hide a caption; if the gate is
     dropped upstream this line simply stops matching a transition. */
  body.deck .masonry img,
  body.deck .masonry figcaption,
  body.deck .who-wall li,
  body.deck .rev-dots button{transition:none}
  /* the progress rail is an orientation affordance, not decoration: render
     it as a static top rule instead of deleting it. js/home.js never scrubs
     it under reduced motion, so scaleX would otherwise sit at 0 forever. */
  .dk-progress{transform:none;background:var(--miami-deep)}
}

/* ---------- responsive ---------- */
@media (max-width: 960px){
  body.deck .masonry{columns:2}
  body.deck .rev-grid,body.deck .about-grid{grid-template-columns:1fr}
  body.deck .about-photo{max-height:340px}
  /* auto-fit resolves to 3 columns for the 4-item strip between roughly
     640 and 1000px, which leaves a 3+1 orphan row in the one grid that is
     supposed to read as instrumentation. Pin it to 2x2 through that range. */
  .dk-slabs{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width: 880px){
  .dk-split,.dk-split.flip{grid-template-columns:1fr;gap:var(--s-7)}
  .dk-split.flip .dk-visual{order:0}
  .dk-ph-grid{grid-template-columns:1fr;gap:var(--s-7)}
  .dk-versus,.dk-ba{grid-template-columns:1fr}
  .dk-ba{gap:var(--s-7)}
  body.deck .faq-cols{grid-template-columns:1fr}
  .dk-step{grid-template-columns:var(--s-7) minmax(0,1fr);gap:var(--s-4);padding:var(--s-5)}
}
@media (max-width: 560px){
  body.deck .masonry{columns:1}
  .press-sheet{padding:var(--s-4)}
  /* below this a 2-up strip cell cannot hold a --t-stat figure and its
     caption without the caption breaking every two words */
  .dk-slabs{grid-template-columns:minmax(0,1fr)}
}
