/* ============================================================================
   G DIGITAL — DESIGN SYSTEM
   Monochrome editorial surface. Physical glass reserved for floating chrome.
   Mobile is authored first and on its own terms; larger screens add, never
   stretch.
   ========================================================================== */

/* ---------- 1. TOKENS ---------- */
:root {
  /* Corner radii. Anything you press is a pill; anything square that holds
     content gets a soft corner; anything round stays round. One place, so the
     whole site agrees with itself. */
  --r-pill: 999px;
  --r-round: 50%;
  --r-soft: 14px;
  --r-card: 20px;
  color-scheme: light;

  /* Light is the default skin. Dark is a deliberate second design, below. */
  --bg:        #f5f4f1;
  --bg-raise:  #ffffff;
  --bg-deep:   #ebeae6;
  --fg:        #0d0d0d;
  --fg-quiet:  #56554f;
  --fg-mute:   #7c7a74;
  --rule:      rgba(0,0,0,.14);
  --rule-soft: rgba(0,0,0,.08);
  --rule-hard: rgba(0,0,0,.3);

  --glass-float-bg:   rgba(255,255,255,.66);
  --glass-float-edge: rgba(0,0,0,.10);
  --glass-float-lip:  rgba(255,255,255,.9);
  --glass-content-bg: rgba(255,255,255,.55);
  --glass-content-edge: rgba(0,0,0,.08);
  --glass-deep-bg:    rgba(245,244,241,.86);
  --glass-menu-bg:    rgba(250,249,247,.93);
  --glass-shadow: 0 1px 1px rgba(0,0,0,.06), 0 14px 44px -16px rgba(0,0,0,.35);

  /* Type */
  --sans: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'SF Pro Display',
          'Segoe UI', Inter, Roboto, Helvetica, Arial, sans-serif;
  --mono: ui-monospace, 'SF Mono', SFMono-Regular, Menlo, monospace;

  --t-xs: .6875rem;   /* 11 */
  --t-sm: .8125rem;   /* 13 */
  --t-base: .9375rem; /* 15 */
  --t-md: 1.0625rem;  /* 17 */
  --t-lg: 1.375rem;   /* 22 */
  --t-xl: 1.875rem;   /* 30 */
  --t-2xl: clamp(2.125rem, 9vw, 3.25rem);
  --t-3xl: clamp(2.75rem, 13vw, 5.5rem);
  --t-4xl: clamp(3.25rem, 16vw, 8rem);

  /* Space */
  --gut: 22px;
  --sec: clamp(76px, 14vh, 150px);
  --max: 1240px;
  --measure: 34em;

  --dock-h: 62px;
  --hdr-h: 60px;                 /* the pill itself */
  --hdr-gap: 12px;               /* how far it floats below the top edge */
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-t: env(safe-area-inset-top, 0px);
  --safe-l: env(safe-area-inset-left, 0px);
  --safe-r: env(safe-area-inset-right, 0px);

  --ease: cubic-bezier(.2,.7,.2,1);
  --ease-out: cubic-bezier(.16,1,.3,1);
  --fast: .18s;
  --med: .34s;
  --slow: .6s;
}

[data-theme='dark'] {
  color-scheme: dark;
  --bg:        #0a0a0a;
  --bg-raise:  #101010;
  --bg-deep:   #050505;
  --fg:        #f2f1ef;
  --fg-quiet:  #8d8c88;
  --fg-mute:   #6a6966;
  --rule:      rgba(255,255,255,.12);
  --rule-soft: rgba(255,255,255,.07);
  --rule-hard: rgba(255,255,255,.22);
  --glass-float-bg:   rgba(22,22,22,.62);
  --glass-float-edge: rgba(255,255,255,.14);
  --glass-float-lip:  rgba(255,255,255,.28);
  --glass-content-bg: rgba(255,255,255,.045);
  --glass-content-edge: rgba(255,255,255,.10);
  --glass-deep-bg:    rgba(8,8,8,.84);
  --glass-menu-bg:    rgba(14,14,14,.90);
  --glass-shadow: 0 1px 1px rgba(0,0,0,.4), 0 12px 40px -12px rgba(0,0,0,.75);
}

/* ---------- 2. RESET ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font: 400 var(--t-base)/1.55 var(--sans);
  letter-spacing: -.011em;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
  padding-left: var(--safe-l);
  padding-right: var(--safe-r);
}
img, video, svg { max-width: 100%; display: block; }
button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; padding: 0; }
a { color: inherit; text-decoration: none; }
h1,h2,h3,h4,p,figure,ul,ol { margin: 0; }
ul, ol { padding: 0; list-style: none; }
[hidden] { display: none !important; }

:focus-visible {
  outline: 2px solid var(--fg);
  outline-offset: 3px;
  border-radius: var(--r-soft);
}

::selection { background: var(--fg); color: var(--bg); }

.skip {
  position: fixed; top: 8px; left: 8px; z-index: 300;
  padding: 10px 18px; border-radius: var(--r-pill); background: var(--fg); color: var(--bg);
  transform: translateY(-160%); transition: transform var(--fast);
  font-size: var(--t-sm); font-weight: 600;
}
.skip:focus { transform: none; }

.vh {
  position: absolute !important; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* ---------- 3. LAYOUT ---------- */
.wrap { width: 100%; max-width: var(--max); margin: 0 auto; padding: 0 var(--gut); }
.wrap--narrow { max-width: 840px; }
main { display: block; }
.sec { padding-block: var(--sec); position: relative; }
.sec--tight { padding-block: clamp(48px, 9vh, 96px); }
.sec--deep { background: var(--bg-deep); }
.sec--raise { background: var(--bg-raise); }

/* Luminance transitions instead of divider lines */
.fade-top::before, .fade-bot::after {
  content: ''; position: absolute; left: 0; right: 0; height: 160px;
  pointer-events: none;
}
.fade-top::before { top: 0; background: linear-gradient(to bottom, var(--bg), transparent); }
.fade-bot::after { bottom: 0; background: linear-gradient(to top, var(--bg), transparent); }

/* ---------- 4. TYPE ---------- */
.eyebrow {
  font-size: var(--t-xs); text-transform: uppercase; letter-spacing: .22em;
  color: var(--fg-mute); font-weight: 600;
}
/* Display type is set big enough that a single long word ("PHOTOGRAPHY") can
   be wider than a 320px screen. Breaking it is better than letting it hang off
   the side, and the hyphen makes the break read as deliberate. */
.display {
  font-size: var(--t-3xl); line-height: .93; letter-spacing: -.045em;
  font-weight: 700; text-transform: uppercase;
  overflow-wrap: break-word; hyphens: auto;
}
.h1 { font-size: var(--t-2xl); line-height: 1.0; letter-spacing: -.035em; font-weight: 700;
      overflow-wrap: break-word; }
.hero__word { overflow-wrap: break-word; }
.h2 { font-size: var(--t-xl); line-height: 1.08; letter-spacing: -.03em; font-weight: 650; }
.h3 { font-size: var(--t-lg); line-height: 1.2; letter-spacing: -.02em; font-weight: 600; }
.lede { font-size: var(--t-md); line-height: 1.5; color: var(--fg-quiet); max-width: var(--measure); }
.body { color: var(--fg-quiet); max-width: var(--measure); }
.tight { letter-spacing: -.03em; }
.caps { text-transform: uppercase; letter-spacing: .12em; }
.num { font-variant-numeric: tabular-nums; }
.quiet { color: var(--fg-quiet); }
.mute { color: var(--fg-mute); }
.strong-fg { color: var(--fg); }

/* Editorial rule — used deliberately, not between every block */
.rule { height: 1px; background: var(--rule-soft); border: 0; margin: 0; }

/* ---------- 5. BUTTONS — outlined fills, solid inverts ---------- */
.btn {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  min-height: 52px; padding: 0 24px;
  background: var(--fg); color: var(--bg);
  box-shadow: inset 0 0 0 1px var(--fg);
  font-size: var(--t-sm); font-weight: 650; letter-spacing: .04em;
  text-transform: uppercase; border-radius: var(--r-pill);
  -webkit-tap-highlight-color: transparent;
  transition: background .16s var(--ease), color .16s var(--ease),
              box-shadow .16s var(--ease), transform .1s var(--ease);
}
.btn:hover { background: transparent; color: var(--fg); box-shadow: inset 0 0 0 1px var(--fg); }
.btn:active { transform: scale(.97); }

.btn--ghost {
  background: transparent; color: var(--fg);
  box-shadow: inset 0 0 0 1px var(--rule-hard);
}
.btn--ghost:hover { background: var(--fg); color: var(--bg); box-shadow: inset 0 0 0 1px var(--fg); }

/* Touch devices get the fill on press instead of hover */
@media (hover: none) {
  .btn:hover { background: var(--fg); color: var(--bg); }
  .btn:active { background: transparent; color: var(--fg); }
  .btn--ghost:hover { background: transparent; color: var(--fg); box-shadow: inset 0 0 0 1px var(--rule-hard); }
  .btn--ghost:active { background: var(--fg); color: var(--bg); }
}

.btn--quiet {
  background: transparent; color: var(--fg-quiet); box-shadow: none;
  min-height: 44px; padding: 0 4px; text-transform: none; letter-spacing: -.01em;
  font-weight: 500; font-size: var(--t-base);
}
.btn--quiet:hover { background: transparent; color: var(--fg); box-shadow: none; }
.btn--sm { min-height: 42px; padding: 0 16px; font-size: var(--t-xs); }
.btn--block { width: 100%; }
.btn[disabled], .btn[aria-disabled='true'] { opacity: .45; pointer-events: none; }

.btn-row { display: flex; flex-wrap: wrap; gap: 12px; }

/* Arrow link */
.alink {
  display: inline-flex; align-items: center; gap: .5em; min-height: 44px;
  font-weight: 550; letter-spacing: -.015em;
  transition: gap var(--fast), color var(--fast);
}
.alink i { font-style: normal; transition: transform var(--med) var(--ease); }
.alink:hover { gap: .85em; }
.alink:hover i { transform: translateX(3px); }

/* ---------- 6. GLASS ---------- */
.g-float {
  background: var(--glass-float-bg);
  -webkit-backdrop-filter: blur(26px) saturate(180%);
  backdrop-filter: blur(26px) saturate(180%);
  box-shadow: var(--glass-shadow), inset 0 1px 0 var(--glass-float-lip),
              inset 0 0 0 1px var(--glass-float-edge);
}
.g-content {
  background: var(--glass-content-bg);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  box-shadow: inset 0 0 0 1px var(--glass-content-edge);
}
.g-deep {
  background: var(--glass-deep-bg);
  -webkit-backdrop-filter: blur(50px) saturate(160%);
  backdrop-filter: blur(50px) saturate(160%);
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .g-float { background: var(--bg-raise); }
  .g-deep { background: var(--bg); }
  .drop { background: var(--bg-raise); }
}

