/* ============================================================================
 * Cadrify Design System — colors_and_type.css
 *
 * NASA modernism × British civic design × quiet operational software.
 * Import this in any HTML surface that should look like Cadrify.
 * ========================================================================== */

@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=IBM+Plex+Mono:wght@400;500&family=Newsreader:ital,wght@0,400;1,400&display=swap');

:root {
  /* ---------------------------------------------------------------------- */
  /* Color — raw                                                            */
  /* ---------------------------------------------------------------------- */

  /* Ink (deep navy → near-paper) */
  --ink-900: #0E1A2B;
  --ink-800: #182438;
  --ink-700: #25334A;
  --ink-600: #3D485C;
  --ink-500: #5C6678;   /* slate */
  --ink-400: #8C94A3;
  --ink-300: #BDC2CC;
  --ink-200: #DCDFE5;
  --ink-100: #EBEDF1;
  --ink-050: #F4F5F8;

  /* Paper (warm, stone) */
  --paper:        #F5F2EC;
  --paper-soft:   #FAF8F3;
  --paper-warm:   #EDE7DA;
  --white:        #FFFFFF;

  /* Civic blue — primary action */
  --blue-700: #1F3F66;
  --blue-600: #2C5A8C;   /* default */
  --blue-500: #3E73AB;
  --blue-400: #6791BE;
  --blue-300: #90AFD1;
  --blue-200: #B9CEE4;
  --blue-100: #DCE7F2;
  --blue-050: #EEF3F9;

  /* Forest — active / positive */
  --forest-700: #21443A;
  --forest-600: #2F5D4F;
  --forest-500: #437A6B;
  --forest-200: #B8CFC6;
  --forest-100: #DBE7E2;
  --forest-050: #ECF2EF;

  /* Signal — warning · draft · needs-review (civic amber) */
  --signal-700: #7A5E10;
  --signal-600: #A38219;
  --signal-500: #C2A12E;
  --signal-200: #E5D696;
  --signal-100: #F0E6BC;
  --signal-050: #F8F2DA;

  /* Crimson — destructive only */
  --crimson-700: #7A1F1F;
  --crimson-600: #9B2C2C;
  --crimson-200: #E4B9B9;
  --crimson-100: #F0D8D8;
  --crimson-050: #F7EAEA;

  /* G-score gradient — the canvass support→oppose scale used app-wide.
     One canonical scheme: bold enough to pop on the muted map basemap, but
     earthy/warm rather than neon so it stays on-brand. 1 = strong support,
     5 = firm against. Change here and it updates everywhere (CSS + inline
     legends; the Chart.js arrays mirror these same hexes in JS). */
  --g-1: #2E8B57;   /* strong support — sea green */
  --g-2: #7FC4A0;   /* leaning support — sage   */
  --g-3: #E0A82E;   /* undecided — gold         */
  --g-4: #DD7A3D;   /* leaning against — terracotta */
  --g-5: #C8403B;   /* opposed — brick red      */
  --g-none: #8C94A3; /* no data — ink-400        */

  /* Translucent ink — for borders/scrims that need to blend on paper */
  --ink-12: rgba(14, 26, 43, 0.12);
  --ink-08: rgba(14, 26, 43, 0.08);
  --ink-20: rgba(14, 26, 43, 0.20);
  --ink-04: rgba(14, 26, 43, 0.04);
  --ink-scrim: rgba(14, 26, 43, 0.28);

  /* ---------------------------------------------------------------------- */
  /* Color — semantic                                                       */
  /* ---------------------------------------------------------------------- */
  --bg-canvas:    var(--paper);
  --bg-canvas-soft: var(--paper-soft);
  --surface-1:    var(--white);          /* cards, panels */
  --surface-2:    var(--paper-soft);     /* nav rails, subtle wells */
  --surface-3:    var(--paper-warm);     /* eyebrow strips, archival panels */

  --fg-default:   var(--ink-900);
  --fg-muted:     var(--ink-500);
  --fg-subtle:    var(--ink-400);
  --fg-inverse:   var(--paper-soft);

  --border-default: var(--ink-12);
  --border-soft:    var(--ink-08);
  --border-strong:  var(--ink-20);
  --border-focus:   var(--blue-600);

  --action-default:   var(--blue-600);
  --action-hover:     var(--blue-700);
  --action-on:        #FFFFFF;

  /* Forest fills — for backgrounds where white text must be readable.
     In light mode these equal forest-600/700 (dark forest, white text fine).
     In dark mode these are pinned to mid-dark values (see dark block) so
     that --forest-600 can be lifted for text/accents without breaking fills. */
  --forest-fill:       var(--forest-600);
  --forest-fill-hover: var(--forest-700);

  --status-active-fg: var(--forest-700);
  --status-active-bg: var(--forest-050);
  --status-active-border: var(--forest-200);

  --status-draft-fg:  var(--signal-700);
  --status-draft-bg:  var(--signal-050);
  --status-draft-border: var(--signal-200);

  --status-info-fg:   var(--blue-700);
  --status-info-bg:   var(--blue-050);
  --status-info-border: var(--blue-200);

  --status-error-fg:  var(--crimson-700);
  --status-error-bg:  var(--crimson-050);
  --status-error-border: var(--crimson-200);

  --status-neutral-fg: var(--ink-700);
  --status-neutral-bg: var(--ink-050);
  --status-neutral-border: var(--ink-200);

  /* Elevation, wells, overlays */
  --surface-overlay: var(--white);     /* popovers, dropdowns, tooltips — one step up */
  --bg-well:         var(--ink-050);   /* recessed wells, hover rows, tracks, disabled */
  --scrim:           var(--ink-scrim); /* modal/overlay backdrops */

  /* Form inputs */
  --input-bg:     var(--white);
  --input-border: var(--ink-12);
  --input-fg:     var(--ink-900);

  /* Code / mono chips */
  --fg-code: var(--ink-700);
  --bg-code: var(--ink-050);

  /* Data-viz chrome — read by Chart.js via getComputedStyle (chart-theme.js).
     The g-score scale (--g-1..5) is data and stays fixed across themes; only
     the chart furniture (grid, ticks, tooltip) adapts. */
  --chart-grid:       #ECECEC;
  --chart-axis:       var(--ink-400);
  --chart-tick:       var(--ink-500);
  --chart-tooltip-bg: var(--ink-900);
  --chart-tooltip-fg: var(--paper-soft);

  /* Map — basemap tile filter + feature paint, read at layer-build time */
  --map-basemap-filter: saturate(.5) brightness(1.08) contrast(.92) sepia(.07);
  --map-water:  #F1F2F5;
  --map-stroke: #0E1A2B;
  --map-halo:   var(--paper);

  /* Party colours — real-world brand hues, identical in both themes.
     Canonical source; JS lookups read these via getComputedStyle. */
  --party-lab: #E4003B;
  --party-con: #0087DC;
  --party-ld:  #FAA61A;
  --party-grn: #02A95B;
  --party-snp: #FDF38E;
  --party-pc:  #3F8428;
  --party-ref: #12B6CF;
  --party-ukip:#70147A;
  --party-ind: #94A3B8;

  /* ---------------------------------------------------------------------- */
  /* Type                                                                   */
  /* ---------------------------------------------------------------------- */
  --font-sans: 'Inter', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Helvetica, Arial, sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --font-editorial: 'Newsreader', 'Iowan Old Style', Georgia, serif;

  /* Type scale (approx 1.2 ratio) */
  --t-display:   32px;   /* page titles, splash */
  --t-h1:        24px;
  --t-h2:        19px;
  --t-h3:        16px;
  --t-body:      14px;
  --t-small:     13px;
  --t-mono:      12px;
  --t-eyebrow:   11px;

  --lh-tight:    1.15;
  --lh-snug:     1.3;
  --lh-body:     1.5;
  --lh-loose:    1.6;

  --tr-tight:    -0.02em;   /* display sizes */
  --tr-normal:   0;
  --tr-wide:     0.08em;    /* eyebrow ALL CAPS */

  /* ---------------------------------------------------------------------- */
  /* Spacing — 8px base, 4 as half-step                                     */
  /* ---------------------------------------------------------------------- */
  --space-1:   4px;
  --space-2:   8px;
  --space-3:  12px;
  --space-4:  16px;
  --space-5:  24px;
  --space-6:  32px;
  --space-7:  48px;
  --space-8:  64px;
  --space-9:  96px;

  /* ---------------------------------------------------------------------- */
  /* Radii — small, architectural                                           */
  /* ---------------------------------------------------------------------- */
  --radius-sm: 2px;
  --radius-md: 4px;
  --radius-lg: 6px;

  /* ---------------------------------------------------------------------- */
  /* Shadows — minimal                                                      */
  /* ---------------------------------------------------------------------- */
  --shadow-1: 0 1px 0 rgba(14,26,43,0.04), 0 1px 2px rgba(14,26,43,0.06);
  --shadow-2: 0 2px 4px rgba(14,26,43,0.06), 0 8px 16px rgba(14,26,43,0.06);
  --shadow-3: 0 12px 32px rgba(14,26,43,0.12);

  /* ---------------------------------------------------------------------- */
  /* Motion                                                                 */
  /* ---------------------------------------------------------------------- */
  --ease-out: cubic-bezier(0.2, 0, 0, 1);
  --dur-fast: 120ms;
  --dur-base: 180ms;
  --dur-slow: 240ms;
}

