/* ==========================================================================
   styles.css — "Operating System for Retail" schematic system.
   Reads tokens from theme.css ONLY. No hardcoded color/font/size here.

   Recurring motif components (the brand's visual grammar):
     .grid-bg   -> faint coordinate grid behind a section
     .tick      -> a measurement tick mark
     .index     -> monospace index label  e.g.  [ 01 / SERVICE ]
     .coord     -> monospace coordinate pair
     .ledger    -> full-width expandable schematic row
   Each major section reuses these but composes them differently so no two
   sections read as clones.
   ========================================================================== */

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

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}

img {
  max-width: 100%;
  display: block;
}

/* ---- Intro curtain ----------------------------------------------------
   Full-screen panel shown on the home page's first load of a session. Sits
   above everything, holds the logo briefly, then wipes upward to reveal the
   hero. main.js adds .intro--done to trigger the wipe and .intro--off (after
   the wipe finishes) to take it out of the layout entirely.

   Themed via tokens so it inverts in dark mode with the rest of the site.
   The wipe uses clip-path so it reveals the real hero underneath rather than
   fading a screenshot — no layout shift, nothing to reflow. */
/* The intro has THREE selectable styles, chosen by data-intro on the .intro
   div in index.html: "wipe" | "fade" | "stamp". Change that one attribute to
   compare them. Shared base below; per-style overrides follow.

   In all three, main.js adds .intro--done after a hold to start the exit, then
   .intro--off once it finishes to remove the panel from the layout. */
.intro {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: grid;
  place-items: center;
}

/* Removed from the flow after the exit so it can't trap a click / tab stop. */
.intro--off {
  display: none;
}

.intro-mark {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
}

.intro-mark img {
  width: clamp(120px, 22vw, 200px);
  height: auto;
}

/* -- STYLE 1: contrast curtain wipe ------------------------------------
   The panel is the dark ink ground (always dark, both themes — same idea as
   the footer band), so the sheet is clearly visible against the lighter hero.
   The logo flattens to white on it. On exit the whole sheet slides up off the
   top edge, uncovering the hero. THIS is the only style where the wipe reads,
   because there's a color edge to see move. */
.intro[data-intro="wipe"] {
  background: var(--end-bg);            /* fixed dark ground, both themes */
  transition: transform 1.1s var(--ease);   /* the upward wipe speed */
}
.intro[data-intro="wipe"] .intro-mark { animation: intro-rise 0.7s var(--ease) both; }
.intro[data-intro="wipe"] .intro-mark img { filter: brightness(0) invert(1); } /* white on dark */
.intro[data-intro="wipe"].intro--done { transform: translateY(-100%); }

/* -- STYLE 2: simple fade -----------------------------------------------
   Same-color panel, no directional motion. Logo fades in, holds, the whole
   panel fades out. Calm, no wipe to interpret. */
.intro[data-intro="fade"] {
  background: var(--paper);
  opacity: 1;
  transition: opacity 0.6s var(--ease);
}
.intro[data-intro="fade"] .intro-mark { animation: intro-rise 0.7s var(--ease) both; }
.intro[data-intro="fade"] .intro-mark img { filter: brightness(0); }
.intro[data-intro="fade"].intro--done { opacity: 0; }

/* -- STYLE 3: logo stamp -------------------------------------------------
   Logo scales up from slightly small while fading in (a brand "stamp"), then
   the whole panel fades out. The motion is on the logo, not a curtain edge. */
.intro[data-intro="stamp"] {
  background: var(--paper);
  opacity: 1;
  transition: opacity 0.6s var(--ease);
}
.intro[data-intro="stamp"] .intro-mark { animation: intro-stamp 0.8s var(--ease) both; }
.intro[data-intro="stamp"] .intro-mark img { filter: brightness(0); }
.intro[data-intro="stamp"].intro--done { opacity: 0; }

/* Dark-mode logo color for the fade/stamp styles (paper panel). The wipe sets
   its own white logo above and must not be overridden, hence :not([wipe]). */
[data-theme="dark"] .intro:not([data-intro="wipe"]) .intro-mark img { filter: brightness(0) invert(1); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) .intro:not([data-intro="wipe"]) .intro-mark img { filter: brightness(0) invert(1); }
}

.intro-word {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
  color: var(--ink-3);
}

