/* Shared RegCanary shell contract. Page-specific styles own their content. */

/* ============================================================================
   Phase 5b: the RegCanary brand layer
   ============================================================================
   The rebrand's whole palette and type scale live here, in ONE block, because
   this stylesheet is the only one loaded by BOTH shells (pageBuilder.js emits
   it on every legacy document page, and portalPage.js links it ahead of
   portal.css on every /app/* page). Components consume these tokens; they do
   not carry brand colour of their own. If a component needs a colour that is
   not here, the token is missing - add it here rather than hard-coding it.

   Design language, from the mockup frames:
     - navy top bar, full width, white wordmark with the gold canary
     - cream hero band, line-art London skyline, a flat yellow sun, and an
       italic serif pull-quote far right
     - display serif headline, large, tight leading, sentence case + full stop
     - GOLD IS THE ONLY ACCENT: active tab underline, primary buttons, the
       left border on a selected row, and the footer rule. Nowhere else.
     - restrained pills, a stat strip of big numerals with two-line labels

   ⚠️ GOLD IS NEVER A TEXT COLOUR ON A LIGHT GROUND. Measured:
   --rc-gold #e8b52b on --rc-cream #f7f1e3 is 1.68:1. For the rare case where
   gold-family TEXT is wanted on a light ground there is --rc-gold-ink
   (#7d600a, 5.25:1 on cream, 5.92:1 on white). On a gold FILL the text token
   is --rc-on-gold (#011530 on #e8b52b, 9.62:1).

   Body-text contrast, RE-MEASURED after the navy moved to the logo's own
   #011530 (WCAG AA needs 4.5:1). The navy got darker in every state, so
   every on-navy pair improved and nothing regressed - the cream and pill
   families do not touch navy and are unchanged:
     light, and unstamped on a light OS
       ink on cream 14.55:1 | on cream-deep 13.18:1 | on surface 16.27:1
       muted on cream 6.11:1 | on cream-deep 5.54:1 | on surface 4.97:1
       on-navy on navy 18.24:1 (was 17.39) | on-navy-muted on navy 11.28:1 (was 10.75)
       on-navy on navy-raised 15.13:1 (was 14.13) | on-navy-muted on navy-raised 9.35:1 (was 8.73)
       on-navy on navy-deep 19.67:1
       on-gold on gold 9.62:1 (was 9.17) | on-gold on gold-deep 6.88:1
       gold-ink on cream 5.25:1 | gold-pale on navy 13.41:1
       pills: high 4.79:1 | medium 8.66:1 | low 4.83:1 | critical 5.93:1 | state 6.86:1
     dark, and unstamped on a dark OS
       ink on band 13.96:1 | on band-deep 11.27:1 | on surface 15.36:1
       muted on band 7.66:1 | on band-deep 6.18:1 | on surface 8.42:1
       on-navy on navy 17.03:1 (was 16.08) | on-navy-muted on navy 8.42:1 (was 7.95)
       on-navy on navy-raised 14.40:1 (was 13.22) | on-navy-muted on navy-raised 7.12:1
       on-navy on navy-deep 18.05:1
       on-gold on gold 11.05:1 (was 10.53) | on-gold on gold-deep 8.37:1
       gold-ink on band 9.53:1 | gold-pale on navy 15.08:1
       pills: high 8.02:1 | medium 7.23:1 | low 6.78:1 | critical 6.98:1 | state 8.47:1

   Theme handling follows the three-state pattern documented below: the FULL
   brand palette is declared on bare :root in its light values, and the two
   override blocks redefine only what changes. No brand token is introduced
   inside a media query or a [data-theme] block. tests/playwright/
   visualRegression.spec.js's `design tokens` probe asserts exactly that, on
   eight real pages in all three states. */