/* ============================================================================
 * Dark theme — remaps the SEMANTIC layer only. Components that reference
 * semantic tokens (--surface-*, --fg-*, --border-*, --status-*) flip for free.
 * Canvas is deep navy, never pure black; text is warm neutral, never pure
 * white, mirroring the light-mode "never pure white at canvas level" rule.
 *
 * The raw palette (--ink-*, --paper*, --white, --blue-*, etc.) stays fixed as
 * anchors EXCEPT the five translucent ink primitives, which flip to translucent
 * white so every hairline/hover/scrim built on them reads correctly on dark.
 * The g-score scale and --party-* are data and never change.
 * ========================================================================== */
html[data-theme="dark"] {
  /* Translucent primitives flip — highest-leverage single change */
  --ink-04:    rgba(255, 255, 255, 0.05);
  --ink-08:    rgba(255, 255, 255, 0.08);
  --ink-12:    rgba(255, 255, 255, 0.12);
  --ink-20:    rgba(255, 255, 255, 0.22);
  --ink-scrim: rgba(0, 0, 0, 0.55);

  /* Canvas & surfaces — step UP in lightness as elevation rises */
  --bg-canvas:      #0B1420;   /* deeper than ink-900; the "never pure black" canvas */
  --bg-canvas-soft: #0E1A2B;
  --surface-1:      #16202F;   /* cards, panels, topbar */
  --surface-2:      #1C2A3E;   /* nav rails, wells, headers */
  --surface-3:      #243246;   /* eyebrow strips, archival/elevated */

  /* Foreground — warm neutral, never pure white */
  --fg-default: #E7E3DA;
  --fg-muted:   #BCC4D0;   /* brightened: #A8B0BE was too faded on dark surfaces */
  --fg-subtle:  #6E7888;
  --fg-inverse: #0E1A2B;       /* dark text on light chips */

  /* Borders — low-alpha light on dark */
  --border-default: rgba(255, 255, 255, 0.12);
  --border-soft:    rgba(255, 255, 255, 0.07);
  --border-strong:  rgba(255, 255, 255, 0.22);
  --border-focus:   #5E92C8;

  /* Action — civic blue lifted for contrast on dark */
  --action-default: #4F86C0;
  --action-hover:   #6FA0D4;
  --action-on:      #0B1420;   /* dark text on the lighter blue fill */

  /* Forest / brand — two-tier approach.
     --forest-600/700 are lifted for text and accents (~6:1 on dark surfaces).
     --forest-fill/fill-hover are darker values reserved for button/fill
     backgrounds, where white text needs ≥4.5:1. Direct usages of --forest-600
     as colour text now pop visibly; button rules are overridden below. */
  --forest-050: #111D17;
  --forest-100: #162B23;
  --forest-200: #243D33;
  --forest-500: #7CC4A5;
  --forest-600: #6BAE95;   /* text/accents: ~6:1 on dark surfaces */
  --forest-700: #5D9B81;   /* secondary accent */
  --forest-fill: #4A7E69;       /* btn fills: white text 4.7:1 */
  --forest-fill-hover: #3D6B57; /* btn hover fills: white text 6.1:1 */

  /* Signal — lifted amber; no dark override existed before. */
  --signal-050: #1A1608;
  --signal-100: #231E0C;
  --signal-200: #2E2810;
  --signal-500: #DFBE3F;
  --signal-600: #D4A827;   /* text/accents: ~6:1 on dark surfaces */
  --signal-700: #B08C1A;   /* darker signal accent */

  /* Status — dark-tinted backgrounds, light-tinted foregrounds */
  --status-active-fg:     #8FD3B6;
  --status-active-bg:     #14271F;
  --status-active-border: #3D6B57;  /* matches new forest-700 */

  --status-draft-fg:      #E5C766;
  --status-draft-bg:      #2A2310;
  --status-draft-border:  #7A5E10;

  --status-info-fg:       #8FB8E0;
  --status-info-bg:       #11202F;
  --status-info-border:   #2C5A8C;

  --status-error-fg:      #E79A9A;
  --status-error-bg:      #2A1414;
  --status-error-border:  #7A1F1F;

  --status-neutral-fg:    #C2C9D3;
  --status-neutral-bg:    #1C2A3E;
  --status-neutral-border:#3D485C;

  /* Elevation, wells, inputs, code */
  --surface-overlay: #1C2A3E;
  --bg-well:         #16202F;
  --scrim:           rgba(0, 0, 0, 0.6);
  --input-bg:        #16202F;
  --input-border:    rgba(255, 255, 255, 0.16);
  --input-fg:        #E7E3DA;
  --fg-code:         #B7C2D0;
  --bg-code:         #16202F;

  /* Data-viz furniture */
  --chart-grid:       rgba(255, 255, 255, 0.08);
  --chart-axis:       #8C94A3;
  --chart-tick:       #BCC4D0;
  --chart-tooltip-bg: #243246;
  --chart-tooltip-fg: #E7E3DA;

  /* G-score — lifted for visibility on the dark basemap. */
  --g-1: #44B87A;   /* strong support — brighter sea green */
  --g-2: #8FCFB0;   /* leaning support — lifted sage */
  --g-3: #EAB830;   /* undecided — lifted gold */
  --g-4: #E38A4A;   /* leaning against — lifted terracotta */
  --g-5: #D85454;   /* opposed — lifted brick red */

  /* Map — dark basemap via invert+hue-rotate, dark water, light strokes */
  --map-basemap-filter: brightness(.62) invert(.92) contrast(.92) hue-rotate(180deg) saturate(.8);
  --map-water:  #0B1420;
  --map-stroke: #C2C9D3;
  --map-halo:   #0B1420;

  /* Shadows deepen — light-mode shadows are invisible on dark */
  --shadow-1: 0 1px 0 rgba(0,0,0,0.4), 0 1px 2px rgba(0,0,0,0.5);
  --shadow-2: 0 2px 4px rgba(0,0,0,0.4), 0 8px 16px rgba(0,0,0,0.5);
  --shadow-3: 0 12px 32px rgba(0,0,0,0.6);
}