@keyframes intro-rise {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes intro-stamp {
  from { opacity: 0; transform: scale(0.82); }
  to   { opacity: 1; transform: scale(1); }
}

/* Reduced motion: no animation. main.js removes the curtain immediately, but
   if JS is slow/off this keeps it from moving. */
@media (prefers-reduced-motion: reduce) {
  .intro { transition: none; }
  .intro-mark { animation: none; }
}

a {
  color: inherit;
  text-decoration: none;
}

/* ---- Type primitives -------------------------------------------------- */
.display {
  font-family: var(--font-display);
  font-weight: 800;
  line-height: var(--lh-tight);
  letter-spacing: var(--tracking-display);
  text-transform: uppercase;
}

h1,
h2,
h3 {
  margin: 0;
}

h1 {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: var(--fs-h1);
  line-height: var(--lh-snug);
  letter-spacing: var(--tracking-display);
  text-transform: uppercase;
}

h2 {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: var(--fs-h2);
  line-height: var(--lh-snug);
  letter-spacing: var(--tracking-display);
  text-transform: uppercase;
}

h3 {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: var(--fs-h3);
  line-height: var(--lh-snug);
}

p {
  margin: 0 0 var(--space-3);
  color: var(--ink-2);
}

.lede {
  font-size: var(--fs-lede);
  line-height: 1.4;
  color: var(--ink);
  font-weight: 500;
}

/* The monospace schematic label — the signature element.
   Used as [ 01 / LABEL ] all over the site. */
.index {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
  color: var(--ink-3);
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
}

.index::before {
  /* the leading tick */
  content: "";
  width: 18px;
  height: 1px;
  background: var(--signal);
  display: inline-block;
}

.index .num {
  color: var(--signal);
}

.coord {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: 0.08em;
  color: var(--ink-3);
}

/* ---- Layout ----------------------------------------------------------- */
.wrap {
  width: min(100% - 2.5rem, var(--maxw));
  margin-inline: auto;
}

.bleed {
  width: 100%;
}

/* Mobile uses noticeably tighter padding (~60% of the old mobile values) so
   sections don't feel sparse on small screens; the larger "release" spacing
   only kicks in on wider screens. */
.section {
  padding-block: var(--space-5);
  /* 2.5rem (was 4rem) */
  position: relative;
}

@media (min-width: 900px) {
  .section {
    padding-block: var(--space-8);
  }
}

.section--airy {
  padding-block: 3rem;
  /* was 5rem */
}

@media (min-width: 900px) {
  .section--airy {
    padding-block: var(--space-9);
  }
}

.section--dense {
  padding-block: 2.25rem;
  /* was 4rem */
}

@media (min-width: 900px) {
  .section--dense {
    padding-block: var(--space-6);
  }
}

/* The faint coordinate grid. ONE fixed, full-page layer so the cells are
   perfectly uniform and continuous down the whole site — no restart or gap
   at section boundaries, no per-section size mismatch. It sits behind all
   content; transparent/paper sections let it show through, and the opaque
   dark end block covers it (the end block draws its own matching grid). */
/* VERTICAL lines only — column guides. The layout already supplies all the
   horizontal rules (ledger rows, borders, dividers), so a full grid would
   double up on horizontals. Vertical-only complements them. No mask: the
   columns run uniformly the full height. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image:
    linear-gradient(to right, var(--grid-line) 1px, transparent 1px);
  background-size: 64px 100%;
  /* anchor to top-left so the columns are stable regardless of scroll */
  background-position: 0 0;
}

/* A second, very soft paper vignette behind the content — gently deepens the
   paper toward the corners so the page has a subtle frame. Sits above the
   grid (z -1) but still behind all content. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  /* fixed dark tint (not --ink, which inverts in dark mode) so corners deepen
     in BOTH themes; --vignette is set per-theme for the right strength */
  background: radial-gradient(130% 130% at 50% 40%, transparent 82%, var(--vignette) 100%);
}

/* .grid-bg is now just a layout marker; the page-wide grid above does the
   drawing. Keep the class so existing markup/stacking still works. */
.grid-bg {
  position: relative;
}

.grid-bg>* {
  position: relative;
  z-index: 1;
}

/* A horizontal ledger rule with end ticks — separates authored sections. */
.rule-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  color: var(--ink-3);
}

.rule-row .line {
  flex: 1;
  height: 1px;
  background: var(--line-strong);
}

/* ---- Buttons ---------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.7em;
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: 1em 1.6em;
  border: 1px solid var(--ink);
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  position: relative;
  overflow: hidden;
  /* isolate creates a stacking context scoped to the button, so the fill's
     z-index: -1 sits behind the TEXT but still inside the button — not behind
     the whole button. This keeps bare text nodes above the fill without
     needing to wrap them in an element. */
  isolation: isolate;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}

/* fill wipes in from the left on hover — a "loading bar" gesture.
   z-index: -1 is scoped behind the text (not the whole button) because .btn
   sets `isolation: isolate`. This is what keeps bare text nodes visible over
   the fill. */
.btn::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--signal);
  transform: scaleX(0);
  transform-origin: left;
  z-index: -1;
  transition: transform var(--dur) var(--ease);
}

/* The periwinkle fill is light, so hover text is dark ink, not white —
   white-on-periwinkle fails contrast. Dark text reads on the fill in both
   themes (the fill is a light periwinkle in light AND dark mode). */
.btn:hover {
  color: var(--on-signal);
  border-color: var(--signal);
}

