﻿/* ==========================================================================
   election.ltd base stylesheet
   Hand-written, tokenised. No Bootstrap / Tailwind / component framework.
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink-700);
  font-family: var(--font-sans);
  font-size: var(--fs-16);
  line-height: var(--lh-body);
  font-variant-numeric: tabular-nums;
}

:lang(hi) { font-family: var(--font-deva); }

h1, h2, h3, h4, h5, h6 {
  color: var(--ink-900);
  font-weight: 600;
  line-height: 1.25;
  margin: 0 0 var(--space-4);
  letter-spacing: -0.01em;
}
h1 { font-size: var(--fs-40); letter-spacing: -0.02em; }
h2 { font-size: var(--fs-28); }
h3 { font-size: var(--fs-23); }
h4 { font-size: var(--fs-19); }

p { margin: 0 0 var(--space-4); }

a { color: var(--brand-600); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--brand-700); }

code, kbd, samp, .mono { font-family: var(--font-mono); font-size: 0.9em; }

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

/* --- Layout ------------------------------------------------------------ */
.container       { max-width: var(--container-marketing); margin-inline: auto; padding-inline: var(--gutter); }
.container-prose { max-width: var(--container-prose);     margin-inline: auto; padding-inline: var(--gutter); }
.container-app   { max-width: var(--container-app);       margin-inline: auto; padding-inline: var(--gutter); }

.section     { padding-block: var(--space-8); }
.section-alt { background: var(--paper-alt); border-block: 1px solid var(--rule); }

.grid   { display: grid; gap: var(--gutter); }
.grid-2 { grid-template-columns: repeat(2, minmax(0,1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0,1fr)); }
.grid-4 { grid-template-columns: repeat(4, minmax(0,1fr)); }

/* The signature three-column documentation grid, used across /data, /wiki
   and /trust. This is the visual grammar of a standards body and the
   strongest differentiator against dashboard-shaped competitors. */
.doc-grid {
  display: grid;
  grid-template-columns: var(--rail-left) minmax(0, 1fr) 260px;
  gap: var(--space-6);
  align-items: start;
}
.doc-rail { position: sticky; top: var(--space-5); font-size: var(--fs-14); }

@media (max-width: 1100px) {
  .doc-grid { grid-template-columns: minmax(0,1fr); }
  .doc-rail { position: static; }
}
@media (max-width: 860px) {
  .grid-2, .grid-3, .grid-4 { grid-template-columns: minmax(0,1fr); }
  h1 { font-size: var(--fs-33); }
}

/* --- Site chrome -------------------------------------------------------- */
.site-header {
  border-bottom: 1px solid var(--rule);
  background: var(--paper);
  position: sticky; top: 0; z-index: 50;
}
/* min-height, not height: the nav wraps at narrow widths and a fixed height would
   let it overflow the header box and paint over the page content below. */
.site-header .bar {
  display: flex; align-items: center; gap: var(--space-5);
  min-height: 64px; flex-wrap: wrap; padding-block: var(--space-2);
}

.site-nav { display: flex; gap: var(--space-5); margin-left: auto; flex-wrap: wrap; }
.site-nav a {
  color: var(--ink-700); text-decoration: none;
  font-size: var(--fs-14); font-weight: 500;
  padding-block: var(--space-2);
  border-bottom: 2px solid transparent;
}
.site-nav a:hover,
.site-nav a[aria-current="page"] { color: var(--brand-700); border-bottom-color: var(--brand-700); }

/* Wordmark: ELECTION 600 at 0.14em tracking, .LTD 400 in brand navy */
.wordmark { display: inline-flex; align-items: center; gap: var(--space-2); text-decoration: none; white-space: nowrap; }
.wordmark .wm-text { font-size: var(--fs-16); letter-spacing: 0.14em; }
.wordmark .wm-a { font-weight: 600; color: var(--ink-900); }
.wordmark .wm-b { font-weight: 400; color: var(--brand-700); }

.site-footer {
  border-top: 1px solid var(--rule);
  background: var(--paper-alt);
  padding-block: var(--space-7);
  font-size: var(--fs-14);
  color: var(--ink-500);
}
/* Column labels use .eyebrow; this rule was the reason pages reached for an
   <h5> to get the look, which broke the heading outline on every one. */