/* Belt-and-braces: also follow the OS for any surface that renders before the
   head script runs or outside an authenticated page (where data-theme is unset
   but data-bs-theme may be). Only applies when no explicit theme is set. */
html[data-theme="dark"] body { color-scheme: dark; }

/* Forest button fills — --forest-600 is now lifted for text readability, so
   button backgrounds that need white text must use --forest-fill instead.
   !important is required to beat any inline <style> block that also sets
   background on these classes (e.g. the marketing nav's .nav .btn-brand). */
html[data-theme="dark"] .btn-brand,
html[data-theme="dark"] .btn-success,
html[data-theme="dark"] .bg-brand {
  background-color: var(--forest-fill) !important;
  border-color: var(--forest-fill) !important;
}
html[data-theme="dark"] .btn-brand:hover,
html[data-theme="dark"] .btn-brand:focus,
html[data-theme="dark"] .btn-brand:active,
html[data-theme="dark"] .btn-check:checked + .btn-brand,
html[data-theme="dark"] .btn-success:hover,
html[data-theme="dark"] .btn-success:focus,
html[data-theme="dark"] .btn-success:active {
  background-color: var(--forest-fill-hover) !important;
  border-color: var(--forest-fill-hover) !important;
}
html[data-theme="dark"] .btn-outline-success:hover {
  background-color: var(--forest-fill) !important;
  border-color: var(--forest-fill) !important;
}
html[data-theme="dark"] .gotv-bar { background: var(--forest-fill); }