.btn:hover::before {
  transform: scaleX(1);
}

.btn .arrow {
  transition: transform var(--dur) var(--ease);
}

.btn:hover .arrow {
  transform: translateX(4px);
}

.btn--solid {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
}

.btn--solid:hover {
  color: var(--on-signal);
  border-color: var(--signal);
}

/* ==========================================================================
   HEADER — a thin instrument bar. Mono nav, live "coordinate" readout.
   ========================================================================== */
.site-header {
  position: sticky;
  top: 0;
  z-index: 60;
  background: color-mix(in srgb, var(--paper) 82%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}

.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 78px;
}

.brand {
  display: flex;
  align-items: center;
}

/* Logo carries the brand — no text beside it. The PNG is blue, which clashes
   with the red accent, so we flatten it to monochrome ink (brightness(0))
   to sit in the schematic system. Header bar height caps how tall it can go. */
.brand img {
  height: 48px;
  width: auto;
  filter: brightness(0);
}

@media (max-width: 520px) {
  .brand img {
    height: 42px;
  }
}

[data-theme="dark"] .brand img {
  filter: brightness(0) invert(1);
}

/* First-visit fallback: before any theme is saved, no data-theme attribute
   exists, so the rule above can't match — the logo would stay black on an
   OS-dark first load until the user clicks the toggle. Mirror the invert via
   the media query for the un-attributed state. (Same pattern theme.css uses
   for its dark tokens.) */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) .brand img {
    filter: brightness(0) invert(1);
  }
}

.nav-links {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  list-style: none;
  margin: 0;
  padding: 0;
}

.nav-links a {
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  letter-spacing: 0.04em;
  color: var(--ink-2);
  position: relative;
  padding-block: 0.3rem;
}

.nav-links a .n {
  color: var(--ink-3);
  margin-right: 0.4em;
  font-size: 0.7em;
}

.nav-links a:hover,
.nav-links a[aria-current="page"] {
  color: var(--ink);
}

.nav-links a[aria-current="page"] .n {
  color: var(--signal);
}

.nav-links a::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -2px;
  height: 2px;
  width: 100%;
  background: var(--signal);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur) var(--ease);
}

.nav-links a:hover::after,
.nav-links a[aria-current="page"]::after {
  transform: scaleX(1);
}

.nav-actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.theme-toggle {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--ink-2);
  cursor: pointer;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}

.theme-toggle:hover {
  color: var(--signal);
  border-color: var(--signal);
}

.theme-toggle .sun {
  display: none;
}

[data-theme="dark"] .theme-toggle .sun {
  display: block;
}

[data-theme="dark"] .theme-toggle .moon {
  display: none;
}

.nav-toggle {
  display: none;
  background: none;
  border: 0;
  cursor: pointer;
  padding: 6px;
  color: var(--ink);
}

.nav-toggle svg {
  width: 26px;
  height: 26px;
}

@media (max-width: 880px) {
  .nav-toggle {
    display: inline-flex;
  }

  .nav-links {
    position: fixed;
    inset: 66px 0 auto 0;
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    background: var(--paper);
    border-bottom: 1px solid var(--line-strong);
    padding: var(--space-2) 0;
    transform: translateY(-10px);
    opacity: 0;
    pointer-events: none;
    transition: transform var(--dur) var(--ease), opacity var(--dur) var(--ease);
  }

  .nav-links.open {
    transform: none;
    opacity: 1;
    pointer-events: auto;
  }

  .nav-links li {
    width: 100%;
  }

  .nav-links a {
    display: block;
    padding: var(--space-3) 1.25rem;
  }

  .nav-links a::after {
    display: none;
  }
}

/* ==========================================================================
   HERO — the visual hook. Oversized statement broken across a drafting
   grid, with hanging mono annotations, a plotted marker, and the wordmark
   bleeding to the right edge. Asymmetric, layered, unmistakable.
   ========================================================================== */
.hero {
  position: relative;
  padding-top: var(--space-6);
  padding-bottom: var(--space-7);
  overflow: hidden;
}

/* The hero no longer draws its own grid — the page-wide body::before grid
   shows through. Element kept for markup compatibility / scan-line layering. */
.hero-grid-bg {
  display: none;
}

/* a single saturated horizontal "scan" rule crossing the hero */
/* Decorative scan rule. Its top: 38% is a fraction of the hero height, which
   on mobile (taller, reflowed hero) drifts onto the headline and looks like a
   strikethrough. It's a desktop composition element, so hide it on mobile. */
.hero-scan {
  display: none;
}

@media (min-width: 760px) {
  .hero-scan {
    display: block;
    position: absolute;
    left: 0;
    right: 0;
    top: 58%;
    height: 1px;
    background: var(--signal);
    opacity: 0.5;
    z-index: 0;
    /* the brand wipe, on load: the scan line sweeps across left-to-right */
    transform: scaleX(0);
    transform-origin: left;
    animation: scan-wipe 1.1s var(--ease) 0.25s forwards;
  }
}