:root {
  /* -- Type ---------------------------------------------------------------
     The display serif is loaded from Google Fonts (Playfair Display, weights
     400/500/700/800 plus 400/500 italic for the pull-quote) by
     src/routes/pages/portalPage.js, the head of the app shell - the only
     surface Phase 5b rebrands. The legacy document shell (/about,
     /countries) and the marketing page still carry their own type, so they do
     NOT request this face: add the link to
     src/views/commonStyles/headLinks.js at the same time as the first legacy
     consumer of --rc-font-display, not before.

     The fallback stack is a real one - four genuinely-installed old-style
     serifs before the generic - because a silent fallback to Times is a
     visual regression no screenshot diff explains. */
  --rc-font-display: "Playfair Display", "Iowan Old Style", "Palatino Linotype", Palatino, "Georgia Pro", Georgia, "Times New Roman", Times, serif;
  --rc-font-sans: Inter, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  /* Display scale. Tight leading on the two headline steps, normal on the
     lede. --rc-display-1 is the full hero; --rc-display-2 is the SAME hero
     compressed on an inner tab (the mockups show one hero at two heights,
     not a hero that disappears). */
  --rc-display-1: 44px;
  --rc-display-2: 30px;
  --rc-display-3: 22px;
  --rc-display-leading: 1.06;
  --rc-lede: 16px;
  --rc-lede-compact: 14px;
  --rc-quote: 17px;
  --rc-numeral: 32px;
  --rc-numeral-compact: 24px;
  --rc-label: 11px;

  /* -- Brand grounds ------------------------------------------------------
     The navy is SAMPLED FROM THE LOGO, not chosen. Opaque pixels of
     public/images/brand/regcanary-primary.png, weighted mean per zone:
       wordmark #011530 (41,206px) | tagline #011632 (6,589px) |
       the bird's dark wing and tail #021631 (22,750px)
     -> --rc-navy #011530. The previous #101a2d was a mockup value: visibly
     lighter and less saturated than the mark, so the real lockup sat on a
     bar that did not match it. deep/raised are the same hue one step down
     and one step up, not a second ramp.

     The golds were measured against the same file and are NOT moved. The
     bird's gold ramp runs #ac7611 -> #c68f17 -> #d59e2b -> #e9c069, and the
     shipped --rc-gold-deep #c9971a / --rc-gold #e8b52b sit inside it (the
     largest channel difference against the nearest measured stop is 8/255,
     below a perceptible step). Repainting them would move every baseline
     for no visible gain.

     --rc-gold-pale is NEW. The bird's breast carries a pale cream the token
     set had no name for: weighted mean #f5daa3 over 11,833px, modal
     #f0d6a1, brightest #f7dea9. The simplified mark in
     src/routes/components/brandMark.js is its consumer - without it the
     mark's third tone would have to be hard-coded.

     Full sampling method and figures: docs/brand/README.md. */
  --rc-navy: #011530;
  --rc-navy-deep: #000b1f;
  --rc-navy-raised: #0d2648;
  --rc-on-navy: #ffffff;
  --rc-on-navy-muted: #c3ccdb;

  --rc-cream: #f7f1e3;
  --rc-cream-deep: #efe6d0;
  --rc-cream-ink: #16202f;
  --rc-cream-muted: #505b6b;

  --rc-gold: #e8b52b;
  --rc-gold-deep: #c9971a;
  --rc-gold-pale: #f5daa3;
  --rc-gold-ink: #7d600a;
  --rc-on-gold: #011530;

  /* Hero artwork: the line-art skyline stroke and the flat sun disc. */
  --rc-skyline-line: #b9ac8e;
  --rc-skyline-line-soft: #d3c9ae;
  --rc-sun: #f2c53d;

  /* -- Pills --------------------------------------------------------------
     Restrained, two-token pairs, one per family: HIGH amber, MEDIUM blue,
     LOW green, CRITICAL red, and a neutral for the state pills (IN REVIEW,
     AWAITING SIGN-OFF, COMPLETED, DRAFT, ARCHIVED). The light values are
     portal.css's existing wash/ink families, so a pill that was already
     correct does not move; the dark values are those SAME families' dark
     steps rather than the one grey chip every pill used to flatten to. */
  --rc-pill-high-wash: #fff5df;
  --rc-pill-high-ink: #a15c00;
  --rc-pill-medium-wash: #edf2ff;
  --rc-pill-medium-ink: #183b9f;
  --rc-pill-low-wash: #e9f7f1;
  --rc-pill-low-ink: #117a55;
  --rc-pill-critical-wash: #fff0ee;
  --rc-pill-critical-ink: #b42318;
  --rc-pill-state-wash: #f1f2f4;
  --rc-pill-state-ink: #475467;

  /* Band geometry, so the compressed hero is one number rather than a
     second set of rules. */
  --rc-hero-pad-block: 40px;
  --rc-hero-pad-block-compact: 20px;
  --rc-hero-gutter: 28px;
  --rc-rule-weight: 3px;
}

