/* =====================================================================================================
   SI Money Tracker: site.css, the shared design system for "The SI Tower" (dark deco noir, dark-only).
   Built 2026-10-12 for branch babylon-rebuild. Page agents NEVER edit this file: page-specific rules go in
   /assets/pages/<page>.css (see _staging/build/CONTRACT.md).

   Sections
     0  Fonts (self-hosted, SIL OFL 1.1, see /assets/fonts/OFL.txt)
     1  Babylon Pixel colour tokens, dark-only form (values exact from design-babylon.json css_tokens)
     2  Site tokens: noir surfaces, deco gold/sky, decoration glows (+ dynamic-range: high), type, space, motion
     3  Base and typography (.fig, Dynamic Type, links, focus)
     4  Layout primitives (.wrap, .section, .stack, .grid-2/3, .visually-hidden, .skip-link)
     5  Elevator panel header (desktop), compact sticky bar + "Floors" sheet (phone), floor dial
     6  Elevator ride overlay
     7  Buttons (one primary style), exit doors, toggles
     8  Deco cards, frames, dividers, floor sign, badges, show-the-math, LED price
     9  Pictures and figures (screenshots with "Sample data" captions, book cover)
    10  Concierge desk, profession tag, bellhop card, itinerary columns
    11  Scenes: lobby hero (letterbox, sky, searchlights, data rain, skyline, rain on glass, chandelier),
        app / vault / engine / library / penthouse / concierge / press / archive wrappers, rooftop CTA
    12  Footer
    13  Prose (legal pages)
    14  Texture: film grain + vignette
    15  Preference gates: reduced motion, motion toggle, reduced data, increase contrast, forced colours, print

   Rules this file enforces
   - Identity colours (brand, ink, data, status) are SDR sRGB hex; oklch() lives only inside @supports.
   - Brand teal/cyan = brand, links, primary CTA, focus. Gold (--deco-*) = decoration only, never body text.
   - --glow-* tokens are decoration only and become transparent under prefers-contrast: more.
   - Headroom (gain-map AVIF) only on .hdr-decoration media; CSS colours never exceed SDR white.
   - Every number is one .fig: nowrap, tabular, set in the UI stack (the display face has no tnum).
   - Colour is never the only cue: current floor = aria-current + underline + lamp; status = glyph + words.
   - Nothing is ever 100vw wide; full-bleed layers use inset:0 inside an overflow:clip parent.
   ===================================================================================================== */

/* -----------------------------------------------------------------------------------------------------
   0  FONTS
   Big Shoulders Display (variable 500-800) and Big Shoulders Inline Display (static 700): The Big Shoulders
   Project Authors, SIL Open Font License 1.1, no Reserved Font Name. Latin subset (covers Spanish: á é í ó ú
   ü ñ ¿ ¡ « »), fetched from Google Fonts on 2026-10-12. Self-hosted; nothing is hotlinked.
   Glyphs outside the subset (√ π Σ →) fall back to the next family in the stack.
   ----------------------------------------------------------------------------------------------------- */