@keyframes scan-wipe {
  to {
    transform: scaleX(1);
  }
}

@media (prefers-reduced-motion: reduce) {
  .hero-scan {
    animation: none;
    transform: scaleX(1);
  }
}

.hero-scan::after {
  content: "";
  position: absolute;
  right: 10%;
  top: -3px;
  width: 7px;
  height: 7px;
  background: var(--signal);
  border-radius: 50%;
}

.hero-inner {
  position: relative;
  z-index: 2;
}

.hero-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: var(--space-5);
}

.hero-meta .coord {
  white-space: nowrap;
}

.hero-statement {
  position: relative;
}

.hero-statement .line {
  display: block;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: var(--fs-mega);
  line-height: var(--lh-tight);
  letter-spacing: var(--tracking-display);
  text-transform: uppercase;
}

/* second line is pushed right — broken grid, not centered */
/* The broken-grid right-shift is a desktop composition. On mobile it just
   pushes long words (e.g. "operational") toward the edge, so drop it and
   let every line start flush left. */
.hero-statement .line.shift {
  padding-left: 0;
}

@media (min-width: 760px) {
  .hero-statement .line.shift {
    padding-left: clamp(0px, 14vw, 16rem);
  }
}

.hero-statement .line .mark {
  color: var(--signal);
}

/* outlined word adds depth/layering without a photo */
.hero-statement .line .outline {
  color: transparent;
  -webkit-text-stroke: 1.5px var(--ink);
}

.hero-statement .sub-line {
  display: block;
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: clamp(0.7rem, 1.6vw, 0.95rem);
  line-height: var(--lh-snug);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-2);
  margin-top: var(--space-3);
  padding-left: 1.4em;
  line-height: 1.7;
  position: relative;
}

.hero-statement .sub-line::before {
  content: "→";
  position: absolute;
  left: 0;
  color: var(--signal);
}

.hero-foot {
  display: grid;
  gap: var(--space-5);
  margin-top: var(--space-6);
}

@media (min-width: 860px) {
  .hero-foot {
    grid-template-columns: 1.2fr 1fr;
    align-items: end;
  }
}

.hero-foot .lede {
  max-width: 40ch;
}

.hero-cta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-4);
}

/* the plotted-stat readout, right column of hero foot — a mini dashboard */
.readout {
  border-top: 1px solid var(--line-strong);
}

.readout .row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: var(--space-3);
  align-items: baseline;
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--line);
}

.readout .row .k {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--tracking-mono);
  color: var(--ink-3);
  text-transform: uppercase;
}

/* .dots span is just the flexible spacer (the row's 1fr middle column) that
   pushes the value right. The dotted leader line was removed — the row
   borders already separate items, so it read as extra clutter. No styles
   needed on .dots itself. */

.readout .row .v {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.5rem;
}

.readout .row .v.signal {
  color: var(--signal);
}

/* ==========================================================================
   SERVICES — a stacked LEDGER, not a card grid. Full-width rows with a
   hanging index number, that reveal detail on hover/focus. Dense.
   ========================================================================== */
.ledger {
  border-top: 1px solid var(--ink);
}

/* Mobile-first: one clean full-width column. Number is a small label row,
   then title, then description, then tags — each on its own line, nothing
   squeezed into a narrow sub-column. */
.ledger-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-2);
  padding: var(--space-4) 0;
  border-bottom: 1px solid var(--line);
  position: relative;
  transition: background var(--dur) var(--ease);
}

/* the arrow is decorative on mobile — hide it so it doesn't float mid-text */
.ledger-row .lr-arrow {
  display: none;
}

.ledger-row .lr-num {
  padding-top: 0;
}

@media (min-width: 820px) {
  .ledger-row {
    grid-template-columns: 5rem minmax(0, 22rem) 1fr auto;
    gap: var(--space-4);
    padding: var(--space-5) 0;
    align-items: baseline;
  }

  .ledger-row .lr-arrow {
    display: block;
  }

  .ledger-row .lr-num {
    padding-top: 0.4rem;
  }
}

.ledger-row:hover {
  background: var(--surface);
}

.ledger-row .lr-num {
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  color: var(--signal);
  letter-spacing: 0.1em;
}

.ledger-row h3 {
  font-family: var(--font-display);
  font-weight: 800;
  text-transform: uppercase;
  font-size: clamp(1.3rem, 1rem + 1.4vw, 2rem);
  line-height: 1.02;
  letter-spacing: -0.01em;
}

.ledger-row .lr-desc {
  color: var(--ink-2);
  max-width: 52ch;
}

.ledger-row .lr-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: var(--space-3);
}

.ledger-row .lr-tags span {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: 0.06em;
  color: var(--ink-3);
  border: 1px solid var(--line);
  padding: 0.3em 0.6em;
  text-transform: uppercase;
}