/* -- The brand lockup ------------------------------------------------------
   The real artwork, on the surfaces big enough to carry it. Two rasters are
   emitted (src/routes/components/brandMark.js) because the lockup's wordmark
   and tagline are brand navy and vanish on a dark ground; this is what picks
   between them.

   ⚠️ It has to be CSS, not a <picture media="(prefers-color-scheme: dark)">.
   A <source> media query cannot see html[data-theme], so on /about - which
   stamps data-theme="light" - a dark-OS visitor was served the on-dark
   lockup on a cream band: pale text on cream. The three-state pattern below
   is the same one the token blocks use, and it gets all three right.

   `display: none` rather than visibility/opacity: it also removes the hidden
   raster from the accessibility tree, so both can carry the real alt text and
   only the visible one is announced. */
.rc-brand-lockup { display: block; }
.rc-brand-lockup img { display: block; width: 100%; height: auto; }
.rc-brand-lockup .rc-lockup-dark { display: none; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .rc-brand-lockup .rc-lockup-light { display: none; }
  :root:not([data-theme="light"]) .rc-brand-lockup .rc-lockup-dark { display: block; }
}

html[data-theme="dark"] .rc-brand-lockup .rc-lockup-light { display: none; }
html[data-theme="dark"] .rc-brand-lockup .rc-lockup-dark { display: block; }

/* State 3 for the brand layer: nothing stamped, prefers-color-scheme decides.
   The rebrand direction is light-first (cream/navy/gold), so dark is NOT an
   inversion of it. These are deliberate steps off the same ramps: the cream
   band becomes a raised navy band, the skyline line-art becomes a cool slate,
   and gold brightens one step so it still reads as an accent on a dark ground
   instead of going muddy. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --rc-navy: #010f24;
    --rc-navy-deep: #00060f;
    --rc-navy-raised: #0b2040;
    --rc-on-navy: #edf2f7;
    --rc-on-navy-muted: #9fadc1;

    --rc-cream: #16233a;
    --rc-cream-deep: #22334f;
    --rc-cream-ink: #edf2f7;
    --rc-cream-muted: #aab6c7;

    --rc-gold: #f0c452;
    --rc-gold-deep: #d8a92f;
    --rc-gold-pale: #f7e2b6;
    --rc-gold-ink: #f0c452;
    --rc-on-gold: #011530;

    --rc-skyline-line: #3c4d6b;
    --rc-skyline-line-soft: #2a3750;
    --rc-sun: #f0c452;

    --rc-pill-high-wash: #3a2b13;
    --rc-pill-high-ink: #f4bd63;
    --rc-pill-medium-wash: #1b3154;
    --rc-pill-medium-ink: #a9c0ff;
    --rc-pill-low-wash: #13392f;
    --rc-pill-low-ink: #63d1a7;
    --rc-pill-critical-wash: #3b1e21;
    --rc-pill-critical-ink: #ff9289;
    --rc-pill-state-wash: #263449;
    --rc-pill-state-ink: #cbd5e1;
  }
}

/* State 2 for the brand layer: an explicit dark choice, which must win on a
   light OS too. Never a bare [data-theme="dark"] - see the warning below. */
html[data-theme="dark"] {
  --rc-navy: #010f24;
  --rc-navy-deep: #00060f;
  --rc-navy-raised: #0b2040;
  --rc-on-navy: #edf2f7;
  --rc-on-navy-muted: #9fadc1;

  --rc-cream: #16233a;
  --rc-cream-deep: #22334f;
  --rc-cream-ink: #edf2f7;
  --rc-cream-muted: #aab6c7;

  --rc-gold: #f0c452;
  --rc-gold-deep: #d8a92f;
  --rc-gold-pale: #f7e2b6;
  --rc-gold-ink: #f0c452;
  --rc-on-gold: #011530;

  --rc-skyline-line: #3c4d6b;
  --rc-skyline-line-soft: #2a3750;
  --rc-sun: #f0c452;

  --rc-pill-high-wash: #3a2b13;
  --rc-pill-high-ink: #f4bd63;
  --rc-pill-medium-wash: #1b3154;
  --rc-pill-medium-ink: #a9c0ff;
  --rc-pill-low-wash: #13392f;
  --rc-pill-low-ink: #63d1a7;
  --rc-pill-critical-wash: #3b1e21;
  --rc-pill-critical-ink: #ff9289;
  --rc-pill-state-wash: #263449;
  --rc-pill-state-ink: #cbd5e1;
}