@font-face {
  font-family: "Big Shoulders Display";
  src: url("/assets/fonts/big-shoulders-display-latin.woff2") format("woff2");
  font-weight: 500 800;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308,
    U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Big Shoulders Inline Display";
  src: url("/assets/fonts/big-shoulders-inline-display-700-latin.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308,
    U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* -----------------------------------------------------------------------------------------------------
   1  BABYLON PIXEL COLOUR TOKENS, DARK-ONLY FORM
   Source: _staging/research/design-babylon.json css_tokens (Babylon Pixel Guide v6, Build 44 cd2700e3).
   The token file says: "If the site stays dark-only, set color-scheme: dark and move the dark values into
   :root." (D28: the site is dark-only.) So every value below is the token file's DARK value, unchanged, and
   tokens with no dark override keep their single value. Block order is the token file's:
   normal hex -> normal OKLCH (@supports) -> Increase Contrast hex -> Increase Contrast OKLCH -> OKLab
   gradient -> wide-gamut glow -> Increase Contrast glow off -> HDR media gates -> .fig.
   The light-scheme blocks are intentionally absent: the site never renders light.
   ----------------------------------------------------------------------------------------------------- */
:root {
  color-scheme: dark;

  /* Surfaces */
  --surface-page: #000000;
  --surface-card: #111B1D;
  --surface-grouped: #000000;
  --surface-instrument: #0B1315;    /* calculator panel: dark in BOTH modes */

  /* Ink: text uses ink-1/2/3 only. mark-2 is for icons and meaningful boundaries, never text. */
  --ink-1: #E8FFFC;
  --ink-2: rgb(154 255 243 / 0.8);  /* 11.13 on #000000, 10.84 on site #05080A */
  --ink-3: rgb(154 255 243 / 0.7);
  --mark-2: rgb(154 255 243 / 0.6);
  --mark-3: rgb(154 255 243 / 0.3);
  --hairline: rgb(42 58 60 / 0.65);  /* separator: decoration only */
  --fill-4: rgb(110 143 140 / 0.18);

  /* Brand family */
  --brand-accent: #9AFFF3;
  --brand-accent-on: #000000;        /* 12.59:1 */
  --brand-accent-start: #9AFFF3;
  --brand-accent-end: #9AFFF3;
  --brand-accent-tint: rgb(154 255 243 / 0.18);
  --brand-secondary: #9AFFF3;
  --brand-violet: #86ABA7;
  --brand-green: #9AFFF3;            /* AMTP Green: PROPOSED, owner to confirm */
  --math-accent: #86ABA7;            /* flat graphite: every "Show the math" control */

  --money-ink: #9AFFF3;              /* 9.35:1 on its 18 % tint over #000000 */
  --money-placeholder: #86ABA7;

  /* Data colours: physical quantity kinds only (Explorer rule), never money, status or decoration */
  --data-e1: #86ABA7;
  --data-e2: #9AFFF3;
  --data-e3: #86ABA7;
  --data-e4: #86ABA7;
  --data-e5: #9AFFF3;
  --data-e6: #86ABA7;
  --data-on: #000000;

  /* Status: verdict GLYPHS only, always beside words */
  --status-pass: #86ABA7;
  --status-warning: #86ABA7;
  --status-critical: #6E8F8C;

  /* LED readout chip (dark in both modes) */
  --led-chip: #0B1315;
  --led-positive: #9AFFF3;
  --led-negative: #6E8F8C;
  --led-unlit: rgb(154 255 243 / 0.13);

  /* Focus: the accent, 2 px */
  --focus-ring: #9AFFF3;

  /* Decoration (switch off under prefers-contrast: more; sRGB values are the exact fallback) */
  --brand-gradient: linear-gradient(135deg, var(--brand-accent-start), var(--brand-accent-end));
  --glow-accent: #9AFFF3;
  --glow-secondary: #9AFFF3;
  --glow-violet: #86ABA7;
  --glow-green: #9AFFF3;
  --glow-strength: 1;
}

/* The same colours authored in OKLCH: each renders the same 8-bit value as the hex above (dark twins). */
@supports (color: #000000) {
  :root {
    --surface-grouped: #000000;
    --surface-card: #111B1D;
    --surface-instrument: #0B1315;
    --ink-2: rgb(154 255 243 / 0.8);
    --ink-3: rgb(154 255 243 / 0.7);
    --mark-2: rgb(154 255 243 / 0.6);
    --mark-3: rgb(154 255 243 / 0.3);
    --hairline: rgb(42 58 60 / 0.65);
    --fill-4: rgb(110 143 140 / 0.18);
    --brand-accent: #9AFFF3;
    --brand-accent-start: #9AFFF3;
    --brand-accent-end: #9AFFF3;
    --brand-accent-tint: rgb(154 255 243 / 0.18);
    --brand-secondary: #9AFFF3;
    --brand-violet: #86ABA7;
    --brand-green: #9AFFF3;
    --math-accent: #86ABA7;
    --money-ink: #9AFFF3;
    --money-placeholder: #86ABA7;
    --data-e1: #86ABA7;
    --data-e2: #9AFFF3;
    --data-e3: #86ABA7;
    --data-e4: #86ABA7;
    --data-e5: #9AFFF3;
    --data-e6: #86ABA7;
    --status-pass: #86ABA7;
    --status-warning: #86ABA7;
    --status-critical: #6E8F8C;
    --led-chip: #0B1315;
    --led-positive: #9AFFF3;
    --led-negative: #6E8F8C;
    --led-unlit: rgb(154 255 243 / 0.13);
    --focus-ring: #9AFFF3;
  }
}

/* Increase Contrast (prefers-contrast: more), after every normal block so it always wins. Dark values, plus the
   mode-independent "solid strokes, no glow" settings from the token file's first Increase Contrast block. */
@media (prefers-contrast: more) {
  :root {
    --ink-2: #9AFFF3;
    --ink-3: #9AFFF3;
    --mark-2: #9AFFF3;
    --mark-3: rgb(154 255 243 / 0.55);
    --brand-accent: #9AFFF3;
    --brand-accent-start: #9AFFF3;
    --brand-accent-end: #9AFFF3;
    --brand-violet: #9AFFF3;
    --math-accent: #9AFFF3;
    --money-ink: #9AFFF3;
    --money-placeholder: #9AFFF3;
    --focus-ring: #9AFFF3;
    --data-e1: #9AFFF3;
    --data-e2: #9AFFF3;
    --data-e3: #9AFFF3;
    --data-e4: #9AFFF3;
    --data-e5: #9AFFF3;
    --data-e6: #9AFFF3;
    --brand-gradient: linear-gradient(var(--brand-accent), var(--brand-accent));
    --glow-strength: 0;
  }
}
/* OKLCH twins of the Increase Contrast tokens (dark). */
@supports (color: #000000) {
  @media (prefers-contrast: more) {
    :root {
      --brand-accent: #9AFFF3;
      --brand-accent-start: #9AFFF3;
      --brand-accent-end: #9AFFF3;
      --brand-violet: #9AFFF3;
      --math-accent: #9AFFF3;
      --money-ink: #9AFFF3;
      --money-placeholder: #9AFFF3;
      --focus-ring: #9AFFF3;
      --data-e1: #9AFFF3;
      --data-e2: #9AFFF3;
      --data-e3: #9AFFF3;
      --data-e4: #9AFFF3;
      --data-e5: #9AFFF3;
      --data-e6: #9AFFF3;
    }
  }
}

/* The gradient is interpolated in OKLab where supported, so the blend keeps the accent's single lightness. */
@supports (background-image: linear-gradient(in oklab, red, blue)) {
  :root { --brand-gradient: linear-gradient(in oklab 135deg, var(--brand-accent-start), var(--brand-accent-end)); }
  @media (prefers-contrast: more) {
    :root { --brand-gradient: linear-gradient(var(--brand-accent), var(--brand-accent)); }
  }
}

/* Wide-gamut decoration only (dark values): same L and H as the brand token, chroma at 98 % of the P3 maximum.
   Never applied to text, logos, data or status colours. On sRGB screens the hex glow above is the fallback. */
@supports (color: #000000) {
  @media (color-gamut: p3) {
    :root {
      --glow-accent: oklch(0.8179 0.1940 182.29);     /* = color(display-p3 0.1004 0.9008 0.8072) */
      --glow-secondary: oklch(0.8173 0.1761 210.51);  /* = color(display-p3 0.2000 0.8618 0.9954) */
      --glow-violet: oklch(0.8085 0.1486 313.48);     /* = color(display-p3 0.8502 0.6470 0.9952) */
      --glow-green: oklch(0.8179 0.3176 142);         /* = color(display-p3 0.3576 0.9275 0.0835) */
    }
  }
}
/* Increase Contrast: "solid strokes, no glow". After the P3 block, so it wins in every mode. */
@media (prefers-contrast: more) {
  :root {
    --glow-strength: 0;
    --glow-accent: transparent;
    --glow-secondary: transparent;
    --glow-violet: transparent;
    --glow-green: transparent;
  }
}

/* HDR media gates: CSS colours never go above SDR white. Only marked decoration media may use headroom. */
img, video { dynamic-range-limit: standard; }
.hdr-decoration { dynamic-range-limit: no-limit; }
@media (prefers-contrast: more) { .hdr-decoration { dynamic-range-limit: standard; } }

/* Figures: one unbreakable, tabular unit. Set in the UI stack because the display face has no "tnum". */
.fig {
  white-space: nowrap;
  font-variant-numeric: tabular-nums lining-nums;
  font-feature-settings: "tnum" 1, "lnum" 1;
  hyphens: none;
  font-family: var(--font-ui);
}

/* -----------------------------------------------------------------------------------------------------
   2  SITE TOKENS
   ----------------------------------------------------------------------------------------------------- */
:root {
  /* Noir surfaces. The Babylon guide measured every dark token on these four (lowest: status-critical
     5.22:1 on #111B1D), so text tokens may sit on any of them. */
  --noir-0: #05080A;   /* page */
  --noir-1: #0B1315;   /* alternate band, sheets */
  --noir-2: #111B1D;   /* card */
  --noir-glass: #0B1315;

  /* Deco palette: DECORATION ONLY (trim, brass, chandeliers, dial, frames, sky). Never body text, links or CTAs. */
  --deco-gold: #86ABA7;
  --deco-gold-hi: #9AFFF3;
  --deco-gold-lo: #6E8F8C;
  --deco-gold-deep: #2A3A3C;
  --deco-gold-line: rgb(134 171 167 / 0.45);   /* hairline trim */
  --deco-gold-faint: rgb(134 171 167 / 0.18);
  --deco-ink: #05080A;         /* silhouettes */
  --deco-sky-top: #05080A;     /* night zenith, oxblood-black */
  --deco-sky-mid: #111B1D;     /* oxblood */
  --deco-sky-low: #2A3A3C;     /* blood-orange horizon */
  --deco-window: #9AFFF3;      /* lit tower window (SDR) */
  --deco-window-dim: #6E8F8C;
  --deco-steel: #111B1D;       /* vault */
  --deco-wood: #111B1D;        /* library */
  --deco-tube: #111B1D;        /* engine room */

  /* Decoration glows (emissive decor only; never text, brand or data). SDR sRGB values; the
     dynamic-range: high block below brightens them on capable screens; Increase Contrast turns them off. */
  --glow-gold: rgb(154 255 243 / 0.45);
  --glow-window: rgb(154 255 243 / 0.75);
  --glow-searchlight: rgb(154 255 243 / 0.1);
  --glow-searchlight-core: rgb(232 255 252 / 0.22);
  --glow-rain-head: #9AFFF3;
  --glow-tube: rgb(154 255 243 / 0.12);
  --glow-deco-strength: 1;

  /* Type */
  --font-ui: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto, "Helvetica Neue", Arial,
    sans-serif;
  --font-display: "Big Shoulders Display", "Avenir Next Condensed", "Arial Narrow", "Helvetica Neue",
    var(--font-ui);
  --font-marquee: "Big Shoulders Inline Display", "Big Shoulders Display", "Avenir Next Condensed",
    "Arial Narrow", var(--font-ui);
  --font-mono: ui-monospace, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;

  /* Apple text styles as em of body 17 (typography_numbers D) */
  --t-large-title: 2em;
  --t-title1: 1.647em;
  --t-title2: 1.294em;
  --t-title3: 1.176em;
  --t-callout: 0.941em;
  --t-subhead: 0.882em;
  --t-footnote: max(11px, 0.765em);  /* em-relative labels compound inside small text: never below 11 px */
  --t-caption1: max(11px, 0.706em);
  --t-caption2: max(11px, 0.647em);   /* the floor: never below 11 px */

  /* Space, size, shape */
  --gutter: max(16px, env(safe-area-inset-left), env(safe-area-inset-right));
  --max: 72rem;
  --max-text: 40rem;
  /* 8 px spacing rhythm (owner 04:10); s-1 is the 4 px half-step for hairline gaps only */
  --s-1: 0.25rem;   /*   4 px */
  --s-2: 0.5rem;    /*   8 px */
  --s-3: 1rem;      /*  16 px */
  --s-4: 1.5rem;    /*  24 px */
  --s-5: 2rem;      /*  32 px */
  --s-6: 2.5rem;    /*  40 px */
  --s-7: 3rem;      /*  48 px */
  --s-8: 4.5rem;    /*  72 px */
  --s-9: 6.5rem;    /* 104 px */
  --radius-1: 4px;
  --radius-2: 10px;
  --radius-3: 18px;
  --target: 44px;              /* minimum touch target (HIG; stricter than WCAG 2.5.8) */
  --bar-h: 3.75rem;            /* sticky bar height, for scroll-margin */

  /* Motion ("Clubbed to Death" pacing: slow, deliberate reveals; press 0.15 s; disclosure 0.2 s) */
  --ease-film: cubic-bezier(0.65, 0, 0.35, 1);
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --dur-press: 150ms;
  --dur-disclosure: 200ms;
  --dur-door: 320ms;
  --dur-reveal: 900ms;
  --dur-sweep: 600ms;

  /* Layers */
  --z-content: 1;
  --z-bar: 100;
  --z-grain: 500;
  --z-ride: 1000;
  --z-skip: 1100;
}

/* Brighter emissive decor on screens with headroom. CSS colours still stay at or below SDR white (the web
   has no HDR CSS colour space); the lift comes from wider P3 chroma and stronger alpha. The real headroom is
   only in gain-map media (.hdr-decoration). */
@media (dynamic-range: high) {
  :root {
    --glow-gold: rgb(154 255 243 / 0.62);
    --glow-window: rgb(154 255 243 / 0.92);
    --glow-searchlight: rgb(154 255 243 / 0.14);
    --glow-searchlight-core: rgb(232 255 252 / 0.32);
    --glow-tube: rgb(154 255 243 / 0.18);
    --glow-deco-strength: 1.35;
  }
}
@supports (color: color(display-p3 1 1 1)) {
  @media (dynamic-range: high) and (color-gamut: p3) {
    :root {
      --glow-gold: color(display-p3 1 0.84 0.42 / 0.62);
      --glow-window: color(display-p3 1 0.83 0.40 / 0.95);
      --glow-rain-head: color(display-p3 0.62 1 0.93);
      --glow-tube: color(display-p3 0.1004 0.9008 0.8072 / 0.2);
    }
  }
}
@media (prefers-contrast: more) {
  :root {
    --glow-gold: transparent;
    --glow-window: var(--deco-window-dim);
    --glow-searchlight: transparent;
    --glow-searchlight-core: transparent;
    --glow-tube: transparent;
    --glow-deco-strength: 0;
  }
}

/* -----------------------------------------------------------------------------------------------------
   3  BASE AND TYPOGRAPHY
   ----------------------------------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  color-scheme: dark;
  background-color: var(--noir-0);
  color: var(--ink-1);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-padding-top: calc(var(--bar-h) + var(--s-3));
}
@media (prefers-reduced-motion: no-preference) {
  html:not([data-motion="off"]) { scroll-behavior: smooth; }
}
/* Dynamic Type on iOS Safari only (touch-callout is iOS-only, so macOS Safari keeps the browser default). */
@supports (font: -apple-system-body) and (-webkit-touch-callout: none) {
  html { font: -apple-system-body; }
}

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100svh;
  font-family: var(--font-ui);
  font-size: 1.0625rem;          /* 17 px at the 16 px default */
  line-height: 1.55;
  font-weight: 400;
  color: var(--ink-1);
  background: transparent;       /* html carries the page colour; body::before carries the vignette */
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  overflow-wrap: break-word;
}
@supports (font: -apple-system-body) and (-webkit-touch-callout: none) {
  body { font-size: 1rem; }      /* html already follows the user's text size (17 px at Large) */
}
@supports (overflow: clip) {
  html, body { overflow-x: clip; }  /* belt and braces; clip keeps position: sticky working */
}

[hidden] { display: none !important; }

img, video { max-width: 100%; height: auto; }
img { border-style: none; }
svg { overflow: visible; }

h1, h2, h3, h4, h5, h6 {
  margin: 0 0 0.5em;
  color: var(--ink-1);
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.04;
  text-wrap: balance;
}
h1 {
  font-size: clamp(2.25rem, 1.55rem + 3.3vw, 4.5rem);
  letter-spacing: 0.015em;
  text-transform: uppercase;
  font-weight: 800;
}
h2 {
  font-size: clamp(1.75rem, 1.35rem + 1.9vw, 2.875rem);
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
h3 {
  font-size: clamp(1.375rem, 1.2rem + 0.7vw, 1.75rem);
  letter-spacing: 0.012em;
  font-weight: 700;
}
h4, h5, h6 {
  font-family: var(--font-ui);
  font-size: 1em;
  font-weight: 600;
  line-height: 1.3;
}
:is(h1, h2, h3, .marquee, .display) .fig {
  font-size: 0.82em;
  font-weight: 700;
  letter-spacing: 0;
  text-transform: none;
}

:is(p, si-p), ul, ol, dl, figure, blockquote, table, pre { margin: 0 0 1em; }
/* <si-p role="paragraph">: a paragraph that Reader heuristics don't count (owner request 2026-10-16: keep Safari
   Reader from treating marketing pages as articles). Same box as <p>; every `p` selector also matches it at the same
   specificity via :is(p, si-p). Write new paragraphs as <si-p role="paragraph">…</si-p>. */
si-p { display: block; }
ul, ol { padding-inline-start: 1.25em; }
li + li { margin-block-start: 0.35em; }
dt { font-weight: 600; }
dd { margin: 0 0 0.75em; color: var(--ink-2); }
strong, b { font-weight: 650; }
small { font-size: var(--t-footnote); }
hr { border: 0; border-block-start: 1px solid var(--hairline); margin: var(--s-6) 0; }
abbr[title] { text-decoration: underline dotted; text-underline-offset: 0.2em; }
code, kbd, samp { font-family: var(--font-mono); font-size: 0.92em; }
sup, sub { line-height: 0; }

/* The marquee face: hero titles and floor signs only (short, large text). */
.marquee {
  font-family: var(--font-marquee);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.035em;
  line-height: 0.98;
}
.display { font-family: var(--font-display); font-weight: 700; }

.kicker {
  display: flex;
  align-items: center;
  gap: 0.75em;
  margin: 0 0 var(--s-3);
  font-family: var(--font-display);
  font-size: 0.875rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.kicker::before {                     /* double gold rule (decor) */
  content: "";
  flex: 0 0 2.25rem;
  height: 4px;
  border-block: 1px solid var(--deco-gold);
  border-block-end-color: var(--deco-gold-line);
}
.kicker--center { justify-content: center; }
.kicker--center::after {
  content: "";
  flex: 0 0 2.25rem;
  height: 4px;
  border-block: 1px solid var(--deco-gold);
  border-block-end-color: var(--deco-gold-line);
}

.lede {
  max-width: var(--max-text);
  font-size: var(--t-title3);
  line-height: 1.45;
  color: var(--ink-2);
}
.muted { color: var(--ink-2); }
.subtle { color: var(--ink-3); }
.fine-print {
  font-size: var(--t-footnote);
  line-height: 1.5;
  color: var(--ink-3);
}
.measure { max-width: var(--max-text); }
.center { text-align: center; margin-inline: auto; }

/* Links: brand teal, underlined in running text (colour is never the only cue). */
a {
  color: var(--brand-accent);
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}
a:hover { text-decoration-thickness: 2px; }
a:visited { color: var(--brand-accent); }

:focus { outline: none; }
:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
  border-radius: 2px;
}
::selection { background: var(--brand-accent); color: var(--brand-accent-on); }

/* Anchored sections land below the sticky bar. */
[id] { scroll-margin-top: calc(var(--bar-h) + var(--s-3)); }

/* Inputs */
input, select, textarea, button { font: inherit; color: inherit; }
input[type="text"], input[type="search"], input[type="email"], textarea, select {
  min-height: 48px;
  padding: 0.65em 0.9em;
  font-size: max(16px, 1rem);       /* 16 px or more: iOS never zooms the page on focus */
  color: var(--ink-1);
  background: var(--noir-1);
  border: 1px solid var(--mark-2);  /* a meaningful boundary uses mark-2 (3:1 or more) */
  border-radius: var(--radius-2);
}
input::placeholder, textarea::placeholder { color: var(--ink-3); opacity: 1; }
input:focus-visible, textarea:focus-visible, select:focus-visible {
  border-color: var(--brand-accent);
  outline-offset: 1px;
}
button { cursor: pointer; }

/* -----------------------------------------------------------------------------------------------------
   4  LAYOUT PRIMITIVES
   ----------------------------------------------------------------------------------------------------- */
.wrap {
  width: 100%;
  max-width: calc(var(--max) + 2 * var(--gutter));
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.wrap--text { max-width: calc(var(--max-text) + 2 * var(--gutter)); }

.section { position: relative; padding-block: clamp(3.5rem, 2.5rem + 5vw, 7rem); }
.section--tight { padding-block: clamp(2rem, 1.5rem + 2.5vw, 3.5rem); }
.section--band { background: var(--noir-1); }
.section + .section--band, .section--band + .section { border-block-start: 1px solid var(--deco-gold-faint); }

.stack > * + * { margin-block-start: var(--stack-gap, var(--s-4)); }
.stack > * { margin-block-end: 0; }
.cluster { display: flex; flex-wrap: wrap; gap: var(--s-3); align-items: center; }

.grid-2, .grid-3, .grid-4 { display: grid; gap: var(--s-5); grid-template-columns: minmax(0, 1fr); }
@media (min-width: 48rem) {
  .grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 64rem) {
  .grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.visually-hidden:not(:focus):not(:active) {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  margin: -1px !important;
  padding: 0 !important;
  overflow: hidden !important;
  clip: rect(0 0 0 0) !important;
  clip-path: inset(50%) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

.skip-link {
  position: absolute;
  inset-block-start: var(--s-2);
  inset-inline-start: var(--s-2);
  z-index: var(--z-skip);
  padding: 0.75em 1.1em;
  background: var(--brand-accent);
  color: var(--brand-accent-on);
  font-weight: 650;
  text-decoration: none;
  border-radius: var(--radius-2);
  transform: translateY(-160%);
}
.skip-link:focus, .skip-link:focus-visible { transform: none; color: var(--brand-accent-on); }

main { display: block; position: relative; z-index: var(--z-content); }

/* Slow reveal (one strong beat per section). site.js adds .is-pending only to elements that start below the
   fold, so nothing is ever hidden without JS or before the observer exists. */
.reveal.is-pending { opacity: 0; transform: translateY(14px); }
.reveal { transition: opacity var(--dur-reveal) var(--ease-film), transform var(--dur-reveal) var(--ease-film); }
.reveal--late { transition-delay: 220ms; }

/* -----------------------------------------------------------------------------------------------------
   5  ELEVATOR PANEL HEADER + PHONE "FLOORS" SHEET + FLOOR DIAL
   Markup: _staging/build/partials/header-{en,es}.html. The bar never uses transform, filter or
   backdrop-filter, so the fixed Floors sheet inside it stays relative to the viewport.
   ----------------------------------------------------------------------------------------------------- */
.tower-bar {
  position: sticky;
  inset-block-start: 0;
  z-index: var(--z-bar);
  background: rgb(5 8 10 / 0.96);
  border-block-end: 1px solid var(--deco-gold-line);
}
.tower-bar::after {                      /* brass rule under the bar (decor) */
  content: "";
  position: absolute;
  inset-inline: 0;
  inset-block-end: -4px;
  height: 3px;
  background: linear-gradient(90deg, transparent, var(--deco-gold-lo) 18%, var(--deco-gold-hi) 50%,
    var(--deco-gold-lo) 82%, transparent);
  opacity: 0.55;
  pointer-events: none;
}
.tower-bar__inner {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  min-height: var(--bar-h);
  max-width: calc(80rem + 2 * var(--gutter));
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  min-height: var(--target);
  min-width: var(--target);
  margin-inline-end: auto;
  color: var(--ink-1);
  text-decoration: none;
  font-family: var(--font-display);
  font-size: 1.125rem;
  font-weight: 700;
  letter-spacing: 0.035em;
  white-space: nowrap;
}
.brand:visited, .brand:hover { color: var(--ink-1); }
.brand__logo {
  display: block;
  width: 30px;
  height: 30px;
  border-radius: 7px;
  box-shadow: 0 0 0 1px var(--deco-gold-line);
}
@media (max-width: 359.98px) { .brand__name { display: none; } }

/* Desktop elevator panel */
.elevator { display: none; }
.elevator__list {
  display: flex;
  align-items: stretch;
  gap: 0.125rem;
  margin: 0;
  padding: 0.25rem 0.5rem;
  list-style: none;
  border: 1px solid var(--deco-gold-line);
  border-radius: 999px;
  background:
    linear-gradient(180deg, rgb(134 171 167 / 0.1), rgb(134 171 167 / 0.02) 60%, rgb(0 0 0 / 0.25)),
    var(--noir-0);
  box-shadow: inset 0 1px 0 rgb(154 255 243 / 0.22), inset 0 -1px 0 rgb(0 0 0 / 0.6);
}
.elevator__list li { margin: 0; }
.floor-btn {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.15rem;
  min-width: var(--target);
  min-height: var(--target);
  padding: 0.25rem 0.45rem;
  color: var(--ink-1);
  font-family: var(--font-display);
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  line-height: 1.1;
  text-align: center;
  text-transform: uppercase;
  text-decoration: none;
  border-radius: var(--radius-2);
}
.floor-btn:visited { color: var(--ink-1); }
.floor-btn__code {
  display: grid;
  place-items: center;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 50%;
  font-size: 0.8125rem;
  letter-spacing: 0.02em;
  color: var(--ink-1);
  background: radial-gradient(circle at 35% 30%, #111B1D, #05080A 70%);
  border: 1.5px solid var(--deco-gold);
  box-shadow: 0 0 0 2px rgb(0 0 0 / 0.6), inset 0 1px 0 rgb(232 255 252 / 0.08);
  transition: box-shadow var(--dur-press) ease-out, transform var(--dur-press) ease-out;
}
.floor-btn__code svg { width: 0.95rem; height: 0.95rem; fill: currentColor; }
.floor-btn__label { max-width: 8.5em; text-wrap: balance; }
.floor-btn:hover { color: var(--ink-1); }
.floor-btn:hover .floor-btn__code { box-shadow: 0 0 0 2px var(--deco-gold-hi), 0 0 calc(12px * var(--glow-deco-strength)) var(--glow-gold); }
.floor-btn:active .floor-btn__code { transform: scale(0.95); }
/* Current floor: teal lamp + underlined label + aria-current (never colour alone). */
.floor-btn[aria-current="page"] { color: var(--ink-1); }
.floor-btn[aria-current="page"] .floor-btn__code {
  color: var(--brand-accent-on);
  background: var(--brand-accent);
  border-color: var(--brand-accent);
  box-shadow: 0 0 0 2px rgb(0 0 0 / 0.6), 0 0 calc(14px * var(--glow-strength)) var(--glow-accent);
}
.floor-btn[aria-current="page"] .floor-btn__label {
  text-decoration: underline 2px;
  text-underline-offset: 0.35em;
  text-decoration-color: var(--brand-accent);
}

@media (min-width: 64rem) {
  .elevator { display: block; }
  .floors { display: none !important; }
  .brand { margin-inline-end: 0; }
  .elevator { margin-inline: auto; }
}
@media (min-width: 64rem) and (max-width: 79.98rem) {
  .brand__name { display: none; }
  .floor-btn__the { display: none; }
}

/* Floor dial: semicircular needle gauge. Angle comes from --dial-angle (set per page by the assembler and
   animated by site.js). Stops: B -90, L -60, 1 -30, 2 0, 3 30, 4 60, PH 90 (degrees). */
.floor-dial {
  position: relative;
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 3.75rem;
  color: var(--deco-gold);
}
.floor-dial svg { display: block; width: 3.5rem; height: 2.2rem; }
.floor-dial__face-arc { fill: none; stroke: var(--deco-gold); stroke-width: 1.5; }
.floor-dial__face-plate { fill: #05080A; stroke: var(--deco-gold-lo); stroke-width: 1; }
.floor-dial__tick { stroke: var(--deco-gold-hi); stroke-width: 1.4; stroke-linecap: round; }
.floor-dial { --dial-angle: var(--page-dial, -60deg); }
body[data-floor="archive"] { --page-dial: -90deg; }
body[data-floor="lobby"], body[data-floor="concierge"], body[data-floor="press"] { --page-dial: -60deg; }
body[data-floor="app"] { --page-dial: -30deg; }
body[data-floor="vault"] { --page-dial: 0deg; }
body[data-floor="engine"] { --page-dial: 30deg; }
body[data-floor="library"] { --page-dial: 60deg; }
body[data-floor="penthouse"] { --page-dial: 90deg; }
.floor-dial__needle {
  transform-box: view-box;
  transform-origin: 32px 36px;
  transform: rotate(var(--dial-angle, -60deg));
  transition: transform var(--dur-sweep) var(--ease-film);
}
.floor-dial__needle line { stroke: var(--deco-gold-hi); stroke-width: 2; stroke-linecap: round; }
.floor-dial__needle circle { fill: var(--deco-gold); }
.floor-dial__readout {
  display: block;
  margin-block-start: -0.05rem;
  font-family: var(--font-display);
  font-size: 0.6875rem;
  font-weight: 800;
  line-height: 1;
  letter-spacing: 0.08em;
  text-align: center;
  color: var(--deco-gold-hi);
}
@media (max-width: 63.98rem) { .tower-bar .floor-dial { display: none; } }

/* Language switch (plain link; lang-splash.js remembers the choice) */
.lang-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--target);
  min-width: var(--target);
  padding-inline: 0.5rem;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--brand-accent);
  text-decoration: none;
  white-space: nowrap;
}
.lang-link:hover { text-decoration: underline; text-underline-offset: 0.25em; }

/* Phone: compact bar + Floors sheet (a <details>, so it opens without JS; site.js adds the modal behaviour) */
.floors { position: static; }
.floors > summary {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: var(--target);
  padding: 0.35rem 0.6rem 0.35rem 0.95rem;
  list-style: none;
  cursor: pointer;
  user-select: none;
  color: var(--ink-1);
  font-family: var(--font-display);
  font-size: 0.9375rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  border: 1px solid var(--deco-gold);
  border-radius: 999px;
  background: linear-gradient(180deg, rgb(134 171 167 / 0.14), rgb(134 171 167 / 0.02));
  position: relative;
  z-index: 3;
}
.floors > summary::-webkit-details-marker { display: none; }
.floors > summary::marker { content: ""; }
.floors__code {
  display: grid;
  place-items: center;
  min-width: 1.6rem;
  height: 1.6rem;
  padding-inline: 0.3rem;
  border-radius: 999px;
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  color: var(--brand-accent-on);
  background: var(--brand-accent);
}
.floors[open] > summary { border-color: var(--brand-accent); }
.floors__backdrop {
  position: fixed;
  inset: 0;
  z-index: 1;
  background: rgb(0 0 0 / 0.66);
}
.floors__panel {
  position: fixed;
  inset-inline: 0;
  inset-block-end: 0;
  z-index: 2;
  max-height: min(86vh, 44rem);
  max-height: min(86dvh, 44rem);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--s-4) var(--gutter) calc(var(--s-5) + env(safe-area-inset-bottom));
  background:
    linear-gradient(180deg, rgb(134 171 167 / 0.08), transparent 7rem),
    var(--noir-1);
  border-block-start: 2px solid var(--deco-gold);
  border-start-start-radius: var(--radius-3);
  border-start-end-radius: var(--radius-3);
  box-shadow: 0 -24px 60px rgb(0 0 0 / 0.65);
}
@media (prefers-reduced-motion: no-preference) {
  html:not([data-motion="off"]) .floors[open] .floors__panel { animation: sheet-up 260ms var(--ease-out) both; }
}
@keyframes sheet-up { from { transform: translateY(24px); opacity: 0; } to { transform: none; opacity: 1; } }
.floors__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  margin-block-end: var(--s-3);
}
.floors__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.25rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.floors__close {
  min-width: var(--target);
  min-height: var(--target);
  padding: 0 0.9rem;
  border: 1px solid var(--mark-2);
  border-radius: 999px;
  background: transparent;
  color: var(--ink-1);
  font-weight: 600;
}
.floors__list {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s-2);
  margin: 0 0 var(--s-4);
  padding: 0;
  list-style: none;
}
@media (min-width: 30rem) { .floors__list { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.floors__list li { margin: 0; }
.floors__list .floor-btn {
  flex-direction: row;
  justify-content: flex-start;
  gap: 0.75rem;
  min-height: 52px;
  padding: 0.5rem 0.75rem;
  font-size: 0.9375rem;
  letter-spacing: 0.06em;
  text-align: start;
  border: 1px solid var(--deco-gold-faint);
  background: rgb(232 255 252 / 0.02);
}
.floors__list .floor-btn__label { max-width: none; }
.floors__list .floor-btn__desc {
  display: inline-block;                 /* inline-block: the current floor's underline stays on the name only */
  width: 100%;
  margin-block-start: 0.15rem;
  font-family: var(--font-ui);
  font-size: 0.8125rem;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-2);
}
.floors__list .floor-btn[aria-current="page"] { border-color: var(--brand-accent); }
.floors__settings { display: flex; flex-wrap: wrap; gap: var(--s-2); padding-block-start: var(--s-3); border-block-start: 1px solid var(--hairline); }
html.sheet-open { overflow: hidden; }

/* Phone and tablet (< 64rem): the top bar scrolls away and the compact sticky panel is the Floors button docked
   in the bottom half of the screen (thumb reach, owner 04:10), showing the current floor's code. */
@media (max-width: 63.98rem) {
  .tower-bar { position: relative; }
  .floors > summary {
    position: fixed;
    inset-block-end: calc(14px + env(safe-area-inset-bottom) + var(--splash-lift, 0px));
    inset-inline-end: var(--gutter);
    min-height: 52px;
    padding: 0.4rem 0.6rem 0.4rem 1.1rem;
    background: linear-gradient(180deg, rgb(134 171 167 / 0.22), rgb(134 171 167 / 0.06)), var(--noir-1);
    box-shadow: 0 0 0 4px rgb(5 8 10 / 0.85), 0 12px 32px rgb(0 0 0 / 0.65);
  }
  .floors__panel { padding-block-end: calc(6.5rem + env(safe-area-inset-bottom)); }
  html { scroll-padding-top: var(--s-3); }
  [id] { scroll-margin-top: var(--s-3); }
  /* While the first-visit language card (lang-splash.js) is open it holds the bottom of the screen: the docked
     Floors button steps aside instead of rising over the hero caption, and returns when the card closes. */
  html.splash-open .floors:not([open]) > summary { visibility: hidden; }
}
/* The language switch inside the Floors sheet (phone): a full-width row under the settings. The language links sit
   in <span data-nosnippet> wrappers (Google honours data-nosnippet on span, div and section, not on <a>). */
.lang-switch { display: contents; }
.floors__lang { flex: 1 0 100%; display: flex; }
.floors__lang .lang-link { padding-inline: 0; }

/* -----------------------------------------------------------------------------------------------------
   6  ELEVATOR RIDE OVERLAY
   Departure (site.js): .ride.is-riding closes the doors and sweeps the ride dial, then the browser navigates.
   Arrival: the head script adds html.ride-arrive before first paint; CSS alone opens the doors, so a page whose
   module never loads still opens. Reduced motion or the motion toggle: no ride at all.
   ----------------------------------------------------------------------------------------------------- */
.ride {
  position: fixed;
  inset: 0;
  z-index: var(--z-ride);
  pointer-events: none;
  visibility: hidden;
  overflow: clip;
}
.ride__door {
  position: absolute;
  inset-block: 0;
  width: 50.5%;
  background:
    url("/assets/art/elevator-doors.svg") 0 0 / 200% 100% no-repeat,
    repeating-linear-gradient(90deg, rgb(134 171 167 / 0) 0 22px, rgb(134 171 167 / 0.1) 22px 23px),
    linear-gradient(180deg, #0B1315, #111B1D 46%, #0B1315);
  transition: transform var(--dur-door) var(--ease-film);
}
.ride__door--l {
  inset-inline-start: 0;
  transform: translateX(-101%);
  background-position: 0 0, 0 0, 0 0;
  box-shadow: inset -1px 0 0 rgb(154 255 243 / 0.55), inset -3px 0 0 rgb(110 143 140 / 0.22),
    inset -14px 0 18px -10px rgb(0 0 0 / 0.8);
}
.ride__door--r {
  inset-inline-end: 0;
  transform: translateX(101%);
  background-position: 100% 0, 0 0, 0 0;
  box-shadow: inset 1px 0 0 rgb(154 255 243 / 0.55), inset 3px 0 0 rgb(110 143 140 / 0.22),
    inset 14px 0 18px -10px rgb(0 0 0 / 0.8);
}
.ride__indicator {
  position: absolute;
  inset-block-start: max(12vh, 4rem);
  inset-inline-start: 50%;
  width: 7.5rem;
  margin-inline-start: -3.75rem;
  padding: 0.6rem 0.6rem 0.75rem;
  text-align: center;
  background: #05080A;
  border: 1px solid var(--deco-gold);
  border-radius: 999px 999px var(--radius-2) var(--radius-2);
  box-shadow: 0 0 0 4px rgb(0 0 0 / 0.6), 0 0 calc(30px * var(--glow-deco-strength)) var(--glow-gold);
  opacity: 0;
  transition: opacity 180ms ease-out;
}
.ride__indicator .floor-dial { width: 100%; }
.ride__indicator .floor-dial svg { width: 6rem; height: 3.8rem; }
.ride__indicator .floor-dial__readout { display: none; }
.ride__floor {
  display: block;
  margin-block-start: 0.15rem;
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 800;
  letter-spacing: 0.16em;
  color: var(--deco-gold-hi);
}
.ride.is-riding { visibility: visible; pointer-events: auto; }
.ride.is-riding .ride__door { transform: none; }
.ride.is-riding .ride__indicator { opacity: 1; transition-delay: 160ms; }

html.ride-arrive .ride { visibility: visible; animation: ride-hide 0s linear 420ms forwards; }
html.ride-arrive .ride__door--l { animation: door-open-l var(--dur-door) var(--ease-film) 80ms both; }
html.ride-arrive .ride__door--r { animation: door-open-r var(--dur-door) var(--ease-film) 80ms both; }
@keyframes door-open-l { from { transform: none; } to { transform: translateX(-101%); } }
@keyframes door-open-r { from { transform: none; } to { transform: translateX(101%); } }
@keyframes ride-hide { to { visibility: hidden; } }

/* -----------------------------------------------------------------------------------------------------
   7  BUTTONS (ONE PRIMARY STYLE), EXIT DOORS, TOGGLES
   ----------------------------------------------------------------------------------------------------- */
/* .btn is THE primary action. One per view. Secondary actions are .btn-quiet or plain links. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6em;
  min-height: 48px;
  padding: 0.75em 1.5em;
  font-family: var(--font-display);
  font-size: 1.0625rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  line-height: 1.15;
  text-align: center;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--brand-accent-on);
  background: var(--brand-gradient);
  border: 0;
  border-radius: var(--radius-1);
  box-shadow: 0 0 0 1px rgb(0 0 0 / 0.5), 0 0 0 3px rgb(134 171 167 / 0.55);
  box-shadow:
    0 0 0 1px rgb(0 0 0 / 0.5),
    0 0 0 3px rgb(134 171 167 / 0.55),
    0 0 calc(26px * var(--glow-strength)) color-mix(in srgb, var(--glow-accent) 45%, transparent);
  transition: transform var(--dur-press) ease-out, filter var(--dur-press) ease-out;
  -webkit-tap-highlight-color: transparent;
}
.btn:visited, .btn:hover { color: var(--brand-accent-on); }
.btn:hover { filter: brightness(1.06); }
.btn:active { transform: scale(0.97); }
.btn:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 5px; }
.btn--block { display: flex; width: 100%; }
.btn__soon {                             /* "Coming soon" inside the primary button until LAUNCH DAY (D16) */
  display: inline-block;
  padding: 0.12em 0.55em;
  font-size: 0.72em;
  letter-spacing: 0.08em;
  white-space: nowrap;
  border: 1px solid rgb(0 0 0 / 0.5);
  border-radius: 999px;
}

.btn-quiet {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5em;
  min-height: var(--target);
  padding: 0.6em 1.15em;
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;
  color: var(--ink-1);
  background: transparent;
  border: 1px solid var(--mark-2);
  border-radius: var(--radius-1);
  transition: border-color var(--dur-press) ease-out, transform var(--dur-press) ease-out;
}
.btn-quiet:visited { color: var(--ink-1); }
.btn-quiet:hover { border-color: var(--brand-accent); color: var(--ink-1); }
.btn-quiet:active { transform: scale(0.97); }

/* A control that cannot act (e.g. the App Store before launch): no href, aria-disabled, and words that say why. */
.is-soon, .btn[aria-disabled="true"], .btn-quiet[aria-disabled="true"] {
  cursor: default;
  pointer-events: none;
  color: var(--ink-2);
  background: transparent;
  border: 1px dashed var(--mark-2);
  box-shadow: none;
  filter: none;
}

.cta-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-3) var(--s-4); }
.cta-note { margin-block-start: var(--s-3); font-size: var(--t-subhead); color: var(--ink-2); }