.ledger-row .lr-arrow {
  font-family: var(--font-mono);
  color: var(--ink-3);
  transition: transform var(--dur) var(--ease), color var(--dur) var(--ease);
  align-self: start;
  padding-top: 0.4rem;
}

.ledger-row:hover .lr-arrow {
  color: var(--signal);
  transform: translateX(6px);
}

/* signal tick that grows on the left edge on hover.
   Sits in the margin OUTSIDE the row content (left: -0.9rem) so it doesn't
   overlap the index number; the number starts at the row's left edge. */
.ledger-row::before {
  content: "";
  position: absolute;
  left: -0.9rem;
  top: 0;
  bottom: 0;
  width: 3px;
  background: var(--signal);
  transform: scaleY(0);
  transform-origin: top;
  transition: transform var(--dur) var(--ease);
}

.ledger-row:hover::before,
.ledger-row.is-active::before {
  transform: scaleY(1);
}

/* scroll spotlight: the row nearest viewport center lights its number */
.ledger-row.is-active .lr-num {
  color: var(--signal);
}

/* ==========================================================================
   APPROACH / WHY — an EDITORIAL SPLIT. Big sticky statement on the left,
   numbered manifest lines on the right. Spacious (release after the dense
   ledger). Overlapping oversized numeral motif.
   ========================================================================== */
.split {
  display: grid;
  gap: var(--space-6);
}

@media (min-width: 920px) {
  .split {
    grid-template-columns: 0.85fr 1.15fr;
    gap: var(--space-7);
    align-items: start;
  }
}

/* Sticky only makes sense once the split is two columns (>=920px). On mobile
   the columns stack, so a sticky lead just hangs over the content scrolling
   behind it. Keep it static until the grid actually splits. */
.split-lead {
  position: static;
}

@media (min-width: 920px) {
  .split-lead {
    position: sticky;
    top: 100px;
  }
}

/* Section-level lead, not a hero — keep it confident but well below the
   hero scale so it doesn't dominate the column or wrap to many lines. */
.split-lead h2 {
  font-size: var(--fs-h2);
  max-width: 16ch;
}

/* Mixed-weight lead: first sentence solid ink, second sentence outlined so
   the block reads as two beats instead of one flat mass — adds tension and
   draws the eye. The accent period gives it a punctuation pop. */
.lead-split .soft {
  color: transparent;
  -webkit-text-stroke: 1px var(--ink);
}

.manifest {
  counter-reset: m;
}

/* Each row: a big hanging accent numeral in the left gutter, title + copy on
   the right. Hover lifts the whole row, grows an accent bar on the left edge,
   nudges the content and brightens the numeral — gives the section motion and
   attention without any icons. */
.manifest .item {
  position: relative;
  padding: var(--space-4) var(--space-3) var(--space-4) 5.5rem;
  border-bottom: 1px solid var(--line);
  transition: background var(--dur) var(--ease), padding-left var(--dur) var(--ease);
}

.manifest .item:first-child {
  border-top: 1px solid var(--line);
}

/* the large hanging numeral */
.manifest .item::before {
  counter-increment: m;
  content: counter(m, decimal-leading-zero);
  position: absolute;
  left: 0;
  top: calc(var(--space-4) - 0.15em);
  width: 4.2rem;
  text-align: left;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 2.2rem;
  line-height: 1;
  color: var(--signal);
  letter-spacing: -0.02em;
  transition: color var(--dur) var(--ease), transform var(--dur) var(--ease);
}

/* accent bar that grows on the left edge on hover.
   Sits in the margin OUTSIDE the content (left: -0.9rem) so it doesn't overlap
   the hanging numeral, which starts at the item's left edge. */
.manifest .item::after {
  content: "";
  position: absolute;
  left: -0.9rem;
  top: 0;
  bottom: 0;
  width: 2px;
  background: var(--signal);
  transform: scaleY(0);
  transform-origin: top;
  transition: transform var(--dur) var(--ease);
}

.manifest .item:hover {
  background: var(--surface);
  padding-left: 6rem;
}

.manifest .item:hover::before {
  transform: translateX(2px);
  filter: brightness(1.1);
}

.manifest .item:hover::after,
.manifest .item.is-active::after {
  transform: scaleY(1);
}

/* scroll spotlight on the manifest row nearest center */
.manifest .item.is-active::before {
  transform: translateX(2px);
  filter: brightness(1.1);
}

.manifest .item.is-active h3 {
  color: var(--signal-ink);
}

.manifest .item h3 {
  font-family: var(--font-display);
  font-weight: 800;
  text-transform: uppercase;
  font-size: 1.3rem;
  margin-bottom: 0.4rem;
  letter-spacing: -0.01em;
  transition: color var(--dur) var(--ease);
}

.manifest .item:hover h3 {
  color: var(--signal-ink);
}

.manifest .item p {
  margin: 0;
  max-width: 54ch;
}

