/* ============================================================
   Studio Practice — Project Dotmatrix
   Scoped dark "dot-matrix / printed-document" theme.

   Activated only on pages whose <html> carries class
   "theme-dotmatrix". Additive over /assets/sp-design-v2.css:
   the light v2 tokens are NEVER mutated, so back-office /
   gated / leak pages stay light and revert is one step
   (drop the class + these assets).

   Values lifted from the approved claude.ai/design reference;
   markup is class-based here (no inline styles).
   ============================================================ */

@font-face {
  font-family: 'Departure Mono';
  src: url('/assets/fonts/DepartureMono-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* Doto draws the full stop as a cross at display sizes. Override ONLY the
   period (U+002E) family-wide with a clean monospace dot. Declared after
   Google's Doto @font-face (loaded in <head> before this sheet) and given the
   full weight range so it wins the glyph for U+002E at any heading weight.
   All other glyphs still come from real Doto; body/mono text is untouched.

   The src is our self-hosted Departure Mono, NOT local() system fonts. The
   earlier local()-only version worked on macOS (Menlo is present) but failed
   anywhere those fonts are absent — the Tesla in-car browser, Chromebooks,
   Windows without Consolas — where every local() misses, the override
   supplies no glyph, and the period falls back to Doto's own cross.
   Departure Mono is already loaded on every themed page (it is the body mono
   face), so this adds no request and renders a byte-identical square dot on
   every device instead of a per-OS system glyph. */
@font-face {
  font-family: 'Doto';
  src: url('/assets/fonts/DepartureMono-Regular.woff2') format('woff2');
  unicode-range: U+002E;
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* ---------- tokens (scoped) ----------
   The .site-footer selector re-asserts the DARK token set inside the light
   sister so the footer stays consistent (dark) with every other page. */
.theme-dotmatrix,
html.theme-dotmatrix.theme-light .site-footer {
  color-scheme: dark;
  /* Re-assert the text colour, not just the token, so a nested dark stage on
     the light sister (a dark plate on light paper) recolours headings that
     only INHERIT color. Without this they keep body's computed light-ink and
     render dark-on-dark. */
  color: var(--dm-ink);

  --dm-bg:        #16171b;   /* page */
  --dm-board:     #15161a;   /* board fill */
  --dm-well:      #0c0d10;   /* canvas / figure wells + sunken zones (deepened for contrast) */
  --dm-panel:     #23252e;   /* featured panels + lifted zones (widened off base #16171b) */
  --dm-overlay:   #121317;   /* intro overlay */

  --dm-ink:       #f3f4f6;   /* primary text */
  --dm-body:      #c7c9cf;   /* body copy */
  --dm-body-2:    #e0e2e7;   /* hero desc */
  --dm-muted:     #9a9ca3;
  --dm-muted-2:   #8e9099;
  --dm-label:     #7c7e85;
  --dm-label-2:   #5a5c63;
  --dm-faint:     #4d4f55;
  --dm-numeral:   #3f4147;   /* dim section numerals */

  --dm-accent:      #67a0e8;
  --dm-accent-2:    #8fbcf2;
  --dm-accent-line: #2f4a6b;

  --dm-line:   #26272c;      /* hairline */
  --dm-line-2: #40424b;      /* stronger — zone edges */
  --dm-btn:    #4d4f55;      /* button borders */

  --dm-dot:    rgba(150,156,168,0.20);  /* board dim dot (alt texture) */
  --dm-glow:   0 0 11px rgba(196,216,242,0.22);
  --dm-glow-2: 0 0 11px rgba(196,216,242,0.28), 0 0 2px rgba(255,255,255,0.20);

  /* tractor-feed — the default "era texture" (settled background) */
  --dm-tractor-band:  rgba(255,255,255,0.022);  /* soft 64px feed band */
  --dm-tractor-line:  rgba(255,255,255,0.05);   /* 1px perforation rule / 64px */
  --dm-sprocket-fill: #1b1c21;                  /* margin strip */
  --dm-sprocket-hole: #07080a;                  /* punched feed hole */

  --dm-display: 'Doto', ui-monospace, 'SF Mono', monospace;
  --dm-mono:    'Departure Mono', ui-monospace, 'SF Mono', monospace;

  --dm-inner:     76%;
  --dm-inner-max: 2000px;
  --dm-sec-pad:   clamp(48px, 7vw, 74px);

  /* printable-area floor: content never enters the fixed 44px sprocket bands
     (44px band + 44px air). Drops to 24px wherever the bands are hidden
     (≤560px, .dm-tex-board). */
  --dm-edge:      88px;
}

/* ---------- base / continuous-feed paper (tractor) ---------- */
.theme-dotmatrix body {
  background-color: var(--dm-bg);
  background-image:
    repeating-linear-gradient(to bottom, var(--dm-tractor-band) 0, var(--dm-tractor-band) 64px, transparent 64px, transparent 128px),
    repeating-linear-gradient(to bottom, transparent 0, transparent 63px, var(--dm-tractor-line) 63px, var(--dm-tractor-line) 64px);
  background-size: 100% 128px, 100% 64px;
  /* NOT background-attachment:fixed — that repaints the whole page on every
     scroll + view-transition snapshot (Safari perf trap, caused nav hangs).
     The tractor bands are uniform, so scrolling them looks identical. */
  background-attachment: scroll;
  color: var(--dm-ink);
  font-family: var(--dm-mono);
  font-size: 15px;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
}
/* sprocket-hole feed margins (decorative, pinned; no markup change) */
.theme-dotmatrix body::before,
.theme-dotmatrix body::after {
  content: "";
  position: fixed;
  top: 0;
  bottom: 0;
  width: 44px;
  z-index: 1;
  pointer-events: none;
  background-color: var(--dm-sprocket-fill);
  background-image: radial-gradient(circle at 50% 50%, var(--dm-sprocket-hole) 7px, rgba(0,0,0,0.55) 8px, transparent 9px);
  background-size: 44px 56px;
}
.theme-dotmatrix body::before { left: 0; border-right: 1px dashed var(--dm-line-2); box-shadow: inset -6px 0 12px rgba(0,0,0,0.45); }
.theme-dotmatrix body::after  { right: 0; border-left: 1px dashed var(--dm-line-2); box-shadow: inset 6px 0 12px rgba(0,0,0,0.45); }

/* alternate era texture — one-class swap back to the LED dot board */
.theme-dotmatrix.dm-tex-board body {
  background-image: radial-gradient(circle, var(--dm-dot) 1px, transparent 1.5px);
  background-size: 8px 8px;
  background-color: var(--dm-board);
  background-attachment: scroll;
}
.theme-dotmatrix.dm-tex-board body::before,
.theme-dotmatrix.dm-tex-board body::after { display: none; }
.theme-dotmatrix.dm-tex-board { --dm-edge: 24px; }   /* no bands to clear */

.theme-dotmatrix ::selection { background: var(--dm-accent); color: var(--dm-bg); }
.theme-dotmatrix a { color: inherit; text-decoration: none; }

/* ============================================================
   LIGHT SISTER — html.theme-dotmatrix.theme-light
   A light-mode sibling of the dark board: same Doto + Departure Mono, the
   same dot motif, hairlines, squared forms and single accent, inverted onto
   a cool light surface (NOT the old cream v2). Everything that reads --dm-*
   tokens (nav, footer, page chrome, components) flips automatically; only
   the few hardcoded dark values are overridden. Pair with dm-tex-board for
   the light dot-grid board. Used on /design-system.
   ============================================================ */
.theme-dotmatrix.theme-light {
  color-scheme: light;

  --dm-bg:        #e5e8ec;   /* page — stepped down from #eceef1 (off near-white) */
  --dm-board:     #e1e3e8;   /* board fill — just under the paper */
  --dm-well:      #d8dbe1;   /* wells — inset depth preserved vs the new paper */
  --dm-panel:     #ffffff;   /* raised panels — stay white so they lift off paper */
  --dm-overlay:   #eef0f3;   /* intro overlay — a hair above paper */

  --dm-ink:       #17181c;   /* primary text (the dark page colour, inverted) */
  --dm-body:      #40424a;
  --dm-body-2:    #2a2c32;
  --dm-muted:     #6c6e76;
  --dm-muted-2:   #7a7c84;
  --dm-label:     #8a8c93;
  --dm-label-2:   #a2a4ab;
  --dm-faint:     #b6b8be;
  --dm-numeral:   #cbcdd3;

  --dm-accent:      #2f6fe0;   /* deeper blue: same family, readable on light */
  --dm-accent-2:    #5a8ee8;
  --dm-accent-line: #bcd0ee;

  --dm-line:   #dcdee3;
  --dm-line-2: #c9cbd1;
  --dm-btn:    #b6b8be;

  --dm-dot:    rgba(28,32,48,0.10);   /* dark dot (alt board texture) */
  --dm-tractor-band:  rgba(24,28,44,0.020);  /* faint feed band on light */
  --dm-tractor-line:  rgba(24,28,44,0.06);   /* perforation rule / 64px */
  --dm-sprocket-fill: #e4e6ea;               /* light margin strip */
  --dm-sprocket-hole: #cfd2d8;               /* punched feed hole */
  --dm-glow:   none;
  --dm-glow-2: none;
}
/* frosted scrolled-nav bg (the dark rule hardcodes a dark rgba) */
.theme-dotmatrix.theme-light .nav.is-scrolled { background: rgba(236,238,241,0.9); }
/* LED fills invert to accent dots so they read on a light track */
.theme-dotmatrix.theme-light .dm-meter-fill { background: repeating-linear-gradient(90deg, var(--dm-accent) 0 2.5px, transparent 2.5px 8px); box-shadow: none; }
/* "lit LED" dots/nodes are near-white (#eef3fb) for the dark board — on light
   paper they vanish. Recolour to the accent (keeps their "lit" intent), drop glow. */
.theme-dotmatrix.theme-light .dm-tl-node::before,
.theme-dotmatrix.theme-light .dm-tier-item::before { background: var(--dm-accent); box-shadow: none; }
.theme-dotmatrix.theme-light .dm-doticon:not([data-doticon]) { --dmi-color: var(--dm-accent); --dmi-glow: none; }
/* light sprocket margins (dark rule hardcodes a dark hole-ring + inset shadows) */
.theme-dotmatrix.theme-light body::before,
.theme-dotmatrix.theme-light body::after {
  background-image: radial-gradient(circle at 15px 15px, var(--dm-sprocket-hole) 3.6px, rgba(24,28,44,0.14) 4.4px, transparent 5px);
}
.theme-dotmatrix.theme-light body::before { box-shadow: inset -6px 0 12px rgba(24,28,44,0.05); }
.theme-dotmatrix.theme-light body::after  { box-shadow: inset 6px 0 12px rgba(24,28,44,0.05); }
/* footer stays the canonical DARK footer even on the light sister (site-wide consistency) */
.theme-dotmatrix.theme-light .site-footer { background: var(--dm-bg); }

/* Content + header columns ride the GridSim "sp" grid (1320 cap · 24px margin),
   site-wide. The homepage hero keeps its own body.has-hero overrides (same
   values); the old 76%/2000 float is retired. */
/* The clamp keeps the 24px pad whenever the auto margins already clear the
   sprocket bands (viewport ≥ 1400px — unchanged from the shipped look) and
   grows it as the window narrows so text stays inside the perforations. */
.dm-inner { width: auto; max-width: 1320px; margin-inline: auto; padding-inline: clamp(24px, calc(var(--dm-edge) - (100vw - 1320px) / 2), var(--dm-edge)); }

/* lit Doto heading helper */
.theme-dotmatrix .dm-lit {
  font-family: var(--dm-display);
  text-shadow: var(--dm-glow-2);
}

/* dotted document rule */
.dm-rule {
  height: 1px;
  background-image: radial-gradient(circle, var(--dm-line-2) 1px, transparent 1.4px);
  background-size: 7px 1px;
  background-repeat: repeat-x;
  border: 0;
}

/* ============================================================
   NAV (injected <sp-nav>) — dark overrides only, layout from v2
   ============================================================ */
.theme-dotmatrix .nav { background: transparent; border-bottom: 1px solid transparent; }
.theme-dotmatrix .nav.is-scrolled {
  background: rgba(22,23,27,0.88);
  border-bottom-color: var(--dm-line);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}
.theme-dotmatrix .nav-sp-wordmark {
  font-family: var(--dm-display);
  font-weight: 800;
  font-size: 17px;
  letter-spacing: 0.04em;
  color: var(--dm-ink);
}
.theme-dotmatrix .nav-links a {
  font-family: var(--dm-mono);
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dm-muted);
}
.theme-dotmatrix .nav-links a:hover,
.theme-dotmatrix .nav-links a.active { color: var(--dm-ink); }
/* Book a Time = the standard squared CTA (see .dm-cta). Selectors mirror v2's
   own nav-book rules (incl. the over-hero state) but prefixed with
   html.theme-dotmatrix so they out-specify v2's pill in every nav state —
   a plain .theme-dotmatrix .nav-book loses to v2's `.nav-links a.nav-book`. */
html.theme-dotmatrix .nav-links a.nav-book,
html.theme-dotmatrix body.has-hero .nav:not(.is-scrolled) .nav-links a.nav-book {
  font-family: var(--dm-mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-weight: 400;
  color: var(--dm-ink);
  background: transparent;
  border: 1px solid var(--dm-accent);
  border-radius: 0;
  padding: 9px 16px;
}
html.theme-dotmatrix .nav-links a.nav-book:hover,
html.theme-dotmatrix body.has-hero .nav:not(.is-scrolled) .nav-links a.nav-book:hover {
  color: var(--dm-bg);
  background: var(--dm-accent);
  border-color: var(--dm-accent);
  transform: none;
  box-shadow: none;
  letter-spacing: 0.16em;
}
.theme-dotmatrix .nav-hamburger span { background: var(--dm-ink); }

/* Light-primary + dark photo hero (homepage only, body.has-hero): the nav rides
   LIGHT while over the hero; once scrolled onto the frosted light bar it returns
   to the default dark-on-light colours. Interior pages have no has-hero → default. */
.theme-dotmatrix.theme-light body.has-hero .nav:not(.is-scrolled) .nav-sp-wordmark,
.theme-dotmatrix.theme-light body.has-hero .nav:not(.is-scrolled) .nav-links a { color: #eef1f5; }
.theme-dotmatrix.theme-light body.has-hero .nav:not(.is-scrolled) .nav-links a:hover,
.theme-dotmatrix.theme-light body.has-hero .nav:not(.is-scrolled) .nav-links a.active { color: #ffffff; }
html.theme-dotmatrix.theme-light body.has-hero .nav:not(.is-scrolled) .nav-links a.nav-book {
  color: #eef1f5; border-color: rgba(238,241,245,0.55);
}
html.theme-dotmatrix.theme-light body.has-hero .nav:not(.is-scrolled) .nav-links a.nav-book:hover {
  color: #ffffff; background: var(--dm-accent); border-color: var(--dm-accent);
}
.theme-dotmatrix.theme-light body.has-hero .nav:not(.is-scrolled) .nav-hamburger span { background: #eef1f5; }

/* mobile menu — flush-left dark sheet.
   The panel is injected by sp-shell.js. Hide it with `visibility` and keep the
   closed state opacity:1 with NO transition, so a freshly-inserted element has
   nothing to animate — that kills the ghost that flashed on every page load
   (a closed-state opacity transition fires 1->0 on insert in Safari). Opacity
   never changes, so the page can never bleed through the panel either. The
   slide-in is applied only on open. */
.theme-dotmatrix #sp-mobile-menu.mobile-menu {
  background: var(--dm-overlay, #121317);
  color: var(--dm-ink);
  opacity: 1;
  visibility: hidden;
  transform: translateY(-10px);
}
.theme-dotmatrix #sp-mobile-menu.mobile-menu.is-open {
  visibility: visible;
  transform: none;
  transition: transform 300ms var(--ease);
}
@media (prefers-reduced-motion: reduce) {
  .theme-dotmatrix #sp-mobile-menu.mobile-menu.is-open { transition: none; transform: none; }
}
.theme-dotmatrix #sp-mobile-menu.mobile-menu a {
  font-family: var(--dm-display);
  color: var(--dm-ink);
}
.theme-dotmatrix #sp-mobile-menu.mobile-menu .mobile-menu-close {
  font-family: var(--dm-mono);
  color: var(--dm-muted);
}

/* ============================================================
   INTRO — the document prints (injected by sp-figure-matrix.js)
   A fresh sheet on the same tractor paper: a print head rasterizes
   the wordmark in LED dots line by line, then the sheet ejects
   upward to reveal the page beneath (identical bands + sprockets,
   so the peel reads as the top sheet leaving the platen).
   ============================================================ */
.dm-intro {
  position: fixed; inset: 0; z-index: 200;
  background-color: var(--dm-bg);
  background-image:
    repeating-linear-gradient(to bottom, var(--dm-tractor-band) 0, var(--dm-tractor-band) 64px, transparent 64px, transparent 128px),
    repeating-linear-gradient(to bottom, transparent 0, transparent 63px, var(--dm-tractor-line) 63px, var(--dm-tractor-line) 64px);
  background-size: 100% 128px, 100% 64px;
  display: flex; align-items: center; justify-content: center;
  will-change: transform;
}
.dm-intro::before,
.dm-intro::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: 44px;
  background-color: var(--dm-sprocket-fill);
  background-image: radial-gradient(circle at 50% 50%, var(--dm-sprocket-hole) 7px, rgba(0,0,0,0.55) 8px, transparent 9px);
  background-size: 44px 56px;
}
.dm-intro::before { left: 0; border-right: 1px dashed var(--dm-line-2); }
.dm-intro::after  { right: 0; border-left: 1px dashed var(--dm-line-2); }
.dm-intro-canvas { display: block; }
.dm-intro-head {
  position: absolute; left: 0; top: 0; width: 3px; border-radius: 1px;
  background: var(--dm-accent);
  box-shadow: 0 0 6px var(--dm-accent), 0 0 18px rgba(103,160,232,0.55);
  opacity: 0; will-change: transform;
}
.dm-intro-job {
  position: absolute; left: 64px; top: 22px;
  font-family: var(--dm-mono); font-size: 10px; letter-spacing: 0.24em;
  color: var(--dm-label-2); text-transform: uppercase; line-height: 2;
}
.dm-intro-job b { display: block; font-weight: 400; }
.dm-intro-status { color: var(--dm-accent); }
.dm-intro.is-eject { animation: dmIntroEject 0.52s cubic-bezier(.7,0,.16,1) forwards; }
@keyframes dmIntroEject { to { transform: translateY(-104%); } }
@media (max-width: 560px) {
  .dm-intro::before, .dm-intro::after { display: none; }
  .dm-intro-job { left: 24px; }
}

/* ============================================================
   HERO — full-bleed canvas
   ============================================================ */
.dm-hero { position: relative; background: var(--dm-well); margin-top: -64px; }
.dm-hero-fig {
  margin: 0; position: relative; overflow: hidden;
  border-bottom: 1px solid var(--dm-line);
  background: var(--dm-well) center / cover no-repeat;
}
.dm-figure { display: block; width: 100%; cursor: crosshair; }
#heroFig { height: clamp(560px, 86vh, 880px); }

.dm-hero-top {
  position: absolute; top: 0; left: 0; right: 0; pointer-events: none;
  background: linear-gradient(to bottom, rgba(14,15,18,0.78), transparent);
}
.dm-hero-top .dm-inner {
  padding: 78px 0 16px; display: flex; justify-content: space-between; align-items: center;
  font-size: 10px; letter-spacing: 0.2em; color: var(--dm-body); text-transform: uppercase;
}
.dm-hero-top .dm-doc-id { color: var(--dm-muted); }

.dm-hero-cap {
  position: absolute; left: 0; right: 0; bottom: 0;
  background: linear-gradient(to top, rgba(14,15,18,0.96) 0%, rgba(14,15,18,0.45) 55%, transparent 100%);
}
.dm-hero-cap .dm-inner {
  padding: 96px 0 56px; display: flex; justify-content: space-between; align-items: flex-end;
  gap: 32px; flex-wrap: wrap;
}
.dm-hero-meta { max-width: 60ch; margin-bottom: 32px; }
.dm-hero-cat { font-size: 11px; letter-spacing: 0.2em; color: var(--dm-accent); text-transform: uppercase; }
.dm-hero-title {
  margin: 10px 0 0; font-family: var(--dm-display); font-weight: 800;
  font-size: clamp(44px, 6.6vw, 96px); line-height: 0.84; letter-spacing: 0.01em;
}
.dm-hero-desc { margin: 16px 0 0; font-size: 16px; line-height: 1.6; color: var(--dm-body-2); }
.dm-hero-url { display: inline-block; margin-top: 14px; font-size: 13px; color: var(--dm-accent); letter-spacing: 0.08em; }
.dm-hero-ctrl { display: flex; align-items: center; gap: 16px; }
.dm-hero-index { font-family: var(--dm-display); font-weight: 300; font-size: 32px; color: var(--dm-muted); letter-spacing: 0.04em; }
.dm-iconbtn {
  border: 1px solid var(--dm-btn); background: rgba(18,19,23,0.55); color: var(--dm-ink);
  width: 44px; height: 42px; cursor: pointer; font-size: 16px; font-family: var(--dm-mono);
  display: inline-flex; align-items: center; justify-content: center;
}
.dm-iconbtn:hover { border-color: var(--dm-accent); }
/* strip prints to the perforation: 44px band + its 1px dashed rule */
.dm-hero-ticks { display: flex; border-bottom: 1px solid var(--dm-line); margin-inline: 45px; }
.dm-tick {
  flex: 1; display: flex; align-items: center; justify-content: center; padding: 9px 0;
  cursor: pointer; border: 0; border-right: 1px solid var(--dm-line);
  border-top: 2px solid transparent; background: transparent; color: var(--dm-label-2);
  font-family: var(--dm-mono); font-size: 10px; letter-spacing: 0.06em; transition: all .16s;
}
.dm-tick:last-child { border-right: 0; }
.dm-tick.is-active { border-top-color: var(--dm-accent); background: var(--dm-panel); color: var(--dm-ink); }

/* ============================================================
   DOCUMENT BODY
   ============================================================ */
.dm-doc { padding-top: 64px; }

.dm-section-head {
  display: flex; justify-content: space-between; align-items: flex-end;
  border-bottom: 1px solid var(--dm-line-2); padding-bottom: 18px;
}
.dm-section-head-l { display: flex; align-items: flex-end; gap: 22px; }
.dm-section-num { font-family: var(--dm-display); font-weight: 700; font-size: clamp(34px, 5vw, 68px); line-height: 0.85; color: var(--dm-numeral); }
.dm-section-title { margin: 0; font-family: var(--dm-display); font-weight: 800; font-size: clamp(30px, 4vw, 52px); line-height: 0.9; text-shadow: var(--dm-glow-2); }
.dm-section-index { font-size: 11px; letter-spacing: 0.2em; color: var(--dm-muted-2); white-space: nowrap; }

/* ---------- 01 voice / abstract ---------- */
/* headline left, smaller copy right — side-by-side keeps the section short */
.dm-abstract { padding: var(--dm-sec-pad) 4px; display: grid; grid-template-columns: 1.05fr 0.95fr; gap: 48px; align-items: start; }
.dm-abstract-copy { padding-top: 6px; }
.dm-abstract-label { font-size: 11px; letter-spacing: 0.22em; color: var(--dm-muted-2); text-transform: uppercase; }
.dm-abstract-tag { font-size: 11px; letter-spacing: 0.16em; color: var(--dm-faint); text-transform: uppercase; margin-top: 28px; }
.dm-abstract-h { margin: 22px 0 0; font-family: var(--dm-display); font-weight: 800; font-size: clamp(40px, 5.2vw, 76px); line-height: 0.9; text-shadow: var(--dm-glow); }
.dm-h-line { display: block; }
.dm-em { color: var(--dm-accent); }

/* headline "power-on" bloom — JS arms it (.dm-anim), scroll-in fires it (.is-on).
   Without JS the lines just stay visible; reduced-motion skips the bloom. */
.dm-abstract-h.dm-anim .dm-h-line { opacity: 0; }
.dm-abstract-h.dm-anim.is-on .dm-h-line { animation: dm-power-on 1250ms cubic-bezier(.2, .7, .2, 1) both; }
.dm-abstract-h.dm-anim.is-on .dm-h-line:last-child { animation-delay: 480ms; }
@keyframes dm-power-on {
  0%   { opacity: 0; transform: scale(0.92); filter: blur(3px); text-shadow: none; }
  55%  { opacity: 1; transform: scale(1.03); filter: blur(0); text-shadow: 0 0 28px rgba(196, 216, 242, 0.7), 0 0 3px rgba(255, 255, 255, 0.5); }
  100% { opacity: 1; transform: scale(1); filter: blur(0); text-shadow: var(--dm-glow); }
}
@media (prefers-reduced-motion: reduce) {
  .dm-abstract-h.dm-anim .dm-h-line { opacity: 1; animation: none; }
}
.dm-abstract-p { margin: 0; font-size: 16px; line-height: 1.72; color: var(--dm-body); max-width: 52ch; }
.dm-inline-link { display: inline-block; margin-top: 24px; font-size: 13px; color: var(--dm-accent); letter-spacing: 0.08em; border-bottom: 1px solid var(--dm-accent-line); padding-bottom: 3px; }

/* ---------- featured panels ---------- */
.dm-featured { border: 1px solid var(--dm-line); background: var(--dm-panel); margin: 44px 0; }
.dm-featured-head {
  display: flex; justify-content: space-between; align-items: baseline; padding: 14px 22px;
  border-bottom: 1px solid var(--dm-line); font-size: 11px; letter-spacing: 0.18em;
  color: var(--dm-muted-2); text-transform: uppercase;
}
.dm-fig-no { color: var(--dm-accent); }
.dm-featured-grid { display: grid; grid-template-columns: 1fr 1fr; }
.dm-featured-text { padding: 40px 22px 40px 40px; display: flex; flex-direction: column; justify-content: center; }
.dm-featured-h { margin: 0; font-family: var(--dm-display); font-weight: 700; font-size: clamp(30px, 3.6vw, 46px); line-height: 0.96; text-shadow: var(--dm-glow-2); }
.dm-featured-p { margin: 20px 0 0; font-size: 15px; line-height: 1.7; color: var(--dm-body); max-width: 48ch; }
.dm-featured-well { padding: 14px; border-left: 1px solid var(--dm-line); }
.dm-featured-rev .dm-featured-text { padding: 40px 40px 40px 22px; }
.dm-featured-rev .dm-featured-well { border-left: 0; border-right: 1px solid var(--dm-line); }
.dm-featured-rev .dm-featured-text { order: 2; }
.dm-featured-fig { width: 100%; height: 312px; }

/* ---------- 02 services ---------- */
.dm-section { padding: var(--dm-sec-pad) 4px; scroll-margin-top: 70px; }
.dm-services { margin-top: 30px; display: grid; grid-template-columns: repeat(3, 1fr); border: 1px solid var(--dm-line); }
.dm-service { display: flex; flex-direction: column; padding: 26px; border-right: 1px solid var(--dm-line); }
.dm-service:last-child { border-right: 0; }
.dm-service-well { border: 1px solid var(--dm-line-2); background: var(--dm-well); padding: 7px; }
.dm-service-fig { width: 100%; height: 148px; }
.dm-service-row { display: flex; align-items: baseline; gap: 12px; margin-top: 22px; }
.dm-service-num { font-family: var(--dm-display); font-weight: 300; font-size: 30px; color: var(--dm-accent); line-height: 1; }
.dm-service-kicker { font-size: 10px; letter-spacing: 0.2em; color: var(--dm-label); text-transform: uppercase; }
.dm-service-h { margin: 14px 0 0; font-family: var(--dm-display); font-weight: 700; font-size: 26px; }
.dm-service-p { margin: 14px 0 0; font-size: 15px; line-height: 1.72; color: var(--dm-body); flex: 1; }
.dm-ledger { margin-top: 22px; display: flex; flex-direction: column; font-size: 12px; color: var(--dm-muted-2); }
.dm-ledger span { border-top: 1px solid var(--dm-line); padding: 8px 0; }

/* ---------- 03 from the lab ---------- */
.dm-twocol { display: grid; grid-template-columns: 1fr 1fr; margin-top: 8px; }
.dm-twocol > div { padding: 34px; }
.dm-twocol > div:first-child { padding-left: 6px; border-right: 1px solid var(--dm-line); }
.dm-twocol > div:last-child { padding-right: 6px; }
.dm-card-kicker { font-size: 10px; letter-spacing: 0.2em; color: var(--dm-label); text-transform: uppercase; }
.dm-card-h { margin: 10px 0 0; font-family: var(--dm-display); font-weight: 700; font-size: 24px; }
.dm-card-p { margin: 16px 0 0; font-size: 15px; line-height: 1.7; color: var(--dm-body); }

/* ---------- 04 process ---------- */
.dm-process { display: grid; grid-template-columns: 1.2fr 1fr; gap: 48px; margin-top: 30px; align-items: start; }
.dm-process-body { display: flex; flex-direction: column; gap: 18px; }
.dm-process-body p { margin: 0; font-size: 16px; line-height: 1.72; color: var(--dm-body); }
.dm-stats { border: 1px solid var(--dm-line); }
.dm-stats-grid { display: grid; grid-template-columns: 1fr 1fr; }
.dm-stat { padding: 18px; border-bottom: 1px solid var(--dm-line); }
.dm-stat:nth-child(odd) { border-right: 1px solid var(--dm-line); }
.dm-stat:nth-child(n+3) { border-bottom: 0; }
.dm-stat-k { font-size: 10px; letter-spacing: 0.18em; color: var(--dm-label); text-transform: uppercase; }
.dm-stat-v { font-family: var(--dm-display); font-weight: 600; font-size: 20px; margin-top: 8px; }

/* ---------- contact ---------- */
.dm-contact { padding: var(--dm-sec-pad) 4px 60px; scroll-margin-top: 70px; }
.dm-contact-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 56px; align-items: start; margin-top: 40px; }
.dm-contact-h { margin: 0; font-family: var(--dm-display); font-weight: 800; font-size: clamp(40px, 6vw, 84px); line-height: 0.88; text-shadow: var(--dm-glow-2); }
.dm-contact-p { margin: 26px 0 0; font-size: 15px; line-height: 1.72; color: var(--dm-body); max-width: 42ch; }
.dm-form { display: flex; flex-direction: column; gap: 22px; }
.dm-field { display: block; }
.dm-field-label { font-size: 10px; letter-spacing: 0.2em; color: var(--dm-label); text-transform: uppercase; }
.dm-field input, .dm-field textarea {
  width: 100%; margin-top: 8px; background: transparent; border: 0;
  border-bottom: 1px solid var(--dm-line-2); color: var(--dm-ink);
  padding: 8px 0; font-size: 15px; font-family: var(--dm-mono); outline: none; resize: vertical;
}
.dm-field input:focus, .dm-field textarea:focus { border-bottom-color: var(--dm-accent); }
.dm-field input::placeholder, .dm-field textarea::placeholder { color: var(--dm-faint); }
/* ---------- standard CTA (squared, outlined-accent) — every button CTA ---------- */
.dm-cta, .dm-submit {
  display: inline-flex; align-items: center; gap: 8px; align-self: flex-start;
  border: 1px solid var(--dm-accent); background: transparent; color: var(--dm-ink);
  padding: 12px 20px; font-family: var(--dm-mono); font-size: 12px;
  letter-spacing: 0.16em; text-transform: uppercase; font-weight: 400;
  border-radius: 0; cursor: pointer; text-decoration: none;
  transition: background 200ms ease, color 200ms ease;
}
.dm-cta:hover, .dm-submit:hover { background: var(--dm-accent); color: var(--dm-bg); }
.dm-form-status { font-size: 12px; color: var(--dm-muted); min-height: 1em; }
.dm-form-status[data-state="ok"] { color: var(--dm-accent-2); }
.dm-form-status[data-state="err"] { color: #e8746a; }

/* ============================================================
   INTERIOR-PAGE COMPONENTS (about / mission / services / legal …)
   ============================================================ */

/* page header — every non-homepage page opens with one.
   A defined "letterhead" band: a subtle lift + slightly stronger feed lines than
   the page body, so the header reads as its own zone. (Light sister does the
   inverse — darker band on light — on .ds-hero.) */
.dm-page-hero {
  position: relative; overflow: hidden;
  padding: clamp(72px, 9vw, 128px) 0 clamp(40px, 5vw, 64px);
  border-bottom: 1px solid var(--dm-line-2);
  background-color: #191a20;
  background-image:
    repeating-linear-gradient(to bottom, rgba(255,255,255,0.03) 0, rgba(255,255,255,0.03) 64px, transparent 64px, transparent 128px),
    repeating-linear-gradient(to bottom, transparent 0, transparent 63px, rgba(255,255,255,0.07) 63px, rgba(255,255,255,0.07) 64px);
  background-size: 100% 128px, 100% 64px;
}
/* Light-primary pages: the letterhead band inverts to a LIGHT band (dark feed
   lines), so the dark headline ink reads. The hardcoded dark fill above is the
   dark-page treatment; this overrides it on the light sister. */
.theme-dotmatrix.theme-light .dm-page-hero {
  background-color: #e5e8ed;
  background-image:
    repeating-linear-gradient(to bottom, rgba(23,27,42,0.05) 0, rgba(23,27,42,0.05) 64px, transparent 64px, transparent 128px),
    repeating-linear-gradient(to bottom, transparent 0, transparent 63px, rgba(23,27,42,0.11) 63px, rgba(23,27,42,0.11) 64px);
}
.dm-page-hero > .dm-inner { position: relative; z-index: 1; }
.dm-page-hero-ghost {
  position: absolute; right: -0.04em; top: 50%; transform: translateY(-50%); z-index: 0;
  font-family: var(--dm-display); font-weight: 800; font-size: clamp(180px, 32vw, 500px);
  line-height: 0.78; letter-spacing: 0.02em; white-space: nowrap;
  /* --dm-line-2 (stronger than the hairline) so the ghost reads on the lighter
     letterhead band — dense words like "enough." washed out at --dm-line. */
  color: var(--dm-line-2); opacity: 0.5; pointer-events: none; user-select: none;
}
.dm-page-hero-eyebrow { font-size: 11px; letter-spacing: 0.22em; text-transform: uppercase; color: var(--dm-accent); }
.dm-page-hero-h { margin: 22px 0 0; font-family: var(--dm-display); font-weight: 800; font-size: clamp(38px, 5.6vw, 84px); line-height: 0.94; letter-spacing: 0.01em; text-shadow: var(--dm-glow); max-width: 18ch; }
.dm-page-hero-h .dm-em { color: var(--dm-accent); }
.dm-page-meta { display: flex; flex-direction: column; gap: 8px; margin-top: 34px; padding-top: 20px; border-top: 1px solid var(--dm-line); max-width: 72ch; font-family: var(--dm-mono); font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--dm-muted); }

/* closing CTA band */
.dm-cta-band { padding: clamp(60px, 9vw, 120px) 0; border-top: 1px solid var(--dm-line); background: var(--dm-bg); }
.dm-cta-band-grid { display: grid; grid-template-columns: 1.35fr 1fr; gap: clamp(32px, 5vw, 72px); align-items: end; }
.dm-cta-eyebrow { font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--dm-accent); }
.dm-cta-h { margin: 20px 0 0; font-family: var(--dm-display); font-weight: 800; font-size: clamp(34px, 4.6vw, 64px); line-height: 0.94; text-shadow: var(--dm-glow); }
.dm-cta-h .dm-em { color: var(--dm-accent); }
.dm-cta-sub { margin: 22px 0 0; font-size: 15px; line-height: 1.7; color: var(--dm-body); max-width: 50ch; }
.dm-cta-actions { display: flex; flex-direction: column; gap: 16px; align-items: flex-start; }

