/* =========================================================
   SURFACES — the site's one background system
   ---------------------------------------------------------
   Loaded on every page by includes/head.php, after every
   legacy global (footer.css and m072224.css, both of which it
   has to clear) and before any page sheet. Nothing else on the
   site may paint a page background; see docs/surfaces.md for
   the rules and `php scripts/check-surfaces.php` for the check
   that keeps them honest.

   WHY THIS EXISTS
   ---------------
   Before this sheet the site had three different page grounds
   and one wash that changed shape per section:

     - `body` (m072224.css / models.css / m051622.css)   #000
     - the five copy-pasted "flow" recipes                #020203
       (.support-flow, .cx-flow, .events-page,            + a ramp
        .careers-main, .vfs-flow-bg)
     - the portal and the form pages                      #050505

   …and `.dark-bg` / `.light-bg` / `.gray-bg` (145 uses across
   ~50 live pages) painted a repeating white wash sized to the
   ELEMENT, so the same class produced a different band on every
   section depending on that section's height. That is the
   "lighting effects" problem: nothing was wrong per section,
   but no two sections agreed.

   THE MODEL
   ---------
   One ground, painted once. Elevation — never a new dark — is
   what separates a card, a panel or a selection from the page.
   Because every rung above the ground is translucent white, a
   container is always exactly one step above whatever it
   happens to sit on, at any scroll position, on any page. That
   is the property that keeps this consistent without anybody
   having to remember a hex.

       plate    #040406            the box behind a photo or video
       well     black .32          inputs, embeds — down, not up
       ─────────────────────────── the ground ───────────
       ground   #050507 → #101013  the page itself
       band     white .025         a section that steps up
       surface  white .05          a card / panel at rest
       hover    white .08          pointed at, or raised
       active   white .11          pressed, or open
       select   red   .14          chosen  ← hue, not more white
       overlay  #101013 .92        modal / dropdown / popover

   THE ONE RULE THAT MATTERS
   -------------------------
   Every gradient here is sized in viewport or pixel units,
   never in percentages of the box it paints. A percentage-sized
   gradient re-scales its stops when the element's height
   changes, so the page re-tones itself when a table collapses
   or a filter hides rows — models-bg.css hit exactly this and
   had to fall back to flat black. Fixed units cannot shift.
   ========================================================= */