/* ==========================================================================
   CLIENT INDEX — not a logo strip. An oversized count + a plotted index
   table with coordinates, logos sitting in a measured frame.
   ========================================================================== */
.clients-head {
  display: grid;
  gap: var(--space-4);
  align-items: end;
  margin-bottom: var(--space-6);
}

@media (min-width: 820px) {
  .clients-head {
    grid-template-columns: auto 1fr;
  }
}

.clients-count {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(4rem, 2rem + 12vw, 13rem);
  line-height: 0.8;
  letter-spacing: -0.03em;
}

.clients-count .plus {
  color: var(--signal);
}

.client-index {
  border-top: 1px solid var(--ink);
}

.client-row {
  position: relative;
  display: grid;
  grid-template-columns: 3.5rem 1fr auto;
  gap: var(--space-4);
  align-items: center;
  padding: var(--space-4) 0;
  border-bottom: 1px solid var(--line);
  transition: padding-left var(--dur) var(--ease), background var(--dur) var(--ease);
}

/* left-tick, shared by hover and the scroll spotlight (.is-active) */
.client-row::before {
  content: "";
  position: absolute;
  left: -0.9rem;
  top: 0;
  bottom: 0;
  width: 3px;
  background: var(--signal);
  transform: scaleY(0);
  transform-origin: top;
  transition: transform var(--dur) var(--ease);
}

.client-row:hover {
  background: var(--surface);
  padding-left: var(--space-3);
}

.client-row:hover::before,
.client-row.is-active::before {
  transform: scaleY(1);
}

/* active row lights its coordinate label */
.client-row.is-active .c-coord {
  color: var(--signal);
}

/* ---- Hover wins over the scroll spotlight ----------------------------
   While the pointer is over a list, any spotlit row that isn't the one being
   hovered drops its .is-active styling, so only the hovered row reads as
   active (no two-lit-rows conflict). The JS keeps tracking; this just hides
   the spotlight visually during hover. */
.ledger:hover .ledger-row.is-active:not(:hover)::before {
  transform: scaleY(0);
}

.manifest:hover .item.is-active:not(:hover)::after {
  transform: scaleY(0);
}

.manifest:hover .item.is-active:not(:hover)::before {
  transform: none;
  filter: none;
}

.manifest:hover .item.is-active:not(:hover) h3 {
  color: var(--ink);
}

.client-index:hover .client-row.is-active:not(:hover)::before {
  transform: scaleY(0);
}

.client-index:hover .client-row.is-active:not(:hover) .c-coord {
  color: var(--ink-3);
}

.client-row .c-coord {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  color: var(--ink-3);
  letter-spacing: 0.08em;
}

/* The source logos are inconsistent: some red, some black, some on a baked
   white background, all different aspect ratios. Filtering can't unify them
   (women'secret carries a white box; black logos vanish on dark themes).
   So each logo sits in a fixed light "chip" — a contact-sheet cell — and
   renders in its natural color on a consistent ground in BOTH themes. */
.client-row .c-logo {
  width: 160px;
  height: 56px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--logo-chip);
  border: 1px solid var(--line);
  padding: 0.5rem 0.9rem;
}

.client-row .c-logo img {
  max-height: 34px;
  max-width: 100%;
  width: auto;
  object-fit: contain;
}

.client-row .c-meta {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  color: var(--ink-3);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

@media (max-width: 520px) {
  .client-row .c-logo {
    width: 120px;
    height: 48px;
  }
}

/* ==========================================================================
   STAGGERED BLOCKS — used for industries / engagement models. Variable
   width, offset rows. No equal grid.
   ========================================================================== */
.stagger {
  display: grid;
  gap: var(--space-3);
}

.stagger .blk {
  position: relative;
  border: 1px solid var(--ink);
  padding: var(--space-5);
  background: var(--surface);
  overflow: hidden;
  isolation: isolate;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
    color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}

/* Accent fill that wipes in from the left when the block scrolls into view
   (JS adds .filled). z-index keeps it behind the text via isolation above. */
.stagger .blk::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--signal);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.7s var(--ease);
}

.stagger .blk.filled {
  color: var(--on-signal);
  border-color: var(--signal);
}

.stagger .blk.filled::before {
  transform: scaleX(1);
}

/* once filled, the index label, heading and copy all read on the accent */
.stagger .blk.filled .index,
.stagger .blk.filled .index .num,
.stagger .blk.filled h3,
.stagger .blk.filled p {
  color: var(--on-signal);
}

.stagger .blk.filled .index::before {
  background: var(--on-signal);
}

.stagger .blk:hover {
  transform: translateY(-5px);
  box-shadow: var(--shadow-md);
}

.stagger .blk .index {
  margin-bottom: var(--space-4);
}

.stagger .blk h3 {
  font-family: var(--font-display);
  font-weight: 800;
  text-transform: uppercase;
  font-size: 1.5rem;
  line-height: 1;
  letter-spacing: -0.01em;
}