/* long-form prose (legal, bio, manifesto) */
.dm-prose { max-width: 68ch; counter-reset: dm-sec; }
.dm-prose > :first-child { margin-top: 0; }
.dm-prose p { margin: 0 0 20px; font-size: 16px; line-height: 1.75; color: var(--dm-body); }
.dm-prose strong { color: var(--dm-ink); font-weight: 400; }
/* Doc / section-heading standard: Doto goes muddy under ~32px, so numbered
   doc headings use the readable monospace "printout" treatment. Title stays
   INK (accent blue is reserved for interactive — links/buttons/hover — so a
   blue title would read as a link); the accent lives only on the auto-number,
   which no one mistakes for a link. Doto stays for the big display headings. */
.dm-prose h2 { counter-increment: dm-sec; font-family: var(--dm-mono); font-weight: 400; font-size: clamp(18px, 2.4vw, 23px); line-height: 1.35; letter-spacing: 0.005em; color: var(--dm-ink); margin: 52px 0 18px; padding-bottom: 12px; border-bottom: 1px solid var(--dm-line); }
.dm-prose h2::before { content: counter(dm-sec) ".\00A0"; color: var(--dm-accent); }
.dm-prose h3 { font-family: var(--dm-mono); font-weight: 400; font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--dm-label); margin: 30px 0 12px; }
.dm-prose ul, .dm-prose ol { margin: 0 0 20px; padding-left: 1.3em; color: var(--dm-body); }
.dm-prose li { margin: 0 0 10px; line-height: 1.7; }
.dm-prose a { color: var(--dm-accent); border-bottom: 1px solid var(--dm-accent-line); }
.dm-prose--doc { margin-inline: auto; }
.dm-prose-note { border: 1px solid var(--dm-line-2); background: var(--dm-panel); padding: 24px 28px; margin-top: 20px; }
.dm-prose-note p { margin: 0 0 6px; font-size: 14px; color: var(--dm-body); }
.dm-prose-note p:last-child { margin-bottom: 0; }
.dm-prose-note strong { color: var(--dm-ink); }
/* un-numbered part divider inside doc prose (e.g. Refund "Part A / Part B") —
   opts out of the auto-numbering counter so the numbered sections stay 1..n */