/* Exit doors: links that leave the SI Tower. The "Leaving the SI Tower -> host" label is in the HTML (or added by
   site.js for [data-exit] links without one); it is visually hidden until hover or focus, always shown on
   touch screens, and always part of the accessible name. Never a blocking dialog. */
.doors { display: grid; gap: var(--s-2); margin: 0; padding: 0; list-style: none; }
.doors li { margin: 0; }
.door {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.15rem 0.6rem;
  min-height: 48px;
  padding: 0.6rem 0.9rem 0.6rem 2.6rem;
  color: var(--ink-1);
  text-decoration: none;
  background: linear-gradient(180deg, rgb(134 171 167 / 0.09), transparent 70%);
  border: 1px solid var(--mark-2);
  border-start-start-radius: 1.4rem;
  border-start-end-radius: 1.4rem;
  border-end-start-radius: var(--radius-1);
  border-end-end-radius: var(--radius-1);
  transition: border-color var(--dur-press) ease-out;
}
.door::before {                         /* a small brass door glyph (decor; the words carry the meaning) */
  content: "";
  position: absolute;
  inset-inline-start: 0.9rem;
  inset-block-start: 50%;
  width: 1rem;
  height: 1.3rem;
  margin-block-start: -0.65rem;
  border: 1.5px solid var(--deco-gold);
  border-radius: 0.5rem 0.5rem 1px 1px;
  background: linear-gradient(90deg, transparent 47%, var(--deco-gold) 47% 53%, transparent 53%);
}
.door:visited { color: var(--ink-1); }
.door:hover, .door:focus-visible { border-color: var(--brand-accent); }
.door__name { font-weight: 600; }
.door__host { font-size: var(--t-footnote); color: var(--ink-2); }
.door__exit {
  flex: 1 0 100%;
  font-size: var(--t-footnote);
  font-weight: 600;
  color: var(--brand-accent);
}
.door__exit:not(.is-shown) {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}
.door:hover .door__exit, .door:focus-visible .door__exit,
[data-exit]:hover > .door__exit, [data-exit]:focus-visible > .door__exit {
  position: static;
  width: auto;
  height: auto;
  overflow: visible;
  clip: auto;
  clip-path: none;
  white-space: normal;
}
@media (hover: none) {
  .door__exit {
    position: static !important;
    width: auto !important;
    height: auto !important;
    overflow: visible !important;
    clip: auto !important;
    clip-path: none !important;
    white-space: normal !important;
  }
}
/* Inline exit links in running text (a[data-exit] that is not a .door): the label follows the text as a quiet
   caption inside the same link, so it never reads as a second link. site.js wraps the link's own words in
   .door__text and only those are underlined (an underline set on the link itself would also run through the label
   when a page makes the link a flex box). The label is an atomic inline box, and it wraps under the words in a
   flex link. */
