/* ============================================================
   HOUSE LIGHTS — LIGHT
   The house lights up. Same lighting-cue system, inverted substrate:
   warm paper stock, dark ink, and every named cue re-pitched dark
   enough to read on it.

   Two scopes, and the pairing is the whole design:

     .theme-light   the light substrate. On <html> it lights a whole
                    page; the cue system keeps working because only the
                    named cue *lightnesses* move, never --cue-l itself.
     .theme-dark    a dark island inside a light page. Restores the
                    tokens.css values verbatim, so a section that was
                    designed as a black box — the homepage hero, a map
                    read as a projection surface — stays one.

   Loaded after core/pages/maps and before any page-specific sheet.
   ============================================================ */

/* ============================================================
   THE LIGHT SUBSTRATE
   ============================================================ */
.theme-light {
  /* ---- Substrate, inverted ------------------------------------- */
  /* Warm off-white rather than #fff: the same paper the dark pages
     use for their type (--bone was #F2EDE4), so the brand still
     recognises itself. */
  --void:        #FBF9F4;
  --ink:         #F4F1E8;
  --ink-2:       #EFEBE0;
  --ink-3:       #E8E3D5;
  --scrim:       #DBD5C6;
  --edge:        rgba(24, 20, 14, 0.14);
  --edge-strong: rgba(24, 20, 14, 0.30);

  /* ---- Ink ----------------------------------------------------- */
  /* --bone is "the text colour" semantically, so inverting it here
     re-points every component that reads from it. */
  --bone:        #141219;
  --bone-dim:    #45424B;
  --bone-faint:  #6B6760;

  /* ---- Cues, re-pitched for a light substrate ------------------
     Only the named cue lightnesses move. Deliberately NOT --cue-l:
     JS mirrors the active cue onto <html> via [data-cue], and a
     declaration here would out-specify it and freeze the page on one
     colour. */
  --cue-ember-l: 34%;
  --cue-xenon-l: 28%;
  --cue-uv-l:    40%;
  --cue-acid-l:  22%;
  --cue-rose-l:  36%;
  --cue-gold-l:  26%;

  /* On black, "bright" means lighter than the cue. On paper it has to
     mean darker, or every emphasis reads as a highlighter. */
  --cue-bright: hsl(var(--cue-h) var(--cue-s) 22%);
  --cue-deep:   hsl(var(--cue-h) calc(var(--cue-s) - 30%) 62%);
  --cue-wash:   hsl(var(--cue-h) 70% 52% / 0.09);
  --cue-haze:   hsl(var(--cue-h) 70% 50% / 0.12);
  --cue-glow:   hsl(var(--cue-h) 85% 45% / 0.20);

  /* Cold rim light, darkened the same way */
  --rim:       #0E6F7A;
  --rim-deep:  #CFE9EC;
  --rim-wash:  rgba(14, 111, 122, 0.07);

  /* Shadows on paper are contact shadows, not stage darkness */
  --shadow-lift: 0 1px 2px rgba(24, 20, 14, .06), 0 12px 32px -14px rgba(24, 20, 14, .18);
  --shadow-pop:  0 2px 6px rgba(24, 20, 14, .08), 0 24px 60px -18px rgba(24, 20, 14, .24);
}

html.theme-light {
  color-scheme: light;
  background: var(--void);
}

/* Until JS mirrors a section cue onto <html> — and permanently, with JS off —
   accents resolve from the root default in tokens.css, pitched at 56% for a
   black substrate and worth only 3.1:1 on paper. Scoped to :not([data-cue])
   so it fixes the first paint without out-specifying the attribute selector
   the cue system runs on. */
html.theme-light:not([data-cue]) { --cue-l: 34%; }

/* ============================================================
   DARK ISLANDS
   A section that only works as a black box keeps its own substrate.
   Restores tokens.css verbatim rather than "darkening" the light
   values, so an island is pixel-identical to the same markup on a
   fully dark page.

   The maps are islands by default: the basemap paints its own near-
   black plate from hardcoded values, so inverting only the labels
   would leave dark type on a dark plate.
   ============================================================ */
.theme-dark,
.theme-light .nav[data-over-hero="true"],
.theme-light .map-stage,
.theme-light .mapframe {
  --void:        #050507;
  --ink:         #0A0A0E;
  --ink-2:       #101016;
  --ink-3:       #17171F;
  --scrim:       #1E1E28;
  --edge:        rgba(255, 255, 255, 0.09);
  --edge-strong: rgba(255, 255, 255, 0.18);

  --bone:        #F2EDE4;
  --bone-dim:    #B9B3A8;
  --bone-faint:  #7A756D;

  --cue-ember-l: 56%;
  --cue-xenon-l: 58%;
  --cue-uv-l:    66%;
  --cue-acid-l:  56%;
  --cue-rose-l:  62%;
  --cue-gold-l:  58%;

  /* --cue is derived from --cue-l, and a derived custom property is
     substituted where it is *declared* — on :root. Inheriting it would carry
     the paper pitch into the island whatever --cue-l says here, so the island
     has to re-derive it from its own. */
  --cue:        hsl(var(--cue-h) var(--cue-s) var(--cue-l));
  --cue-bright: hsl(var(--cue-h) calc(var(--cue-s) - 6%) 72%);
  --cue-deep:   hsl(var(--cue-h) var(--cue-s) 34%);
  --cue-wash:   hsl(var(--cue-h) 60% 50% / 0.14);
  --cue-haze:   hsl(var(--cue-h) 80% 55% / 0.30);
  --cue-glow:   hsl(var(--cue-h) 100% 60% / 0.55);

  --rim:       #63E6F0;
  --rim-deep:  #0C4A55;
  --rim-wash:  rgba(99, 230, 240, 0.12);

  --shadow-lift: 0 2px 8px rgba(0,0,0,.4), 0 18px 50px -12px rgba(0,0,0,.7);
  --shadow-pop:  0 4px 12px rgba(0,0,0,.5), 0 32px 80px -16px rgba(0,0,0,.85);
}