.dm-prose h2.dm-part { counter-increment: none; margin-top: 64px; font-size: clamp(20px, 2.8vw, 28px); color: var(--dm-ink); }
.dm-prose h2.dm-part::before { content: none; }

/* ---- 404 (dot-matrix error readout) ---- */
.dm-404 { min-height: 72vh; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: clamp(80px, 10vw, 140px) clamp(24px, 5vw, 72px); }
.dm-404-eyebrow { font-family: var(--dm-mono); font-size: 11px; letter-spacing: 0.22em; text-transform: uppercase; color: var(--dm-label); margin: 0 0 24px; }
.dm-404-code { font-family: var(--dm-display); font-weight: 800; font-size: clamp(120px, 22vw, 280px); line-height: 0.86; letter-spacing: 0.03em; color: var(--dm-ink); margin: 0; text-shadow: var(--dm-glow-2); user-select: none; }
.dm-404-zero { color: var(--dm-line-2); text-shadow: none; } /* burnt-out LED segment */
.dm-404-title { font-family: var(--dm-display); font-weight: 800; font-size: clamp(28px, 4vw, 48px); line-height: 0.96; color: var(--dm-ink); margin: 28px 0 16px; max-width: 22ch; text-shadow: var(--dm-glow); }
.dm-404-title em { color: var(--dm-body); font-style: normal; } /* muted, not accent (blue = interactive) */
.dm-404-desc { font-family: var(--dm-mono); font-size: 14px; line-height: 1.65; color: var(--dm-body); max-width: 48ch; margin: 0 auto 40px; }
.dm-404-actions { display: flex; flex-direction: column; align-items: center; gap: 26px; }
.dm-404-nav { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px 24px; }
.dm-404-nav a { font-family: var(--dm-mono); font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--dm-accent); }
@media (prefers-reduced-motion: no-preference) {
  .dm-404-zero { animation: dm-led-flicker 7s steps(1, end) infinite; }
}
@keyframes dm-led-flicker {
  0%, 90%, 100% { color: var(--dm-line-2); }
  93% { color: var(--dm-label); }
  95% { color: var(--dm-line-2); }
  97% { color: var(--dm-label); }
}