a[data-exit]:not(.door):not(.btn):not(.btn-quiet) { flex-wrap: wrap; }
a[data-exit]:not(.door):not(.btn):not(.btn-quiet):has(> .door__text) { text-decoration-line: none; }
a[data-exit]:not(.door) > .door__text { text-decoration-line: underline; text-decoration-thickness: 1px; text-underline-offset: 0.18em; }
a[data-exit]:not(.door):hover > .door__text { text-decoration-thickness: 2px; }
a[data-exit]:not(.door) .door__exit {
  display: inline-block;
  flex: 0 1 auto;
  margin-inline-start: 0.4em;
  font-weight: 400;
  color: var(--ink-2);
  text-decoration: none;
}
/* A .btn-quiet exit (e.g. the press page's mailto): wrap inside the screen, label on its own row. */
.btn-quiet[data-exit] { flex-wrap: wrap; max-width: 100%; white-space: normal; overflow-wrap: anywhere; text-align: center; }
a.btn-quiet[data-exit] > .door__exit { flex: 1 0 100%; margin-inline-start: 0; }

.door--soon { cursor: default; color: var(--ink-2); border-style: dashed; background: transparent; }
.door--soon::before { opacity: 0.55; }
.door__state {
  display: inline-block;
  padding: 0.1rem 0.5rem;
  font-size: var(--t-caption1);
  font-weight: 650;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-1);
  border: 1px solid var(--mark-2);
  border-radius: 999px;
}

/* Toggles (sound, motion): real <button aria-pressed>, hidden until site.js can act on them. The state is
   spoken by aria-pressed and shown as words + switch position, never colour alone. */
.toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  min-height: var(--target);
  padding: 0.4rem 0.85rem 0.4rem 0.6rem;
  font-size: var(--t-subhead);
  font-weight: 600;
  color: var(--ink-1);
  background: transparent;
  border: 1px solid var(--mark-2);
  border-radius: 999px;
}
.toggle:hover { border-color: var(--brand-accent); }
.toggle__switch {
  position: relative;
  flex: 0 0 auto;
  width: 2.25rem;
  height: 1.3rem;
  border-radius: 999px;
  background: var(--fill-4);
  border: 1px solid var(--mark-2);
}
.toggle__switch::after {
  content: "";
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 0.15rem;
  width: 0.95rem;
  height: 0.95rem;
  margin-block-start: -0.475rem;
  border-radius: 50%;
  background: var(--ink-2);
  transition: transform var(--dur-press) ease-out;
}
.toggle[aria-pressed="true"] .toggle__switch { background: var(--brand-accent-tint); border-color: var(--brand-accent); }
.toggle[aria-pressed="true"] .toggle__switch::after { transform: translateX(0.9rem); background: var(--brand-accent); }
.toggle__state { color: var(--ink-2); font-weight: 500; }
.toggle-group { display: flex; flex-wrap: wrap; gap: var(--s-2); }

/* -----------------------------------------------------------------------------------------------------
   8  DECO CARDS, FRAMES, DIVIDERS, FLOOR SIGN, BADGES, SHOW-THE-MATH, LED PRICE
   ----------------------------------------------------------------------------------------------------- */
.deco-card {
  position: relative;
  padding: clamp(1.25rem, 1rem + 1.2vw, 2rem);
  background:
    linear-gradient(180deg, rgb(134 171 167 / 0.06), transparent 40%),
    var(--noir-2);
  border: 1px solid var(--deco-gold-line);
  border-radius: var(--radius-1);
}
.deco-card::before {                    /* inner double rule (decor) */
  content: "";
  position: absolute;
  inset: 5px;
  border: 1px solid var(--deco-gold-faint);
  border-radius: 2px;
  pointer-events: none;
}
.deco-card::after {                     /* stepped crown at the top centre (decor) */
  content: "";
  position: absolute;
  inset-block-start: -1px;
  inset-inline-start: 50%;
  width: 4.5rem;
  height: 5px;
  margin-inline-start: -2.25rem;
  background:
    linear-gradient(var(--deco-gold), var(--deco-gold)) 50% 0 / 100% 1px no-repeat,
    linear-gradient(var(--deco-gold), var(--deco-gold)) 50% 2px / 60% 1px no-repeat,
    linear-gradient(var(--deco-gold), var(--deco-gold)) 50% 4px / 24% 1px no-repeat;
  pointer-events: none;
}
.deco-card > :last-child { margin-block-end: 0; }
.deco-card__icon { display: block; width: 2.5rem; height: 2.5rem; margin-block-end: var(--s-3); }
.deco-card--plain::after { display: none; }

/* Frame around art or images: pure CSS (gold rule + black mat + inner hairline) so it never depends on an art
   file. .deco-frame--art additionally lays /assets/art/deco-frame.svg over the frame as a decorative overlay
   (stretched to the box; if the file is missing, the CSS frame is what you see). */
.deco-frame {
  position: relative;
  display: block;
  padding: clamp(0.6rem, 0.4rem + 0.8vw, 1.1rem);
  background: #05080A;
  border: 2px solid var(--deco-gold);
  border-radius: 2px;
  box-shadow: 0 0 0 4px #05080A, 0 0 0 5px var(--deco-gold-lo), 0 30px 60px -30px rgb(0 0 0 / 0.9);
}
.deco-frame::before {
  content: "";
  position: absolute;
  inset: 5px;
  border: 1px solid var(--deco-gold-faint);
  pointer-events: none;
}
.deco-frame--art::after {
  content: "";
  position: absolute;
  inset: -8px;
  background: url("/assets/art/deco-frame.svg") 50% 50% / 100% 100% no-repeat;
  pointer-events: none;
}
.deco-frame > img, .deco-frame > picture > img { display: block; width: 100%; height: auto; }

/* Divider: the art file over a CSS fallback rule with a centre diamond. */
.deco-divider {
  display: block;
  height: 22px;
  margin: var(--s-7) auto;
  max-width: 28rem;
  border: 0;
  background:
    url("/assets/art/deco-divider.svg") 50% 50% / auto 100% no-repeat,
    linear-gradient(var(--deco-gold), var(--deco-gold)) 50% 50% / 100% 1px no-repeat;
}

/* Floor sign: the page's floor plaque above its h1. */
.floor-sign {
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  margin: 0 0 var(--s-4);
  padding: 0.35rem 1rem 0.35rem 0.35rem;
  font-family: var(--font-display);
  font-size: 0.9375rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-1);
  background: linear-gradient(180deg, rgb(134 171 167 / 0.16), rgb(134 171 167 / 0.04));
  border: 1px solid var(--deco-gold);
  border-radius: 999px;
}
.floor-sign__code {
  display: grid;
  place-items: center;
  min-width: 2.1rem;
  height: 2.1rem;
  padding-inline: 0.35rem;
  border-radius: 999px;
  font-size: 0.9375rem;
  letter-spacing: 0.04em;
  color: var(--ink-1);
  background: radial-gradient(circle at 35% 30%, #111B1D, #05080A 70%);
  border: 1.5px solid var(--deco-gold-hi);
}
.page-head { padding-block: clamp(2.5rem, 2rem + 3vw, 5rem) var(--s-6); }
.page-head .lede { margin-block-start: var(--s-4); }

/* Badges and tags (words always present; glyphs are decor or verdicts beside words) */
.tag, .sample-tag, .example-tag {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  padding: 0.15rem 0.55rem;
  font-size: var(--t-caption1);
  font-weight: 650;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  line-height: 1.4;
  color: var(--ink-1);
  background: var(--fill-4);
  border: 1px solid var(--mark-2);
  border-radius: 999px;
  white-space: nowrap;
}
.badge-construction {
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  padding: 0.2rem 0.65rem;
  font-size: var(--t-caption1);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  line-height: 1.4;
  color: var(--ink-1);
  border: 1px solid var(--deco-gold);
  border-radius: var(--radius-1);
  background: repeating-linear-gradient(135deg, rgb(134 171 167 / 0.16) 0 6px, transparent 6px 12px), var(--noir-0);
  white-space: nowrap;
}
.badge-construction::before {          /* scaffold glyph (decor; the words say the status) */
  content: "";
  width: 0.8em;
  height: 0.8em;
  border: 1.5px solid var(--deco-gold-hi);
  background: linear-gradient(45deg, transparent 45%, var(--deco-gold-hi) 45% 55%, transparent 55%);
}

/* Verdict glyphs beside words (status colours only here) */
.verdict { display: inline-flex; align-items: baseline; gap: 0.45em; }
.verdict::before {
  content: "";
  flex: 0 0 auto;
  width: 0.85em;
  height: 0.85em;
  transform: translateY(0.08em);
  border-radius: 50%;
}
.verdict--pass::before { background: var(--status-pass); clip-path: polygon(14% 52%, 0 66%, 38% 100%, 100% 22%, 86% 8%, 38% 72%); border-radius: 0; }
.verdict--warn::before { background: var(--status-warning); clip-path: polygon(50% 0, 100% 100%, 0 100%); border-radius: 0; }
.verdict--no::before { border: 2px solid var(--mark-2); background: linear-gradient(45deg, transparent 43%, var(--mark-2) 43% 57%, transparent 57%); }

/* Show the math: flat graphite, no glow, no gradient (the app's rule). */
.math {
  margin-block: var(--s-3);
  border: 1px solid var(--mark-3);
  border-radius: var(--radius-2);
  background: rgb(134 171 167 / 0.05);
}
.math > summary {
  display: flex;
  align-items: center;
  gap: 0.5em;
  min-height: var(--target);
  padding: 0.4rem 0.9rem;
  cursor: pointer;
  font-weight: 600;
  color: var(--math-accent);
  list-style: none;
}
.math > summary::-webkit-details-marker { display: none; }
.math > summary::before { content: "f(x)"; font-family: var(--font-mono); font-style: italic; font-size: 0.9em; }
.math > summary::after { content: ""; width: 0.5em; height: 0.5em; margin-inline-start: auto; border-inline-end: 2px solid currentColor; border-block-end: 2px solid currentColor; transform: rotate(45deg); transition: transform var(--dur-disclosure) ease-in-out; }
.math[open] > summary::after { transform: rotate(-135deg); }
.math__body { padding: 0 0.9rem 0.9rem; color: var(--ink-2); }
.math__eq {
  display: block;
  margin: 0.4rem 0;
  padding: 0.6rem 0.75rem;
  overflow-x: auto;
  font-family: var(--font-mono);
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--ink-1);
  background: var(--surface-instrument);
  border-radius: var(--radius-1);
}

/* LED price chip (the app's seven-segment readout look; digits in the UI face, tabular) */
.led {
  display: inline-flex;
  align-items: baseline;
  gap: 0.15em;
  padding: 0.35rem 0.8rem;
  font-family: var(--font-mono);
  font-weight: 700;
  color: var(--led-positive);
  background: var(--led-chip);
  border: 1px solid rgb(154 255 243 / 0.28);
  border-radius: var(--radius-2);
  box-shadow: inset 0 0 0 1px rgb(0 0 0 / 0.6);
}
.led .fig { font-family: var(--font-mono); }
.price { font-size: clamp(2rem, 1.6rem + 2vw, 3rem); }
.price-disclosure { max-width: 34rem; font-size: var(--t-subhead); color: var(--ink-2); }

/* -----------------------------------------------------------------------------------------------------
   9  PICTURES AND FIGURES
   ----------------------------------------------------------------------------------------------------- */
figure { margin: 0 0 var(--s-5); }
figcaption {
  margin-block-start: var(--s-3);
  font-size: var(--t-subhead);
  line-height: 1.45;
  color: var(--ink-2);
}
figcaption .sample-tag, figcaption .example-tag { margin-inline-end: 0.5em; vertical-align: 0.1em; }