/* --cue-l is only *recomputed* where a [data-cue] sits; everywhere between
   those elements it simply inherits. So an island that carries no cue of its
   own inherits the paper-pitched lightness from the section above it — dark
   gold pins on a near-black map. Restate the tokens.css default for exactly
   those islands, and leave the ones that do carry a cue to resolve it from
   their own re-darkened --cue-<name>-l. */
.theme-dark:not([data-cue]),
.theme-light .nav[data-over-hero="true"],
.theme-light .map-stage,
.theme-light .mapframe { --cue-l: 56%; }

/* `color` is inherited from <body>, which resolved --bone before the island
   re-pointed it, so an island has to restate it for any text that does not
   name a colour of its own. */
.theme-dark,
.theme-light .nav[data-over-hero="true"] { color: var(--bone); }

/* An island that sits in normal flow has to paint its own substrate —
   the body's is now paper. The maps already paint theirs. */
.theme-light .hero.theme-dark {
  background: var(--void);
  color: var(--bone);
}
/* The global .vignette is a fixed overlay, so it cannot be dark over the
   hero and faint everywhere else. Give the island its own falloff, behind
   the copy rather than over it. */
.theme-light .hero.theme-dark::after {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: radial-gradient(120% 90% at 50% 45%, transparent 42%, rgba(0, 0, 0, .62) 100%);
}

/* ============================================================
   ATMOSPHERE, DIALLED DOWN
   The grain stays — at this weight it reads as paper tooth rather
   than film stock. The stage vignette, the followspot and the CTA
   rig do not: a light beam on white paper is either invisible or a
   smudge.
   ============================================================ */
html.theme-light .grain { opacity: 0.06; }
html.theme-light .vignette {
  background: radial-gradient(120% 90% at 50% 45%, transparent 58%, rgba(28, 24, 16, .055) 100%);
}
html.theme-light .followspot { display: none; }
html.theme-light .cta-rig { display: none; }

/* Glows are additive light. On paper they are a grey halo around the
   letterform, which reads as a printing fault. Only killed where the
   component actually sits on paper — the same glow inside a dark island is
   still doing the job it was drawn for. */
.theme-light .cta-title em { text-shadow: none; }
.theme-light .nav:not([data-over-hero="true"]) .wordmark .wm-b,
.theme-light .footer .wordmark .wm-b { text-shadow: none; }
.theme-light .eyebrow::before { box-shadow: none; }
.theme-light .marquee .dot { box-shadow: none; }
.theme-light .process li::before { box-shadow: none; }

/* ============================================================
   CHROME FIXES WHERE A COLOUR WAS HARDCODED
   Everything else in the system reads from a token and inverts for
   free. These are the exceptions, and each one is a literal colour
   that had no token to follow.
   ============================================================ */

/* The sticky nav scrim. Excluded while the bar is still over the hero, where
   core.css's near-black scrim is the correct one. */
html.theme-light .nav[data-stuck="true"]:not([data-over-hero="true"]) {
  background: rgba(251, 249, 244, 0.82);
}
@media (max-width: 1039px) {
  html.theme-light .nav[data-stuck="true"]:not([data-over-hero="true"]) {
    background: rgba(251, 249, 244, 0.94);
  }
}
/* With JS off nothing updates data-over-hero, so the bar keeps the hero's
   register all the way down the page and would float invisibly over light
   copy. Give it a plate rather than a register it cannot change. */
html.theme-light:not(.js) .nav[data-over-hero] {
  background: var(--void);
  border-bottom-color: var(--edge);
}

/* The white light-sweep vanishes against a paper-coloured label;
   sweep with the substrate colour instead. */
.theme-light .btn::after {
  background: linear-gradient(100deg, transparent 20%, rgba(255, 255, 255, .55) 50%, transparent 80%);
}

.theme-light .spec-table tbody tr:hover { background: rgba(24, 20, 14, 0.035); }

/* The cast rail holds dark plates. Its caption scrim was near-black, so
   on paper it hid the dark type it is meant to carry. */
.theme-light .cast-meta {
  background: linear-gradient(transparent, rgba(251, 249, 244, .94) 45%);
}

/* Form error reds pitched for a black field are unreadable on paper. */
.theme-light .field input[aria-invalid="true"],
.theme-light .field textarea[aria-invalid="true"] { border-color: #C0362C; }
.theme-light .form-status[data-state="error"] { color: #A32018; }