/* ---- LED dot-matrix icons (rendered by sp-doticons.js) ---- */
.dm-doticon { width: 60px; aspect-ratio: 1 / 1; --dmi-color: #eef3fb; --dmi-glow: rgba(210,225,245,0.7); }
.dm-doticon svg { width: 100%; height: 100%; display: block; overflow: visible; }
.dm-doticon .dmi-off circle { fill: var(--dm-line-2); }
.dm-doticon .dmi-lit circle { fill: var(--dmi-color); }
.dm-doticon .dmi-lit { filter: drop-shadow(0 0 1.5px var(--dmi-glow)) drop-shadow(0 0 4px var(--dmi-glow)); transform-origin: 50% 50%; }
/* per-icon color treatment (LED hues; icons are decorative, not interactive) */
.dm-doticon[data-doticon="heart"]  { --dmi-color: #ff5b60; --dmi-glow: rgba(255,91,96,0.72); }
.dm-doticon[data-doticon="cup"]    { --dmi-color: #f2a24e; --dmi-glow: rgba(242,162,78,0.68); }
/* hardhat runs deeper than the rest: safety yellow measured 1.26:1 on the light
   card, the worst in the set. #c9631a is 3.48:1 there and 4.51:1 on the dark
   design-system stage, so it holds in both places doticons appear. */
.dm-doticon[data-doticon="hardhat"]{ --dmi-color: #c9631a; --dmi-glow: rgba(201,99,26,0.55); }
.dm-doticon[data-doticon="growth"] { --dmi-color: #5fcf8e; --dmi-glow: rgba(95,207,142,0.68); }
.dm-doticon[data-doticon="bolt"]   { --dmi-color: #f2c94e; --dmi-glow: rgba(242,201,78,0.68); }
.dm-doticon[data-doticon="spark"]  { --dmi-color: #8fbcf2; --dmi-glow: rgba(143,188,242,0.68); }
/* power-on bloom when scrolled into view (JS toggles .is-lit) */
.dm-doticon--anim .dmi-lit { opacity: 0; transform: scale(0.86); }
.dm-doticon--anim.is-lit .dmi-lit { opacity: 1; transform: scale(1); transition: opacity 720ms ease, transform 760ms cubic-bezier(0.2,0.7,0.2,1); }
/* growth grows from its base */
.dm-doticon[data-doticon="growth"] .dmi-lit { transform-origin: 50% 92%; }
@media (prefers-reduced-motion: no-preference) {
  /* default: gentle glow breath (bolt / spark) */
  .dm-doticon.is-lit .dmi-lit { animation: dmi-pulse 4.6s ease-in-out 1000ms infinite; }
  /* per-icon character motion, layered over the glow breath */
  .dm-doticon[data-doticon="heart"].is-lit .dmi-lit  { animation: dmi-heart 3s   ease-in-out 1000ms infinite, dmi-pulse 4.6s ease-in-out 1000ms infinite; }
  .dm-doticon[data-doticon="cup"].is-lit .dmi-lit    { animation: dmi-steam 3.6s ease-in-out 1000ms infinite, dmi-pulse 4.6s ease-in-out 1000ms infinite; }
  .dm-doticon[data-doticon="growth"].is-lit .dmi-lit { animation: dmi-grow 3.4s  ease-in-out 1000ms infinite, dmi-pulse 4.6s ease-in-out 1000ms infinite; }
  .dm-doticon[data-doticon="hardhat"].is-lit .dmi-lit{ animation: dmi-tap 4.2s  ease-in-out 1000ms infinite, dmi-pulse 4.6s ease-in-out 1000ms infinite; }
}
@keyframes dmi-pulse {
  0%, 100% { filter: drop-shadow(0 0 1.4px var(--dmi-glow)) drop-shadow(0 0 3px var(--dmi-glow)); }
  50%      { filter: drop-shadow(0 0 2.3px var(--dmi-glow)) drop-shadow(0 0 6.5px var(--dmi-glow)); }
}
@keyframes dmi-heart { 0%, 46%, 100% { transform: scale(1); } 10% { transform: scale(1.09); } 22% { transform: scale(1); } 32% { transform: scale(1.05); } }
@keyframes dmi-steam { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-1.6px); } }
@keyframes dmi-grow  { 0%, 100% { transform: translateY(0) scale(1); } 50% { transform: translateY(-1px) scale(1.045); } }
/* hard hat settles, like it's been tapped on */
@keyframes dmi-tap   { 0%, 58%, 100% { transform: translateY(0); } 10% { transform: translateY(-2px); } 24% { transform: translateY(0); } 32% { transform: translateY(-0.7px); } 42% { transform: translateY(0); } }

/* ---- 3-up cards with an LED icon (Mission "who this is for") ---- */
.dm-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(16px, 2vw, 26px); margin-top: 10px; }
.dm-cards > article { border: 1px solid var(--dm-line); background: var(--dm-panel); padding: 30px 28px; }
.dm-cards .dm-doticon { margin-bottom: 22px; }

/* ---- heading / content split (Mission "the name") ---- */
.dm-split { display: grid; grid-template-columns: 1fr 2fr; gap: clamp(40px, 6vw, 96px); align-items: start; }

/* ---- horizontal dot-matrix timeline ---- */
.dm-timeline { margin-top: clamp(34px, 5vw, 56px); }
.dm-tl-track { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(16px, 3vw, 40px); border-top: 1px dotted var(--dm-line-2); padding-top: 30px; }
.dm-tl-node { position: relative; }
.dm-tl-node::before { content: ""; position: absolute; top: -34px; left: 0; width: 9px; height: 9px; border-radius: 50%; background: #eef3fb; box-shadow: 0 0 7px rgba(210,225,245,0.6); }
.dm-tl-date { font-family: var(--dm-mono); font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--dm-label); }
.dm-tl-label { font-family: var(--dm-display); font-weight: 700; font-size: clamp(18px, 2vw, 24px); line-height: 1; color: var(--dm-ink); margin-top: 8px; }
.dm-tl-sub { font-family: var(--dm-mono); font-size: 12px; line-height: 1.55; color: var(--dm-body); margin-top: 8px; }

/* ---- big Doto stat callouts ---- */
.dm-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(20px, 3vw, 44px); border-block: 1px solid var(--dm-line); padding-block: clamp(34px, 4vw, 56px); }
.dm-stat-num { font-family: var(--dm-display); font-weight: 800; font-size: clamp(48px, 7vw, 92px); line-height: 0.82; color: var(--dm-ink); text-shadow: var(--dm-glow-2); }
.dm-stat-label { font-family: var(--dm-mono); font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--dm-label); margin-top: 16px; }
.dm-stat-sub { font-family: var(--dm-mono); font-size: 12.5px; line-height: 1.55; color: var(--dm-body); margin-top: 8px; }

/* ---- manifesto lead prose with a Doto drop-cap ---- */
.dm-prose--lead p { font-size: 16.5px; }
.dm-prose--lead > p:first-of-type::first-letter { font-family: var(--dm-display); font-weight: 800; font-size: 3.1em; line-height: 0.72; float: left; margin: 0.06em 0.14em 0 0; color: var(--dm-ink); text-shadow: var(--dm-glow); }

/* ---- lead paragraph + pull-quote beats ---- */
.dm-lead { font-family: var(--dm-mono); font-size: 15px; line-height: 1.7; color: var(--dm-body); max-width: 62ch; margin: 0 0 clamp(28px, 4vw, 44px); }
.dm-pullquote { margin: clamp(40px, 6vw, 72px) 0; padding-left: clamp(18px, 3vw, 36px); border-left: 2px solid var(--dm-line-2); }
.dm-pullquote p { margin: 0; font-family: var(--dm-display); font-weight: 800; font-size: clamp(28px, 4vw, 52px); line-height: 1.04; color: var(--dm-ink); text-shadow: var(--dm-glow); }

/* ---- LED meter (unified) — mission gap diagram + Core Web Vitals readouts ----
   Row = label · dotted-LED track/fill · optional value. Fill extent set from
   data-fill by sp-meters.js (JS width, so no inline styles); draw-in is CSS,
   driven by the shared .reveal / .is-entering mechanism (on the meter itself
   or any ancestor). --gap variant = 2-col rows, wider label, capped width. */
.dm-meter { display: grid; gap: 14px; --dm-meter-label-w: 88px; }
.dm-meter-row { display: grid; grid-template-columns: var(--dm-meter-label-w) 1fr auto; align-items: center; gap: 14px; }
.dm-meter-label { font-family: var(--dm-mono); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--dm-label); }
.dm-meter-track { position: relative; height: 12px; border: 1px solid var(--dm-line-2); overflow: hidden; }
.dm-meter-fill { position: absolute; inset: 1px auto 1px 1px; width: 100%; background: repeating-linear-gradient(90deg, #eef3fb 0 2.5px, transparent 2.5px 8px); box-shadow: 0 0 6px rgba(210,225,245,0.3); transform-origin: left center; transform: scaleX(0); }
.dm-meter-value { font-family: var(--dm-mono); font-size: 11px; letter-spacing: 0.1em; color: var(--dm-accent); opacity: 0; }
.dm-meter-note { font-family: var(--dm-mono); font-size: 11.5px; letter-spacing: 0.04em; color: var(--dm-body); margin: 4px 0 0; }

.dm-meter--gap { --dm-meter-label-w: 120px; gap: 16px; max-width: 640px; margin-top: clamp(30px, 4vw, 50px); }
.dm-meter--gap .dm-meter-row { grid-template-columns: var(--dm-meter-label-w) 1fr; gap: 20px; }

/* draw-in + value reveal when the meter (or its section) scrolls into view */
.dm-meter.is-entering .dm-meter-fill { transform: scaleX(1); transition: transform 900ms cubic-bezier(0.2, 0.7, 0.2, 1); }
.dm-meter.is-entering .dm-meter-row:nth-child(2) .dm-meter-fill { transition-delay: 140ms; }
.dm-meter.is-entering .dm-meter-row:nth-child(3) .dm-meter-fill { transition-delay: 280ms; }
.dm-meter.is-entering .dm-meter-value { opacity: 1; transition: opacity 320ms ease; transition-delay: 780ms; }
.dm-meter.is-entering .dm-meter-row:nth-child(2) .dm-meter-value { transition-delay: 900ms; }
.dm-meter.is-entering .dm-meter-row:nth-child(3) .dm-meter-value { transition-delay: 1020ms; }
@media (prefers-reduced-motion: reduce) { .dm-meter-fill { transform: none; } .dm-meter-value { opacity: 1; } }
.dm-section-actions { margin-top: clamp(32px, 4vw, 44px); }

/* ============================================================
   SERVICES — pricing tiers, add-on cards, process steps
   ============================================================ */
/* hero descriptive paragraph (services lead under the h1) */
.dm-page-hero-desc { margin: 24px 0 0; max-width: 56ch; font-family: var(--dm-mono); font-size: 14.5px; line-height: 1.68; color: var(--dm-body); }
.dm-page-hero-desc strong { color: var(--dm-ink); font-weight: 400; }

/* card-grid column modifiers + card footer (add-ons) */
.dm-cards--two { grid-template-columns: 1fr 1fr; }
.dm-cards--two > article { display: flex; flex-direction: column; }
.dm-cards--two .dm-card-p { flex: 1; }
.dm-card-foot { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-top: 24px; padding-top: 16px; border-top: 1px solid var(--dm-line); }
.dm-card-price { font-family: var(--dm-mono); font-size: 12.5px; letter-spacing: 0.04em; color: var(--dm-body); }
.dm-card-foot .dm-inline-link { margin-top: 0; }

/* pricing tiers */
.dm-tiers { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(18px, 2vw, 28px); margin-top: 12px; }
.dm-tier { display: flex; flex-direction: column; border: 1px solid var(--dm-line); background: var(--dm-panel); padding: clamp(30px, 4vw, 46px); }
.dm-tier--featured { border-color: var(--dm-line-2); box-shadow: 0 24px 60px -40px rgba(0,0,0,0.85); }
.dm-tier-badge { font-family: var(--dm-mono); font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--dm-label); margin-bottom: 22px; }
.dm-tier-name { margin: 0 0 18px; font-family: var(--dm-display); font-weight: 800; font-size: clamp(30px, 3.6vw, 46px); line-height: 0.92; color: var(--dm-ink); text-shadow: var(--dm-glow); }
.dm-tier-name em { font-style: normal; color: var(--dm-muted); }
.dm-tier-price { font-family: var(--dm-mono); font-size: 22px; letter-spacing: 0.01em; color: var(--dm-ink); }
.dm-tier-price-note { font-family: var(--dm-mono); font-size: 12px; color: var(--dm-muted); margin-top: 6px; }
.dm-tier-rule { height: 1px; background: var(--dm-line); margin: 26px 0; }
.dm-tier-inc { font-family: var(--dm-mono); font-size: 10.5px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--dm-label); margin-bottom: 16px; }
.dm-tier-items { list-style: none; margin: 0 0 32px; padding: 0; display: flex; flex-direction: column; gap: 13px; flex: 1; }
.dm-tier-item { display: flex; gap: 13px; font-size: 14px; line-height: 1.55; color: var(--dm-body); padding-bottom: 13px; border-bottom: 1px solid var(--dm-line); }
.dm-tier-item:last-child { padding-bottom: 0; border-bottom: 0; }
.dm-tier-item::before { content: ""; flex-shrink: 0; width: 5px; height: 5px; margin-top: 6px; border-radius: 50%; background: #eef3fb; box-shadow: 0 0 5px rgba(210,225,245,0.5); }
.dm-tier-label { color: var(--dm-ink); }
.dm-tier .dm-cta { align-self: stretch; justify-content: center; }
.dm-tier-offer { margin-top: 16px; font-family: var(--dm-mono); font-size: 10.5px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--dm-muted); text-align: center; }

/* process — four numbered steps */
.dm-steps { display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(14px, 1.6vw, 22px); margin-top: 12px; }
.dm-steps > article { border: 1px solid var(--dm-line); background: var(--dm-panel); padding: 26px 24px; }
.dm-step-num { font-family: var(--dm-display); font-weight: 300; font-size: clamp(30px, 3vw, 42px); line-height: 1; color: var(--dm-accent); }
.dm-step-h { margin: 14px 0 0; font-family: var(--dm-display); font-weight: 700; font-size: 21px; line-height: 1.1; }
.dm-step-p { margin: 14px 0 0; font-size: 13.5px; line-height: 1.65; color: var(--dm-body); }

@media (max-width: 860px) {
  .dm-cards { grid-template-columns: 1fr; }
  .dm-split { grid-template-columns: 1fr; gap: 28px; }
  .dm-tiers { grid-template-columns: 1fr; }
  .dm-steps { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 520px) {
  .dm-steps { grid-template-columns: 1fr; }
}
@media (max-width: 760px) {
  .dm-tl-track { grid-template-columns: 1fr; gap: 30px; }
  .dm-tl-node::before { top: -22px; }
  .dm-stats { grid-template-columns: 1fr; gap: 30px; }
}

/* bio — portrait figure + prose */
.dm-bio { display: grid; grid-template-columns: 0.85fr 1.4fr; gap: clamp(32px, 5vw, 80px); align-items: start; }
/* square matte LED portrait — full-frame square photo in a thin well mat,
   consistent with the other dot-matrix figures */
.dm-bio-fig { position: relative; border: 1px solid var(--dm-line-2); background: var(--dm-well); aspect-ratio: 1 / 1; }
.dm-bio-fig canvas { position: absolute; top: 7px; left: 7px; width: calc(100% - 14px); height: calc(100% - 14px); display: block; }

/* beliefs — numbered two-column list */
.dm-beliefs { display: grid; grid-template-columns: 1fr 1fr; gap: 0 clamp(28px, 3vw, 56px); }
.dm-belief { display: grid; grid-template-columns: auto 1fr; gap: 20px; padding: 26px 0; border-top: 1px solid var(--dm-line); }
.dm-belief-num { font-family: var(--dm-display); font-weight: 300; font-size: 30px; line-height: 1; color: var(--dm-accent); }
.dm-belief-title { font-family: var(--dm-display); font-weight: 700; font-size: 17px; line-height: 1.3; color: var(--dm-ink); margin: 0 0 10px; }
.dm-belief-text { font-size: 14.5px; line-height: 1.65; color: var(--dm-muted); }

/* metrics — big-number cards (experience / stats) */
.dm-metrics { display: grid; grid-template-columns: repeat(3, 1fr); border: 1px solid var(--dm-line); margin-top: 30px; }
.dm-metric { padding: 34px 28px; border-right: 1px solid var(--dm-line); }
.dm-metric:last-child { border-right: 0; }
.dm-metric-num { font-family: var(--dm-display); font-weight: 800; font-size: clamp(48px, 6vw, 82px); line-height: 1; color: var(--dm-ink); text-shadow: var(--dm-glow); }
.dm-metric-title { font-family: var(--dm-display); font-weight: 700; font-size: 16px; margin: 18px 0 10px; color: var(--dm-ink); }
.dm-metric-desc { font-size: 14px; line-height: 1.65; color: var(--dm-muted); }

/* interior-page stacking */
@media (max-width: 860px) {
  .dm-cta-band-grid { grid-template-columns: 1fr; align-items: start; gap: 28px; }
  .dm-bio { grid-template-columns: 1fr; }
  .dm-bio-fig { max-width: 340px; }
  .dm-beliefs { grid-template-columns: 1fr; }
  .dm-metrics { grid-template-columns: 1fr; }
  .dm-metric { border-right: 0; border-bottom: 1px solid var(--dm-line); }
  .dm-metric:last-child { border-bottom: 0; }
}

/* ============================================================
   FOOTER (injected <sp-footer>) — dark overrides
   ============================================================ */
.theme-dotmatrix .site-footer { background: transparent; border-top: 1px solid var(--dm-line-2); color: var(--dm-muted); }
.theme-dotmatrix .footer-wordmark span { font-family: var(--dm-display); font-weight: 800; letter-spacing: 0.04em; color: var(--dm-ink); }
.theme-dotmatrix .footer-brand p { color: var(--dm-muted-2); }
.theme-dotmatrix .footer-meta { color: var(--dm-label-2); }
.theme-dotmatrix .footer-col h3 { font-family: var(--dm-mono); font-size: 10px; letter-spacing: 0.2em; color: var(--dm-label); text-transform: uppercase; }
.theme-dotmatrix .footer-col a { color: var(--dm-muted); }
.theme-dotmatrix .footer-col a:hover { color: var(--dm-ink); }
.theme-dotmatrix .footer-social a { color: var(--dm-muted); }
.theme-dotmatrix .footer-social a:hover { color: var(--dm-accent); }

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (max-width: 980px) {
  .dm-abstract { grid-template-columns: 1fr; gap: 22px; }
  .dm-abstract-copy { padding-top: 0; }
  .dm-featured-grid { grid-template-columns: 1fr; }
  .dm-featured-rev .dm-featured-text { order: 0; }
  .dm-featured-well, .dm-featured-rev .dm-featured-well { border-left: 0; border-right: 0; border-top: 1px solid var(--dm-line); }
  .dm-twocol { grid-template-columns: 1fr; }
  .dm-twocol > div:first-child { border-right: 0; border-bottom: 1px solid var(--dm-line); padding-left: 6px; }
  .dm-twocol > div:last-child { padding-left: 6px; }   /* stacked: align with first child, was left-indented by base 34px pad */
  .dm-process { grid-template-columns: 1fr; gap: 28px; }
  .dm-contact-grid { grid-template-columns: 1fr; gap: 32px; }
}
@media (max-width: 860px) {
  .theme-dotmatrix { --dm-inner: 88%; }
  .dm-services { grid-template-columns: 1fr; }
  .dm-service { border-right: 0; border-bottom: 1px solid var(--dm-line); }
  .dm-service:last-child { border-bottom: 0; }
  .dm-featured-text { padding: 28px 22px; }
  .dm-featured-rev .dm-featured-text { padding: 28px 22px; }
}
@media (max-width: 560px) {
  .theme-dotmatrix { --dm-inner: 90%; --dm-edge: 24px; }
  /* content nears full width here — pull the feed margins so they don't clip it */
  .theme-dotmatrix body::before,
  .theme-dotmatrix body::after { display: none; }
  #heroFig { height: clamp(420px, 70vh, 560px); }
  .dm-hero-cap .dm-inner { padding: 64px 0 32px; }
  .dm-hero-ctrl { gap: 10px; }
  .dm-featured-fig { height: 220px; }
  .dm-stats-grid { grid-template-columns: 1fr; }
  .dm-meter--gap { --dm-meter-label-w: 84px; }
  .dm-meter--gap .dm-meter-row { gap: 14px; }
}

/* ============================================================
   REDUCED MOTION — kill the wipe/intro transitions
   (the JS also skips the sweep + intro entirely)
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  .dm-intro { display: none; }
  .dm-dotmark span { transition: none; opacity: 1; transform: none; }
  .dm-tick { transition: none; }
}

/* ============================================================
   HOMEPAGE — Project Dotmatrix "dark done right"
   The dark board on the GridSim "sp" grid (1320 max-width · 24px margin ·
   12 cols · 24px gutter) with full-bleed tonal zones. Scoped to the homepage
   (body.has-hero) as the reference build; generalize to the other pages on
   rollout. Reversible: drop this block + restore the light flip.
   ============================================================ */

/* --- container: anchor to the sp grid (1320/24), replacing the 76%/2000 float --- */
body.has-hero .dm-doc.dm-inner,
body.has-hero .dm-hero-top .dm-inner,
body.has-hero .dm-hero-cap .dm-inner {
  width: auto;
  max-width: 1320px;
  margin-inline: auto;
  padding-inline: clamp(24px, calc(var(--dm-edge) - (100vw - 1320px) / 2), var(--dm-edge));
}
body.has-hero .dm-hero-cap .dm-inner { padding-top: 64px; padding-bottom: 32px; }

/* homepage: the hero (desktop ticks / mobile caption) flows straight into the
   first letterhead band — drop the 64px doc gap that read as an empty band */
body.has-hero .dm-doc { padding-top: 0; }

/* --- every content section becomes a 12-col grid on the shared lines --- */
body.has-hero .dm-doc > section {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: 24px;
  padding-left: 0;
  padding-right: 0;
  position: relative;
}
/* default: section children span all 12; specific splits override below */
body.has-hero .dm-doc > section > * { grid-column: 1 / -1; }

/* abstract — headline cols 1-6, body cols 8-12 */
body.has-hero .dm-abstract > .dm-abstract-lead { grid-column: 1 / 7; align-self: start; }
body.has-hero .dm-abstract > .dm-abstract-copy { grid-column: 8 / 13; align-self: start; }

/* contact — copy/form split on the same column lines */
body.has-hero .dm-contact-grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: 24px;
}
body.has-hero .dm-contact-grid > :first-child { grid-column: 1 / 7; }
body.has-hero .dm-contact-grid > :last-child  { grid-column: 8 / 13; }

/* Mobile: collapse the homepage section grids to one stacked column. Otherwise
   the abstract body (cols 8-12) and the contact copy/form split stay pinned to a
   narrow half-width column — in monospace that wraps to 2-3 words per line on a
   phone (an unreadable ribbon). Stack full-width below the heading instead. */
@media (max-width: 860px) {
  body.has-hero .dm-doc > section,
  body.has-hero .dm-contact-grid {
    grid-template-columns: 1fr;
    row-gap: 28px;
  }
  body.has-hero .dm-abstract > .dm-abstract-lead,
  body.has-hero .dm-abstract > .dm-abstract-copy,
  body.has-hero .dm-contact-grid > :first-child,
  body.has-hero .dm-contact-grid > :last-child {
    grid-column: 1 / -1;
  }
  /* mobile-only hero declutter (desktop keeps the numbered strip + index + full
     controls): hide the tick strip + index, shrink the play controls, strengthen
     the title scrim over the busy emblem, and tighten the hero -> content gap */
  .dm-hero-index, .dm-hero-ticks { display: none; }
  .dm-hero-ctrl { gap: 10px; }
  .dm-iconbtn { width: 34px; height: 34px; font-size: 12px; }
  .dm-hero-cap { background: linear-gradient(to top, rgba(14,15,18,0.97) 0%, rgba(14,15,18,0.9) 40%, rgba(14,15,18,0.6) 70%, transparent 100%); }
  .dm-hero-meta { margin-bottom: 0; }
  body.has-hero .dm-hero-cap .dm-inner { padding-bottom: 16px; }
}

/* --- full-bleed tonal zones (content stays gridded, band spans the viewport) --- */
body.has-hero .dm-abstract,
body.has-hero .dm-section:not([id]),
body.has-hero #process,
body.has-hero .dm-contact { background: transparent; }

body.has-hero .dm-abstract::before,
body.has-hero .dm-section:not([id])::before,
body.has-hero #process::before,
body.has-hero .dm-contact::before {
  content: "";
  position: absolute; top: 0; bottom: 0;
  left: 50%; margin-left: -50vw; width: 100vw;
  z-index: -1;
  border-top: 1px solid var(--dm-line-2);
}
body.has-hero .dm-abstract::before,
body.has-hero .dm-section:not([id])::before,
body.has-hero .dm-contact::before {
  background-color: var(--dm-well);
  background-image: repeating-linear-gradient(
    to bottom,
    rgba(255,255,255,0.014) 0, rgba(255,255,255,0.014) 64px,
    transparent 64px, transparent 128px);
  background-size: 100% 128px;
}
body.has-hero #process::before { background-color: var(--dm-panel); }

/* featured — lifted, bordered plate spanning the grid width */
body.has-hero .dm-featured { border-color: var(--dm-line-2); }

/* footer — onto the sp grid (site-wide): 1320 cap already correct, fix padding
   72→24 and gutter 32→24 so its 12 columns (brand span-4 + 4× span-2) land on
   the lines; same printable-area clamp as .dm-inner so it tracks the content gutter */
.theme-dotmatrix .site-footer .inner { padding-inline: clamp(24px, calc(var(--dm-edge) - (100vw - 1320px) / 2), var(--dm-edge)); column-gap: 24px; }

/* nav — bar stays full-width; cap its content to the sp grid (site-wide) so the
   logo lands on col 1, aligned with content + footer on every page */
.theme-dotmatrix .nav { padding-inline: max(var(--dm-edge), calc((100% - 1320px) / 2 + 24px)); }

/* ============================================================
   BACK-TO-TOP — scroll shortcut, injected on every page by sp-shell.js.
   Surfaces after ~a screenful of scroll; hidden otherwise.
   ============================================================ */
.dm-totop {
  position: fixed; right: 24px; bottom: 24px; z-index: 60;
  width: 46px; height: 46px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--dm-line-2);
  background: rgba(18, 19, 23, 0.82);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  color: var(--dm-ink); font-family: var(--dm-mono); font-size: 18px; line-height: 1;
  cursor: pointer;
  opacity: 0; visibility: hidden; transform: translateY(10px);
  transition: opacity .25s ease, transform .25s ease, visibility .25s, border-color .2s, color .2s;
}
.dm-totop.is-shown { opacity: 1; visibility: visible; transform: none; }
.dm-totop:hover { border-color: var(--dm-accent); color: var(--dm-accent); }
@media (prefers-reduced-motion: reduce) { .dm-totop { transition: opacity .25s ease, visibility .25s; transform: none; } }