/* Screenshot: phone-shaped frame with a gold hairline; the cropped captures end with a soft fade. */
.shot { max-width: 20rem; margin-inline: auto; }
.shot__frame {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: clamp(1.2rem, 0.9rem + 1.5vw, 2.2rem);
  background: #000000;
  border: 1px solid var(--deco-gold-line);
  box-shadow: 0 0 0 6px #05080A, 0 0 0 7px var(--deco-gold-faint), 0 30px 60px -30px rgb(0 0 0 / 0.9);
}
.shot__frame img { display: block; width: 100%; height: auto; }
.shot__frame--fade img {
  -webkit-mask-image: linear-gradient(180deg, #000000 86%, transparent 100%);
  mask-image: linear-gradient(180deg, #000000 86%, transparent 100%);
}
.shot figcaption { text-align: center; }
.shot-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s-6);
  justify-items: center;
}
@media (min-width: 40rem) { .shot-row { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 64rem) { .shot-row { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

/* Book cover on its lectern (the only gain-map image today, D2) */
.cover {
  display: block;
  width: min(100%, 22rem);
  margin-inline: auto;
  box-shadow: 0 0 0 1px var(--deco-gold-line), 0 40px 80px -30px rgb(0 0 0 / 0.95),
    0 0 calc(60px * var(--glow-deco-strength)) -10px rgb(154 255 243 / 0.25);
}
.cover img { display: block; width: 100%; height: auto; }

/* -----------------------------------------------------------------------------------------------------
   10  CONCIERGE DESK, PROFESSION TAG, BELLHOP CARD, ITINERARY COLUMNS
   Markup contract with /assets/concierge.js (another agent): [data-concierge] root, form [data-concierge-form],
   input [data-concierge-input], chips [data-concierge-chip="<key>"] (real links), result [data-concierge-result]
   (aria-live), routes JSON [data-concierge-routes], optional profession tag [data-concierge-profession].
   ----------------------------------------------------------------------------------------------------- */
.concierge {
  position: relative;
  padding: clamp(1.5rem, 1rem + 2.5vw, 3rem);
  background:
    radial-gradient(70% 60% at 85% 0%, rgb(154 255 243 / 0.1), transparent 70%),
    linear-gradient(180deg, #0B1315, var(--noir-2) 45%);
  border: 1px solid var(--deco-gold);
  border-radius: var(--radius-3) var(--radius-3) var(--radius-1) var(--radius-1);
  box-shadow: inset 0 1px 0 rgb(154 255 243 / 0.25), 0 30px 60px -40px #000000;
}
.concierge__bell { display: block; width: 3.25rem; height: auto; margin-block-end: var(--s-3); }
.concierge__question { margin-block-end: var(--s-2); }
.concierge__form {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin-block: var(--s-4) var(--s-2);
}
.concierge__form label { flex: 1 0 100%; font-weight: 600; }
.concierge__input { flex: 1 1 14rem; min-width: 0; }
.concierge__submit { flex: 0 0 auto; }
.concierge__privacy {
  display: flex;
  align-items: center;
  gap: 0.5em;
  margin: 0 0 var(--s-4);
  font-size: var(--t-footnote);
  color: var(--ink-2);
}
.concierge__privacy::before {           /* padlock glyph (decor; the sentence carries the promise) */
  content: "";
  flex: 0 0 auto;
  width: 0.8em;
  height: 0.7em;
  margin-block-start: 0.25em;
  border: 1.5px solid var(--ink-2);
  border-radius: 2px;
  box-shadow: 0 -0.32em 0 -0.12em transparent;
  background: radial-gradient(circle at 50% 45%, var(--ink-2) 0 18%, transparent 20%);
}
.chips { display: flex; flex-wrap: wrap; gap: var(--s-2); margin: 0 0 var(--s-4); padding: 0; list-style: none; }
.chips li { margin: 0; }
.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  min-height: var(--target);
  padding: 0.45rem 0.95rem;
  font-size: var(--t-subhead);
  font-weight: 600;
  line-height: 1.2;
  color: var(--ink-1);
  text-decoration: none;
  background: rgb(232 255 252 / 0.03);
  border: 1px solid var(--mark-2);
  border-radius: 999px;
  transition: border-color var(--dur-press) ease-out, transform var(--dur-press) ease-out;
}
.chip:visited { color: var(--ink-1); }
.chip:hover { border-color: var(--brand-accent); color: var(--ink-1); }
.chip:active { transform: scale(0.96); }
.chip[aria-pressed="true"], .chip[aria-current="true"], .chip.is-selected {
  color: var(--money-ink);
  background: var(--brand-accent-tint);
  border-color: var(--brand-accent);
}
.chip[aria-pressed="true"]::before, .chip[aria-current="true"]::before, .chip.is-selected::before {
  content: "";
  width: 0.7em;
  height: 0.4em;
  margin-block-start: -0.2em;
  border-inline-start: 2px solid currentColor;
  border-block-end: 2px solid currentColor;
  transform: rotate(-45deg);
}
.chip--all { border-style: dashed; }
.concierge__result { min-height: 1px; scroll-margin-block-start: calc(var(--bar-h) + var(--s-3)); }
@media (max-width: 63.98rem) { .concierge__result { scroll-margin-block-start: var(--s-3); } }   /* never display:none: it is the aria-live region concierge.js refills */
.concierge__confidence { font-size: var(--t-footnote); color: var(--ink-3); }

/* "Sounds like: musician · change" (editable, never a sensitive trait) */
.profession-tag {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem 0.5rem;
  margin: 0 0 var(--s-3);
  padding: 0.25rem 0.35rem 0.25rem 0.8rem;
  font-size: var(--t-subhead);
  color: var(--ink-2);
  background: var(--noir-1);
  border: 1px solid var(--deco-gold-line);
  border-radius: 999px;
}
.profession-tag__value { font-weight: 650; color: var(--ink-1); }
.profession-tag__change {
  min-height: var(--target);
  padding: 0 0.85rem;
  font-size: var(--t-subhead);
  font-weight: 600;
  color: var(--brand-accent);
  background: transparent;
  border: 0;
  border-radius: 999px;
  text-decoration: underline;
  text-underline-offset: 0.2em;
}
.clarify { display: grid; gap: var(--s-2); margin-block: var(--s-3); }
.clarify__q { margin: 0; font-weight: 600; }

/* Bellhop card: "First visit? Here's the quick way up" (paycheck -> plan -> what to fix first) */
.bellhop {
  position: relative;
  padding: clamp(1.25rem, 1rem + 1.5vw, 2rem);
  padding-block-start: clamp(2.5rem, 2rem + 1.5vw, 3rem);
  background: linear-gradient(180deg, #0B1315, var(--noir-2) 55%);
  border: 1px solid var(--deco-gold);
  border-radius: var(--radius-2);
}
.bellhop__cap {
  position: absolute;
  inset-block-start: -1.6rem;
  inset-inline-start: clamp(1rem, 0.8rem + 1vw, 1.75rem);
  width: 3.4rem;
  height: auto;
}
.bellhop__title { font-size: clamp(1.375rem, 1.2rem + 0.7vw, 1.75rem); }
.bellhop__steps {
  display: grid;
  gap: var(--s-3);
  margin: var(--s-4) 0 var(--s-5);
  padding: 0;
  list-style: none;
  counter-reset: bell;
}
@media (min-width: 48rem) { .bellhop__steps { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.bellhop__steps li {
  position: relative;
  margin: 0;
  padding: 0.75rem 0.9rem 0.75rem 3.1rem;
  counter-increment: bell;
  background: rgb(232 255 252 / 0.02);
  border: 1px solid var(--deco-gold-faint);
  border-radius: var(--radius-2);
}
.bellhop__steps li::before {           /* brass button numerals */
  content: counter(bell);
  position: absolute;
  inset-inline-start: 0.7rem;
  inset-block-start: 0.7rem;
  display: grid;
  place-items: center;
  width: 1.8rem;
  height: 1.8rem;
  font-family: var(--font-display);
  font-weight: 800;
  color: var(--ink-1);
  border: 1.5px solid var(--deco-gold);
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #111B1D, #05080A 70%);
}
.bellhop__steps strong { display: block; color: var(--ink-1); }
.bellhop__steps span { color: var(--ink-2); font-size: var(--t-subhead); }

/* Itinerary: three honest columns, each with its heading words + glyph (never colour alone). */
.itinerary { display: grid; gap: var(--s-4); grid-template-columns: minmax(0, 1fr); margin-block: var(--s-4); }
@media (min-width: 56rem) { .itinerary { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.itin-col {
  padding: var(--s-4);
  background: var(--noir-1);
  border: 1px solid var(--mark-3);
  border-block-start: 3px solid var(--mark-2);
  border-radius: var(--radius-1);
}
.itin-col__title {
  display: flex;
  align-items: center;
  gap: 0.55em;
  margin: 0 0 var(--s-3);
  font-family: var(--font-display);
  font-size: 1.125rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.itin-col__title::before { content: ""; flex: 0 0 auto; width: 1em; height: 1em; }
.itin-col--today { border-block-start-color: var(--brand-accent); }
.itin-col--today .itin-col__title::before {
  background: var(--status-pass);
  clip-path: polygon(14% 52%, 0 66%, 38% 100%, 100% 22%, 86% 8%, 38% 72%);
}
.itin-col--construction { border-block-start-color: var(--deco-gold); }
.itin-col--construction .itin-col__title::before {
  border: 1.5px solid var(--deco-gold-hi);
  background: linear-gradient(45deg, transparent 44%, var(--deco-gold-hi) 44% 56%, transparent 56%);
}
.itin-col--notdo .itin-col__title::before {
  border: 2px solid var(--mark-2);
  border-radius: 50%;
  background: linear-gradient(45deg, transparent 42%, var(--mark-2) 42% 58%, transparent 58%);
}
.itin-list { margin: 0; padding: 0; list-style: none; }
.itin-list li { margin: 0; padding: 0.5rem 0; border-block-start: 1px solid var(--hairline); }
.itin-list li:first-child { border-block-start: 0; padding-block-start: 0; }
.itin-list a { font-weight: 600; }
.itin-list .itin-why { display: block; font-size: var(--t-subhead); color: var(--ink-2); }
.itin-route { counter-reset: stop; margin: 0 0 var(--s-4); padding: 0; list-style: none; }
.itin-route li { counter-increment: stop; display: flex; gap: 0.75rem; align-items: baseline; margin: 0 0 0.5rem; }
.itin-route li::before {
  content: counter(stop);
  flex: 0 0 1.6rem;
  height: 1.6rem;
  display: grid;
  place-items: center;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 0.875rem;
  border: 1.5px solid var(--deco-gold);
  border-radius: 50%;
}

/* Rendered by concierge.js defaultRender (classes concierge-*, groups carry data-status). Same look as the
   itinerary columns above; item rows get a common min-height so the three columns line up row by row. */
.concierge-status, .concierge-clarify { margin: var(--s-3) 0 var(--s-2); color: var(--ink-2); }
.concierge-clarify { font-weight: 600; color: var(--ink-1); }
.concierge-options { display: flex; flex-wrap: wrap; gap: var(--s-2); margin: 0 0 var(--s-3); }
.concierge-option {
  min-height: var(--target);
  padding: 0.45rem 1rem;
  font-weight: 600;
  color: var(--ink-1);
  background: rgb(232 255 252 / 0.03);
  border: 1px solid var(--mark-2);
  border-radius: 999px;
}
.concierge-option:hover { border-color: var(--brand-accent); }
.concierge-suggests {
  margin: var(--s-4) 0 var(--s-1);
  font-family: var(--font-display);
  font-size: 0.875rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.concierge-label { margin: 0 0 var(--s-2); }
.concierge-label:focus { outline: none; }
.concierge-welcome { max-width: var(--max-text); color: var(--ink-2); }
.concierge-columns { display: grid; gap: var(--s-3); grid-template-columns: minmax(0, 1fr); margin-block: var(--s-3); }
@media (min-width: 56rem) { .concierge-columns { grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); } }
.concierge-group {
  padding: var(--s-3);
  background: var(--noir-1);
  border: 1px solid var(--mark-3);
  border-block-start: 3px solid var(--mark-2);
  border-radius: var(--radius-1);
}
.concierge-group[data-status="today"] { border-block-start-color: var(--brand-accent); }
.concierge-group[data-status="construction"] { border-block-start-color: var(--deco-gold); }
.concierge-group-title {
  display: flex;
  align-items: center;
  gap: 0.55em;
  margin: 0 0 var(--s-2);
  font-family: var(--font-display);
  font-size: 1.0625rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.concierge-group-title::before { content: ""; flex: 0 0 auto; width: 1em; height: 1em; }
.concierge-group[data-status="today"] .concierge-group-title::before {
  background: var(--status-pass);
  clip-path: polygon(14% 52%, 0 66%, 38% 100%, 100% 22%, 86% 8%, 38% 72%);
}
.concierge-group[data-status="construction"] .concierge-group-title::before {
  border: 1.5px solid var(--deco-gold-hi);
  background: linear-gradient(45deg, transparent 44%, var(--deco-gold-hi) 44% 56%, transparent 56%);
}
.concierge-group[data-status="not_us"] .concierge-group-title::before {
  border: 2px solid var(--mark-2);
  border-radius: 50%;
  background: linear-gradient(45deg, transparent 42%, var(--mark-2) 42% 58%, transparent 58%);
}
.concierge-items { margin: 0; padding-inline-start: 1.25em; }
.concierge-item { min-height: 3.25rem; margin: 0; padding-block: 0.35rem; }
.concierge-item a { font-weight: 600; }
.concierge-item--text { min-height: 0; color: var(--ink-2); }
.concierge-note { margin: var(--s-2) 0 0; font-size: var(--t-footnote); color: var(--ink-3); }
.concierge-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2) var(--s-3); margin-block: var(--s-3) 0; }
.concierge-another {
  min-height: var(--target);
  padding: 0.5rem 1rem;
  font-weight: 600;
  color: var(--ink-1);
  background: transparent;
  border: 1px solid var(--mark-2);
  border-radius: var(--radius-1);
}
.concierge-another:hover { border-color: var(--brand-accent); }
.concierge-everything { display: inline-flex; align-items: center; min-height: var(--target); font-weight: 600; }
.itin-list li { min-height: 3.25rem; }

/* -----------------------------------------------------------------------------------------------------
   10b  ROW MATCHING / PAIRING (owner 04:10): label-value pairs on one grid, paired comparison rows,
        equal-height cards with CTAs on one baseline. The layout changes before any figure shrinks or wraps.
   ----------------------------------------------------------------------------------------------------- */
.pairs { container-type: inline-size; margin: 0 0 var(--s-3); padding: 0; }
.pair {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline;
  gap: var(--s-1) var(--s-3);
  min-height: var(--target);
  padding-block: 0.625rem;
  border-block-end: 1px solid var(--hairline);
}
.pair > dt, .pair__label { margin: 0; font-weight: 500; color: var(--ink-2); }
.pair > dd, .pair__value { margin: 0; text-align: end; font-weight: 650; color: var(--ink-1); }
@container (max-width: 17rem) {
  .pair { grid-template-columns: minmax(0, 1fr); }
  .pair > dd, .pair__value { text-align: start; }
}
/* A figure that does not fit shrinks to 0.75 of its style and never below 11 px (typography_numbers B). */
.fig--fit { font-size: clamp(max(11px, 0.75em), 7cqi, 1em); }

/* Paired comparison ("On your iPhone" vs "In a cloud dashboard"): one row = one question, both answers. */
.compare { width: 100%; margin: 0 0 var(--s-4); border-collapse: collapse; font-size: var(--t-callout); }
.compare caption { margin-block-end: var(--s-2); text-align: start; color: var(--ink-2); font-size: var(--t-subhead); }
.compare th, .compare td { padding: 0.75rem; text-align: start; vertical-align: top; border-block-end: 1px solid var(--hairline); }
.compare thead th {
  font-family: var(--font-display);
  font-size: 0.9375rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-1);
  border-block-end: 1px solid var(--deco-gold-line);
}
.compare tbody th { width: 28%; font-weight: 600; color: var(--ink-2); }
.compare td { color: var(--ink-1); }
@media (max-width: 39.98rem) {
  .compare thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .compare tr { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); border-block-end: 1px solid var(--hairline); }
  .compare tbody th { grid-column: 1 / -1; width: auto; padding-block-end: 0.25rem; border: 0; }
  .compare td { border: 0; }
  .compare td::before { content: attr(data-label); display: block; margin-block-end: 0.15rem; font-size: var(--t-caption1); font-weight: 650; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-3); }
}

/* Equal-height cards in a row; each card's action sits on the same baseline at the bottom. */
.card-row { display: grid; gap: var(--s-4); grid-template-columns: minmax(0, 1fr); align-items: stretch; }
@media (min-width: 48rem) { .card-row { grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); } }
.card { display: flex; flex-direction: column; height: 100%; }
.card > .card__cta, .card > :last-child.cta-row { margin-block-start: auto; padding-block-start: var(--s-3); }
.card__cta a:not(.btn):not(.btn-quiet) { display: inline-flex; align-items: center; min-height: var(--target); }

/* -----------------------------------------------------------------------------------------------------
   11  SCENES
   Every scene: <section class="scene scene--<floor>"> with optional .scene__art (aria-hidden decor) and
   .scene__content. Art never sits under body text: on phones it stacks above the text, on wide screens it
   takes its own grid column (.scene__grid).
   ----------------------------------------------------------------------------------------------------- */
.scene {
  position: relative;
  isolation: isolate;
  overflow: clip;
  padding-block: clamp(3.5rem, 2.5rem + 5vw, 7rem);
  background: var(--noir-0);
}
.scene__grid { display: grid; gap: var(--s-6); grid-template-columns: minmax(0, 1fr); align-items: center; }
@media (min-width: 56rem) {
  .scene__grid { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
  .scene__grid--art-first { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
  .scene__grid--art-first > .scene__art { order: -1; }
}
.scene__art {
  position: relative;
  display: grid;
  place-items: center;
  pointer-events: none;
  user-select: none;
}
.scene__art img { display: block; width: 100%; max-width: 28rem; height: auto; max-height: 40vh; object-fit: contain; }
@media (min-width: 56rem) { .scene__art img { max-height: 34rem; } }
.scene__content { position: relative; z-index: 1; min-width: 0; }

.scene--app {
  background:
    radial-gradient(110% 70% at 50% 0%, #111B1D 0%, transparent 62%),
    var(--noir-0);
}
.scene--vault {
  background:
    radial-gradient(80% 60% at 85% 10%, var(--deco-steel), transparent 65%),
    linear-gradient(180deg, #0B1315, var(--noir-0));
}
.scene--engine {
  background:
    radial-gradient(60% 45% at 18% 0%, var(--glow-tube), transparent 70%),
    radial-gradient(50% 40% at 90% 20%, rgb(154 255 243 / 0.05), transparent 70%),
    linear-gradient(180deg, var(--deco-tube), var(--noir-0) 70%);
}
.scene--library {
  background:
    radial-gradient(70% 55% at 50% 0%, var(--deco-wood), transparent 70%),
    linear-gradient(180deg, #0B1315, #05080A);
}
.scene--penthouse {
  background:
    radial-gradient(120% 60% at 50% 110%, rgb(42 58 60 / 0.22), transparent 60%),
    linear-gradient(180deg, #0B1315, var(--noir-0));
}
.scene--concierge {
  background:
    radial-gradient(55% 45% at 75% 0%, rgb(134 171 167 / 0.12), transparent 70%),
    var(--noir-0);
}
.scene--press {
  background:
    repeating-linear-gradient(180deg, transparent 0 31px, rgb(232 255 252 / 0.018) 31px 32px),
    linear-gradient(180deg, #0B1315, var(--noir-0));
}
.scene--archive { background: var(--noir-0); }

/* Chandelier: original SVG plus a glints overlay (gain-map AVIF on capable screens, identical SDR PNG
   otherwise). Static: no pulse, ever. */
.chandelier {
  position: relative;
  width: clamp(8rem, 5rem + 12vw, 15rem);
  margin-inline: auto;
  pointer-events: none;
}
.chandelier > img, .chandelier > picture > img { display: block; width: 100%; height: auto; }
.chandelier__glints { position: absolute; inset: 0; display: block; }
.chandelier__glints img { width: 100%; height: 100%; object-fit: contain; mix-blend-mode: screen; }

/* ---- Lobby hero: letterbox + sky + searchlights + data rain + skyline + rain on glass ---- */
.hero {
  position: relative;
  isolation: isolate;
  overflow: clip;
  display: grid;
  align-items: start;
  min-height: min(92vh, 56rem);
  min-height: min(92svh, 56rem);
  background: var(--deco-ink);
  --letterbox: clamp(10px, 3.2vh, 34px);
}
.hero__layers { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.hero__sky {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(120% 62% at 50% 100%, var(--deco-sky-low) 0%, var(--deco-sky-mid) 40%, transparent 78%),
    linear-gradient(180deg, var(--noir-0) 0%, var(--deco-sky-top) 30%, #0B1315 62%, var(--deco-sky-mid) 100%);
}
/* Searchlights: two slow CSS beams that sweep ONCE (about 4.8 s) and settle; static under reduced motion. */
.searchlights { position: absolute; inset: 0; z-index: 0; }
.searchlights::before, .searchlights::after {
  content: "";
  position: absolute;
  inset-block-end: 30%;
  width: 34rem;
  height: 130%;
  margin-inline-start: -17rem;
  transform-origin: 50% 100%;
  background: linear-gradient(0deg, var(--glow-searchlight-core) 0%, var(--glow-searchlight) 35%, transparent 90%);
  clip-path: polygon(48.5% 100%, 51.5% 100%, 100% 0, 0 0);
  opacity: calc(0.9 * var(--glow-deco-strength));
}
.searchlights::before { inset-inline-start: 28%; transform: rotate(-17deg); animation: beam-a 4.8s var(--ease-film) 1 both; }
.searchlights::after { inset-inline-start: 74%; transform: rotate(13deg); animation: beam-b 4.8s var(--ease-film) 1 both; }
@keyframes beam-a { from { transform: rotate(-34deg); } to { transform: rotate(-17deg); } }
@keyframes beam-b { from { transform: rotate(30deg); } to { transform: rotate(13deg); } }
.searchlights--art { background: url("/assets/art/searchlights.svg") 50% 100% / cover no-repeat; }
.searchlights--art::before, .searchlights--art::after { display: none; }

/* Data rain canvas (site.js). Without JS, or before it runs, a static glyph texture shows instead. */
.data-rain {
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  display: block;
  width: 100%;
  height: 74%;
  z-index: 1;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='264' height='264' font-family='Menlo,monospace' font-size='14' fill='%239AFFF3'%3E%3Cg opacity='.2'%3E%3Ctext x='8' y='20'%3E7%3C/text%3E%3Ctext x='8' y='38'%3E$%3C/text%3E%3Ctext x='8' y='56'%3E2%3C/text%3E%3Ctext x='52' y='92'%3E%25%3C/text%3E%3Ctext x='52' y='110'%3E0%3C/text%3E%3Ctext x='96' y='30'%3E%26%232A3A3C;%3C/text%3E%3Ctext x='96' y='48'%3E4%3C/text%3E%3Ctext x='96' y='66'%3E%26%23111B1D;%3C/text%3E%3Ctext x='96' y='84'%3E9%3C/text%3E%3Ctext x='140' y='140'%3E%26%232A3A3C;%3C/text%3E%3Ctext x='140' y='158'%3E1%3C/text%3E%3Ctext x='184' y='60'%3E=%3C/text%3E%3Ctext x='184' y='78'%3E%26%238730;%3C/text%3E%3Ctext x='184' y='96'%3E5%3C/text%3E%3Ctext x='228' y='190'%3E%26%236E8F8C;%3C/text%3E%3Ctext x='228' y='208'%3E3%3C/text%3E%3Ctext x='30' y='200'%3E%26%238364;%3C/text%3E%3Ctext x='30' y='218'%3E8%3C/text%3E%3Ctext x='118' y='236'%3E%26%232A3A3C;%3C/text%3E%3Ctext x='206' y='250'%3E6%3C/text%3E%3C/g%3E%3Cg opacity='.45'%3E%3Ctext x='8' y='74'%3E4%3C/text%3E%3Ctext x='96' y='102'%3E$%3C/text%3E%3Ctext x='184' y='114'%3E%25%3C/text%3E%3C/g%3E%3C/svg%3E");
  background-size: 264px 264px;
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000000 8%, #000000 72%, transparent 100%);
  mask-image: linear-gradient(180deg, transparent 0%, #000000 8%, #000000 72%, transparent 100%);
}
.data-rain.is-live { background-image: none; }

.skyline { position: absolute; inset-inline: 0; inset-block-end: 0; height: 58%; z-index: 2; }
.skyline__layer {
  position: absolute;
  inset-inline: 0;
  inset-block-end: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 100%;
}
.skyline__far { height: 100%; opacity: 0.75; }
.skyline__mid { height: 78%; }
.skyline__near { height: 52%; }
/* Lit windows (CSS fallback layer: tiny emissive rectangles on the near silhouette) */
.skyline__windows {
  position: absolute;
  inset-inline: 0;
  inset-block-end: 6%;
  height: 30%;
  background-image:
    radial-gradient(1.5px 2.5px at 12% 40%, var(--glow-window) 98%, transparent),
    radial-gradient(1.5px 2.5px at 27% 62%, var(--glow-window) 98%, transparent),
    radial-gradient(1.5px 2.5px at 41% 35%, var(--glow-window) 98%, transparent),
    radial-gradient(1.5px 2.5px at 58% 70%, var(--glow-window) 98%, transparent),
    radial-gradient(1.5px 2.5px at 73% 48%, var(--glow-window) 98%, transparent),
    radial-gradient(1.5px 2.5px at 88% 58%, var(--glow-window) 98%, transparent);
  background-size: 220px 100%;
  opacity: 0.9;
}
/* Rain on glass: faint diagonal streaks in front of the city, behind the text. Slides for 4.8 s, then rests. */
.rain-glass {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  opacity: 0.55;
  background-image:
    repeating-linear-gradient(103deg, transparent 0 23px, rgb(154 255 243 / 0.05) 23px 24px, transparent 24px 61px),
    repeating-linear-gradient(97deg, transparent 0 41px, rgb(154 255 243 / 0.035) 41px 42px, transparent 42px 97px),
    radial-gradient(2px 3px at 18% 22%, rgb(154 255 243 / 0.1), transparent),
    radial-gradient(2px 3px at 67% 38%, rgb(154 255 243 / 0.08), transparent),
    radial-gradient(2px 3px at 84% 12%, rgb(154 255 243 / 0.09), transparent);
  background-size: 100% 240px, 100% 300px, 100% 100%, 100% 100%, 100% 100%;
  animation: glass-rain 1.2s linear 4 both;
}
@keyframes glass-rain { from { background-position: 0 0, 0 0, 0 0, 0 0, 0 0; } to { background-position: 0 240px, 0 300px, 0 0, 0 0, 0 0; } }

/* WebGL hero (D29, assets/hero-webgl.js, another module): a <canvas class="hero__gl" aria-hidden="true"> inside
   .hero__layers. When it has drawn its first frame it adds .is-webgl to .hero and dispatches "si:hero-webgl"; the
   CSS/2D layers it replaces are then hidden. Any fallback simply never adds the class. */
.hero__gl { position: absolute; inset: 0; z-index: 1; display: block; width: 100%; height: 100%; }
.hero.is-webgl .data-rain, .hero.is-webgl .searchlights, .hero.is-webgl .skyline, .hero.is-webgl .skyline__windows { visibility: hidden; }

/* Hero text block: <header class="wrap" id="top"> (exact markup; the release-banner tool depends on it). */
.hero > .wrap {
  position: relative;
  z-index: 4;
  padding-block: calc(var(--letterbox) + clamp(2.5rem, 1.5rem + 6vh, 6rem)) calc(var(--letterbox) + 14rem);
}
.hero__scrim {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  background: linear-gradient(180deg, rgb(5 8 10 / 0.78) 0%, rgb(5 8 10 / 0.5) 45%, transparent 72%);
}
.hero__title { max-width: 14ch; }
.hero__sub { max-width: 34rem; font-size: var(--t-title3); line-height: 1.45; color: var(--ink-2); }
.hero__example {
  max-width: 34rem;
  margin-block-start: var(--s-4);
  font-size: var(--t-footnote);
  color: var(--ink-2);
}
.hero--letterbox::before, .hero--letterbox::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  height: var(--letterbox);
  z-index: 5;
  background: #000000;
  pointer-events: none;
}
.hero--letterbox::before { inset-block-start: 0; }
.hero--letterbox::after { inset-block-end: 0; }
.hero__motion { position: absolute; z-index: 6; inset-inline-end: var(--gutter); inset-block-end: calc(var(--letterbox) + 0.5rem); }

/* Gentle parallax where scroll-driven animations exist (user-driven, so not auto-motion); off when reduced. */
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    html:not([data-motion="off"]) .skyline__far { animation: px-far linear both; animation-timeline: scroll(root); animation-range: 0 100vh; }
    html:not([data-motion="off"]) .skyline__mid { animation: px-mid linear both; animation-timeline: scroll(root); animation-range: 0 100vh; }
  }
}
@keyframes px-far { to { transform: translateY(9%); } }
@keyframes px-mid { to { transform: translateY(4%); } }

/* Theater (the lobby's video room) */
.theater {
  position: relative;
  padding: clamp(0.5rem, 0.3rem + 1vw, 1rem);
  background: #000000;
  border: 1px solid var(--deco-gold-line);
  border-radius: var(--radius-1);
  box-shadow: 0 0 0 6px #05080A, 0 0 0 7px var(--deco-gold-faint);
}
.theater__screen { position: relative; aspect-ratio: 16 / 9; background: #000000; }
.theater__screen iframe, .theater__screen video { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* Rooftop CTA (peak-end): one promise + the single primary action at every page end. */
.rooftop {
  position: relative;
  isolation: isolate;
  overflow: clip;
  padding-block: clamp(4rem, 3rem + 5vw, 8rem);
  text-align: center;
  background:
    radial-gradient(60% 80% at 50% 120%, rgb(42 58 60 / 0.35), transparent 70%),
    linear-gradient(180deg, var(--noir-0), #05080A);
  border-block-start: 1px solid var(--deco-gold-line);
}
.rooftop::before {                       /* deco sunburst rays (decor) */
  content: "";
  position: absolute;
  inset-inline-start: 50%;
  inset-block-end: -30%;
  width: 70rem;
  height: 70rem;
  margin-inline-start: -35rem;
  z-index: -1;
  background: repeating-conic-gradient(from 0deg at 50% 50%, rgb(134 171 167 / 0.07) 0deg 2deg, transparent 2deg 10deg);
  -webkit-mask-image: radial-gradient(closest-side, #000000, transparent 75%);
  mask-image: radial-gradient(closest-side, #000000, transparent 75%);
}
.rooftop .lede { margin-inline: auto; }
.rooftop .cta-row { justify-content: center; }

/* -----------------------------------------------------------------------------------------------------
   12  FOOTER  (markup must open as a bare <footer> then <div class="wrap">: the release-banner tool's regex)
   ----------------------------------------------------------------------------------------------------- */
body > footer {
  position: relative;
  z-index: var(--z-content);
  padding-block: var(--s-8) calc(var(--s-6) + env(safe-area-inset-bottom));
  font-size: var(--t-subhead);
  color: var(--ink-2);
  background: linear-gradient(180deg, var(--noir-0), #020304);
  border-block-start: 1px solid var(--deco-gold-line);
}
.foot { display: grid; gap: var(--s-6); grid-template-columns: minmax(0, 1fr); }
@media (min-width: 48rem) { .foot { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); } }
@media (min-width: 64rem) { .foot { grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr) minmax(0, 0.9fr); } }
.foot__brand { display: flex; align-items: center; gap: 0.6rem; margin: 0 0 var(--s-2); color: var(--ink-1); font-family: var(--font-display); font-size: 1.25rem; font-weight: 700; letter-spacing: 0.04em; }
.foot__brand img { width: 32px; height: 32px; border-radius: 7px; }
.foot__heading {
  margin: 0 0 var(--s-3);
  font-family: var(--font-display);
  font-size: 0.9375rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-1);
}
.foot__links { display: grid; gap: 0.25rem; margin: 0; padding: 0; list-style: none; }
.foot__links li { margin: 0; }
.foot__links a { display: inline-flex; align-items: center; min-height: var(--target); }
.foot__meta { margin-block-start: var(--s-6); padding-block-start: var(--s-5); border-block-start: 1px solid var(--hairline); }
.foot__meta :is(p, si-p) { margin: 0 0 var(--s-2); }
.foot__legal { font-size: var(--t-footnote); color: var(--ink-3); }
body > footer :is(p, si-p) { max-inline-size: 72ch; }
.lang-foot a { display: inline-flex; align-items: center; min-height: var(--target); padding-inline: 0.25rem; }
/* Phone: room under the last footer line for the docked Floors button (52 px + 14 px offset). This must come after
   the unconditional body > footer rule above, or that rule's padding wins. */
@media (max-width: 63.98rem) {
  body > footer { padding-block-end: calc(7.5rem + env(safe-area-inset-bottom)); }
}

/* -----------------------------------------------------------------------------------------------------
   13  PROSE (legal pages: privacy, terms; the legal TEXT stays byte-identical, only the chrome changes)
   ----------------------------------------------------------------------------------------------------- */
.prose { max-width: 44rem; }
.prose h1 { font-size: clamp(2rem, 1.6rem + 2vw, 3rem); }
.prose h2 { margin-block-start: 2em; font-size: clamp(1.375rem, 1.2rem + 0.8vw, 1.75rem); }
.prose h3 { margin-block-start: 1.6em; font-size: 1.25rem; }
.prose :is(p, si-p), .prose li { color: var(--ink-2); }
.prose strong { color: var(--ink-1); }
.prose ul, .prose ol { padding-inline-start: 1.4em; }
.prose blockquote {
  margin: var(--s-4) 0;
  padding: var(--s-3) var(--s-4);
  color: var(--ink-2);
  background: var(--noir-1);
  border-inline-start: 3px solid var(--deco-gold);
}
.prose table { width: 100%; border-collapse: collapse; font-size: var(--t-subhead); display: block; overflow-x: auto; }
/* With JS, site.js wraps each legal table in .table-scroll (the table bytes stay as they are). The wrapper is the
   scroller, so the table keeps its table role; when it overflows it becomes a labelled, focusable region with a
   teal edge glow on the side that has more columns. */
.prose .table-scroll { margin-block: var(--s-3); overflow-x: auto; overscroll-behavior-x: contain; }
.prose .table-scroll > table { display: table; overflow: visible; margin: 0; }
.prose .table-scroll.is-scrollable {
  background:
    linear-gradient(90deg, var(--noir-0) 30%, rgb(5 8 10 / 0)) left / 2rem 100% no-repeat local,
    linear-gradient(270deg, var(--noir-0) 30%, rgb(5 8 10 / 0)) right / 2rem 100% no-repeat local,
    radial-gradient(farthest-side at 0 50%, rgb(154 255 243 / 0.35), transparent) left / 0.75rem 100% no-repeat scroll,
    radial-gradient(farthest-side at 100% 50%, rgb(154 255 243 / 0.35), transparent) right / 0.75rem 100% no-repeat scroll;
}
.prose .table-scroll.is-scrollable > table { background: transparent; }
.prose th, .prose td { padding: 0.6rem 0.75rem; text-align: start; vertical-align: top; border-block-end: 1px solid var(--mark-3); }
.prose th { color: var(--ink-1); font-weight: 650; background: var(--noir-1); }
.prose .translation-note, .prose .note {
  padding: var(--s-3) var(--s-4);
  font-size: var(--t-subhead);
  color: var(--ink-2);
  background: var(--noir-1);
  border: 1px solid var(--mark-3);
  border-radius: var(--radius-1);
}

/* -----------------------------------------------------------------------------------------------------
   14  TEXTURE: VIGNETTE (behind content) + FILM GRAIN (over everything, 3.5 % alpha, static)
   ----------------------------------------------------------------------------------------------------- */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(120% 90% at 50% 40%, transparent 55%, rgb(0 0 0 / 0.55) 100%);
}
html::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: var(--z-grain);
  pointer-events: none;
  opacity: 0.035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1.2 -.1'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 160px 160px;
}

/* -----------------------------------------------------------------------------------------------------
   15  PREFERENCE GATES
   ----------------------------------------------------------------------------------------------------- */
/* Reduced motion: all auto motion stops (loops get iteration-count 1 AND animation: none), decoration becomes
   still frames with the same composition. Data still updates. A <=200 ms cross-fade is allowed. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .searchlights::before, .searchlights::after, .rain-glass, .skyline__layer, .floors__panel { animation: none !important; }
  .reveal.is-pending { opacity: 1; transform: none; }
  html::after, body::before { display: none; }   /* grain and vignette off (task spec) */
}
html[data-motion="off"] *, html[data-motion="off"] *::before, html[data-motion="off"] *::after {
  animation-duration: 0.001ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.001ms !important;
  scroll-behavior: auto !important;
}
html[data-motion="off"] .searchlights::before, html[data-motion="off"] .searchlights::after,
html[data-motion="off"] .rain-glass, html[data-motion="off"] .skyline__layer { animation: none !important; }
html[data-motion="off"] .reveal.is-pending { opacity: 1; transform: none; }
html[data-motion="off"]::after, html[data-motion="off"] body::before { display: none; }

/* Reduced data: no grain or vignette layers, no canvas rain (site.js also checks Save-Data). */
@media (prefers-reduced-data: reduce) {
  html::after, body::before { display: none; }
  .data-rain { background-image: none; }
}

/* Increase Contrast: solid surfaces, solid 1 px mark-2 borders, no glow, gradient, grain, blur or headroom. */
@media (prefers-contrast: more) {
  html::after, body::before, .rain-glass, .searchlights, .skyline__windows, .chandelier__glints { display: none; }
  .tower-bar { background: var(--noir-0); }
  .tower-bar::after { display: none; }
  .btn { box-shadow: 0 0 0 2px var(--ink-1); }
  .deco-card, .concierge, .bellhop, .itin-col, .door, .chip, .toggle, .btn-quiet, .floor-sign, .math {
    border: 1px solid var(--mark-2);
    background: var(--noir-1);
  }
  .deco-card::before, .deco-card::after { display: none; }
  .hero__sky { background: var(--noir-0); }
  .hero__scrim { background: rgb(5 8 10 / 0.9); }
  .data-rain { opacity: 0.35; }
  .shot__frame--fade img { -webkit-mask-image: none; mask-image: none; }
  .cover { box-shadow: 0 0 0 1px var(--mark-2); }
}

/* Reduce Transparency: no translucent glass streaks; the hero scrim and the Tin caption plate turn solid. */
@media (prefers-reduced-transparency: reduce) {
  .rain-glass { display: none; }
  /* html body[data-floor] beats the lobby's own body[data-floor="lobby"] rules in home.css */
  html body[data-floor] .hero__scrim {
    background: linear-gradient(180deg, var(--noir-0) 0%,
      var(--noir-0) calc(100% - var(--skyline-band, 45%) - var(--s-6)),
      rgb(5 8 10 / 0) calc(100% - var(--skyline-band, 45%) + var(--s-7)));
  }
  html body[data-floor] .hero__example, html body[data-floor] .tin-caption { background: var(--noir-0); }
}

/* Forced colours (Windows High Contrast etc.): system colours, outlines for focus, decor removed. */
@media (forced-colors: active) {
  .btn, .btn-quiet, .door, .chip, .toggle, .floors > summary, .floor-btn__code, .floor-sign {
    border: 2px solid ButtonText;
    forced-color-adjust: auto;
  }
  .floor-btn[aria-current="page"] .floor-btn__code { border-color: Highlight; outline: 2px solid Highlight; }
  :focus-visible { outline: 2px solid Highlight; }
  .ride, .data-rain, .rain-glass, .searchlights, .skyline__windows, html::after, body::before, .chandelier__glints { display: none; }
  .hero__sky, .hero__scrim { background: Canvas; }
}

@media print {
  .tower-bar, .ride, .floors, .data-rain, .rain-glass, .searchlights, .hero__layers, .skip-link, .toggle,
  html::after, body::before { display: none !important; }
  html, body { background: #E8FFFC !important; color: #000000 !important; }
  a { color: #000000; }
}