.stagger .blk p {
  margin: var(--space-3) 0 0;
  color: var(--ink-2);
}

@media (min-width: 760px) {
  .stagger {
    grid-template-columns: repeat(12, 1fr);
  }

  /* deliberately uneven spans + vertical offsets = broken grid */
  .stagger .blk:nth-child(1) {
    grid-column: 1 / 6;
  }

  .stagger .blk:nth-child(2) {
    grid-column: 7 / 13;
    margin-top: var(--space-6);
  }

  .stagger .blk:nth-child(3) {
    grid-column: 2 / 8;
  }

  .stagger .blk:nth-child(4) {
    grid-column: 8 / 13;
    margin-top: var(--space-5);
  }

  .stagger .blk:nth-child(5) {
    grid-column: 1 / 7;
    margin-top: var(--space-6);
  }

  .stagger .blk:nth-child(6) {
    grid-column: 7 / 12;
  }
}

/* ==========================================================================
   TIMELINE — a horizontal-feeling plotted axis with markers, mono years.
   ========================================================================== */
.axis {
  position: relative;
  padding-left: var(--space-5);
}

.axis::before {
  content: "";
  position: absolute;
  left: 4px;
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--line-strong);
}

.axis-node {
  position: relative;
  padding: 0 0 var(--space-6) var(--space-5);
}

.axis-node::before {
  content: "";
  position: absolute;
  left: -4px;
  top: 8px;
  width: 9px;
  height: 9px;
  background: var(--paper);
  border: 1.5px solid var(--signal);
}

.axis-node:last-child::before {
  background: var(--signal);
}

.axis-node .yr {
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  color: var(--signal);
  letter-spacing: 0.12em;
}

.axis-node h3 {
  font-family: var(--font-display);
  font-weight: 800;
  text-transform: uppercase;
  font-size: 1.5rem;
  margin: 0.3rem 0 0.5rem;
  letter-spacing: -0.01em;
}

.axis-node p {
  margin: 0;
  max-width: 58ch;
}

/* ==========================================================================
   CTA / FOOTER — a dense schematic block with a giant wordmark bleeding off
   the right edge. The "thing you remember." Inverted to ink ground.
   ========================================================================== */
/* Fixed dark band in BOTH themes — uses --end-* tokens, never --ink/--paper,
   so the footer text never goes light-on-light when the theme flips. */
.endblock {
  background: var(--end-bg);
  color: var(--end-fg);
  position: relative;
  overflow: hidden;
}

/* The footer needs its own grid because it's always a dark ground and the
   page grid (body::before) draws dark lines in light mode — invisible here.
   background-attachment: fixed anchors this grid to the viewport, the same
   origin as the fixed page grid, so the cells line up and stay continuous
   across the footer's top edge instead of drifting on scroll. */
/* vertical column guides only, matching the page background */
.endblock .grid-overlay {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(to right, var(--end-grid) 1px, transparent 1px);
  background-size: 64px 100%;
  background-position: 0 0;
  background-attachment: fixed;
}

.endblock .wrap {
  position: relative;
  z-index: 1;
}

.endblock h2 {
  color: var(--end-fg);
  font-size: var(--fs-h1);
  max-width: 16ch;
}

.endblock .index {
  color: var(--end-fg-3);
}

.endblock .index::before {
  background: var(--signal);
}

.endblock .btn {
  border-color: var(--end-fg);
  color: var(--end-fg);
}

.endblock .btn:hover {
  border-color: var(--signal);
  color: var(--on-signal);
}

/* the oversized bleeding wordmark — pulled tight under the CTA so there is
   no dead gap between the heading and the footer directory */
.endmark {
  font-family: var(--font-display);
  font-weight: 800;
  text-transform: uppercase;
  /* Mobile floor lowered so the full "PROMINENT I" fits the screen width and
     reads in one piece; scales up to a big bleed on desktop. */
  font-size: clamp(2.1rem, 1rem + 11vw, 17rem);
  line-height: 0.78;
  letter-spacing: -0.03em;
  color: transparent;
  -webkit-text-stroke: 1px var(--end-mark);
  white-space: nowrap;
  margin-top: var(--space-5);
  /* --shift is driven by main.js for a horizontal scroll parallax; defaults
     to the static resting offset when JS is off. */
  --shift: -1.5%;
  transform: translateX(var(--shift));
  will-change: transform;
  user-select: none;
}

.endmark .dot {
  color: var(--signal);
  -webkit-text-stroke: 0;
}

/* Footer directory — denser, with a clear contact line so the area never
   reads as blank. Separated from the CTA by a hairline rule. */
.foot-meta {
  display: grid;
  gap: var(--space-6);
  padding-top: var(--space-6);
  margin-top: var(--space-5);
}

@media (min-width: 760px) {
  .foot-meta {
    grid-template-columns: 1.4fr 0.8fr 1.2fr;
  }
}