/* Print — never let dark mode leak onto paper or PDF exports. Force the
   light canvas/surface/ink anchors regardless of the active theme. */
@media print {
  html, html[data-theme="dark"] {
    --bg-canvas: #FFFFFF;
    --bg-canvas-soft: #FFFFFF;
    --surface-1: #FFFFFF;
    --surface-2: #FFFFFF;
    --surface-3: #FFFFFF;
    --fg-default: #0E1A2B;
    --fg-muted: #5C6678;
    --border-default: rgba(14,26,43,0.12);
    --ink-12: rgba(14,26,43,0.12);
    --ink-08: rgba(14,26,43,0.08);
  }
}

/* ============================================================================
 * Semantic type — apply to elements directly OR via these utility classes
 * ========================================================================== */

html, body {
  background: var(--bg-canvas);
  color: var(--fg-default);
  font-family: var(--font-sans);
  font-size: var(--t-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-feature-settings: 'cv11', 'ss01', 'ss03';
}

.display, h1.display {
  font: 500 var(--t-display)/var(--lh-tight) var(--font-sans);
  letter-spacing: var(--tr-tight);
  color: var(--fg-default);
}

h1, .t-h1 {
  font: 600 var(--t-h1)/var(--lh-snug) var(--font-sans);
  letter-spacing: -0.01em;
  margin: 0;
}

h2, .t-h2 {
  font: 600 var(--t-h2)/var(--lh-snug) var(--font-sans);
  margin: 0;
}

h3, .t-h3 {
  font: 600 var(--t-h3)/var(--lh-snug) var(--font-sans);
  margin: 0;
}

.t-body  { font: 400 var(--t-body)/var(--lh-body) var(--font-sans); }
.t-small { font: 400 var(--t-small)/var(--lh-body) var(--font-sans); color: var(--fg-muted); }
.t-mono  { font: 400 var(--t-mono)/var(--lh-snug) var(--font-mono); letter-spacing: 0.01em; }

.t-eyebrow {
  font: 500 var(--t-eyebrow)/1 var(--font-mono);
  text-transform: uppercase;
  letter-spacing: var(--tr-wide);
  color: var(--fg-muted);
}

.t-editorial {
  font: 400 var(--t-h2)/1.45 var(--font-editorial);
  font-style: italic;
  color: var(--fg-default);
}

/* Mono used inline for IDs/timestamps inside body copy */
code, kbd, .mono-inline {
  font: 400 0.92em/1.2 var(--font-mono);
  letter-spacing: 0.01em;
  color: var(--fg-code);
}

a {
  color: var(--action-default);
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}
a:hover { color: var(--action-hover); }

hr {
  border: 0;
  border-top: 1px solid var(--border-default);
  margin: var(--space-5) 0;
}

::selection { background: var(--blue-100); color: var(--ink-900); }

/* ── GOTV teller coverage timeline ──────────────────────────────────────── */
.gotv-axis, .gotv-row { display: flex; align-items: stretch; }
.gotv-axis-label, .gotv-row-label { flex: 0 0 220px; padding-right: 12px; }
.gotv-row-action { flex: 0 0 110px; padding-left: 12px; display: flex; align-items: center; }
.gotv-axis-track { position: relative; flex: 1 1 auto; height: 20px; }
.gotv-track {
  position: relative; flex: 1 1 auto; height: 38px;
  background: var(--bg-well);
  border: 1px solid var(--border-default); border-radius: 2px; overflow: hidden;
}
.gotv-row { margin-bottom: 8px; }
.gotv-row-label { display: flex; flex-direction: column; justify-content: center; }
.gotv-row-meta { font-family: var(--mono, 'IBM Plex Mono', monospace); font-size: 12px; }
.gotv-tick { position: absolute; top: 0; bottom: 0; transform: translateX(-50%); }
.gotv-tick-label { font-family: var(--mono, 'IBM Plex Mono', monospace); font-size: 12px; color: var(--fg-muted); }
.gotv-gap {
  position: absolute; top: 0; bottom: 0;
  background: var(--crimson-100); border-right: 1px solid var(--crimson-200);
}
.gotv-bar {
  position: absolute; top: 3px; bottom: 3px;
  background: var(--forest-600); color: var(--white); border-radius: 2px;
  display: flex; align-items: center; gap: 4px;
  padding: 0 6px; min-width: 0; overflow: hidden;
}
.gotv-bar-text { font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gotv-bar-remove {
  flex: 0 0 auto; background: transparent; border: 0; color: var(--white);
  font-size: 15px; line-height: 1; padding: 0 2px; cursor: pointer;
}
.gotv-bar-remove:hover { color: var(--crimson-100); }