/* ============================================================
   INTERIOR PAGES — tonal zone rhythm ("dark done right" everywhere)
   Content sections drop into full-bleed recessed well bands with the
   feed-line texture, alternating with base-bg sections, so content pages
   carry the same printed-document rhythm as the homepage. Multi-section
   pages (dm-doc) band every other section; single-section pages (prose,
   USA memo) band their one content section. Homepage keeps its own zones.
   ============================================================ */
body:not(.has-hero) .dm-doc > .dm-section,
body:not(.has-hero) main > .dm-section,
body:not(.has-hero) .dm-cta-band { position: relative; }

body:not(.has-hero) .dm-doc > .dm-section:nth-of-type(odd)::before,
body:not(.has-hero) main > .dm-section::before {
  content: "";
  position: absolute; top: 0; bottom: 0;
  left: 50%; margin-left: -50vw; width: 100vw; z-index: -1;
  border-top: 1px solid var(--dm-line-2);
  border-bottom: 1px solid var(--dm-line-2);
  background-color: var(--dm-well);
  background-image: repeating-linear-gradient(
    to bottom,
    rgba(255,255,255,0.014) 0, rgba(255,255,255,0.014) 64px,
    transparent 64px, transparent 128px);
  background-size: 100% 128px;
}

/* closing CTA band — a full-bleed lifted plate so it spans the width like the
   sections above it, reading as the page's deliberate call to action */