:root {
  /* ---- The ground ------------------------------------------------------
     The floor the whole site sits on, and the lit tone it opens at. The two
     are 11 levels apart, which is about as small a step as survives an 8-bit
     gradient without banding — the change should be felt, not seen. */
  --tv-ground: #050507;
  --tv-ground-top: #101013;
  --tv-ground-mid: #0a0a0c;
  --tv-ground-low: #07070a;

  /* How far the opening ramp runs before the page settles onto the floor.
     Viewport units, so it is the same arc on a short page and a long one, and
     so no amount of content can re-scale it. 220vh is chosen against the two
     shapes a Titan page takes: a full-height photo hero leaves the last ~55%
     of the ramp visible below it, and a header-led page (support, contact,
     events) runs the whole arc over its first two screens. */
  --tv-ground-ramp-h: 220vh;

  /* The spill of light under the navbar. Kept from the "flow" recipe this
     replaces — it is what stops the top of the page reading as a lid. */
  --tv-ground-spill: rgba(255, 255, 255, 0.045);

  --tv-ground-ramp:
    radial-gradient(
      125% 34% at 50% 0%,
      var(--tv-ground-spill) 0%,
      rgba(255, 255, 255, 0) 72%
    ),
    linear-gradient(
      180deg,
      var(--tv-ground-top) 0%,
      var(--tv-ground-mid) 42%,
      var(--tv-ground-low) 74%,
      var(--tv-ground) 100%
    );

  /* ---- Elevation -------------------------------------------------------
     Translucent white, so a rung reads the same over the lit top of the page
     and over the floor at its end. Never substitute a hex for one of these:
     a hex is only correct at one scroll position.

     The steps are even — .025 apart — because an uneven ladder is what lets a
     hover state on one page read as a rest state on another. Over the ground
     they resolve to roughly #0b0b0d, #121214, #191919, #202022.

     Until 2026-08-13 a stray comment terminator sat after "one scroll
     position", closing this comment three lines early and leaving the prose
     below it to be parsed as CSS.
     A declaration list swallows an invalid declaration up to the next
     semicolon — and the next semicolon was the one ending --tv-band, so the
     first rung of the ladder was never defined. Its 48 call sites across 18
     sheets all carry no fallback, so every one of them painted nothing:
     .tv-band itself, the checkout and scheduling surfaces, the cart, the
     footer's close, the nav. check-surfaces.php scanned the raw file,
     comments included, so it saw a definition and passed. Both are fixed. */
  --tv-band: rgba(255, 255, 255, 0.025);
  --tv-surface: rgba(255, 255, 255, 0.05);
  --tv-surface-hover: rgba(255, 255, 255, 0.08);
  --tv-surface-active: rgba(255, 255, 255, 0.11);

  /* How tall a band's tint runs before it dies out. Pixels, for the reason in
     the header — a band is a seam of light at a section's start, and it has to
     be the same seam whether the section is 400px tall or 4000. */
  --tv-band-h: 340px;

  /* ---- The same three rungs, pre-composited over the ground -------------
     Translucent rungs COMPOUND when they nest: a .08 panel inside a .08 panel
     is not .08, it is .16, and a dense UI drifts pale a level at a time. The
     checkout, scheduling and builder flows are walls of nested panels, so they
     take these instead — the identical tone, as a solid, which cannot stack.

     Reach for a translucent rung by default; reach for a solid one only when
     the surface sits inside another surface. If you change a rung above,
     change its twin here — they are the same step of the same ladder. */
  --tv-surface-solid: #121214;
  --tv-surface-hover-solid: #191919;
  --tv-surface-active-solid: #202022;

  /* ---- Below the ground ------------------------------------------------
     A well goes down rather than up: inputs, embeds and anything holding a
     photograph. --tv-plate is the darkest thing on the site on purpose, so
     imagery reads as lit against it. */
  --tv-well: rgba(0, 0, 0, 0.32);
  --tv-plate: #040406;

  /* ---- Chosen ----------------------------------------------------------
     Selection is carried by hue, not by another step of white. A fifth grey
     is indistinguishable from hover; brand red is not, and it costs the page
     nothing because it is only ever on one element at a time. */
  --tv-select: rgba(170, 0, 0, 0.14);
  --tv-select-line: rgba(170, 0, 0, 0.45);

  /* ---- Floating --------------------------------------------------------
     Anything that covers page content has to be legible over whatever it
     lands on, so this rung is the one that is nearly opaque. Pair it with
     --tv-blur; the two together are the navbar dropdown's material, which the
     section-nav rail and the media modals already borrow. */
  --tv-overlay: rgba(16, 16, 19, 0.92);
  --tv-blur: blur(14px);

  /* ---- Edges -----------------------------------------------------------
     One hairline, one strong. These are deliberately the same values as
     --theme-border-soft / --theme-border-strong, which now alias to them. */
  --tv-line: rgba(255, 255, 255, 0.08);
  --tv-line-strong: rgba(255, 255, 255, 0.16);
}

/* =========================================================
   THE GROUND
   ---------------------------------------------------------
   Painted once, here, for every page on the site. No page,
   section or wrapper paints a page background of its own —
   the seven that used to are now transparent and inherit
   this, which is the whole point of the sheet.

   `background-color` covers the canvas at the floor tone;
   the ramp is laid over its first --tv-ground-ramp-h and ends
   ON that same colour, so the two meet with no seam and a
   page of any length is continuous.
   ========================================================= */
body {
  background-color: var(--tv-ground);
  background-image: var(--tv-ground-ramp);
  background-repeat: no-repeat;
  background-position: 50% 0;
  /* Both layers take this. Viewport-sized, so content height cannot
     re-tone the page — see THE ONE RULE THAT MATTERS above. */
  background-size: 100% var(--tv-ground-ramp-h);
  /* `fixed` would pin the ramp to the viewport and re-light the page on every
     scroll, and it janks on iOS. The ramp belongs to the top of the DOCUMENT. */
  background-attachment: scroll;
}