.site-footer ul { list-style: none; padding: 0; margin: 0; }
.site-footer li { margin-bottom: var(--space-2); }
.site-footer a { color: var(--ink-700); text-decoration: none; }
.site-footer a:hover { text-decoration: underline; }

/* --- Buttons ------------------------------------------------------------ */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  font: inherit; font-size: var(--fs-14); font-weight: 500;
  padding: 10px 18px; border-radius: var(--radius);
  border: 1px solid transparent; cursor: pointer; text-decoration: none;
}
.btn-primary { background: var(--verify); color: #fff; box-shadow: var(--elev-inner); }
.btn-primary:hover { background: #0C5F59; color: #fff; }
.btn-secondary { background: var(--paper); color: var(--ink-900); border-color: var(--rule-strong); }
.btn-secondary:hover { background: var(--paper-sunken); color: var(--ink-900); }

/* --- Cards: elevation is border + inner highlight, never drop-shadow ---- */
.card {
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  box-shadow: var(--elev-inner);
}
/* A heading inside a card is a callout title, not a page section title, so it
   takes card weight whichever level the document outline requires it to be. */
.card h2, .card h3 { font-size: var(--fs-19); margin-bottom: var(--space-2); }
.card p:last-child { margin-bottom: 0; }

/* --- Stat strip --------------------------------------------------------- */
.stat { border-left: 3px solid var(--brand-700); padding-left: var(--space-4); }
.stat .stat-value { font-size: var(--fs-33); font-weight: 600; color: var(--ink-900); line-height: 1.1; }
.stat .stat-label {
  font-size: var(--fs-13); color: var(--ink-400);
  text-transform: uppercase; letter-spacing: 0.06em;
}

/* --- Verification chip -------------------------------------------------- */
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--font-mono); font-size: 11px; font-weight: 500;
  text-transform: uppercase; letter-spacing: 0.06em;
  padding: 3px 8px; border-radius: 3px; border: 1px solid currentColor;
  white-space: nowrap;
}
.chip-unknown     { color: var(--status-unknown); }
.chip-verified    { color: var(--status-verified); }
.chip-provisional { color: var(--status-provisional); }
.chip-ocr         { color: var(--status-ocr); }
.chip-error       { color: var(--status-error); }

/* Property lifecycle, a separate vocabulary from data verification. Kept in the
   same shape so a reader learns one chip grammar, not two. */
.chip-live          { color: var(--verify); }
.chip-forthcoming   { color: var(--warn); }
.chip-authenticated { color: var(--brand-700); }
.chip-illustrative  { color: var(--ink-500); }

/* --- Geo tier: colour as a dot and a left rule, never a fill ------------ */
.tier { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-13); color: var(--ink-500); }
.tier::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--tier-color, var(--rule-strong)); }
.tier-state         { --tier-color: var(--tier-state); }
.tier-district      { --tier-color: var(--tier-district); }
.tier-parliamentary { --tier-color: var(--tier-parliamentary); }
.tier-assembly      { --tier-color: var(--tier-assembly); }
.tier-sector        { --tier-color: var(--tier-sector); }
.tier-booth         { --tier-color: var(--tier-booth); }

/* --- Tables ------------------------------------------------------------- */
.table-wrap { overflow-x: auto; border: 1px solid var(--rule); border-radius: var(--radius-lg); }
table.data { width: 100%; border-collapse: collapse; font-size: var(--fs-13); line-height: var(--lh-table); }
table.data th, table.data td {
  padding: 0 var(--space-3); height: 34px; text-align: left;
  border-bottom: 1px solid var(--rule);
}
table.data thead th {
  position: sticky; top: 0; background: var(--paper-sunken);
  font-size: var(--fs-12); text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--ink-500); font-weight: 600; z-index: 1;
}
table.data tbody tr:nth-child(even) { background: color-mix(in srgb, var(--ink-900) 2%, transparent); }
table.data td.num, table.data th.num { text-align: right; font-variant-numeric: tabular-nums; }
table.data tbody tr:last-child td { border-bottom: 0; }