/* The FULL shell palette is declared here, on bare :root, in its light
   values. The two override blocks below redefine only the tokens that
   change - neither of them introduces a token, because a custom property
   that exists ONLY inside a media query or ONLY under a [data-theme]
   selector is absent in the state the other one does not cover, and that
   is exactly the defect this block fixes.

   There are THREE theme states in this product, not two
   (docs/visual-regression.md):
     1. data-theme="light"  - an explicit light choice.
     2. data-theme="dark"   - an explicit dark choice.
     3. NOTHING STAMPED     - a visitor who has never toggled, and the
                              pre-paint state on every page. Here
                              prefers-color-scheme alone decides.
   State 3 is the one that broke: every --rc-shell-* token was light-only
   with no counterpart at all, and .regcanary-shell sets
   `color: var(--rc-shell-ink)` on every authenticated page. So anything
   inside the shell that merely INHERITED its colour painted #172033 on a
   dark ground - 1.06:1 against the portal surface (#111b2a) and 1.15:1
   against the portal wash (#0b1220), i.e. invisible. /app/firm and
   /app/today?tab=my-sectors were both caught this way, and the Research
   question label and the assurance band's RAG letter before them (those
   two were patched locally in Phase 4c; this is the root fix).

   The dark values are portal.css's dark palette, not a new one, so the
   shell and the workspace it wraps agree instead of fighting. Measured
   after the fix: ink 15.36:1 on the portal surface, 16.62:1 on the portal
   wash, 12.99:1 on the legacy dark card; muted 8.42:1 / 9.12:1 / 7.12:1.
   All well past 4.5:1 for body text.

   ⚠️ Never write a bare [data-theme="dark"] selector: that attribute is
   reused for an unrelated meaning on .breach-category elements in
   public/css/publications/_case-studies.css. Always html[data-theme=...]. */
:root {
  --rc-shell-sidebar-width: 280px;
  --rc-shell-header-height: 48px;
  --rc-shell-ink: #172033;
  --rc-shell-muted: #667085;
  --rc-shell-line: #dfe3ea;
  --rc-shell-surface: #fff;
  --rc-shell-wash: #f5f7fa;
  --rc-shell-brand: #2454d6;
  --rc-shell-brand-wash: #edf2ff;
  /* Kept invariant on purpose: the focus ring is a fixed brand tint in
     both themes, tokenised here only so a rebrand has one place to
     retint it. */
  --rc-shell-focus-ring: rgba(36, 84, 214, .35);
}

/* State 3: nothing stamped - prefers-color-scheme decides. The
   :not([data-theme="light"]) guard means an explicit LIGHT choice still
   wins on a dark OS, which a bare `@media` block would not give. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --rc-shell-ink: #edf2f7;
    --rc-shell-muted: #aab6c7;
    --rc-shell-line: #2c394b;
    --rc-shell-surface: #111b2a;
    --rc-shell-wash: #0b1220;
    --rc-shell-brand: #7da2ff;
    --rc-shell-brand-wash: #1b3154;
  }
}

/* State 2: an explicit dark choice, which must win on a light OS too. */
html[data-theme="dark"] {
  --rc-shell-ink: #edf2f7;
  --rc-shell-muted: #aab6c7;
  --rc-shell-line: #2c394b;
  --rc-shell-surface: #111b2a;
  --rc-shell-wash: #0b1220;
  --rc-shell-brand: #7da2ff;
  --rc-shell-brand-wash: #1b3154;
}

.regcanary-shell {
  font-family: Inter, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  color: var(--rc-shell-ink);
  font-synthesis: none;
}

.regcanary-shell-sidebar,
.regcanary-shell-header,
.regcanary-shell-nav {
  font-family: inherit;
}

.regcanary-shell-header {
  min-height: var(--rc-shell-header-height);
  border-color: var(--rc-shell-line);
}

.regcanary-shell-sidebar {
  border-color: var(--rc-shell-line);
}

.regcanary-shell-nav a:focus-visible,
.regcanary-shell-header a:focus-visible,
.regcanary-shell-sidebar button:focus-visible {
  outline: 3px solid var(--rc-shell-focus-ring);
  outline-offset: 2px;
}

@media (max-width: 680px) {
  :root { --rc-shell-header-height: 60px; }
}