/* ---------- 7. HEADER (desktop) ----------
   A pill that floats clear of the page, the same shape as the dock at the
   bottom of a phone. The bar itself is only a positioning frame and paints
   nothing; the pill inside it carries the frosted glass, so the page shows
   through above and beside it rather than being cut off by a full-width band.
   Logo hard left inside the pill, everything else packed to the right edge. */
.hdr {
  position: fixed; top: 0; left: 0; right: 0; z-index: 90;
  padding: calc(var(--hdr-gap) + var(--safe-t)) var(--gut) 0;
  pointer-events: none;                       /* the gap beside the pill is page */
  transition: transform var(--med) var(--ease), padding-top var(--med) var(--ease);
}
.hdr__in {
  pointer-events: auto;
  display: flex; align-items: center; gap: 28px;
  height: var(--hdr-h); max-width: var(--max); margin: 0 auto;
  padding: 0 8px 0 20px;
  border-radius: var(--r-pill);
  background: var(--glass-float-bg);
  -webkit-backdrop-filter: blur(26px) saturate(180%);
  backdrop-filter: blur(26px) saturate(180%);
  box-shadow: var(--glass-shadow), inset 0 1px 0 var(--glass-float-lip),
              inset 0 0 0 1px var(--glass-float-edge);
  transition: box-shadow var(--med), height var(--med) var(--ease);
}
/* Once the page has moved under it, the pill tucks up a little and its shadow
   deepens — enough to read as lifted, not enough to jump. */
.hdr.is-stuck .hdr__in {
  box-shadow: 0 2px 4px rgba(0,0,0,.05), 0 20px 46px -20px rgba(0,0,0,.45),
              inset 0 1px 0 var(--glass-float-lip),
              inset 0 0 0 1px var(--glass-float-edge);
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .hdr__in { background: var(--bg-raise); }
}
/* Hidden, but never out of reach: anything inside it taking keyboard focus
   brings it straight back, whatever the script thinks. This is the belt to the
   script's braces — a nav you can scroll away from and not tab back to would
   be unusable with a keyboard. */
.hdr.is-hidden { transform: translateY(calc(-100% - 20px)); }
.hdr.is-hidden:focus-within { transform: none; }

/* On a phone the primary nav lives in the dock at the bottom, so the pill up
   here holds only the logo. Rather than stretch an almost-empty bar across the
   screen it shrinks to fit and sits on the left margin, in line with the
   content below it. */
@media (max-width: 899px) {
  :root { --hdr-h: 54px; --hdr-gap: 10px; }
  .hdr__in { width: fit-content; max-width: 100%; margin: 0 auto 0 0; padding: 0 20px; gap: 0; }
}

.logo { display: flex; align-items: center; gap: 10px; min-height: 44px; }
.logo__mark { width: 26px; height: 26px; flex: none; }
.logo__mark svg, .logo__mark img { width: 100%; height: 100%; object-fit: contain; }
.logo__txt {
  font-size: var(--t-sm); font-weight: 700; letter-spacing: .3em;
  text-transform: uppercase; padding-left: 2px;
}
.hdr__nav { display: none; margin-left: auto; align-items: center; gap: 4px; }
.hdr__link {
  display: inline-flex; align-items: center; height: 44px; padding: 0 14px;
  font-size: var(--t-sm); font-weight: 500; color: var(--fg-quiet);
  transition: color var(--fast);
}
.hdr__link:hover, .hdr__link[aria-expanded='true'], .hdr__link.is-active { color: var(--fg); }
.hdr__tools { display: none; align-items: center; gap: 8px; margin-left: 12px; }

.icon-btn {
  width: 44px; height: 44px; display: inline-flex; align-items: center;
  justify-content: center; border-radius: var(--r-round); color: var(--fg-quiet);
  transition: color var(--fast), background var(--fast), transform .12s var(--ease);
}
.icon-btn svg { width: 20px; height: 20px; flex: none; }
.icon-btn:hover { color: var(--fg); background: var(--glass-content-bg); }
.icon-btn:active { transform: scale(.92); }

/* Desktop dropdowns — full-width panel that drops across the page */
.nav-item { position: static; display: inline-flex; }
.hdr__link i {
  font-style: normal; margin-left: 6px; font-size: .7em; opacity: .55;
  transition: transform var(--fast);
}
.nav-item.is-open .hdr__link i { transform: rotate(180deg); }

/* The panel hangs off the pill rather than spanning the window, so the two
   read as one floating object with the page running past either side. */
.drop {
  position: fixed; z-index: 4;
  left: var(--gut); right: var(--gut);
  top: calc(var(--hdr-gap) + var(--hdr-h) + 10px + var(--safe-t));
  max-width: var(--max); margin-inline: auto;
  border-radius: var(--r-card); overflow: hidden;
  background: var(--glass-menu-bg);
  -webkit-backdrop-filter: blur(40px) saturate(200%);
  backdrop-filter: blur(40px) saturate(200%);
  opacity: 0; visibility: hidden; transform: translateY(-10px);
  transition: opacity .24s var(--ease), transform .28s var(--ease-out), visibility .24s;
  box-shadow: var(--glass-shadow), inset 0 0 0 1px var(--glass-float-edge);
}
.nav-item.is-open .drop { opacity: 1; visibility: visible; transform: none; }

.drop__in {
  padding: 32px 34px 36px;
  display: grid; grid-template-columns: repeat(var(--drop-cols, 3), minmax(0, 1fr));
  gap: 0 44px; align-items: start;
}
.drop__grp h4 {
  font-size: var(--t-sm); font-weight: 500; color: var(--fg-mute);
  margin: 0 0 14px; letter-spacing: -.01em; text-transform: none;
}
.drop__item {
  display: grid; gap: 2px; padding: 8px 0;
  transition: color var(--fast), padding-left var(--fast);
}
.drop__item:hover, .drop__item:focus-visible { padding-left: 5px; }
.drop__item b {
  font-weight: 600; letter-spacing: -.03em; font-size: 1.3125rem; line-height: 1.22;
}
.drop__grp:not(:first-child) .drop__item b { font-size: var(--t-md); font-weight: 550; letter-spacing: -.02em; }
.drop__item span { font-size: var(--t-xs); color: var(--fg-mute); letter-spacing: .02em; }
.drop__item i { font-style: normal; font-size: .8em; color: var(--fg-mute); }

/* ---------- 8. FLOATING DOCK (mobile primary nav) ---------- */
.dock {
  position: fixed; z-index: 95;
  left: 50%; transform: translateX(-50%);
  bottom: calc(10px + var(--safe-b));
  width: min(440px, calc(100vw - 24px));
  border-radius: 20px; padding: 6px;
  display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
  transition: transform var(--med) var(--ease), opacity var(--med), box-shadow var(--med);
}
.dock.is-compact { transform: translateX(-50%) scale(.94); }
.dock.is-away { transform: translateX(-50%) translateY(160%); opacity: 0; }
.dock__btn {
  position: relative; display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 3px; height: 50px; border-radius: 15px;
  color: var(--fg-mute); transition: color var(--fast), background var(--fast), transform .12s var(--ease);
  -webkit-tap-highlight-color: transparent;
}
.dock__btn svg { width: 19px; height: 19px; }
.dock__btn span { font-size: 9.5px; letter-spacing: .06em; text-transform: uppercase; font-weight: 600; }
.dock__btn:active { transform: scale(.9); }
.dock__btn.is-active { color: var(--fg); }
.dock__btn.is-active::after {
  content: ''; position: absolute; inset: 0; border-radius: 15px;
  background: var(--glass-content-bg); z-index: -1;
  box-shadow: inset 0 0 0 1px var(--glass-content-edge);
}
.dock__btn--accent { color: var(--fg); }

/* ---------- 9. HERO ---------- */
.hero { position: relative; min-height: 100svh; display: flex; align-items: flex-end;
        padding-top: calc(96px + var(--safe-t)); padding-bottom: clamp(88px, 16vh, 140px); overflow: clip; }
.hero__in { position: relative; z-index: 2; width: 100%; }
.hero__words { display: block; }
.hero__word {
  display: block; font-size: var(--t-4xl); line-height: .86; letter-spacing: -.055em;
  font-weight: 700; text-transform: uppercase;
  opacity: .22; transition: opacity var(--slow) var(--ease), color var(--slow);
}
.hero__word.is-lit { opacity: 1; }
.hero__slogan {
  margin-top: 26px; font-size: clamp(1.0625rem, 4.6vw, 1.5rem);
  letter-spacing: -.03em; font-weight: 550; max-width: 20ch;
}
.hero__sub { margin-top: 14px; max-width: 42ch; color: var(--fg-quiet); font-size: var(--t-base); }
.hero__cta { margin-top: 30px; }
@media (max-width: 519px) { .hero__cta .btn { flex: 1 1 100%; } }
.hero__sig { margin-top: 34px; font-size: var(--t-xs); letter-spacing: .28em;
             text-transform: uppercase; color: var(--fg-mute); }

/* ---- hero device shot ----
   Two real phones, not a stock mockup. It carries the weight of the hero on a
   wide screen, so it gets its own column there and sits under the copy on a
   phone. Everything it does on load and on scroll is driven by three custom
   properties, which keeps it to one compositor-friendly transform. */
/* Below the two-column breakpoint the hero stops being exactly one screen and
   grows to hold the device shot, so it is never clipped by the hero's own
   overflow. The type and the buttons still fill the first screen; the phones
   are what you find the moment you start scrolling. */
@media (max-width: 899px) {
  .hero {
    min-height: auto;
    padding-bottom: calc(clamp(72px, 12vh, 110px) + var(--safe-b));
  }
  .hero__copy { min-height: calc(100svh - 200px); display: flex; flex-direction: column;
                justify-content: flex-end; }
}
.hero__copy { min-width: 0; }
.hero__device {
  position: relative;
  margin: clamp(30px, 6vh, 52px) auto 0;
  width: min(80vw, 310px);
  transform-origin: 50% 85%;

  /* Resting state is set by JS; these are the values before it runs, so a
     visitor with JS off still sees the image, in place, straight away. */
  --dv-o: 1; --dv-y: 0px; --dv-s: 1; --dv-blur: 0px;
  opacity: var(--dv-o);
  /* The scroll drift owns --dv-*, the hover lean owns --tl-*. Two sets of
     properties in one chain, so neither ever overwrites the other. */
  transform: perspective(1500px)
             rotateX(var(--tl-rx, 0deg)) rotateY(var(--tl-ry, 0deg))
             translate3d(0, var(--dv-y), 0)
             scale(var(--dv-s)) scale(var(--tl-s, 1));
  filter: blur(var(--dv-blur));
}
.hero__device img { width: 100%; height: auto; display: block; }