/* --- Provenance footer -------------------------------------------------- */
.provenance {
  border: 1px solid var(--rule); border-left: 3px solid var(--verify);
  background: var(--paper-alt);
  padding: var(--space-4);
  font-size: var(--fs-13); color: var(--ink-500);
  border-radius: var(--radius);
}
.provenance dl {
  display: grid; grid-template-columns: max-content 1fr;
  gap: var(--space-1) var(--space-4); margin: 0;
}
.provenance dt {
  color: var(--ink-400); text-transform: uppercase;
  font-size: var(--fs-12); letter-spacing: 0.06em;
}
.provenance dd { margin: 0; font-family: var(--font-mono); font-size: var(--fs-12); color: var(--ink-700); }

/* --- Coverage bar ------------------------------------------------------- */
.coverage { font-size: var(--fs-13); color: var(--ink-500); }
.coverage-track { height: 6px; background: var(--paper-sunken); border-radius: 3px; overflow: hidden; margin-block: var(--space-2); }
.coverage-fill { height: 100%; background: var(--verify); }
.coverage-fill.low { background: var(--warn); }

/* --- ECI non-affiliation band ------------------------------------------ */
/* --ink-400 #64748B on --paper-sunken #F1F5F9 measures 4.34:1 - under AA for
   12px body text, and this band renders in the footer of every page on the
   site, carrying the ECI non-affiliation statement. --ink-500 measures 6.92:1
   on the same ground and still reads as quiet. */
.eci-band {
  background: var(--paper-sunken); border-top: 1px solid var(--rule);
  font-size: var(--fs-12); color: var(--ink-500);
  padding-block: var(--space-3); text-align: center;
}

/* --- Page utilities ----------------------------------------------------- */
/* Small uppercase label sitting above a heading, or heading a rail list. It is
   a label, never a heading: making it an <h5> to borrow the footer's styling
   put an outline break on eleven pages. Use <p class="eyebrow">. */
.eyebrow {
  font-size: var(--fs-12); text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--ink-400); font-weight: 600;
  margin: 0 0 var(--space-3);
}
.eyebrow a { color: inherit; text-decoration: none; }
.eyebrow a:hover { color: var(--ink-700); }

/* An unconfirmed fact. Every "[to be confirmed]" placeholder on the site wears
   this, so an unshipped value looks identical wherever it appears and cannot
   be mistaken for a published one. */
.tbc {
  font-family: var(--font-mono); font-size: 0.9em;
  color: var(--status-provisional);
  border-bottom: 1px dashed currentColor;
  white-space: nowrap;
}

/* Index, rail and reference lists: the marker carries no meaning. */
.list-plain { list-style: none; padding: 0; margin: 0; }
.list-plain > li { margin-bottom: var(--space-2); }
.list-plain > li:last-child { margin-bottom: 0; }

/* The header is sticky, so an anchored heading has to clear it or it lands
   underneath. Declared once here rather than inline on every anchor. */
[id] { scroll-margin-top: calc(64px + var(--space-4)); }

/* --- Accessibility ------------------------------------------------------ */
/* --brand-600 is chosen for paper: 6.12:1 on --paper, comfortably over the
   3:1 SC 1.4.11 asks of a focus indicator. See the .deep override further
   down - the same ring measures 1.90:1 on a deep band and has to change. */
:focus-visible { outline: 2px solid var(--brand-600); outline-offset: 2px; }
.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}
.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--brand-700); color: #fff; padding: var(--space-3) var(--space-4);
}
.skip-link:focus { left: 0; }

/* --- Blazor error UI ---------------------------------------------------- */
#blazor-error-ui {
  display: none; position: fixed; bottom: 0; left: 0; right: 0; z-index: 1000;
  background: var(--bad); color: #fff; padding: var(--space-3) var(--space-5); font-size: var(--fs-14);
}
#blazor-error-ui .dismiss { cursor: pointer; float: right; }
/* The bar sets color:#fff, but its "Reload" link fell through to the global
   `a { color: var(--brand-600) }` - #2563A8 on the #B91C1C bar is 1.06:1, an
   invisible recovery link on the one screen a reader most needs one. 6.47:1. */
#blazor-error-ui a { color: #fff; text-decoration: underline; }