body:not(.has-hero) .dm-cta-band { background: transparent; border-top: 0; }
body:not(.has-hero) .dm-cta-band::before {
  content: "";
  position: absolute; top: 0; bottom: 0;
  left: 50%; margin-left: -50vw; width: 100vw; z-index: -1;
  border-top: 1px solid var(--dm-line-2);
  border-bottom: 1px solid var(--dm-line-2);
  background-color: var(--dm-panel);
}

/* ============================================================
   SPECIAL carousel slide — USA 250 (July 4th). Celebratory type over the
   flag: warm gold from the seal, glowing headline, a clear CTA to the memo.
   ============================================================ */
.dm-hero-meta.is-special .dm-hero-cat { color: #e8c877; }
.dm-hero-meta.is-special .dm-hero-title {
  text-shadow: 0 0 26px rgba(232, 200, 119, 0.30), 0 2px 10px rgba(0, 0, 0, 0.6);
}
.dm-hero-meta.is-special .dm-hero-url {
  display: inline-flex; align-items: center; margin-top: 20px;
  padding: 9px 16px; border: 1px solid rgba(232, 200, 119, 0.55);
  color: #f0d99a; letter-spacing: 0.08em;
  transition: background 200ms ease, color 200ms ease, border-color 200ms ease;
}
.dm-hero-meta.is-special .dm-hero-url:hover {
  background: #e8c877; color: #1a1206; border-color: #e8c877;
}
/* "America" in red/white/blue — a flag gradient clipped to the Doto dots */
.dm-usa-flag {
  background: linear-gradient(96deg,
    #d92d3f 0%, #d92d3f 33%,
    #eceef2 42%, #eceef2 58%,
    #3f6fd6 67%, #3f6fd6 100%);
  -webkit-background-clip: text; background-clip: text;
  color: transparent; -webkit-text-fill-color: transparent;
  text-shadow: none;
}