/* On a dark background the phone bodies are nearly the same colour as the
   page, so a soft pool of light sits behind them to lift them off it. */
.hero__device__glow {
  position: absolute; left: 50%; top: 52%; translate: -50% -50%;
  width: 118%; aspect-ratio: 1 / 1; border-radius: 50%;
  background: radial-gradient(circle, rgba(0,0,0,.09) 0%, rgba(0,0,0,0) 62%);
  z-index: -1; pointer-events: none;
}
[data-theme='dark'] .hero__device__glow {
  background: radial-gradient(circle, rgba(255,255,255,.14) 0%, rgba(255,255,255,0) 62%);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .hero__device__glow {
    background: radial-gradient(circle, rgba(255,255,255,.14) 0%, rgba(255,255,255,0) 62%);
  }
}

/* Before the reveal. The class is added by JS, so this state only ever exists
   in a browser that can take it away again. */
.js-reveal .hero__device {
  --dv-o: 0; --dv-y: 34px; --dv-s: .94; --dv-blur: 14px;
}
.hero__device.is-in {
  transition:
    opacity 1150ms cubic-bezier(.16, 1, .3, 1),
    transform 1400ms cubic-bezier(.16, 1, .3, 1),
    filter 900ms cubic-bezier(.16, 1, .3, 1);
  --dv-o: 1; --dv-y: 0px; --dv-s: 1; --dv-blur: 0px;
}
/* Once the reveal has played, the scroll handler owns these properties and a
   transition would make every frame of the parallax lag a second behind. The
   blur goes too — a 0px blur still costs a compositing pass. */
.hero__device.is-settled { transition: none; filter: none; }

@media (min-width: 900px) {
  .hero { align-items: center; }
  .hero__in {
    display: grid; align-items: center; gap: clamp(28px, 5vw, 72px);
    grid-template-columns: minmax(0, 1fr) minmax(280px, 38%);
  }
  .hero__device {
    margin: 0; width: 100%; max-width: 430px; justify-self: end;
    transform-origin: 50% 50%;
  }
  /* The abstract line art steps back once there is a real product shot to
     look at — two focal points on one screen is one too many. */
  .stage { opacity: .34; }
}
@media (min-width: 1400px) {
  .hero__device { max-width: 480px; }
}

/* Reduced motion: it appears, it just does not travel. */
@media (prefers-reduced-motion: reduce) {
  .js-reveal .hero__device { --dv-o: 0; --dv-y: 0px; --dv-s: 1; --dv-blur: 0px; }
  .hero__device.is-in { transition: opacity 400ms linear; }
}