@media print {
  .site-header, .site-footer, .site-nav, .skip-link { display: none !important; }
  body { color: #000; background: #fff; }
  a { color: #000; text-decoration: underline; }
}

/* --- Forms and auth ------------------------------------------------------
   The Identity scaffold shipped reaching for Bootstrap classes that this
   stylesheet never defined (form-control, form-floating, row, col-md-4,
   text-danger, mb-3, nav-pills), so every account page rendered unstyled.
   These are the replacements. Buttons reuse the existing .btn family.
   ------------------------------------------------------------------------ */

/* A narrow, centred column for sign-in, register, reset. */
.auth-shell { max-width: 30rem; margin-inline: auto; padding-block: var(--space-8); }
.auth-shell h1 { font-size: var(--fs-28); }

/* Two-column shell for account management: side nav plus panel. */
.auth-manage { display: grid; grid-template-columns: 220px minmax(0, 1fr); gap: var(--space-6); align-items: start; }
@media (max-width: 860px) { .auth-manage { grid-template-columns: minmax(0, 1fr); } }

/* Vertical nav, replacing nav-pills. */
.side-nav { display: flex; flex-direction: column; gap: 2px; }
.side-nav a {
  display: block; padding: var(--space-2) var(--space-3);
  color: var(--ink-700); text-decoration: none;
  font-size: var(--fs-14); border-left: 2px solid transparent; border-radius: 0 var(--radius) var(--radius) 0;
}
.side-nav a:hover { background: var(--paper-sunken); color: var(--ink-900); }
.side-nav a.active,
.side-nav a[aria-current="page"] { border-left-color: var(--brand-700); color: var(--brand-700); background: var(--brand-050); font-weight: 500; }

/* Fields. Stacked label above control - no floating labels: they hide the
   label at the moment a screen-reader user most needs it, and they break
   entirely when the field is prefilled by a password manager. */
.form-field { margin-bottom: var(--space-4); }
.form-label { display: block; font-size: var(--fs-14); font-weight: 500; color: var(--ink-900); margin-bottom: var(--space-1); }
.form-input,
.form-select,
.form-textarea {
  display: block; width: 100%; font: inherit; font-size: var(--fs-14);
  color: var(--ink-900); background: var(--paper);
  padding: 9px var(--space-3);
  border: 1px solid var(--rule-strong); border-radius: var(--radius);
}
.form-input:focus,
.form-select:focus,
.form-textarea:focus { border-color: var(--brand-600); outline: 2px solid var(--brand-600); outline-offset: -1px; }
.form-input[aria-invalid="true"], .form-input.invalid { border-color: var(--bad); }
.form-textarea { min-height: 8rem; resize: vertical; }
.form-help { font-size: var(--fs-13); color: var(--ink-400); margin-top: var(--space-1); }

.form-check { display: flex; align-items: baseline; gap: var(--space-2); margin-bottom: var(--space-4); }
.form-check input { margin: 0; }

/* Validation. Replaces text-danger, which was never defined here. */
.field-error,
.validation-message { display: block; font-size: var(--fs-13); color: var(--bad); margin-top: var(--space-1); }
.validation-summary,
.validation-errors {
  border: 1px solid var(--bad); border-left: 3px solid var(--bad);
  background: color-mix(in srgb, var(--bad) 5%, var(--paper));
  color: var(--ink-900); padding: var(--space-3) var(--space-4);
  border-radius: var(--radius); margin-bottom: var(--space-4); font-size: var(--fs-14);
}
.validation-summary ul, .validation-errors ul { margin: 0; padding-left: var(--space-5); }
.validation-summary:empty, .validation-errors:empty { display: none; }

/* Status banner used by StatusMessage. */
.status-message {
  border: 1px solid var(--rule); border-left: 3px solid var(--verify);
  background: var(--paper-alt); color: var(--ink-700);
  padding: var(--space-3) var(--space-4); border-radius: var(--radius);
  margin-bottom: var(--space-4); font-size: var(--fs-14);
}
.status-message.error { border-left-color: var(--bad); }

/* Button variants the scaffold expects, built on the existing .btn base. */
.btn-block  { width: 100%; }
.btn-danger { background: var(--bad); color: #fff; box-shadow: var(--elev-inner); }
.btn-danger:hover { background: #9B1C1C; color: #fff; }
.btn-link   { background: none; border: 0; padding: 0; color: var(--brand-600); text-decoration: underline; }
.btn-link:hover { color: var(--brand-700); }

/* Spacing utilities, so a rewrite does not need a bespoke class per gap. */
.stack > * + * { margin-top: var(--space-4); }
.mt-4 { margin-top: var(--space-4); }
.mb-4 { margin-bottom: var(--space-4); }

/* ==========================================================================
   FUTURISTIC SURFACES
   Applied to marketing surfaces (home, services, group, company). Document
   surfaces keep the light treatment - see the note in tokens.css.
   ========================================================================== */

/* --- Deep band: the hero and any full-bleed feature section ------------- */
.deep {
  position: relative;
  background: var(--grad-hero);
  color: var(--on-deep-600);
  isolation: isolate;
  overflow: hidden;
}
.deep h1, .deep h2, .deep h3, .deep h4 { color: var(--on-deep-900); }
.deep a { color: var(--lum-cyan); }
.deep a:hover { color: #67E8F9; }
.deep .eyebrow { color: var(--lum-cyan); }
/* `.eyebrow a:hover { color: var(--ink-700) }` is a light-ground rule that
   outranks `.deep a:hover` on specificity (0,2,1 against 0,1,1), so the "Group"
   breadcrumb on the four property pages turned #1E293B on hover - 1.15:1, i.e.
   it vanished under the pointer. Hover is a state of the text and has to meet
   4.5:1 like any other; this lands at 8.3:1. */
.deep .eyebrow a:hover { color: #67E8F9; }

/* Mesh overlay. Pure CSS, no image request. Masked so it fades out rather
   than ending on a hard edge. */
.deep::before {
  content: "";
  position: absolute; inset: 0; z-index: -1;
  background-image:
    linear-gradient(var(--mesh-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--mesh-line) 1px, transparent 1px);
  background-size: var(--mesh-size) var(--mesh-size);
  mask-image: radial-gradient(120% 90% at 50% 0%, #000 35%, transparent 75%);
  -webkit-mask-image: radial-gradient(120% 90% at 50% 0%, #000 35%, transparent 75%);
}

/* A luminous hairline to close a deep band. */
.deep-rule { height: 1px; background: var(--grad-rule); border: 0; margin: 0; }

/* --- Gradient text. One per page, on the hero <h1> line only. -----------
   Clipped text has NO contrast guarantee of its own - the reader sees the
   gradient, so the WORST stop is the one that has to pass, not the first.
   It therefore uses --grad-accent-text, whose three stops all clear 4.5:1 on
   the composite deep ground, and not --grad-accent (the button fill), whose
   --lum-violet tail measures 2.17:1 there.

   Two standing constraints, because this class cannot enforce them itself:
     - Deep grounds only. Every stop is a light tint; on paper the same text
       measures about 1.8:1. All 17 current uses are inside a .deep band.
     - Large text only, i.e. the hero <h1> (40px/600, 33px under 860px). Never
       put it on body copy, a chip, a stat value or a caption. */
.grad-text {
  background: var(--grad-accent-text);
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
  /* Fallback for engines that ignore background-clip on text. */
  -webkit-text-fill-color: transparent;
}
@supports not (background-clip: text) {
  .grad-text { color: var(--lum-cyan); -webkit-text-fill-color: currentColor; }
}
/* Forced-colours mode discards the background and would leave the text
   transparent-on-transparent, i.e. an invisible half of every hero line. */
@media (forced-colors: active) {
  .grad-text { color: CanvasText; -webkit-text-fill-color: CanvasText; background: none; }
}

/* --- Glass panel, for cards sitting on a deep band ---------------------- */
.glass {
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  color: var(--on-deep-600);
}
.glass h3, .glass h2 { color: var(--on-deep-900); }
.glass:hover { border-color: rgba(34,211,238,0.35); }

/* --- Glow, reserved for the primary CTA and the hero mark --------------- */
.glow      { box-shadow: var(--glow-cyan); }
.glow-soft { box-shadow: var(--glow-soft); }
.btn-glow  { background: var(--grad-accent); color: var(--deep-900); border: 0; font-weight: 600; box-shadow: var(--glow-cyan); }
.btn-glow:hover { color: var(--deep-900); filter: brightness(1.08); }

/* Every .btn-glow and .btn-primary on this site is an <a>, and `.deep a`
   (0,1,1) outranks `.btn-glow` (0,1,0). So on a deep band the label of the
   primary CTA was being repainted --lum-cyan ON TOP OF its own cyan-to-violet
   fill: 1.00:1 over the cyan stop, 2.04:1 over the blue, 2.34:1 over the
   violet. The most important control on the marketing surfaces - the hero CTA
   on home, work, services and all four property pages - was illegible, and
   only in its resting state: `.btn-glow:hover` ties `.deep a:hover` on
   specificity and wins on source order, so the label appeared on hover. With
   --deep-900 restored the same label measures 11.13 / 5.47 / 4.75:1.
   These selectors are (0,2,0) so they clear `.deep a` for good. */
.deep .btn-glow, .deep .btn-glow:hover { color: var(--deep-900); }
.deep .btn-primary, .deep .btn-primary:hover { color: #fff; }

/* --- Icons -------------------------------------------------------------
   Inline SVG, sized by CSS, coloured by currentColor. No icon font: the
   estate audit found assemblys.site rendering every icon as blank space
   because it referenced Bootstrap Icons without ever loading the stylesheet.
   An inline SVG cannot fail that way. ----------------------------------- */
.icon { width: var(--icon-md); height: var(--icon-md); flex: none; display: inline-block; vertical-align: -0.15em; }
.icon-sm { width: var(--icon-sm); height: var(--icon-sm); }
.icon-lg { width: var(--icon-lg); height: var(--icon-lg); }
.icon-xl { width: var(--icon-xl); height: var(--icon-xl); }
.icon-accent { color: var(--lum-cyan); }

/* Icon in a bordered tile - the feature-card treatment.

   Light is the DEFAULT and the deep band is the override, not the other way
   round. The rule used to be `.section:not(.deep) .icon-tile`, which gave a
   tile its light colours only if it happened to sit inside an element carrying
   `.section`. A tile on a light page outside a `.section` - or inside a shared
   component that cannot know where it will be rendered, which is exactly the
   case for ExternalLoginPicker - fell through to the glass values instead:
   rgba(255,255,255,0.04) on white paper with a #22D3EE glyph, i.e. an
   invisible box around an icon at roughly 1.8:1 contrast. Defaulting to light
   and overriding under `.deep` cannot fail that way, because a deep band is
   always an ancestor of the tiles that want the glass treatment. */
.icon-tile {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border-radius: var(--radius-lg);
  border: 1px solid var(--rule);
  background: var(--brand-050);
  color: var(--brand-700);
  margin-bottom: var(--space-3);
}
.deep .icon-tile {
  border-color: var(--glass-border); background: var(--glass-bg); color: var(--lum-cyan);
}

/* --- Feature grid: icon + heading + line. Previously banned; now the
       requested treatment for marketing surfaces. --------------------------- */
.feature { display: flex; flex-direction: column; }
.feature h3 { font-size: var(--fs-19); margin-bottom: var(--space-2); }
.feature p  { margin-bottom: 0; font-size: var(--fs-14); }

/* --- Stat on a deep band ------------------------------------------------ */
.deep .stat { border-left-color: var(--lum-cyan); }
.deep .stat .stat-value { color: var(--on-deep-900); }
.deep .stat .stat-label { color: var(--on-deep-400); }

/* --- Focus ring on a deep band -----------------------------------------
   The global ring is --brand-600 #2563A8, which measures 6.12:1 on paper but
   only 1.90:1 against the composite deep ground - well under the 3:1 SC 1.4.11
   requires, and in practice a keyboard user tabbing through the hero CTAs, the
   glass-panel links and the property cards could not see where focus was.
   --lum-cyan measures 6.05:1 on the same ground.

   outline-offset keeps a 2px gap of the band between the control and the ring,
   so the ring's adjacent colour is the deep ground on both sides. That matters
   for .btn-glow, whose fill is itself cyan: without the gap the ring would sit
   cyan-on-cyan. Do not remove the offset. */
.deep :focus-visible { outline-color: var(--lum-cyan); }

/* --- Chips, tiers and placeholders on deep -------------------------------
   Every one of these takes its colour from a token tuned for white paper, and
   every one of them failed on a deep band before this block existed. Measured
   against the composite ground, worst case:

     .chip-live / .chip-verified   --verify     #0F766E   1.80:1
     .chip-forthcoming/provisional --warn       #B45309   1.96:1
     .chip-authenticated           --brand-700  #1B3A6B   1.01:1  (invisible)
     .chip-illustrative            --ink-500    #475569   1.30:1
     .chip-ocr                     --accent-600 #9A3412   1.35:1
     .chip-error                   --bad        #B91C1C   1.52:1
     .tier label                   --ink-500    #475569   1.30:1
     .tbc                          --warn       #B45309   1.96:1

   Several pages had already worked around this by rebinding --verify, --warn
   and --brand-700 in an inline style on the section (Group/Index, the four
   property pages, Work). Those rebinds are now redundant but harmless, and
   they are left in place. The home page had NO rebind, so all four lifecycle
   chips in its group grid were failing, .chip-authenticated invisibly.
   Fixing it here rather than page by page means the next deep band gets it
   right without anyone remembering to. Replacements measure 5.4-6.6:1. */
.deep .chip { border-color: currentColor; }
.deep .chip-unknown       { color: var(--on-deep-400); }
.deep .chip-verified,
.deep .chip-live          { color: var(--on-deep-ok); }
.deep .chip-provisional,
.deep .chip-forthcoming   { color: var(--on-deep-warn); }
.deep .chip-ocr           { color: var(--on-deep-ocr); }
.deep .chip-error         { color: var(--on-deep-bad); }
.deep .chip-authenticated { color: var(--on-deep-info); }
.deep .chip-illustrative  { color: var(--on-deep-600); }

/* The dot keeps its tier hue - the six tier colours are all light enough to
   read on deep - but the label beside it must leave --ink-500 behind. */
.deep .tier { color: var(--on-deep-600); }

/* An unconfirmed value must stay conspicuous on a deep band, not fade into it. */
.deep .tbc { color: var(--on-deep-warn); }

/* An outlined control on a deep band. --glass-border is 1.28:1 against its own
   ground: right for a decorative panel edge, wrong for the boundary of a
   button. Pages set these three properties inline; the rule is here so that a
   new deep band gets a legible secondary button without repeating them. */
.deep .btn-secondary {
  background: transparent;
  color: var(--on-deep-900);
  border-color: var(--deep-control-border);
}
.deep .btn-secondary:hover {
  background: var(--glass-bg);
  color: var(--on-deep-900);
  border-color: var(--lum-cyan);
}

/* --- Decorative SVG figure slot ---------------------------------------- */
.figure-plate { width: 100%; height: auto; display: block; }
.figure-caption { font-size: var(--fs-13); color: var(--ink-400); margin-top: var(--space-2); }
.deep .figure-caption { color: var(--on-deep-400); }

/* --- Motion: opt out for users who ask ---------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; }
}

/* Deep bands must not burn ink on paper. */
@media print {
  .deep { background: #fff !important; color: #000 !important; }
  .deep::before { display: none !important; }
  .deep h1, .deep h2, .deep h3 { color: #000 !important; }
  .grad-text { color: #000 !important; -webkit-text-fill-color: #000 !important; }
  .glass { border-color: #999 !important; background: none !important; }
  /* The band is now white, so the glass tile would print a cyan glyph inside an
     invisible box. Send it back to the light treatment. */
  .deep .icon-tile { border-color: #999 !important; background: none !important; color: #000 !important; }

  /* Everything else this stylesheet lightens for a dark ground has to come back
     for paper, or it prints as a pale ghost on white. `a { color: #000 }` in the
     earlier print block loses to `.deep a` on specificity (0,1,1 beats 0,0,1),
     so a printed link inside a deep band was still cyan at 1.8:1 on white, and
     the deep chip and .tbc colours were 1.7-2.3:1. These are the same
     procurement pages that get printed into tender packs. */
  .deep a, .deep .eyebrow { color: #000 !important; }
  .deep .chip, .deep .tier, .deep .tbc,
  .deep .stat .stat-value, .deep .stat .stat-label,
  .deep .figure-caption { color: #000 !important; }
  .deep .stat { border-left-color: #000 !important; }
  .deep .btn-secondary { color: #000 !important; border-color: #666 !important; }
  .btn-glow { background: none !important; color: #000 !important;
              border: 1px solid #666 !important; box-shadow: none !important; }
  .deep-rule { background: #999 !important; }
}