.foot-meta h4 {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
  color: var(--end-fg-3);
  margin: 0 0 var(--space-4);
}

.foot-meta p {
  color: var(--end-fg-2);
}

.foot-meta a {
  color: var(--end-fg-2);
}

.foot-meta a:hover {
  color: var(--signal);
}

.foot-meta ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.foot-meta li {
  margin-bottom: 0.7rem;
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
}

/* Footer logo — large enough to actually read (the PNG is wide, not tall).
   Footer is a dark ground, so flatten the blue logo to white. */
.foot-brand .foot-logo {
  height: 50px;
  width: auto;
  filter: brightness(0) invert(1);
}

@media (max-width: 520px) {
  .foot-brand .foot-logo {
    height: 42px;
  }
}

/* a prominent email line so "contact" is unmistakably present, not a tiny link */
.foot-contact .email {
  display: inline-block;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.3rem, 1rem + 1.2vw, 2rem);
  letter-spacing: -0.01em;
  color: var(--end-fg);
  text-transform: none;
  margin-bottom: var(--space-3);
  transition: color var(--dur) var(--ease);
}

.foot-contact .email:hover {
  color: var(--signal);
}

.foot-contact .loc {
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  color: var(--end-fg-2);
}

.foot-bottom {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  justify-content: space-between;
  padding: var(--space-5) 0;
  margin-top: var(--space-6);
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: 0.06em;
  color: var(--end-fg-3);
  text-transform: uppercase;
}

/* Mobile: stack copyright + tagline centered instead of pushed to the edges.
   Desktop restores the edge-to-edge row below. */
.foot-bottom {
  flex-direction: column;
  align-items: center;
  text-align: center;
}

@media (min-width: 700px) {
  .foot-bottom {
    flex-direction: row;
    align-items: baseline;
    text-align: left;
  }
}

/* Designer credit — sits in the footer bar, dimmed below the other items so
   it reads as a quiet signature, not a third headline. Wraps to its own line
   on narrow screens via the bar's flex-wrap. */
.foot-credit {
  width: 100%;
  text-align: center;
  margin-top: var(--space-3);
  opacity: 0.6;
}

@media (min-width: 700px) {
  .foot-credit {
    width: auto;
    text-align: right;
    margin-top: 0;
  }
}

/* ==========================================================================
   Forms (contact)
   ========================================================================== */
.form-grid {
  display: grid;
  gap: var(--space-6);
}

@media (min-width: 900px) {
  .form-grid {
    grid-template-columns: 1.1fr 0.9fr;
  }
}

.field {
  margin-bottom: var(--space-4);
}

.field label {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 0.5rem;
}

.field input,
.field textarea,
.field select {
  width: 100%;
  font: inherit;
  font-size: var(--fs-body);
  color: var(--ink);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--line-strong);
  padding: 0.7em 0;
  transition: border-color var(--dur) var(--ease);
}

.field textarea {
  resize: vertical;
  min-height: 120px;
}

.field input:focus,
.field textarea:focus,
.field select:focus {
  outline: none;
  border-color: var(--signal);
}

.field select {
  -webkit-appearance: none;
  appearance: none;
}

/* Honeypot — kept in the DOM for bots, off-screen for humans. Not display:none
   so headless bots that skip hidden fields still see and fill it. */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Inline submit result. Sits below the fields; the form is never removed. */
.form-feedback {
  margin: var(--space-4) 0 0;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--line);
  border-radius: 4px;
  font-size: 0.95rem;
}

.form-feedback.is-success {
  border-color: var(--signal);
  color: var(--signal);
}

.form-feedback.is-error {
  border-color: #c0392b;
  color: #c0392b;
}

.contact-line {
  display: grid;
  grid-template-columns: 7rem 1fr;
  gap: var(--space-3);
  padding: var(--space-4) 0;
  border-bottom: 1px solid var(--line);
}

.contact-line:first-child {
  border-top: 1px solid var(--ink);
}

.contact-line .k {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
  color: var(--ink-3);
}

.contact-line .v {
  color: var(--ink);
}

/* ==========================================================================
   Motion / a11y
   ========================================================================== */
.reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.8s var(--ease), transform 0.8s var(--ease);
}

.reveal.in-view {
  opacity: 1;
  transform: none;
}

/* staggered children */
.reveal[data-delay="1"] {
  transition-delay: 0.08s;
}

.reveal[data-delay="2"] {
  transition-delay: 0.16s;
}

.reveal[data-delay="3"] {
  transition-delay: 0.24s;
}

@media (prefers-reduced-motion: reduce) {
  .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }

  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }
}

.skip-link {
  position: absolute;
  left: -999px;
  top: 0;
  background: var(--signal);
  color: var(--on-signal);
  padding: 0.6em 1em;
  z-index: 100;
  font-family: var(--font-mono);
}

.skip-link:focus {
  left: 0;
}

:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 3px;
}