/* Hero stage: original UI illustrations, no stock imagery */
.stage {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  -webkit-mask-image: radial-gradient(120% 78% at 70% 22%, #000 38%, transparent 76%);
  mask-image: radial-gradient(120% 78% at 70% 22%, #000 38%, transparent 76%);
}
.stage__layer {
  position: absolute; inset: 0; opacity: 0;
  transition: opacity var(--slow) var(--ease), transform var(--slow) var(--ease);
  transform: scale(1.04);
}
.stage__layer.is-on { opacity: 1; transform: none; }

.scrim { position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(to top, var(--bg) 4%, rgba(255,255,255,0) 62%); }
[data-theme='dark'] .scrim { background: linear-gradient(to top, var(--bg) 4%, rgba(0,0,0,0) 62%); }

/* ---------- 10. SECTION HEADS ---------- */
.shead { display: grid; gap: 14px; margin-bottom: clamp(30px, 6vw, 52px); }
.shead__k { display: flex; align-items: center; gap: 12px; }
.shead__k::after { content: ''; flex: 1; height: 1px; background: var(--rule-soft); }

/* ---------- 11. DISCOVERY LIST (problems, not services) ---------- */
.disc { border-top: 1px solid var(--rule); }
.disc__item { border-bottom: 1px solid var(--rule-soft); }
.disc__q {
  width: 100%; text-align: left; display: flex; align-items: flex-start; gap: 16px;
  padding: 22px 0; font-size: clamp(1.0625rem, 4.4vw, 1.5rem);
  letter-spacing: -.03em; font-weight: 550; line-height: 1.2;
  transition: padding-left var(--med) var(--ease), color var(--fast);
}
.disc__q:hover { padding-left: 8px; }
.disc__q i {
  font-style: normal; margin-left: auto; flex: none; color: var(--fg-mute);
  font-size: 1.25rem; line-height: 1; transition: transform var(--med) var(--ease);
}
.disc__item.is-open .disc__q i { transform: rotate(45deg); }
.disc__item.is-open .disc__q { color: var(--fg); }
.disc__a {
  overflow: hidden; height: 0; transition: height var(--med) var(--ease);
}
.disc__a > div { padding: 0 0 28px; display: grid; gap: 20px; }
/* Paragraphs of one answer sit closer together than the answer sits to the
   price and the links below it — otherwise a four-paragraph answer reads as
   four separate statements rather than one explanation. */
.disc__body { display: grid; gap: 12px; }
.disc__a p { color: var(--fg-quiet); max-width: 62ch; line-height: 1.62; }
@media (max-width: 699px) { .disc__a p { line-height: 1.6; } }
.disc__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; }
.disc__price { font-size: var(--t-sm); letter-spacing: .06em; text-transform: uppercase;
               color: var(--fg); font-weight: 600; }

/* ---------- 12. PACKAGES (editorial, not four identical cards) ---------- */
.pk { display: grid; gap: 34px; }
.pk__item { position: relative; padding-top: 28px; border-top: 1px solid var(--rule); }
.pk__item--heavy { border-top-color: var(--rule-hard); }
.pk__top { display: flex; flex-wrap: wrap; align-items: baseline; gap: 10px 18px; }
.pk__name { font-size: var(--t-lg); font-weight: 650; letter-spacing: -.025em; }
.pk__price { margin-left: auto; font-size: clamp(1.75rem, 8vw, 2.5rem); font-weight: 700;
             letter-spacing: -.045em; font-variant-numeric: tabular-nums; }
.pk__per { font-size: var(--t-sm); color: var(--fg-mute); font-weight: 500; letter-spacing: 0; }
.pk__pos { margin-top: 12px; font-size: var(--t-md); letter-spacing: -.02em; max-width: 26ch; font-weight: 500; }
.pk__nums { display: flex; gap: 30px; margin: 24px 0 20px; }
.pk__num b { display: block; font-size: clamp(1.75rem, 7vw, 2.25rem); font-weight: 700;
             letter-spacing: -.04em; line-height: 1; font-variant-numeric: tabular-nums; }
.pk__num span { display: block; margin-top: 6px; font-size: var(--t-xs); color: var(--fg-mute);
                max-width: 14ch; line-height: 1.3; }
.pk__list { display: flex; flex-wrap: wrap; gap: 6px 0; margin-bottom: 20px; }
.pk__list li { font-size: var(--t-sm); color: var(--fg-quiet); }
.pk__list li:not(:last-child)::after { content: '·'; margin: 0 10px; color: var(--fg-mute); }
.pk__plat { display: flex; gap: 14px; margin-bottom: 26px; font-size: var(--t-xs);
            text-transform: uppercase; letter-spacing: .14em; color: var(--fg-mute); }

/* ---------- 13. CONTENT PARTNER DEMO ---------- */
.brief { display: grid; gap: 0; }
.brief__row {
  display: grid; grid-template-columns: 112px minmax(0, 1fr); gap: 18px; padding: 16px 0;
  border-top: 1px solid var(--rule-soft); align-items: start;
}
.brief__row dt { font-size: var(--t-xs); text-transform: uppercase; letter-spacing: .16em;
                 color: var(--fg-mute); padding-top: 4px; font-weight: 600; line-height: 1.4; }
.brief__row dd { margin: 0; font-size: var(--t-base); letter-spacing: -.015em; line-height: 1.45; }

/* Said to camera, so it is set as speech rather than as another instruction. */
.brief__quote { margin: 0; letter-spacing: -.015em; }

/* How to film: one instruction per line, read down like a checklist, not a
   sentence with full stops standing in for line breaks. */
.brief__steps { display: grid; gap: 5px; }
.brief__steps li { color: var(--fg); }

/* Points to cover. */
.brief__row dd ul:not(.brief__steps) { display: grid; gap: 7px; }
.brief__row dd ul:not(.brief__steps) li { color: var(--fg-quiet); padding-left: 15px; position: relative; }
.brief__row dd ul:not(.brief__steps) li::before { content: ''; position: absolute; left: 0; top: .72em;
  width: 6px; height: 1px; background: var(--fg-mute); }

/* The last instruction in the brief, and it should read as the last one. */
.brief__row:last-child { border-bottom: 1px solid var(--rule-soft); }

@media (max-width: 559px) {
  /* Under 112px of label plus a line of answer, a narrow phone leaves four
     words a line. The label goes above its answer instead. */
  .brief__row { grid-template-columns: minmax(0, 1fr); gap: 8px; padding: 15px 0; }
  .brief__row dt { padding-top: 0; }
}

.turn { display: grid; gap: 20px; }
.turn__arrow { display: flex; align-items: center; gap: 12px; color: var(--fg-mute);
               font-size: var(--t-xs); text-transform: uppercase; letter-spacing: .2em; }
.turn__arrow::after { content: ''; flex: 1; height: 1px; background: var(--rule-soft); }

/* The finished-reel shot: a real phone, cut out, sat on the page */
.turn__shot { margin: 0; width: 100%; max-width: 268px;
  transform: perspective(1100px)
             rotateX(var(--tl-rx, 0deg)) rotateY(var(--tl-ry, 0deg))
             scale(var(--tl-s, 1));
  will-change: transform; }
/* The shadow shifts against the lean, so the phone reads as lifting off the
   page rather than as a flat picture being rotated. */
.turn__shot img { display: block; width: 100%; height: auto;
  filter: drop-shadow(calc(var(--tl-sx, 0px) * 2) calc(34px + var(--tl-sy, 0px)) 44px rgba(0,0,0,.20))
          drop-shadow(var(--tl-sx, 0px) calc(4px + var(--tl-sy, 0px) * .4) 10px rgba(0,0,0,.10)); }
@media (max-width: 700px) { .turn__shot { max-width: 232px; margin-inline: auto; } }

/* Phone frame — original, drawn in CSS */
.phone {
  width: 100%; max-width: 252px; aspect-ratio: 9/16.5; border-radius: 30px;
  background: var(--bg-raise); position: relative; overflow: hidden;
  box-shadow: inset 0 0 0 1px var(--rule), 0 30px 70px -30px rgba(0,0,0,.9);
}
.phone__bar { position: absolute; top: 10px; left: 50%; transform: translateX(-50%);
  width: 78px; height: 5px; border-radius: 3px; background: var(--rule-hard); z-index: 3; }
.phone__reel { position: absolute; inset: 0; display: flex; flex-direction: column;
  justify-content: flex-end; padding: 16px; gap: 8px; }
.phone__hook { position: absolute; top: 16%; left: 16px; right: 16px; font-size: 15px;
  font-weight: 700; line-height: 1.16; letter-spacing: -.02em; text-transform: uppercase; }
.phone__prog { position: absolute; left: 16px; right: 16px; bottom: 10px; height: 2px;
  background: var(--rule-soft); }
.phone__prog i { display: block; height: 100%; width: 42%; background: var(--fg); }
.phone__cap { font-size: 12px; line-height: 1.35; letter-spacing: -.01em; }
.phone__meta { font-size: 10px; color: var(--fg-mute); letter-spacing: .06em; text-transform: uppercase; }
.phone__grid { position: absolute; inset: 0; opacity: .5;
  background-image: linear-gradient(var(--rule-soft) 1px, transparent 1px),
                    linear-gradient(90deg, var(--rule-soft) 1px, transparent 1px);
  background-size: 28px 28px; }

/* ---------- 14. PROGRAMME / NUMBERED LISTS ---------- */
.steps { border-top: 1px solid var(--rule); }
/* minmax(0, 1fr) on the content column and min-width: 0 on both children are
   what stop this from breaking. A grid item defaults to min-width: auto, so a
   long label in the 54px gutter does not wrap — it overruns its track and sits
   on top of the column next to it, which is exactly how the demo block ended
   up with its heading crushed into 54px. */
.steps li { display: grid; grid-template-columns: 54px minmax(0, 1fr); gap: 16px;
            padding: 20px 0; border-bottom: 1px solid var(--rule-soft); }
.steps li > * { min-width: 0; }
/* A row with no gutter label — the whole width is the content.
   Qualified with .steps so it out-specifies ".steps li" above; as a bare class
   it loses and the row silently keeps its 54px gutter. */
.steps li.steps__li--wide { grid-template-columns: minmax(0, 1fr); }
.steps b { font-size: var(--t-xs); letter-spacing: .1em; color: var(--fg-mute);
           padding-top: 4px; font-weight: 600;
           overflow-wrap: anywhere; hyphens: auto; }

/* Lists whose label is a word or a price rather than "01" need a real column,
   and on a narrow screen they read better stacked than in a 54px gutter. */
.steps--wordy li { grid-template-columns: minmax(0, 1fr); gap: 6px; }
.steps--wordy b { padding-top: 0; letter-spacing: .14em; text-transform: uppercase; }
@media (min-width: 680px) {
  .steps--wordy li { grid-template-columns: 168px minmax(0, 1fr); gap: 22px; }
  .steps--wordy b { padding-top: 4px; }
}
.steps__meta { margin-top: 4px !important; font-size: var(--t-xs) !important;
               text-transform: uppercase; letter-spacing: .14em;
               color: var(--fg-mute) !important; }
.steps h4 { font-size: var(--t-md); font-weight: 600; letter-spacing: -.02em; }
.steps p { margin-top: 5px; color: var(--fg-quiet); font-size: var(--t-sm); max-width: 44ch; }

/* ---------- 15. SYSTEMS SCENE ----------
   The connected business. An Obsidian-style graph: hairlines, small dots and
   labels beside them, with one frosted node in the middle. Everything here is
   deliberately thin and quiet — the only thing allowed to feel solid is the
   middle, and only once the lines have found it. */
.sysnet__sub { margin-top: 14px; font-size: var(--t-lg); letter-spacing: -.02em;
  color: var(--fg); max-width: 34ch; }
.sysnet__mess { margin-top: 8px; font-size: var(--t-sm); line-height: 1.6;
  color: var(--fg-quiet); max-width: 58ch; }

.sysnet { position: relative; margin: clamp(10px, 1.6vw, 16px) 0 0; }
/* The graph has to fit on a screen with the heading above it, so its height is
   capped. preserveAspectRatio keeps the whole thing visible — it scales down
   and centres rather than cropping — which is why nothing has to be dropped to
   make it fit. */
.sysnet__svg { display: block; width: 100%; height: auto; overflow: visible;
  max-height: min(47vh, 520px); touch-action: manipulation; }
@media (max-width: 699px) { .sysnet__svg { max-height: none; } }

/* the barely-there light behind the middle */
.sysnet__light { color: var(--fg); opacity: 0; transition: opacity 900ms var(--ease); }
.is-connected .sysnet__light { opacity: .62; }

/* ---- lines ---- */
.sysnet__edge {
  fill: none; stroke: var(--rule-hard); stroke-width: 1; stroke-linecap: round;
  opacity: .78;
  transition: opacity var(--med) var(--ease), stroke var(--med) var(--ease);
}
.sysnet__edge.is-cold { opacity: .2; }
.sysnet__edge.is-hot  { opacity: .92; stroke: var(--fg); }

.sysnet__signal { fill: var(--fg); opacity: 0; pointer-events: none; }
.sysnet__signal { mix-blend-mode: normal; }
/* a travelling dot on a line you have just faded out reads as a bug */
.is-focused .sysnet__signal { opacity: 0 !important; }

/* ---- nodes ---- */
.sysnet__node { cursor: default; }
.sysnet__hit { fill: transparent; }
.sysnet__dot { fill: var(--fg-mute); transition: fill var(--med) var(--ease), r var(--med) var(--ease); }
.sysnet__label {
  font-size: 19px; font-weight: 500; letter-spacing: -.015em; fill: var(--fg-quiet);
  /* a background-coloured stroke underneath, so a line passing close is cut
     cleanly behind the word instead of drawn through it */
  paint-order: stroke; stroke: var(--bg); stroke-width: 5px; stroke-linejoin: round;
  transition: fill var(--med) var(--ease);
}
/* What hangs off the ten: smaller and quieter, so the shape of the graph is
   legible before any of it is read. */
.sysnet__node--t2 .sysnet__label { font-size: 16px; fill: var(--fg-mute); }
.sysnet__node--t2 { opacity: .8; }
.sysnet__node--t2 .sysnet__dot { fill: var(--rule-hard); }
.sysnet__node { transition: opacity var(--med) var(--ease); }
.sysnet__node.is-cold { opacity: .34 !important; }
.sysnet__node.is-hot .sysnet__dot { fill: var(--fg); }
.sysnet__node.is-hot .sysnet__label { fill: var(--fg); }

/* ---- the middle ----
   No ring, no disc: just the name, set bigger than everything else. The lines
   stop short of the words, and each word is painted over a background-coloured
   stroke so anything passing behind is cut cleanly rather than drawn through. */
.sysnet__hub { opacity: .42; transition: opacity var(--slow) var(--ease);
  transform-origin: center; transform-box: fill-box; }
.is-connected .sysnet__hub { opacity: 1; }
.sysnet__hubname {
  font-size: 27px; font-weight: 650; letter-spacing: -.03em; fill: var(--fg);
  paint-order: stroke; stroke: var(--bg); stroke-width: 9px; stroke-linejoin: round;
}
.sysnet__hubnote {
  font-size: 11px; font-weight: 600; letter-spacing: .22em; fill: var(--fg-mute);
  paint-order: stroke; stroke: var(--bg); stroke-width: 7px; stroke-linejoin: round;
}
/* the one moment it is allowed to move: everything has just arrived */
.is-connected .sysnet__hub { animation: sysSettle 900ms var(--ease) 1; }
@keyframes sysSettle {
  0%   { transform: scale(1); }
  38%  { transform: scale(1.035); }
  100% { transform: scale(1); }
}

/* ---- the two lines under it ---- */
.sysnet__near { margin-top: clamp(10px, 1.6vw, 18px); text-align: center;
  font-size: var(--t-lg); font-weight: 600; letter-spacing: -.025em; }
.sysnet__close { margin: 10px auto 0; text-align: center; max-width: 54ch;
  font-size: var(--t-sm); line-height: 1.6; color: var(--fg-quiet); }

@media (max-width: 699px) {
  .sysnet__label { font-size: 21px; stroke-width: 7px; }
  .sysnet__hubname { font-size: 26px; stroke-width: 10px; }
  .sysnet__hubnote { font-size: 12px; letter-spacing: .18em; }
  .sysnet__near { text-align: left; }
  .sysnet__close { text-align: left; margin-inline: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .sysnet__light, .sysnet__hub { transition: none; }
  .is-connected .sysnet__hub { animation: none; }
}

.beat { display: grid; gap: 8px; }
.beat p { font-size: clamp(1.375rem, 6.4vw, 2.5rem); line-height: 1.06; letter-spacing: -.04em;
          font-weight: 650; opacity: .28; transition: opacity var(--slow) var(--ease); }
.beat p.is-lit { opacity: 1; }

/* ---------- 16. SELECTOR CHIPS (restrained, not pills everywhere) ---------- */
.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip {
  min-height: 42px; padding: 0 15px; display: inline-flex; align-items: center;
  font-size: var(--t-sm); font-weight: 550; letter-spacing: -.01em; border-radius: var(--r-pill);
  color: var(--fg-quiet); box-shadow: inset 0 0 0 1px var(--rule);
  transition: color var(--fast), box-shadow var(--fast), background var(--fast), transform .12s var(--ease);
}
.chip:hover { color: var(--fg); box-shadow: inset 0 0 0 1px var(--rule-hard); }
.chip:active { transform: scale(.96); }
.chip[aria-pressed='true'], .chip.is-on {
  color: var(--bg); background: var(--fg); box-shadow: none;
}

/* Module grid — plain type, hairlines, no boxes-in-boxes */
.mods { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0; border-top: 1px solid var(--rule); }
.mods li {
  padding: 15px 0; border-bottom: 1px solid var(--rule-soft); font-size: var(--t-sm);
  letter-spacing: -.01em; display: flex; align-items: center; gap: 10px;
  animation: mod-in .42s var(--ease) both;
}
.mods li:nth-child(odd) { padding-right: 16px; }
.mods li::before { content: ''; width: 4px; height: 4px; background: var(--fg-mute); flex: none; }
@keyframes mod-in { from { opacity: 0; transform: translateY(6px); } }

/* ---------- 16b. SCROLL SHOWCASE ---------- */
.show { margin: clamp(34px, 6vw, 60px) 0 0; display: grid; gap: 16px; }
.show__shot {
  transform: perspective(1800px)
             rotateX(var(--tl-rx, 0deg)) rotateY(var(--tl-ry, 0deg))
             translateY(var(--fx-y, 0))
             scale(var(--fx-scale, 1)) scale(var(--tl-s, 1));
  opacity: var(--fx-o, 1);
  will-change: transform;
}
.show__shot img { width: 100%; height: auto; display: block;
  filter: drop-shadow(calc(var(--tl-sx, 0px) * 2) calc(40px + var(--tl-sy, 0px)) 52px rgba(0,0,0,.22))
          drop-shadow(var(--tl-sx, 0px) calc(6px + var(--tl-sy, 0px) * .4) 14px rgba(0,0,0,.10)); }
/* Side by side with the words, the shot does not want the section's own top
   margin — it should sit level with the heading beside it. */
.show--bare { margin-top: 0; }
.sysout { margin-top: clamp(36px, 6vw, 64px); align-items: center; }
.sysout .stmt { gap: 18px; }
.show__cap {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 12px;
  font-size: var(--t-sm); color: var(--fg-mute);
}
.show__cap b { color: var(--fg); font-weight: 600; letter-spacing: -.01em; }
.show--tight { margin-top: 26px; }

/* ---------- 17. CLIENTS ---------- */
.clients { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1px;
           background: var(--rule-soft); border: 1px solid var(--rule-soft); }
.client {
  background: var(--bg); min-height: 108px; display: flex; align-items: center;
  justify-content: center; padding: 18px 14px; text-align: center;
  transition: background var(--med), transform .14s var(--ease);
}
.client:hover { background: var(--bg-raise); }
.client:active { transform: scale(.985); }
.client__word {
  font-size: var(--t-sm); font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
  color: var(--fg-quiet); line-height: 1.3; transition: color var(--med);
}
.client:hover .client__word { color: var(--fg); }
.client img { max-height: 44px; width: auto; object-fit: contain; }

/* ---------- 18. PORTFOLIO WALL ---------- */
.wall { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
.tile {
  position: relative; overflow: hidden; background: var(--bg-raise); border-radius: var(--r-soft);
  box-shadow: inset 0 0 0 1px var(--rule-soft);
  transition: transform .18s var(--ease);
}
.tile:active { transform: scale(.985); }
.tile--tall { aspect-ratio: 9/16; }
.tile--wide { aspect-ratio: 4/5; }
.tile--sq { aspect-ratio: 1; }
.tile img, .tile video { width: 100%; height: 100%; object-fit: cover; }
.tile__cap {
  position: absolute; inset: auto 0 0; padding: 14px 13px 12px;
  background: linear-gradient(to top, rgba(0,0,0,.82), transparent);
  color: #fff; font-size: var(--t-xs); letter-spacing: .04em;
}
.tile__ph { position: absolute; inset: 0; display: grid; align-content: center; justify-items: start;
            padding: 16px; gap: 6px; }
.tile__ph b { font-size: var(--t-sm); font-weight: 600; letter-spacing: -.01em; }
.tile__ph span { font-size: var(--t-xs); color: var(--fg-mute); text-transform: uppercase; letter-spacing: .14em; }

.empty {
  padding: 30px 0; border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule);
  display: grid; gap: 8px;
}
.empty b { font-size: var(--t-md); letter-spacing: -.02em; font-weight: 600; }

/* ---------- 19. SHEET / MODAL (deep glass) ---------- */
.sheet { position: fixed; inset: 0; z-index: 120; display: none; }
.sheet.is-open { display: block; }
.sheet__scrim { position: absolute; inset: 0; background: rgba(0,0,0,.5);
  opacity: 0; transition: opacity var(--med); }
.sheet.is-in .sheet__scrim { opacity: 1; }
.sheet__panel {
  position: absolute; inset: auto 0 0; max-height: 92svh; overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  border-radius: 22px 22px 0 0; padding: 8px var(--gut) calc(34px + var(--safe-b));
  transform: translateY(100%); transition: transform var(--med) var(--ease-out);
  box-shadow: 0 -1px 0 var(--glass-float-edge), 0 -30px 80px -30px rgba(0,0,0,.9);
}
.sheet.is-in .sheet__panel { transform: none; }
.sheet__grab { width: 38px; height: 4px; border-radius: 2px; background: var(--rule-hard);
  margin: 8px auto 18px; }
.sheet__close { position: sticky; top: 0; margin-left: auto; display: block; }

/* ---------- 20. SEARCH ---------- */
.srch { position: fixed; inset: 0; z-index: 140; display: none; }
.srch.is-open { display: block; }
.srch__bg {
  position: absolute; inset: 0; opacity: 0;
  transition: opacity var(--med);
  -webkit-backdrop-filter: blur(26px) saturate(140%); backdrop-filter: blur(26px) saturate(140%);
}
.srch.is-in .srch__bg { opacity: 1; }
.srch__in {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  padding: calc(14px + var(--safe-t)) var(--gut) calc(12px + var(--safe-b));
  opacity: 0; transform: scale(1.015) translateY(-10px);
  transition: opacity var(--med), transform var(--med) var(--ease-out);
}
.srch.is-in .srch__in { opacity: 1; transform: none; }
.srch__bar { display: flex; align-items: center; gap: 10px; }
.srch__field {
  flex: 1; display: flex; align-items: center; gap: 12px; height: 58px;
  padding: 0 8px 0 20px; border-radius: var(--r-pill); min-width: 0;
}
.srch__field > svg { width: 20px; height: 20px; flex: none; color: var(--fg-mute); }
.srch__field input {
  flex: 1; background: none; border: 0; outline: 0; font-size: var(--t-md);
  letter-spacing: -.02em; min-width: 0; color: var(--fg);
}
.srch__field input::placeholder { color: var(--fg-mute); }
.srch__field input::-webkit-search-cancel-button { display: none; }
.srch__clear {
  width: 40px; height: 40px; flex: none; display: grid; place-items: center;
  border-radius: 50%; color: var(--fg-mute); transition: color var(--fast), background var(--fast);
}
.srch__clear svg { width: 16px; height: 16px; }
.srch__clear:hover { color: var(--fg); background: var(--bg-deep); }

.srch__results {
  flex: 1; overflow-y: auto; margin-top: 18px; padding-bottom: 18px;
  -webkit-overflow-scrolling: touch; overscroll-behavior: contain;
}
.srch__hint {
  display: none; gap: 18px; padding-top: 10px; border-top: 1px solid var(--rule-soft);
  font-size: var(--t-xs); color: var(--fg-mute); letter-spacing: .02em;
}
@media (min-width: 900px) and (pointer: fine) { .srch__hint { display: flex; } }

/* ---- shared between the overlay and /search ---- */
.sgrp + .sgrp { margin-top: 26px; }
.sgrp__h {
  display: flex; align-items: center; gap: 10px;
  font-size: var(--t-xs); text-transform: uppercase; letter-spacing: .2em;
  color: var(--fg-mute); font-weight: 600; margin-bottom: 8px;
}
.sgrp__x {
  margin-left: auto; font-size: var(--t-xs); letter-spacing: .08em; color: var(--fg-mute);
  text-transform: uppercase; transition: color var(--fast);
}
.sgrp__x:hover { color: var(--fg); }

.sugg { display: flex; flex-direction: column; }
.sugg button {
  text-align: left; min-height: 52px; padding: 13px 2px;
  border-bottom: 1px solid var(--rule-soft);
  font-size: var(--t-base); letter-spacing: -.015em; color: var(--fg-quiet);
  transition: padding-left var(--fast), color var(--fast);
}
.sugg button:hover, .sugg button:focus-visible { padding-left: 6px; color: var(--fg); }

.sres {
  display: flex; align-items: center; gap: 14px;
  min-height: 62px; padding: 12px 14px 12px 12px;
  border-radius: var(--r-soft); color: inherit; text-decoration: none;
  background: var(--glass-content-bg);
  border: 1px solid var(--glass-content-edge);
  -webkit-backdrop-filter: blur(14px) saturate(130%); backdrop-filter: blur(14px) saturate(130%);
  transition: background var(--fast), border-color var(--fast), transform var(--fast),
              box-shadow var(--fast);
}
.sres + .sres { margin-top: 6px; }
.sres__ico {
  width: 40px; height: 40px; flex: none; display: grid; place-items: center;
  border-radius: var(--r-round); background: var(--bg-deep); color: var(--fg-quiet);
  border: 1px solid var(--rule-soft);
}
.sres__ico svg { width: 19px; height: 19px; }
.sres__b { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.sres__t {
  font-size: var(--t-base); font-weight: 620; letter-spacing: -.02em; color: var(--fg);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sres__c {
  font-size: var(--t-xs); text-transform: uppercase; letter-spacing: .14em;
  color: var(--fg-mute);
}
.sres__d {
  font-size: var(--t-sm); color: var(--fg-quiet); line-height: 1.45;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sres__go { flex: none; color: var(--fg-mute); opacity: 0; transition: opacity var(--fast), transform var(--fast); }
.sres__go svg { width: 18px; height: 18px; display: block; }

.sres:hover, .sres.is-on, .sres:focus-visible {
  background: var(--glass-float-bg); border-color: var(--glass-float-edge);
  box-shadow: 0 1px 1px rgba(0,0,0,.05), 0 10px 26px -14px rgba(0,0,0,.4);
  outline: none;
}
.sres:focus-visible { box-shadow: 0 0 0 2px var(--fg); }
.sres:hover .sres__go, .sres.is-on .sres__go { opacity: 1; transform: translateX(3px); }
.sres:active { transform: scale(.985); }

.sres--best {
  background: var(--glass-float-bg); border-color: var(--glass-float-edge);
  box-shadow: inset 0 1px 0 var(--glass-float-lip);
}
.sres--best .sres__ico { background: var(--fg); color: var(--bg); border-color: var(--fg); }
.sres--best .sres__t {
  font-size: var(--t-md); white-space: normal;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.sres--best .sres__d {
  white-space: normal;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
}
.sres--best { align-items: flex-start; }
.sres--best .sres__ico { margin-top: 2px; }
.sres--best .sres__go { align-self: center; }

.hl { font-style: normal; color: var(--fg); box-shadow: inset 0 -.32em 0 var(--rule); border-radius: 2px; }

.scta {
  margin-top: 26px; padding: 18px 0 2px; border-top: 1px solid var(--rule-soft);
  display: grid; gap: 7px; justify-items: start;
}
.scta b { font-size: var(--t-base); letter-spacing: -.02em; }
.scta p { font-size: var(--t-sm); color: var(--fg-quiet); max-width: 52ch; }
.scta .btn { margin-top: 5px; }

.sall {
  display: flex; align-items: center; gap: 8px; margin-top: 22px; padding-top: 16px;
  border-top: 1px solid var(--rule-soft);
  font-size: var(--t-sm); font-weight: 600; letter-spacing: -.01em; color: var(--fg);
}
.sall svg { width: 16px; height: 16px; transition: transform var(--fast); }
.sall:hover svg { transform: translateX(3px); }

.snone { display: grid; gap: 8px; padding-bottom: 8px; }
.snone b { font-size: var(--t-md); letter-spacing: -.025em; }
.snone p { font-size: var(--t-sm); color: var(--fg-quiet); max-width: 54ch; }
.snone__dym button {
  font-weight: 650; color: var(--fg); box-shadow: inset 0 -1px 0 var(--fg);
}

/* ---- /search ---- */
.sp { padding-top: calc(104px + var(--safe-t)); padding-bottom: var(--sec); }
.sp__head { display: grid; gap: 10px; }
.sp__form { display: flex; align-items: center; gap: 12px; margin-top: 26px;
  height: 58px; padding: 0 22px; border-radius: var(--r-pill); }
.sp__form > svg { width: 20px; height: 20px; flex: none; color: var(--fg-mute); }
.sp__form input {
  flex: 1; min-width: 0; background: none; border: 0; outline: 0;
  font-size: var(--t-md); letter-spacing: -.02em; color: var(--fg);
}
.sp__tabs { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 24px; }
.sp__tab {
  display: inline-flex; align-items: center; gap: 8px; min-height: 40px; padding: 0 14px;
  border-radius: 999px; box-shadow: inset 0 0 0 1px var(--rule-hard);
  font-size: var(--t-sm); font-weight: 600; letter-spacing: -.01em; color: var(--fg-quiet);
  transition: background var(--fast), color var(--fast), box-shadow var(--fast);
}
.sp__tab span { font-size: var(--t-xs); color: var(--fg-mute); }
.sp__tab:hover { color: var(--fg); background: var(--bg-raise); }
.sp__tab.is-on { background: var(--fg); color: var(--bg); box-shadow: inset 0 0 0 1px var(--fg); }
.sp__tab.is-on span { color: var(--bg); opacity: .7; }
.sp__out { margin-top: 30px; }
.sp__out .sres { margin-left: -12px; margin-right: -12px; }

@media (min-width: 760px) {
  .srch__field { height: 64px; }
  .srch__field input { font-size: 1.25rem; }
  .sres { min-height: 68px; padding: 14px 16px 14px 14px; }
  .sres__d { font-size: var(--t-base); }
}

/* ---------- 21. QUALIFICATION FLOW ---------- */
.q { display: grid; gap: 26px; }
.q__bar { height: 2px; background: var(--rule-soft); position: relative; overflow: hidden; }
.q__bar i { position: absolute; inset: 0 auto 0 0; background: var(--fg);
            transition: width var(--med) var(--ease); }
.q__step { display: grid; gap: 20px; animation: q-in .4s var(--ease) both; }
@keyframes q-in { from { opacity: 0; transform: translateY(10px); } }
.q__q { font-size: clamp(1.375rem, 5.6vw, 2rem); line-height: 1.12; letter-spacing: -.035em; font-weight: 650; }
.q__opts { display: grid; gap: 8px; }
.q__opt {
  text-align: left; min-height: 56px; padding: 15px 18px; border-radius: var(--r-soft);
  box-shadow: inset 0 0 0 1px var(--rule); font-size: var(--t-base); letter-spacing: -.015em;
  display: flex; align-items: center; gap: 12px;
  transition: box-shadow var(--fast), background var(--fast), transform .12s var(--ease);
}
.q__opt:hover { box-shadow: inset 0 0 0 1px var(--rule-hard); }
.q__opt:active { transform: scale(.99); }
.q__opt[aria-pressed='true'] { background: var(--fg); color: var(--bg); box-shadow: none; }
.q__opt i { font-style: normal; width: 16px; height: 16px; flex: none;
  box-shadow: inset 0 0 0 1px currentColor; opacity: .4; border-radius: 2px; }
.q__opt[aria-pressed='true'] i { opacity: 1; background: currentColor; }
.q__in, .q__ta {
  width: 100%; background: none; border: 0; border-bottom: 1px solid var(--rule);
  padding: 14px 0; font-size: var(--t-md); letter-spacing: -.02em; outline: none;
  border-radius: var(--r-soft); transition: border-color var(--fast), box-shadow var(--fast);
}
.q__ta { resize: vertical; min-height: 110px; line-height: 1.5; }
.q__in:focus, .q__ta:focus { border-bottom-color: var(--fg); }
.q__in::placeholder, .q__ta::placeholder { color: var(--fg-mute); }
.q__foot { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.q__err {
  font-size: var(--t-sm); font-weight: 550; letter-spacing: -.01em;
  padding-left: 12px; border-left: 2px solid var(--fg); margin-top: -4px;
}
.q__count { font-size: var(--t-xs); color: var(--fg-mute); letter-spacing: .12em; text-transform: uppercase; }

.gate { display: grid; gap: 14px; padding: 22px; border-radius: var(--r-soft); }
.gate h4 { font-size: var(--t-lg); letter-spacing: -.03em; font-weight: 650; }

.summary { display: grid; gap: 0; border-top: 1px solid var(--rule); }
.summary__row { display: grid; grid-template-columns: 116px 1fr; gap: 14px; padding: 13px 0;
  border-bottom: 1px solid var(--rule-soft); align-items: start; }
.summary__row dt { font-size: var(--t-xs); text-transform: uppercase; letter-spacing: .14em;
  color: var(--fg-mute); font-weight: 600; padding-top: 2px; }
.summary__row dd { margin: 0; font-size: var(--t-sm); letter-spacing: -.01em; }

.msg {
  padding: 20px; border-radius: var(--r-soft); font-size: var(--t-sm); line-height: 1.6;
  white-space: pre-wrap; color: var(--fg-quiet); max-height: 300px; overflow-y: auto;
}

/* ---------- 22. FAQ ---------- */
.faq { border-top: 1px solid var(--rule); }
.faq__i { border-bottom: 1px solid var(--rule-soft); }
.faq__q { width: 100%; text-align: left; display: flex; gap: 16px; align-items: flex-start;
  padding: 18px 0; font-size: var(--t-md); font-weight: 550; letter-spacing: -.02em; }
.faq__q i { font-style: normal; margin-left: auto; flex: none; color: var(--fg-mute);
  transition: transform var(--med) var(--ease); }
.faq__i.is-open .faq__q i { transform: rotate(45deg); }
.faq__a { overflow: hidden; height: 0; transition: height var(--med) var(--ease); }
.faq__a p { padding-bottom: 20px; color: var(--fg-quiet); font-size: var(--t-sm); max-width: 52ch; }

/* ---------- 23. STATEMENTS ---------- */
.stmt { display: grid; gap: 16px; }
.stmt h2, .stmt h3 { font-size: clamp(1.5rem, 7vw, 2.75rem); line-height: 1.04; letter-spacing: -.04em;
  font-weight: 700; text-transform: uppercase; max-width: 16ch; }
.stmt p { color: var(--fg-quiet); max-width: 44ch; }

/* ---------- 24. TEAM ---------- */
.team { border-top: 1px solid var(--rule); }
.team li { padding: 20px 0; border-bottom: 1px solid var(--rule-soft);
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 16px; }
.team b { font-size: var(--t-lg); font-weight: 650; letter-spacing: -.025em; }
.team span { font-size: var(--t-xs); text-transform: uppercase; letter-spacing: .16em; color: var(--fg-mute); }
.team p { width: 100%; color: var(--fg-quiet); font-size: var(--t-sm); }

/* ---------- 25. FOOTER ---------- */
.ftr { padding: clamp(50px, 9vh, 80px) 0 calc(var(--dock-h) + 40px + var(--safe-b)); background: var(--bg-deep); }
.ftr__top { display: grid; gap: 26px; }
.ftr__slogan { font-size: var(--t-md); letter-spacing: -.02em; max-width: 24ch; }
.ftr__cols { display: grid; grid-template-columns: repeat(2, 1fr); gap: 26px; }
.ftr__cols h4 { font-size: var(--t-xs); text-transform: uppercase; letter-spacing: .2em;
  color: var(--fg-mute); font-weight: 600; margin-bottom: 8px; }
.ftr__cols a { display: block; padding: 7px 0; font-size: var(--t-sm); color: var(--fg-quiet);
  transition: color var(--fast); }
.ftr__cols a:hover { color: var(--fg); }
.ftr__base { margin-top: 36px; padding-top: 20px; border-top: 1px solid var(--rule-soft);
  display: flex; flex-wrap: wrap; gap: 8px 18px; font-size: var(--t-xs); color: var(--fg-mute); }

/* ---------- 26. REVEAL ---------- */
.rv { opacity: 0; transform: translateY(18px); transition: opacity .7s var(--ease), transform .7s var(--ease); }
.rv.is-in { opacity: 1; transform: none; }
.rv-d1 { transition-delay: .07s; } .rv-d2 { transition-delay: .14s; } .rv-d3 { transition-delay: .21s; }

/* ---------- 27. TOAST ---------- */
.toast {
  position: fixed; left: 50%; bottom: calc(var(--dock-h) + 26px + var(--safe-b));
  transform: translate(-50%, 20px); z-index: 160; opacity: 0; pointer-events: none;
  padding: 13px 22px; border-radius: var(--r-pill); font-size: var(--t-sm); font-weight: 550;
  transition: opacity var(--med), transform var(--med) var(--ease);
}
.toast.is-on { opacity: 1; transform: translate(-50%, 0); }

/* ---------- 28. RESPONSIVE — tablet ---------- */
@media (min-width: 700px) {
  :root { --gut: 34px; }
  .brief__row { grid-template-columns: 120px 1fr; }
  .clients { grid-template-columns: repeat(3, 1fr); }
  .wall { grid-template-columns: repeat(3, 1fr); gap: 14px; }
  .mods { grid-template-columns: repeat(3, 1fr); }
  .mods li:nth-child(odd) { padding-right: 0; }
  .mods li { padding-right: 16px; }
  .ftr__cols { grid-template-columns: repeat(4, 1fr); }
  .sheet__panel { left: 50%; right: auto; transform: translate(-50%, 100%);
    width: min(760px, 94vw); border-radius: 22px 22px 0 0; }
  .sheet.is-in .sheet__panel { transform: translate(-50%, 0); }
  .q__opts--2 { grid-template-columns: repeat(2, 1fr); }
  .pk { grid-template-columns: repeat(2, 1fr); gap: 40px; }
}

/* Foldable / narrow-tall split: use the extra width as two panes, not a stretch */
@media (min-width: 620px) and (max-width: 899px) and (min-height: 680px) {
  .split-fold { display: grid; grid-template-columns: minmax(0,.9fr) minmax(0,1.1fr); gap: 40px; align-items: start; }
  .dock { width: min(400px, 68vw); }
}

/* ---------- 29. RESPONSIVE — desktop ---------- */
@media (min-width: 900px) {
  :root { --gut: 44px; --sec: clamp(104px, 13vh, 172px); }
  .hdr__nav, .hdr__tools { display: flex; }
  .dock { display: none; }
  .ftr { padding-bottom: 54px; }
  .toast { bottom: 30px; }

  .hero { align-items: center; padding-bottom: 0; }
  .hero__slogan { font-size: 1.75rem; max-width: 22ch; }
  .hero__sub { font-size: var(--t-md); }

  .split { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 64px; align-items: start; }
  .split--wide { grid-template-columns: minmax(0,1fr) minmax(0,1.25fr); }
  .split--narrow-right { grid-template-columns: minmax(0,1.25fr) minmax(0,1fr); }
  .sticky { position: sticky; top: calc(var(--hdr-gap) + var(--hdr-h) + 40px); }

  .clients { grid-template-columns: repeat(4, 1fr); }
  .wall { grid-template-columns: repeat(4, 1fr); }
  .disc__q { font-size: 1.625rem; padding: 26px 0; }
  .q__opts--2 { grid-template-columns: repeat(2, 1fr); }
  .srch__in { padding: 90px max(var(--gut), calc(50vw - 420px)) 40px; }
  .srch__field { height: 66px; border-radius: 18px; }
  .srch__hint { padding-left: 4px; }
  .sheet__panel { top: 50%; bottom: auto; left: 50%; transform: translate(-50%, -46%) scale(.98);
    width: min(880px, 90vw); max-height: 86vh; border-radius: var(--r-card); opacity: 0;
    transition: transform var(--med) var(--ease-out), opacity var(--med); padding: 28px 40px 40px; }
  .sheet.is-in .sheet__panel { transform: translate(-50%, -50%); opacity: 1; }
  .mess { height: 420px; }
}

@media (min-width: 1280px) {
  .hero__word { font-size: clamp(5rem, 8.5vw, 9rem); }
}

/* Proximity lighting — desktop, pointer only, deliberately subtle */
@media (hover: hover) and (pointer: fine) {
  .lit { position: relative; }
  .lit::after {
    content: ''; position: absolute; inset: 0; pointer-events: none; opacity: 0;
    transition: opacity var(--med);
    background: radial-gradient(240px circle at var(--mx,50%) var(--my,50%),
      rgba(0,0,0,.05), transparent 70%);
  }
  .lit:hover::after { opacity: 1; }
  [data-theme='dark'] .lit::after {
    background: radial-gradient(240px circle at var(--mx,50%) var(--my,50%),
      rgba(255,255,255,.07), transparent 70%);
  }
}

/* ---------- 30. REDUCED MOTION ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important;
  }
  .rv { opacity: 1; transform: none; }
  .hero__word, .beat p { opacity: 1; }
  .stage__layer { opacity: 1; transform: none; }
}

@media print {
  .hdr, .dock, .srch, .sheet, .toast { display: none !important; }
  body { background: #fff; color: #000; }
}

/* ---------- 26. CONSENT ---------- */
/* A bar, not a barricade. It sits above the dock, never over the content, and
   Accept and Reject are the same size and weight — the ICO asks that refusing
   be as easy as agreeing, and here it visibly is. */
.cc {
  position: fixed; left: 0; right: 0; z-index: 120;
  bottom: 0; padding: 12px var(--gut) calc(12px + var(--safe-b));
  opacity: 0; transform: translateY(14px);
  transition: opacity var(--med), transform var(--med) var(--ease-out);
  pointer-events: none;
}
.cc.is-in { opacity: 1; transform: none; pointer-events: auto; }
.cc__in {
  position: relative; margin: 0 auto; max-width: 1180px;
  border-radius: var(--r-card); padding: 18px 52px 18px 22px;
  display: grid; gap: 14px;
  /* A legal notice has to be readable over whatever is behind it, so this
     uses the opaque menu glass rather than the lighter floating tier. */
  background: var(--cc-bg);
  -webkit-backdrop-filter: blur(40px) saturate(180%); backdrop-filter: blur(40px) saturate(180%);
}
/* Frosted, but only just — a legal notice sits over the hero's display type on
   a phone, and anything lighter than this lets the words behind it show
   through the words in front. */
:root { --cc-bg: rgba(250, 249, 247, .975); }
:root[data-theme='dark'] { --cc-bg: rgba(16, 16, 16, .975); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) { --cc-bg: rgba(16, 16, 16, .975); }
}
/* An inline link inside running text must not be a 44px tap target — it breaks
   the line spacing. The whole notice is already a generous touch area. */
.cc__txt .alink, .ccp__foot .alink, .lgl .alink { min-height: 0; display: inline; }
.cc__h { font-size: var(--t-base); font-weight: 650; letter-spacing: -.02em; }
.cc__txt p { margin-top: 5px; font-size: var(--t-sm); color: var(--fg-quiet); max-width: 74ch; line-height: 1.5; }
.cc__acts { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.cc__acts .btn, .ccp__acts .btn {
  flex: 1 1 auto; min-width: 150px; justify-content: center; min-height: 48px;
}
.cc__x {
  position: absolute; top: 10px; right: 10px;
  width: 36px; height: 36px; display: grid; place-items: center;
  border-radius: 50%; color: var(--fg-mute);
  transition: color var(--fast), background var(--fast);
}
.cc__x svg { width: 15px; height: 15px; }
.cc__x:hover { color: var(--fg); background: var(--bg-deep); }

/* The dock and the notice both live at the bottom of a phone screen. Rather
   than shunting the dock up into the middle of the page, it steps out of the
   way entirely and comes straight back the moment the notice is answered —
   the notice is the only thing being asked for, so it gets the space. */
body.has-cc .dock {
  opacity: 0; pointer-events: none;
  transform: translateX(-50%) translateY(16px);
}

@media (min-width: 900px) {
  .cc { bottom: 0; }
  .cc__in {
    grid-template-columns: 1fr auto; align-items: center; gap: 26px;
    padding: 18px 52px 18px 26px;
  }
  .cc__acts { flex-wrap: nowrap; }
  .cc__acts .btn { flex: none; min-width: 0; }
}

/* ---- preferences ---- */
.ccp { position: fixed; inset: 0; z-index: 150; display: none; }
.ccp.is-open { display: block; }
.ccp__bg {
  position: absolute; inset: 0; background: var(--glass-deep-bg); opacity: 0;
  -webkit-backdrop-filter: blur(20px); backdrop-filter: blur(20px);
  transition: opacity var(--med);
}
.ccp.is-in .ccp__bg { opacity: 1; }
.ccp__box {
  position: absolute; left: 50%; bottom: 0; width: min(620px, 100%);
  transform: translateX(-50%) translateY(16px);
  border-radius: 22px 22px 0 0; padding: 26px var(--gut) calc(26px + var(--safe-b));
  max-height: 88svh; overflow-y: auto; opacity: 0;
  transition: transform var(--med) var(--ease-out), opacity var(--med);
}
.ccp.is-in .ccp__box { transform: translateX(-50%); opacity: 1; }
@media (min-width: 720px) {
  .ccp__box {
    top: 50%; bottom: auto; border-radius: 16px; padding: 30px 32px 28px;
    transform: translate(-50%, -46%) scale(.99);
  }
  .ccp.is-in .ccp__box { transform: translate(-50%, -50%) scale(1); }
}
.ccp__lede { margin-top: 10px; font-size: var(--t-sm); color: var(--fg-quiet); }
.ccp__list { margin-top: 22px; display: grid; }
.ccp__row {
  display: flex; align-items: flex-start; gap: 18px;
  padding: 16px 0; border-top: 1px solid var(--rule-soft);
}
.ccp__meta { flex: 1; min-width: 0; }
.ccp__meta b { font-size: var(--t-base); letter-spacing: -.02em; }
.ccp__meta p { margin-top: 4px; font-size: var(--t-sm); color: var(--fg-quiet); line-height: 1.5; }
.ccp__acts { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 22px; }
.ccp__acts .btn { min-width: 140px; }
.ccp__foot { margin-top: 18px; font-size: var(--t-xs); color: var(--fg-mute); }

/* A switch that reads as on or off without relying on colour alone —
   the knob moves, and the track fills. */
.sw { position: relative; flex: none; width: 52px; height: 32px; margin-top: 2px; cursor: pointer; }
.sw input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.sw__t {
  position: absolute; inset: 0; border-radius: 999px;
  background: var(--bg-deep); box-shadow: inset 0 0 0 1px var(--rule-hard);
  transition: background var(--fast), box-shadow var(--fast);
}
.sw__t::after {
  content: ''; position: absolute; top: 4px; left: 4px; width: 24px; height: 24px;
  border-radius: 50%; background: var(--fg-mute);
  transition: transform var(--med) var(--ease-out), background var(--fast);
}
.sw input:checked + .sw__t { background: var(--fg); box-shadow: inset 0 0 0 1px var(--fg); }
.sw input:checked + .sw__t::after { transform: translateX(20px); background: var(--bg); }
.sw input:focus-visible + .sw__t { box-shadow: 0 0 0 2px var(--fg); }
.sw--locked { opacity: .55; cursor: not-allowed; }
.sw--locked input { cursor: not-allowed; }

/* ---- legal pages ----
   Spacing follows the sense of the text, not a uniform grid gap: a heading
   sits close to the paragraph it introduces and far from the one before it. */
.lgl { margin-top: 34px; }
.lgl h2 {
  font-size: var(--t-lg); letter-spacing: -.03em; font-weight: 650;
  margin-top: 46px; padding-top: 22px; border-top: 1px solid var(--rule-soft);
}
.lgl > :first-child { margin-top: 0; }
.lgl h2:first-child { padding-top: 0; border-top: 0; }
.lgl h3 { font-size: var(--t-base); letter-spacing: -.02em; font-weight: 650; margin-top: 26px; }
.lgl p { margin-top: 12px; color: var(--fg-quiet); line-height: 1.65; max-width: 72ch; }
.lgl h2 + p, .lgl h3 + p { margin-top: 10px; }
.lgl ul { margin-top: 14px; display: grid; gap: 10px; }
.lgl li {
  position: relative; padding-left: 20px; color: var(--fg-quiet);
  line-height: 1.6; max-width: 72ch;
}
.lgl li::before {
  content: ''; position: absolute; left: 2px; top: .68em;
  width: 7px; height: 1px; background: var(--fg-mute);
}
.lgl li b, .lgl p b { color: var(--fg); font-weight: 650; }
.lgl__box {
  border-left: 2px solid var(--fg); padding: 4px 0 4px 16px;
  display: grid; gap: 6px; margin-top: 16px;
}
.lgl__box p { margin-top: 0; }
.lgl__todo {
  border-left: 2px solid #a3241f; padding: 10px 0 10px 16px; margin-top: 16px;
  font-size: var(--t-sm); color: var(--fg-quiet);
}
.lgl__todo b { color: #a3241f; }

.tbl { margin-top: 16px; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.tbl table { width: 100%; border-collapse: collapse; min-width: 620px; font-size: var(--t-sm); }
.tbl th, .tbl td {
  text-align: left; vertical-align: top; padding: 12px 14px 12px 0;
  border-bottom: 1px solid var(--rule-soft);
}
.tbl th {
  font-size: var(--t-xs); text-transform: uppercase; letter-spacing: .14em;
  color: var(--fg-mute); font-weight: 600; border-bottom-color: var(--rule-hard);
}
.tbl td { color: var(--fg-quiet); line-height: 1.55; }
.tbl td:first-child { color: var(--fg); font-family: var(--mono); font-size: .92em; white-space: nowrap; }
.tbl tr:last-child td { border-bottom: 0; }

/* ---------- 27. PREVIEW EDITING ----------
   Only ever active inside the site manager's preview frame. A visitor never
   loads any of this, because the class is only set when ?preview=1. */
html.is-preview [data-cms] {
  outline: 1px dashed transparent; outline-offset: 3px; border-radius: 2px;
  transition: outline-color var(--fast), background var(--fast);
  cursor: text;
}
html.is-preview [data-cms]:hover {
  outline-color: var(--rule-hard);
  background: color-mix(in srgb, var(--fg) 4%, transparent);
}
html.is-preview [data-cms].is-editing,
html.is-preview [data-cms]:focus {
  outline: 2px solid var(--fg); outline-offset: 3px;
  background: color-mix(in srgb, var(--fg) 5%, transparent);
}
/* A caret inside a button should look like a caret, not a pointer. */
html.is-preview button[data-cms],
html.is-preview a[data-cms] { cursor: text; }

/* ---------- 28. HOLDING SCREEN ----------
   A curtain over the site while it is being finished. It is drawn before
   first paint, so nothing behind it is ever seen — but see the top of
   assets/js/gate.js: it hides an unfinished site from a casual visitor, it
   does not protect anything. Switched off in one line in data.js. */
html.is-gated, html.is-gated body { overflow: hidden; height: 100%; }
html.is-gated body > *:not(.hold) { visibility: hidden !important; }

.hold {
  position: fixed; inset: 0; z-index: 9999; background: var(--bg);
  display: grid; place-items: center; padding: 28px 22px calc(28px + var(--safe-b, 0px));
  transition: opacity 380ms var(--ease);
}
.hold.is-out { opacity: 0; pointer-events: none; }
.hold__in { width: 100%; max-width: 520px; text-align: left; }
.hold__k { color: var(--fg-mute); }
.hold__h { margin-top: 18px; font-size: clamp(2rem, 8vw, 3.25rem); line-height: 1.02;
  letter-spacing: -.045em; font-weight: 700; }
.hold__p { margin-top: 16px; color: var(--fg-quiet); max-width: 40ch; line-height: 1.55; }
.hold__form { margin-top: 32px; }
.hold__lab { display: block; font-size: var(--t-xs); text-transform: uppercase;
  letter-spacing: .2em; color: var(--fg-mute); }
.hold__row { display: flex; gap: 10px; margin-top: 12px; flex-wrap: wrap; }
.hold__pin {
  flex: 1 1 160px; min-width: 0; min-height: 48px; padding: 0 16px;
  font: inherit; font-size: var(--t-md); letter-spacing: .35em;
  color: var(--fg); background: var(--bg-raise);
  border: 1px solid var(--rule-hard); border-radius: var(--r-pill);
}
.hold__pin::placeholder { letter-spacing: .35em; color: var(--fg-mute); }
.hold__pin:focus-visible { outline: 2px solid var(--fg); outline-offset: 2px; }
.hold__row .btn { min-height: 48px; }
.hold__err { margin-top: 10px; min-height: 1.2em; font-size: var(--t-sm); color: var(--fg); }
.hold__foot { margin-top: 30px; font-size: var(--t-sm); color: var(--fg-mute); }

.hold.is-wrong .hold__in { animation: holdNo 380ms var(--ease) 1; }
@keyframes holdNo {
  0%, 100% { transform: translateX(0); }
  22% { transform: translateX(-7px); }
  58% { transform: translateX(6px); }
  80% { transform: translateX(-3px); }
}
@media (prefers-reduced-motion: reduce) {
  .hold { transition: none; }
  .hold.is-wrong .hold__in { animation: none; }
}

/* ---------- 29. THE LINEUP ----------
   A row of cards you move along and press. Four things side by side get
   compared at a glance; four stacked blocks get read one at a time, and the
   last one never does. It scrolls horizontally inside its own row — the page
   itself never moves sideways. */
.lu { margin-top: clamp(22px, 4vw, 36px); }
.lu__row {
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(268px, 1fr);
  gap: 16px; overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory; scroll-padding-inline: var(--gut);
  padding: 4px var(--gut) 18px; margin-inline: calc(var(--gut) * -1);
  -webkit-overflow-scrolling: touch;
}
.lu__row::-webkit-scrollbar { height: 0; }
.lu__row { scrollbar-width: none; }

.lu__card {
  /* Two rows: the picture at its natural height, then the words taking all the
     remaining room. Cards in a row are already the same height, so giving the
     words the leftover space is what lets the link at the bottom of each one
     land on the same line as its neighbours however long the description runs. */
  scroll-snap-align: start; text-align: left; display: grid; gap: 0;
  grid-template-rows: auto 1fr; min-width: 0; color: inherit;
  border-radius: var(--r-card); background: var(--bg-raise);
  /* A real border, not an inset shadow: the picture at the top has its own
     opaque background and would paint straight over an inset one, leaving the
     card apparently open along its top edge. */
  border: 1px solid var(--rule); overflow: hidden;
  transition: border-color var(--fast), transform .16s var(--ease), background var(--fast);
}
.lu__card:hover { border-color: var(--rule-hard); }
.lu__card:active { transform: scale(.985); }
.lu__card:hover .lu__shot { background: var(--bg-raise); }
.lu__card:focus-visible { outline: 2px solid var(--fg); outline-offset: 3px; }

/* the picture, or an honest gap where one is coming */
.lu__shot {
  display: grid; place-items: center; aspect-ratio: 4 / 3.9; overflow: hidden;
  background: var(--bg-deep); border-bottom: 1px solid var(--rule-soft);
  position: relative;
}
/* Mockups are cut-out devices of every shape — a tall pair of phones, a wide
   laptop. They are fitted whole rather than cropped to fill, so a portrait one
   is not beheaded by a landscape slot. */
/* Laid over the whole slot rather than placed in it: as a centred grid item a
   percentage height has nothing to resolve against, so a tall mockup sized
   itself off the width and grew straight out of the bottom of the card. */
.lu__shot picture { display: contents; }
.lu__shot img { position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: contain; display: block; padding: 16px 18px; box-sizing: border-box; }
/* Some mockups are much wider than they are tall — three machines side by
   side. Their slot goes wide rather than cropping two of the three away, and
   the row it is in simply sits a little shorter. */
.lu__shot--wide { aspect-ratio: 16 / 7.4; }
.lu__shot--wide img { padding: 10px 12px; }
.lud__shot.lu__shot--wide { aspect-ratio: 16 / 7.4; }
.lu__shot--ph { background: var(--bg-deep); }
.lu__dev {
  width: 34%; height: 62%; border-radius: 18px;
  box-shadow: inset 0 0 0 1px var(--rule-hard);
}
.lu__phlab {
  position: absolute; bottom: 12px; left: 0; right: 0; text-align: center;
  font-size: var(--t-xs); letter-spacing: .16em; text-transform: uppercase;
  color: var(--fg-mute);
}

.lu__meta { display: flex; flex-direction: column; gap: 6px; padding: 18px 20px 20px; min-width: 0; }
.lu__k { font-size: var(--t-xs); letter-spacing: .14em; text-transform: uppercase;
  color: var(--fg-mute); }
.lu__k, .lu__name, .lu__line { overflow-wrap: anywhere; }
.lu__name { font-size: var(--t-lg); font-weight: 650; letter-spacing: -.03em; margin-top: 2px; }
.lu__line { font-size: var(--t-sm); color: var(--fg-quiet); line-height: 1.5; }
.lu__more {
  margin-top: auto; padding-top: 14px; font-size: var(--t-sm); font-weight: 600; color: var(--fg);
  display: inline-flex; align-items: center; gap: 7px; align-self: flex-start;
}
.lu__more::after {
  content: ''; width: 7px; height: 7px; flex: none;
  border-right: 1.6px solid currentColor; border-top: 1.6px solid currentColor;
  transform: rotate(45deg); transition: transform .18s var(--ease);
}
.lu__card:hover .lu__more::after { transform: rotate(45deg) translate(2px, -2px); }

@media (min-width: 900px) {
  .lu__row { grid-auto-columns: minmax(300px, 1fr); }
}

/* the panel it opens */
.lud { display: grid; gap: 18px; }
.lud__shot { border-radius: var(--r-card); overflow: hidden; background: var(--bg-deep);
  aspect-ratio: 4 / 3; display: grid; place-items: center; position: relative; }
.lud__shot picture { display: contents; }
.lud__shot img { position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: contain; display: block; padding: 18px; box-sizing: border-box; }
.lud__k { font-size: var(--t-xs); letter-spacing: .14em; text-transform: uppercase; color: var(--fg-mute); }
.lud__h { font-size: clamp(1.5rem, 6vw, 2.125rem); line-height: 1.06; letter-spacing: -.035em; font-weight: 700; }
.lud__p { color: var(--fg-quiet); line-height: 1.6; }
.lud__nums { display: flex; flex-wrap: wrap; gap: 26px; }
.lud__num b { display: block; font-size: clamp(1.75rem, 7vw, 2.25rem); font-weight: 700;
  letter-spacing: -.04em; line-height: 1; font-variant-numeric: tabular-nums; }
.lud__num span { display: block; margin-top: 6px; font-size: var(--t-xs); color: var(--fg-mute);
  max-width: 16ch; line-height: 1.3; }
.lud__price { font-size: clamp(1.75rem, 8vw, 2.5rem); font-weight: 700; letter-spacing: -.045em;
  font-variant-numeric: tabular-nums; }
.lud__price span { font-size: var(--t-sm); color: var(--fg-mute); font-weight: 500; letter-spacing: 0; }
.lud__list { display: flex; flex-wrap: wrap; gap: 6px 0; }
.lud__list li { font-size: var(--t-sm); color: var(--fg-quiet); }
.lud__list li:not(:last-child)::after { content: '·'; margin: 0 10px; color: var(--fg-mute); }