/* =========================================================
   THE LEGACY BANDS
   ---------------------------------------------------------
   `.dark-bg`, `.light-bg` and `.gray-bg` (m072224.css, and
   again in models.css / m051622.css) are on 145 sections
   across the live site. Each painted a repeating white wash
   at `background-size: 100%` — element-sized, so its band
   grew and moved with whatever section carried it, and no
   two sections on a page matched.

   The three definitions are deleted at source. The classes
   are left in the markup — removing them from ~50 pages buys
   nothing — and this rule is the backstop that keeps them
   inert: a page sheet, an inline <style> or a fourth copy of
   the utilities cannot bring the wash back, whatever it
   loads. `php scripts/check-surfaces.php` fails the moment
   anything paints one of these again.

   A section that genuinely needs to step up asks for
   `.tv-band` instead. models-bg.css and models-detail.css
   each carried their own copy of this neutraliser — both are
   gone now that it is done once, for everyone.
   ========================================================= */
.dark-bg,
.light-bg,
.gray-bg {
  background-image: none !important;
  background-color: transparent !important;
}

/* =========================================================
   THE BAND — the one way a section steps up
   ---------------------------------------------------------
   A hairline at the seam and a short fall of light under it,
   dying out well before the section does. Not a slab: a slab
   of another dark is how the page ended up with three of
   them. Fixed height, so every band on the site is the same
   band. `.pg-section--tint` is the same recipe and now defers
   to this one.
   ========================================================= */
.tv-band {
  border-top: 1px solid var(--tv-line);
  background-color: transparent;
  background-image: linear-gradient(
    180deg,
    var(--tv-band) 0%,
    rgba(255, 255, 255, 0) 100%
  );
  background-repeat: no-repeat;
  background-position: 0 0;
  background-size: 100% var(--tv-band-h);
  background-attachment: scroll;
}

/* The first band on a page has the header's own rule above it already. */
.tv-band--seamless {
  border-top: 0;
}

/* =========================================================
   CONTAINERS
   ---------------------------------------------------------
   The shared card/panel recipe. A component with its own
   sheet does not have to use these classes, but it must use
   the tokens above rather than a hex of its own.
   ========================================================= */
.tv-surface {
  background: var(--tv-surface);
  border: 1px solid var(--tv-line);
  border-radius: var(--theme-radius-lg, 1.25rem);
}

.tv-surface--raised {
  background: var(--tv-surface-hover);
  border-color: var(--tv-line-strong);
}

.tv-surface--selected {
  background: var(--tv-select);
  border-color: var(--tv-select-line);
}

/* Inputs, embeds, and any box that holds a photograph or a video: down a rung,
   not up, so the thing inside it is the lit element. */
.tv-well {
  background: var(--tv-well);
  border: 1px solid var(--tv-line);
}

.tv-plate {
  background: var(--tv-plate);
}

/* Anything that floats over page content. Nearly opaque by necessity. */
.tv-overlay {
  background: var(--tv-overlay);
  border: 1px solid var(--tv-line);
  -webkit-backdrop-filter: var(--tv-blur);
  backdrop-filter: var(--tv-blur);
}

/* =========================================================
   THE FOOTER
   ---------------------------------------------------------
   The page's closing band, and part of the ground system by
   the same rules as everything else: it was `background:
   transparent` and simply ran off the bottom of whatever
   ground it happened to land on.

   It gets the band's treatment — hairline, then a fall of
   light that dies out — so every page on the site ends the
   same way, and the footer reads as the last section rather
   than as the place the page stopped.

   `footer.footer` (0,1,1) to clear the legacy footer rules
   still live in m072224.css / m051622.css / legacy-nav.css,
   exactly as footer.css does. It also clears the stray
   `light-bg` on the footer's own class list, which has been
   inert for as long as footer.css has set a background.
   ========================================================= */
footer.footer {
  border-top: 1px solid var(--tv-line);
  background-color: transparent;
  background-image: linear-gradient(
    180deg,
    var(--tv-band) 0%,
    rgba(255, 255, 255, 0) 100%
  );
  background-repeat: no-repeat;
  background-position: 0 0;
  background-size: 100% var(--tv-band-h);
  background-attachment: scroll;
}

/* The portal footer sits under a signed-in dashboard that is already a wall of
   panels; the seam is enough there without the light. */
footer.footer--portal {
  background-image: none;
}
