/* ══════════════════════════════════════════════════════
   Frontera Facts — Styles
   ══════════════════════════════════════════════════════ */

:root {
    --sand: #F5F0E8;
    --sand-dark: #E8E0D0;
    --ink: #2C2418;
    --ink-soft: #5C5040;
    --color-text-tertiary: #8A8275;
    --terracotta: #C4654A;
    --terracotta-light: #E8906E;
    --sage: #7A9A6D;
    --sage-light: #A4C496;
    --sky: #6B9DB8;
    --sky-light: #A0CBE0;
    --ochre: #D4A843;
    --ochre-light: #E8C96A;
    --warmwhite: #FDFBF7;
    --radius: 12px;
    --radius-lg: 20px;
    --brick: #A8342A;
    --navy: #2A4159;
    --navy-soft: #EAEEF3;
    --ffa-ink-dark: #1D1A16;      /* the dark ground */
    --ffa-card-dark: #2A2621;     /* cards on the dark ground */
    --accent: #3D6B85;            /* links and primary marks; same value as --issue-accent */
    --ffa-radius-card: 28px;
    --ffa-radius-media: 36px;
    /* .site-nav declares height: 48px (the mockup's .nav, docs/design/apple/src/desk.css),
       so the bar is no longer padding-derived and no longer wraps: one value at every
       width, no breakpoint overrides. This feeds every scroll-margin-top and sticky
       `top` below — a value that does not match the bar hides anchor targets under it. */
    --nav-h: 48px;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

body {
    font-family: 'DM Sans', sans-serif;
    background: var(--warmwhite);
    color: var(--ink);
    line-height: 1.65;
    font-size: 17px;
    -webkit-font-smoothing: antialiased;
}

a { color: inherit; }


/* ── Framework: load-data states ── */

.load-data.loading { opacity: 0.5; pointer-events: none; transition: opacity 0.3s; }
.load-data.loaded { opacity: 1; transition: opacity 0.3s; }
.load-data.load-error { border-left: 3px solid var(--terracotta); }
.load-data:not(.loaded):not(.loading):not(.cached) [class*="view-"] { visibility: hidden; }

/* Hide .template elements */
.template { display: none !important; }


/* ── Navigation ── */

/* The mockup's .nav (docs/design/apple/src/desk.css): a 48px bar whose items —
   logo, the four labels, the pill, the language pair — sit in one centred row
   at a uniform 44px gap. position/top/z-index are the site's own: the mockup
   artboard does not scroll, so it never had to say the bar is sticky. */
.site-nav {
    height: 48px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 44px;
    font-size: 13px;
    color: var(--ink-soft);
    background: rgba(253,251,247,.9);
    border-bottom: 1px solid rgba(44,36,24,.08);
    position: sticky;
    top: 0;
    /* 1100, not 100 (round 3, 2026-09-23): Leaflet paints its panes at 400 and its
       controls at 1000, and the home's and the neighborhood's map mounts open no
       stacking context of their own, so at 100 a map scrolled under the bar painted
       OVER it — and would have painted over the phone menu that hangs off the bar.
       Under the map bar's 1200 (.site-nav--map below) and the picker's 3000. */
    z-index: 1100;
}

/* 26px tall, and 96px wide from the SVG's own 506:137.43 (26 × 506/137.43).
   The "FronteraFacts" text is the no-CSS fallback and is painted transparent;
   with the box now a fixed size it would otherwise spill past 96px and count
   toward the document's scroll width, which is the one thing a nav must not
   do (see the .admin-nav note in css/admin.css:24-29). */
.nav-logo {
    background:transparent url(/images/frontera-facts.svg) center center no-repeat;
    background-size:contain;
    font-family: 'DM Serif Display', serif;
    font-size: 22px;
    color:#fff0;
    display:block;
    width: 96px;
    height: 26px;
    overflow: hidden;
    flex: none;
    text-decoration: none;
    letter-spacing: -0.5px;
}

/* The list is a plain segment of the centred row, so no auto margin: the same
   44px gap runs between its items as between it and its neighbours. */
.nav-links {
    display: flex;
    gap: 44px;
    list-style: none;
}
/* The mockup's labels are sentence case at 13px — no uppercasing, no tracking. */
.nav-links a {
    text-decoration: none;
    color: var(--ink-soft);
    font-size: 13px;
    font-weight: 500;
    white-space: nowrap;
    transition: color 0.2s;
}
.nav-links a:hover { color: var(--terracotta); }

/* House rule 5: one black pill per page, and this is it. Mockup: .nav .cta.
   Both colour and weight need !important: .nav-links a (0,1,1) outranks
   .nav-cta (0,1,0), so a plain declaration here loses to the list rule —
   which is why the pre-Apple-way version carried font-size: 13px !important
   for the same reason. */
.nav-cta {
    background: var(--ink);
    color: var(--warmwhite) !important;
    border-radius: 999px;
    padding: 6px 14px;
    font-weight: 600 !important;
}
.nav-cta:hover { background: var(--ffa-ink-dark); color: var(--warmwhite) !important; }

/* Nav pills (sitewide) — the mockup's trailing "EN · ES", which is plain text
   at 13px in #8A8275 (= --color-text-tertiary). Two real links here, so they
   keep pill padding as the hit target, but no fill: the black Get Updates pill
   is the page's only one (house rule 5). The current language is marked the way
   the mockup marks the current nav item — #2C2418 at weight 600.
   These sat at the end of the file, after the responsive blocks — equal
   specificity and later, so every `.nav-lang a` override in a media query below
   was dead. They belong here, with the rest of the bar. */
.nav-lang { display: flex; align-items: center; gap: 4px; }
.nav-lang a { padding: 5px 12px; border-radius: 999px; font-size: 13px; font-weight: 500; text-decoration: none; color: var(--color-text-tertiary); }
.nav-lang a:hover { color: var(--terracotta); }
.nav-lang a.active { color: var(--ink); font-weight: 600; }
.nav-lang a.active:hover { color: var(--ink); }

/* ── Map mode (page/template.header.php $nav_mode === 'map'; only /map-2 sets it) ──
   The bar holds the page's own control (the measure pill + address search, .ffa-navbar,
   styled in css/map-2.css) between the logo and a menu button; the five links and EN/ES
   live in the menu. 56px, not 48: the pill's 34px icon and the field's 40px row need it,
   and the map page overrides --nav-h to match (css/map-2.css .ffa-map-body). */
/* Doubled selector on purpose: the ≤768px and ≤600px blocks further down restate
   .site-nav's gap and padding at (0,1,0), and this block sits ABOVE them in the file.
   (0,2,0) wins at every width without moving the block. z-index 1200 (not the bar's
   100): the map's panes, corners, cards and panel stack at 400–1100 and nothing on
   the map page opens a stacking context under them, so the menu and the search's
   result list — descendants of this bar — would paint under the map otherwise.
   #ffa-picker is 3000 and still covers the bar. */
.site-nav.site-nav--map { height: 56px; justify-content: space-between; gap: 16px; padding: 0 16px; z-index: 1200; }
.site-nav.site-nav--map .nav-slot { flex: 1 1 auto; min-width: 0; display: flex; justify-content: center; }

.nav-menu-btn {
    flex: none; width: 40px; height: 40px; border: 1px solid rgba(44,36,24,.14); border-radius: 12px;
    background: #FFFFFF; cursor: pointer; display: flex; align-items: center; justify-content: center;
    color: var(--ink);
}
.nav-menu-btn:hover { background: var(--sand); }
.nav-menu-bars, .nav-menu-bars::before, .nav-menu-bars::after {
    display: block; width: 18px; height: 2px; background: currentColor; border-radius: 2px; content: "";
    position: relative;
}
.nav-menu-bars::before { position: absolute; top: -6px; }
.nav-menu-bars::after  { position: absolute; top: 6px; }

.nav-menu {
    position: absolute; top: calc(100% + 8px); right: 16px; z-index: 120;
    min-width: 220px; background: #FFFFFF; border-radius: 16px;
    box-shadow: 0 12px 40px rgba(44,36,24,.18); padding: 8px;
}
.nav-menu[hidden] { display: none; }
.nav-menu-links { list-style: none; display: flex; flex-direction: column; gap: 2px; margin: 0 0 8px; }
.nav-menu-links a { display: block; padding: 10px 12px; border-radius: 10px; text-decoration: none; color: var(--ink); font-size: 14px; font-weight: 500; }
.nav-menu-links a:hover { background: var(--sand); }
/* The Get Updates pill keeps its pill: .nav-menu-links a (0,1,1) would otherwise
   square its corners and its :hover (0,2,1) would put sand under the !important
   warmwhite text. */
.nav-menu-links .nav-cta { display: inline-block; margin: 6px 12px 4px; border-radius: 999px; }
.nav-menu-links .nav-cta:hover { background: var(--ffa-ink-dark); }
.nav-menu .nav-lang { padding: 4px 8px 4px; border-top: 1px solid rgba(44,36,24,.08); padding-top: 10px; }

/* Standard pages carry the same button and menu (round 3, 2026-09-23) but show them
   only on a phone (the ≤600px nav block further down); the map page shows its own at
   every width. The menu is hidden here too, so one left open on a phone does not stay
   open when the window widens past 600px. */
.site-nav:not(.site-nav--map) .nav-menu-btn { display: none; }
.site-nav:not(.site-nav--map) .nav-menu { display: none; }

@media (max-width: 600px) {
    /* Two rows: logo + menu button, then the control full width (css/map-2.css sizes it
       as a two-row card here, the measure over the address field: 90px).
       48 (the logo row: 26 + 11 + 11; the 40px button + 4 + 4 is the same 48) + 8 (row gap)
       + 90 (the card) + 10 (bottom padding) + 1 (the border-bottom, height: auto under
       border-box) = 157px, which css/map-2.css .ffa-map-body sets as --nav-h at this width
       (measured 157 at 375 wide, 2026-09-23). */
    .site-nav.site-nav--map { height: auto; flex-wrap: wrap; padding: 0 12px 10px; gap: 8px 12px; min-height: 48px; }
    .site-nav.site-nav--map .nav-logo { margin: 11px 0; }
    .site-nav.site-nav--map .nav-menu-btn { margin: 4px 0; }
    .site-nav.site-nav--map .nav-slot { flex-basis: 100%; order: 3; }
    .nav-menu { right: 12px; left: 12px; }
}


/* ── Hero ── */

.hero {
    padding: 80px 40px 60px;
    max-width: 900px;
    margin: 0 auto;
    text-align: center;
}

.hero-badge {
    display: inline-block;
    background: var(--sand);
    color: var(--ink-soft);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 2px;
    text-transform: uppercase;
    padding: 6px 16px;
    border-radius: 20px;
    margin-bottom: 28px;
}

.hero h1 {
    font-family: 'DM Serif Display', serif;
    font-size: 52px;
    line-height: 1.15;
    color: var(--ink);
    margin-bottom: 24px;
    letter-spacing: -1px;
}
.hero h1 em {
    color: var(--terracotta);
    font-style: italic;
}

.hero > p {
    font-size: 20px;
    color: var(--ink-soft);
    max-width: 640px;
    margin: 0 auto 36px;
    font-weight: 300;
    line-height: 1.7;
}

.hero-topics {
    display: flex;
    justify-content: center;
    gap: 12px;
    flex-wrap: wrap;
}

.topic-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: var(--sand);
    color: var(--ink-soft);
    padding: 8px 18px;
    border-radius: 24px;
    font-size: 14px;
    font-weight: 400;
    cursor: pointer;
    transition: all 0.2s;
    border: 1px solid transparent;
    text-decoration: none;
}
.topic-pill:hover {
    background: white;
    border-color: var(--sand-dark);
    color: var(--ink);
}

.dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    display: inline-block;
}
.dot-water { background: var(--sky); }
.dot-air { background: var(--sage); }
.dot-health { background: var(--terracotta); }
.dot-heat { background: #D47A3A; }
.dot-growth { background: var(--ochre); }
.dot-equity { background: #8B6DB8; }


/* ── Container ── */

.container {
    max-width: 1100px;
    margin: 0 auto;
    padding: 0 40px;
}


/* ── Section headers ── */

.section-header {
    padding: 48px 0 32px;
}
.section-header h2 {
    font-family: 'DM Serif Display', serif;
    font-size: 36px;
    line-height: 1.2;
    margin-bottom: 12px;
}
.section-header p {
    font-size: 17px;
    color: var(--ink-soft);
    max-width: 560px;
    font-weight: 300;
}


/* ── Featured Vignette ── */

.featured-vignette {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0;
    background: var(--ink);
    border-radius: var(--radius-lg);
    overflow: hidden;
    margin-bottom: 40px;
    min-height: 380px;
}

.featured-visual {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 40px;
}

.featured-chart-area {
    width: 100%;
}
.featured-chart-area svg {
    width: 100%;
    height: auto;
}
.featured-chart-area .placeholder-chart-svg svg {
    width: 100%;
    height: auto;
    max-height: 200px;
}

.featured-body {
    padding: 48px 40px;
    display: flex;
    flex-direction: column;
    justify-content: center;
}

.featured-topic-tag {
    display: inline-block;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 2px;
    text-transform: uppercase;
    margin-bottom: 16px;
}

.featured-body h2 {
    font-family: 'DM Serif Display', serif;
    font-size: 30px;
    color: white;
    line-height: 1.25;
    margin-bottom: 16px;
}

.featured-body p {
    color: rgba(255,255,255,0.6);
    font-size: 16px;
    font-weight: 300;
    line-height: 1.7;
    margin-bottom: 24px;
}

.read-link {
    color: var(--terracotta-light);
    text-decoration: none;
    font-weight: 500;
    font-size: 15px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    transition: color 0.2s;
}
.read-link:hover { color: var(--terracotta); }


/* ── Vignette Card Grid ── */

.vignettes-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: 24px;
    padding-bottom: 48px;
}

.vignette-card {
    background: white;
    border-radius: var(--radius-lg);
    overflow: hidden;
    border: 1px solid var(--sand-dark);
    transition: transform 0.25s, box-shadow 0.25s;
    cursor: pointer;
    position: relative;
    text-decoration: none;
    color: inherit;
    display: block;
}
.vignette-card:hover {
    transform: translateY(-4px);
    box-shadow: 0 12px 40px rgba(44,36,24,0.08);
}

.card-visual {
    height: 200px;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    overflow: hidden;
    padding: 20px;
}

.card-chart {
    width: 85%;
    height: auto;
}
.card-chart svg {
    width: 100%;
    height: auto;
}

.card-topic-badge {
    position: absolute;
    top: 14px;
    left: 14px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 1px;
    text-transform: uppercase;
    padding: 4px 12px;
    border-radius: 12px;
    color: white;
    z-index: 2;
}

.card-body {
    padding: 20px 24px 24px;
}
.card-body h3 {
    font-family: 'DM Serif Display', serif;
    font-size: 22px;
    line-height: 1.3;
    margin-bottom: 10px;
    color: var(--ink);
}
.card-body p {
    font-size: 15px;
    color: var(--ink-soft);
    line-height: 1.6;
    font-weight: 300;
}

.card-stat {
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin-top: 16px;
    padding-top: 16px;
    border-top: 1px solid var(--sand);
}
/* scoped to .card-stat: bare .stat-number also appears on admin dashboards
   (admin.css owns those) and in the issue data modules (sans by design) */
.card-stat .stat-number {
    font-family: 'DM Serif Display', serif;
    font-size: 28px;
    color: var(--terracotta);
    line-height: 1;
}
.stat-label {
    font-size: 13px;
    color: var(--ink-soft);
}


/* ── Vignette Detail Page ── */

.vignette-detail {
    max-width: 720px;
    margin: 0 auto;
    padding: 60px 40px 80px;
}

.back-link {
    color: var(--ink-soft);
    text-decoration: none;
    font-size: 14px;
    font-weight: 500;
    margin-bottom: 32px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    transition: color 0.2s;
}
.back-link:hover { color: var(--ink); }

.detail-topic {
    display: inline-block;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 2px;
    text-transform: uppercase;
    padding: 5px 14px;
    border-radius: 12px;
    margin-bottom: 20px;
    margin-top: 20px;
    color: white;
}

.vignette-detail h1 {
    font-family: 'DM Serif Display', serif;
    font-size: 40px;
    line-height: 1.2;
    margin-bottom: 20px;
}

.detail-intro {
    font-size: 19px;
    color: var(--ink-soft);
    font-weight: 300;
    line-height: 1.7;
    margin-bottom: 36px;
}

.big-stat-block {
    background: var(--sand);
    border-radius: var(--radius-lg);
    padding: 40px;
    text-align: center;
    margin: 36px 0;
}
.big-number {
    font-family: 'DM Serif Display', serif;
    font-size: 72px;
    line-height: 1;
    margin-bottom: 8px;
}
.big-label {
    font-size: 16px;
    color: var(--ink-soft);
    font-weight: 300;
}
.big-source {
    font-size: 12px;
    color: #AAA;
    margin-top: 12px;
}

.detail-prose {
    font-size: 17px;
    line-height: 1.75;
    color: var(--ink);
    margin: 24px 0;
}
.detail-prose p { margin-bottom: 16px; }
.detail-prose p:last-child { margin-bottom: 0; }
.detail-prose strong { font-weight: 600; }

.detail-chart-area {
    margin: 32px 0;
}

.chart-placeholder {
    background: var(--sand);
    border-radius: var(--radius);
    height: 280px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--ink-soft);
    font-size: 14px;
    border: 1px dashed var(--sand-dark);
    padding: 20px;
    text-align: center;
}

.why-it-matters {
    background: var(--ink);
    color: white;
    border-radius: var(--radius-lg);
    padding: 36px 40px;
    margin: 40px 0;
}
.why-it-matters h3 {
    font-family: 'DM Serif Display', serif;
    font-size: 24px;
    margin-bottom: 12px;
}
.why-it-matters p {
    font-weight: 300;
    line-height: 1.7;
    color: rgba(255,255,255,0.75);
}

/* ── Where this comes up ── */

.where-it-comes-up {
    background: var(--sand);
    border-radius: var(--radius-lg);
    padding: 32px 36px;
    margin: 32px 0;
}
.where-it-comes-up h3 {
    font-family: 'DM Serif Display', serif;
    font-size: 22px;
    margin-bottom: 16px;
    color: var(--ink);
}

.comes-up-list {
    display: flex;
    flex-direction: column;
    gap: 0;
}

.comes-up-item {
    padding: 10px 0 10px 20px;
    border-left: 2px solid var(--sand-dark);
    font-size: 15px;
    color: var(--ink-soft);
    line-height: 1.5;
    font-weight: 400;
    transition: border-color 0.2s;
}
.comes-up-item:hover {
    border-left-color: var(--terracotta);
    color: var(--ink);
}


/* ── Who uses this ── */

.who-uses-this {
    margin: 32px 0;
}
.who-uses-this h3 {
    font-family: 'DM Serif Display', serif;
    font-size: 22px;
    margin-bottom: 16px;
    color: var(--ink);
}

.who-uses-list {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.who-uses-item {
    background: white;
    border: 1px solid var(--sand-dark);
    border-radius: var(--radius);
    padding: 20px 24px;
}
.who-uses-item p {
    font-size: 15px;
    color: var(--ink-soft);
    line-height: 1.65;
    font-weight: 300;
    font-style: italic;
}


.detail-share {
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 32px 0;







    padding: 20px 0;
    border-top: 1px solid var(--sand-dark);
}
.detail-share span {
    font-size: 13px;
    color: var(--ink-soft);
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 1px;
}

.share-btn {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: var(--sand);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 14px;
    cursor: pointer;
    transition: background 0.2s;
    text-decoration: none;
    color: var(--ink-soft);
}
.share-btn:hover { background: var(--sand-dark); }


/* ── Card: Used-by tags ── */

.card-used-by {
    margin-top: 12px;
    font-size: 13px;
    line-height: 1.5;
}
.used-by-label {
    color: #B0A898;
    font-weight: 500;
    font-size: 11px;
    letter-spacing: 0.5px;
    text-transform: uppercase;
    margin-right: 4px;
}
.used-by-tags {
    color: var(--ink-soft);
    font-weight: 300;
}


/* ── Related Stories ── */

.related-section {
    max-width: 720px;
    margin: 0 auto;
    padding: 0 40px 80px;
}
.related-section h3 {
    font-family: 'DM Serif Display', serif;
    font-size: 24px;
    margin-bottom: 20px;
}

.related-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 20px;
}

.related-card {
    background: white;
    border: 1px solid var(--sand-dark);
    border-radius: var(--radius);
    padding: 20px;
    cursor: pointer;
    transition: all 0.2s;
    text-decoration: none;
    color: inherit;
    display: block;
}
.related-card:hover { border-color: var(--terracotta-light); }

.r-topic {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 1px;
    text-transform: uppercase;
    margin-bottom: 8px;
}
.related-card h4 {
    font-family: 'DM Serif Display', serif;
    font-size: 18px;
    line-height: 1.3;
}


/* ── Pullquote (About page) ── */

.pullquote {
    background: var(--sand);
    border-radius: var(--radius-lg);
    padding: 32px 36px;
    margin: 36px 0;
}
.pullquote p {
    font-family: 'DM Serif Display', serif;
    font-size: 22px;
    line-height: 1.5;
    color: var(--ink);
}
.pullquote em {
    color: var(--terracotta);
}


/* ── Feedback CTA ── */

.feedback-block {
    background: linear-gradient(135deg, var(--sand) 0%, var(--sand-dark) 100%);
    border-radius: var(--radius-lg);
    padding: 56px 48px;
    text-align: center;
    margin: 48px 0 64px;
}
.feedback-block h2 {
    font-family: 'DM Serif Display', serif;
    font-size: 32px;
    margin-bottom: 12px;
}
.feedback-block p {
    color: var(--ink-soft);
    font-weight: 300;
    font-size: 17px;
    max-width: 480px;
    margin: 0 auto 28px;
    line-height: 1.6;
}

.input-row {
    display: flex;
    max-width: 440px;
    margin: 0 auto;
    gap: 12px;
}
.input-row input {
    flex: 1;
    padding: 14px 20px;
    border-radius: 28px;
    border: 1px solid var(--sand-dark);
    font-family: 'DM Sans', sans-serif;
    font-size: 15px;
    background: white;
    outline: none;
    transition: border-color 0.2s;
}

/* ── Audience hero: two-column + photo ──────────────────── */
.audience-hero-inner { display: flex; gap: 32px; align-items: flex-start; }
.audience-hero-text { flex: 1 1 0; min-width: 0; }
.audience-hero-media { flex: 0 0 38%; margin: 0; }
.audience-hero-img { width: 100%; height: auto; border-radius: 10px; display: block; }
.audience-photo-credit { font-size: 11px; color: var(--ink-soft, #8A8275); margin-top: 6px; }
.audience-photo-credit a { color: inherit; }

/* ── Ways to take action ────────────────────────────────── */
.audience-actions { margin: 22px 0; padding: 16px 0 0; border-top: 1px solid var(--sand-dark, #E8E0D0); }
.audience-actions-label { font-size: 12px; font-weight: 600; letter-spacing: 1px; text-transform: uppercase; color: var(--ink-soft, #6b6256); margin: 0 0 12px; }
.audience-actions-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 18px; }

.aa-title { display: block; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--ink, #2C2418); margin-bottom: 6px; }
.aa-list { list-style: none; margin: 0; padding: 0; }
.aa-item { font-size: 13px; line-height: 1.4; margin-bottom: 6px; }
.aa-item a { text-decoration: none; border-bottom: 1px solid currentColor; }
.aa-scope { display: inline-block; font-size: 9px; text-transform: uppercase; letter-spacing: .04em; padding: 1px 5px; border-radius: 8px; margin-left: 5px; vertical-align: middle; }
.aa-scope--inside { background: #e7eef0; color: #355; }
.aa-scope--outside { background: #efe9dd; color: #6b5a32; }

/* ── Stat position-bar (data graphic) ───────────────────── */
.audience-stat-bar { position: relative; height: 6px; border-radius: 3px; margin: 8px 0 6px;
    background: linear-gradient(to right, #D6E8F7, #A8CCE8, #7BAFE0, #4A8FD1, #2B6CB0, #1A3A5C); }
.asb-marker { position: absolute; top: -3px; width: 3px; height: 12px; border-radius: 1px; background: var(--ink, #2C2418); transform: translateX(-1.5px); }
.asb-median { position: absolute; top: -1px; width: 1px; height: 8px; background: var(--ink-soft, #6b6256); opacity: .7; }

/* ── Mobile ─────────────────────────────────────────────── */
@media (max-width: 768px) {
  .audience-hero-inner { flex-direction: column; }
  .audience-hero-media { flex-basis: auto; width: 100%; }
}
.input-row input:focus { border-color: var(--terracotta); }
.input-row button {
    padding: 14px 28px;
    border-radius: 28px;
    border: none;
    background: var(--terracotta);
    color: white;
    font-family: 'DM Sans', sans-serif;
    font-weight: 600;
    font-size: 15px;
    cursor: pointer;
    transition: background 0.2s;
}
.input-row button:hover { background: #B55A42; }

/* ── Audience landing pages ─────────────────────────────── */
.audience-hero { border-top: 4px solid #888; padding: 48px 0 32px; background: var(--sand, #F7F3EC); }
.audience-eyebrow { font-size: 12px; font-weight: 600; letter-spacing: 1px; text-transform: uppercase; color: var(--ink-soft, #6b6256); margin: 0 0 8px; }
.audience-blurb { font-size: 1.4rem; line-height: 1.4; max-width: 40ch; margin: 0 0 20px; color: var(--ink, #2C2418); }
.audience-cta { display: inline-block; padding: 10px 18px; border-radius: 6px; background: var(--ink, #2C2418); color: #fff; text-decoration: none; font-weight: 600; }
.audience-section { margin: 40px 0; }
.audience-h2 { font-size: 1.1rem; text-transform: uppercase; letter-spacing: 1px; color: var(--ink-soft, #6b6256); margin: 0 0 16px; }
.audience-findings { display: grid; gap: 16px; }
.audience-finding { background: #fff; border: 1px solid var(--sand-dark, #E8E0D0); border-radius: 8px; padding: 20px; }
.audience-finding-title { margin: 0 0 8px; font-size: 1.25rem; }
.audience-finding-foot { display: flex; justify-content: space-between; align-items: baseline; margin-top: 12px; gap: 12px; flex-wrap: wrap; }
.audience-source { font-size: 12px; color: var(--ink-soft, #8A8275); }
.audience-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 16px; }
.audience-stat { background: #fff; border: 1px solid var(--sand-dark, #E8E0D0); border-radius: 8px; padding: 18px; }
.audience-stat-value { font-family: 'DM Serif Display', serif; font-size: 2rem; line-height: 1; color: var(--ink, #2C2418); }
.audience-stat-label { font-weight: 600; margin: 6px 0 2px; }
.audience-stat-detail { font-size: 13px; color: var(--ink-soft, #6b6256); }
.audience-stat-link, .audience-finding-link { display: inline-block; margin-top: 8px; font-size: 13px; font-weight: 600; text-decoration: none; }
.audience-related { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px; }
.audience-related-card { display: block; padding: 14px; border: 1px solid var(--sand-dark, #E8E0D0); border-radius: 8px; text-decoration: none; color: var(--ink, #2C2418); }
.audience-related-topic { display: block; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .5px; margin-bottom: 4px; }


/* ── Footer ── */

/* The mockup's .foot (docs/design/apple/src/desk.css): no dark band and no
   centred column — a 12px rule-topped row on the page's own ground, place on
   the left, the onward links on the right. css/ffa.css's .ffa-foot is the same
   grammar; this is the site chrome's copy, so every page gets it whether or not
   it has been converted to the ffa- vocabulary yet. */
.site-footer {
    background: var(--warmwhite);
    color: var(--color-text-tertiary);
    font-size: 12px;
    padding: 0 40px;
}
/* 980px is the mockup's .wrap, and the rule spans exactly that. */
.footer-inner {
    width: 980px;
    max-width: 100%;
    margin: 0 auto;
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 24px;
    padding: 24px 0;
    border-top: 1px solid rgba(44,36,24,.1);
}

/* Left: the mark and where we are — the mockup's inline flex/12px gap. */
.footer-place { display: flex; align-items: center; gap: 12px; }
/* The ground is warm white now, so this is the dark mark, not the light one.
   22px tall, 81px wide from the same 506:137.43; overflow for the same reason
   as .nav-logo above. */
.site-footer .footer-logo {
    background:transparent url(/images/frontera-facts.svg) center center no-repeat;
    background-size:contain;
    font-family: 'DM Serif Display', serif;
    font-size: 20px;
    color:#fff0;
    display:block;
    width: 81px;
    height: 22px;
    overflow: hidden;
    flex: none;
}

/* Right: the link row, then where the numbers come from. */
.footer-right { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; text-align: right; }
.site-footer a { color: inherit; text-decoration: none; }
.site-footer a:hover { color: var(--ink); }


/* ── Responsive ── */

@media (max-width: 768px) {

    .hero { padding: 48px 20px 40px; }
    .hero h1 { font-size: 34px; }

    .featured-vignette { grid-template-columns: 1fr; }
    .featured-visual { padding: 24px; }
    .featured-body { padding: 28px 24px 32px; }
    .featured-body h2 { font-size: 24px; }

    .vignettes-grid { grid-template-columns: 1fr; }
    .related-grid { grid-template-columns: 1fr; }

    /* The bar stays ONE 48px row at every width — it no longer wraps, so --nav-h
       needs no override here and the anchor offsets stay exact. All that changes
       is the gap: logo + four labels + the pill + EN/ES need 684px at the 44px
       desktop gap, more than a 768px viewport has once gutters are counted. */
    .site-nav { gap: 20px; padding: 0 20px; }
    .nav-links { gap: 20px; }
    .nav-links a { font-size: 13px; }
    .nav-lang a { padding: 4px 10px; }
    .container { padding: 0 20px; }
    .site-footer { padding: 0 24px; }

    .vignette-detail { padding: 40px 20px 60px; }
    .vignette-detail h1 { font-size: 30px; }
    .related-section { padding: 0 20px 60px; }

    .big-number { font-size: 52px; }
    .big-stat-block { padding: 28px 20px; }

    .why-it-matters { padding: 28px 24px; }

    .feedback-block { padding: 36px 24px; }
    .input-row { flex-direction: column; }
}

/* Phone nav (round 3, 2026-09-23): one 48px row, the logo left and the menu button
   right. The four labels no longer squeeze into a scrolling row at 12px and EN/ES
   leave the bar: both are in the menu (page/template.header.php prints it on every
   page), with the Get Updates pill back — it had dropped from the row for want of
   room. `> .nav-links ~ .nav-lang` is the bar's own pair, and ONLY where a row of links
   precedes it: the shared-map visitor's nav on the frozen /map (a logo span and EN/ES,
   no links, no menu — ffa/t18 pins its bytes) must keep its EN/ES, or a phone would
   leave those visitors with no way to switch language (the round-3 whole-diff review).
   The menu's own pair (.nav-menu .nav-lang) is untouched by either rule.
   The bar's height is declared (48px), so --nav-h needs no override here. */
@media (max-width: 600px) {
    .site-nav { justify-content: space-between; gap: 10px; padding: 0 12px; }
    .site-nav:not(.site-nav--map) .nav-links,
    .site-nav:not(.site-nav--map) > .nav-links ~ .nav-lang { display: none; }
    .site-nav:not(.site-nav--map) .nav-menu-btn { display: flex; margin: 4px 0; }
    .site-nav:not(.site-nav--map) .nav-menu:not([hidden]) { display: block; }
    .nav-lang a { padding: 4px 6px; font-size: 12px; }   /* the menu's EN/ES, every page (kept from before: the map page's menu already looked like this) */

    /* The foot stacks: place over links, both left-aligned. */
    .footer-inner { flex-direction: column; align-items: flex-start; gap: 14px; }
    .footer-right { align-items: flex-start; text-align: left; }
}

@media (max-width: 480px) {
    .hero h1 { font-size: 28px; }
    .hero > p { font-size: 17px; }
    .section-header h2 { font-size: 28px; }
}

/* ════════════════════════════════════════════════════════════
   Issue Guide ( /issue/{slug} ) — consolidated (2026-07-01 polish)
   ONE block ordered by page anatomy; replaces the former v1.1
   base block + module styles + dashboard-layout override block.
   Spec: docs/superpowers/specs/2026-07-01-issue-css-polish-design.md
   ════════════════════════════════════════════════════════════ */

body.page-issue { background:#fff;}

.issue-guide {
  /* tokens */
  --issue-accent: #3D6B85;                   /* deepened --sky; ~5.5:1 on warmwhite, ~5.1:1 on sand */
  --issue-shadow: 0 1px 3px rgba(0, 0, 0, .04);
  --issue-section-gap: 2.25rem;
  --issue-card-gap: 1rem;
  --chip-sage-bg: rgba(164, 196, 150, .35);  --chip-sage-ink: #4A6B3F;
  --chip-sky-bg: rgba(160, 203, 224, .35);   --chip-sky-ink: #33607C;
  --chip-ochre-bg: rgba(232, 201, 106, .35); --chip-ochre-ink: #7C6420;
  --note-bg: rgba(232, 201, 106, .18);       /* ochre "editorial note" family (guardrail + what's next) */
  --note-border: rgba(212, 168, 67, .35);
  /* Font Awesome duotone: secondary layer = sage (Brandon's screen-D pick); primary tracks text (== FA default) */
  --fa-primary-color: currentColor;
  --fa-secondary-color: var(--sage);
  --fa-secondary-opacity: .45;

  max-width: 1140px; margin: 0 auto; padding: 1.5rem 1.25rem 4rem;
}

/* ── one panel recipe ─────────────────────────────────────── */
.standing-action, .matter-item, .issue-guide .stat-card, .process-step,
.issue-fullstory, .issue-outcome, .issue-related, .issue-sources,
.ai-mapcard, .issue-module--donut {
    background:#fff;
  border: 1px solid var(--sand-dark);
  border-radius: var(--radius);
  box-shadow: var(--issue-shadow);
}
.issue-fullstory, .issue-outcome, .issue-related, .issue-sources,
.ai-mapcard, .issue-module--donut { padding: 1.25rem 1.35rem; }

/* ── topbar: status pill + language toggle ────────────────── */
.issue-topbar { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: .4rem; }
.issue-status { display: inline-flex; align-items: center; gap: .45rem; padding: .32rem .85rem; border-radius: 999px; font-size: .72rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; background: #EDE7DA; color: var(--ink-soft); }
.issue-status::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.issue-status.status-active     { background: rgba(164, 196, 150, .28); color: #46603C; }  /* green = live (Brandon's call) */
.issue-status.status-monitoring { background: rgba(232, 201, 106, .22); color: #7C6420; }
.issue-status.status-resolved   { background: #EDE7DA; color: var(--ink-soft); }            /* neutral once closed — keeps it distinct from active */
.issue-lang a { display: inline-block; padding: .25rem .6rem; border: 1px solid var(--sand-dark); border-radius: 16px; margin-left: .35rem; font-size: .8rem; text-decoration: none; color: var(--ink-soft); }
.issue-lang a.active { background: var(--ink); color: var(--warmwhite); border-color: var(--ink); }
.back-link { display: inline-block; margin: .25rem 0 .9rem; color: var(--color-text-tertiary); font-size: .85rem; text-decoration: none; }

/* ── headline block ───────────────────────────────────────── */
.issue-guide h1 { font-family: "DM Serif Display", Georgia, serif; font-size: clamp(1.9rem, 1.4rem + 2vw, 2.5rem); line-height: 1.12; margin: .2rem 0 .5rem; }
.issue-hook { font-size: 1.18rem; line-height: 1.6; color: var(--ink-soft); margin: 0 0 1.3rem; }

/* ── kicker: ONE style for every section heading ──────────────
   (module renderers emit h3.issue-section-head, so JS-emitted
   headings — stat-grid-head, donut-head, map-head, process-head —
   harmonize with the PHP section heads for free) */
.issue-section-head {
  display: flex; align-items: center; gap: .5rem;
  font-family: 'DM Sans', sans-serif; font-size: 1rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .07em; color: var(--ink);
  margin: 0 0 .9rem;
}
.issue-section-head .section-icon { display: inline-flex; color: var(--color-text-tertiary); }
.issue-section-head svg { width: 16px; height: 16px; flex: 0 0 auto; }
/* Font Awesome duotone icons (issue page) — one block, all six render surfaces.
   svg rules above are retained for the matter chips + any transitional inline SVG.
   Wrappers .stat-icon/.process-icon keep line-height:0; the kit sets the <i>'s own
   line-height:1, so the glyph is not collapsed — do not "fix" the wrappers. */
.issue-guide .issue-section-head i,
.issue-guide .issue-guardrail .guardrail-label i { font-size: 15px; line-height: 1; flex: 0 0 auto; }
.issue-guide .stat-card .stat-icon i { font-size: 35px; padding:5px 0 10px 0;}
.issue-guide .process-icon i { font-size: 34px; padding:5px 0; }
.issue-guide .issue-metric i { font-size: 16px; color: var(--color-text-tertiary); }
.issue-guide .issue-latest-chip .chip-label i { font-size: 14px; line-height: 1; flex: 0 0 auto; }
.issue-guide .photo-placeholder > i { font-size: 24px; }

/* ── guardrail + "what's next": the ochre note family ─────── */
/* (padding deliberately unified across both notes; supersedes the
   spec's per-note values — reviewer-checked, cosmetic) */
.issue-guardrail, .issue-next {
  background: var(--note-bg);
  border: 1px solid var(--note-border);
  border-radius: var(--radius);
  padding: .95rem 1.15rem;
  margin: 0 0 var(--issue-section-gap);
}
.issue-guardrail .guardrail-label {
  display: flex; align-items: center; gap: .5rem;
  font-size: .8rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
  color: var(--chip-ochre-ink); margin-bottom: .35rem;
}
.issue-guardrail .guardrail-label svg { width: 16px; height: 16px; flex: 0 0 auto; }
.issue-guardrail p { margin: 0; line-height: 1.6; color: var(--ink-soft); }
.issue-next .issue-section-head { color: var(--chip-ochre-ink); margin-bottom: .5rem; }
.issue-next .issue-section-head .section-icon { color: var(--chip-ochre-ink); }
.issue-next-text { font-size: 1.02rem; line-height: 1.55; color: var(--ink); margin: 0; }

/* ── latest-update chip (anchors to #issue-standing) ──────── */
.issue-latest-chip { display: flex; align-items: baseline; gap: .6rem; background: #fff; border: 1px solid var(--sand-dark); border-radius: var(--radius); box-shadow: var(--issue-shadow); padding: .6rem 1rem; margin: 0 0 var(--issue-section-gap); text-decoration: none; min-width: 0; }
.issue-latest-chip .chip-label { display: inline-flex; align-items: center; gap: .4rem; font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-soft); flex: 0 0 auto; }
.issue-latest-chip .chip-date { font-size: .8rem; font-weight: 700; color: var(--issue-accent); flex: 0 0 auto; }
.issue-latest-chip .chip-body { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: .88rem; color: var(--ink-soft); }
.issue-latest-chip .chip-more { flex: 0 0 auto; font-size: .82rem; font-weight: 600; color: var(--issue-accent); }
.issue-latest-chip:hover .chip-more, .issue-latest-chip:focus-visible .chip-more { text-decoration: underline; }
@media (max-width: 640px) { .issue-latest-chip { flex-wrap: wrap; } .issue-latest-chip .chip-body { flex-basis: 100%; white-space: normal; } }

/* ── glance strip (standalone module zone; zero footprint when empty) ── */
.issue-glance { margin: 0 0 var(--issue-section-gap); }
.issue-glance:empty { display: none; margin: 0; }

/* ── "where things stand": timeline + action card ─────────── */
.issue-standing { margin: 0 0 var(--issue-section-gap); }
.standing-grid { display: grid; grid-template-columns: 3fr 2fr; gap: 1.25rem; align-items: start; }
/* resolved issues: page.js REMOVES the take-part card (show_participation=''), so let the timeline span both tracks */
.standing-grid > .timeline-col:only-child { grid-column: 1 / -1; }
.timeline-rail { position: relative; padding-left: 1.5rem; }
.timeline-rail::before { content: ''; position: absolute; left: 5px; top: .5rem; bottom: .5rem; width: 2px; background: var(--sand-dark); border-radius: 1px; }
.timeline-item { position: relative; padding: 0 0 1.1rem; }
.timeline-item::before { content: ''; position: absolute; left: -1.5rem; top: .28rem; width: 12px; height: 12px; border-radius: 50%; background: var(--issue-accent); box-shadow: 0 0 0 2px #fff; }
.timeline-item--future::before { background: #fff; border: 2px dashed var(--issue-accent); width: 8px; height: 8px; }
.timeline-label { display: block; font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--chip-ochre-ink); margin-bottom: .25rem; }
.timeline-date { display: block; font-size: .78rem; font-weight: 700; color: var(--issue-accent); }
.timeline-body { display: block; font-size: .92rem; line-height: 1.5; color: var(--ink-soft); }
.timeline-body--future { background: var(--note-bg); border: 1px solid var(--note-border); border-radius: var(--radius); padding: .7rem .85rem; margin: 0; font-size: .98rem; line-height: 1.55; color: var(--ink); }
.timeline-link { display: block; font-size: .82rem; margin-top: .15rem; }
.timeline-link a { color: var(--issue-accent); font-weight: 600; }
.timeline-col .issue-update-form { margin: .5rem 0 0; }
.standing-action { padding: 1.1rem 1.15rem; }
.standing-action .standing-action-head { margin-bottom: .5rem; }
.standing-action-body { font-size: .95rem; line-height: 1.55; color: var(--ink); }
.standing-action-body p { margin: 0 0 .5rem; }
.standing-action-body a { color: var(--issue-accent); font-weight: 600; }

/* ── admin: "add update" form (admin IP only) ─────────────── */
.issue-update-form { border: 1px dashed var(--sand-dark); border-radius: var(--radius); padding: 1rem 1.1rem; margin: 0 0 var(--issue-section-gap); background: var(--warmwhite); display: flex; flex-direction: column; gap: .5rem; }
.issue-update-form .iuf-head { font-size: .78rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--color-text-tertiary); }
.issue-update-form textarea, .issue-update-form input { width: 100%; border: 1px solid var(--sand-dark); border-radius: 8px; padding: .5rem .6rem; font: inherit; font-size: .9rem; box-sizing: border-box; background: #fff; }
.issue-update-form .iuf-row { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; }
.issue-update-form .iuf-row input { flex: 1; min-width: 140px; }
.issue-update-form .iuf-date { max-width: 200px; }
.issue-update-submit { flex: 0 0 auto; background: var(--ink); color: var(--warmwhite); border: none; border-radius: 8px; padding: .5rem 1rem; font: inherit; font-size: .9rem; cursor: pointer; }
.issue-update-submit:disabled { opacity: .6; cursor: default; }
.issue-update-status { font-size: .85rem; color: var(--ink-soft); }

/* ── admin: module editor ─────────────────────────────────── */
.issue-module-editor { border: 1px dashed var(--sand-dark); border-radius: var(--radius); padding: 1rem; margin: 0 0 var(--issue-section-gap); background: rgba(0, 0, 0, .015); }
.issue-module-editor .ime-head { font-weight: 700; color: var(--ink-soft); margin-bottom: .6rem; }
.issue-module-editor .ime-item { display: flex; align-items: center; gap: .4rem; padding: .35rem 0; }
.issue-module-editor .ime-item span { flex: 1; }
.issue-module-editor .ime-row { display: flex; flex-wrap: wrap; gap: .4rem; margin-bottom: .4rem; }
.issue-module-editor .ime-row input, .issue-module-editor .ime-row select { padding: .35rem .5rem; border: 1px solid var(--sand-dark); border-radius: 6px; font: inherit; }
.issue-module-editor button { cursor: pointer; padding: .3rem .6rem; border: 1px solid var(--sand-dark); border-radius: 6px; background: var(--warmwhite); font: inherit; }
.issue-module-editor .ime-status { color: var(--ink-soft); margin-left: .5rem; }
.issue-module-editor .ime-note { font-size: .8rem; color: var(--color-text-tertiary); font-style: italic; }

/* ── "this might matter to you if" — chip cards ───────────── */
.issue-matter { margin: 0 0 var(--issue-section-gap); }
.matter-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--issue-card-gap); }
.matter-item { display: grid; grid-template-columns: 42px 1fr; column-gap: .8rem; align-content: start; padding: 1rem 1.05rem; }
.matter-item::before {
  content: ''; grid-column: 1; grid-row: 1 / span 2;
  width: 42px; height: 42px; border-radius: 11px;
  background-color: var(--chip-sage-bg);   /* one calm color for all — each item is a confirmation, not a category */
  background-repeat: no-repeat; background-position: center; background-size: 22px 22px;
}
/* Icon rotation offsets account for the hidden .template first child
   (page.js keeps it in the DOM): first VISIBLE item = 3n+2 = house. */
.matter-item:nth-child(3n+2)::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234A6B3F' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 11l9-7 9 7'/%3E%3Cpath d='M5 10v10h14V10'/%3E%3C/svg%3E"); }
.matter-item:nth-child(3n)::before   { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234A6B3F' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='9' cy='8' r='3'/%3E%3Cpath d='M3 19c0-3 2.7-5 6-5s6 2 6 5'/%3E%3Cpath d='M16 5.6a3 3 0 0 1 0 5.8'/%3E%3Cpath d='M21.5 19c0-2.4-1.6-4.2-4-4.8'/%3E%3C/svg%3E"); }
.matter-item:nth-child(3n+1)::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234A6B3F' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='4' y='5' width='16' height='12' rx='2'/%3E%3Cpath d='M4 11h16'/%3E%3Ccircle cx='8' cy='19' r='1.5'/%3E%3Ccircle cx='16' cy='19' r='1.5'/%3E%3C/svg%3E"); }
.matter-label { grid-column: 2; font-weight: 700; color: var(--ink); line-height: 1.3; }
.matter-detail { grid-column: 2; font-size: .9rem; line-height: 1.5; color: var(--ink-soft); }

/* ── data modules grid (main zone) ────────────────────────── */
.issue-modules { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--issue-card-gap); margin: 0 0 var(--issue-section-gap); }
.issue-modules:empty { display: none; }
.issue-module { margin: 0; }
/* zero-context reading order: where it is → how the process works → the numbers.
   (keep DB sort_order in the same order — CSS `order` changes visual order only,
   screen readers and tab order follow the DOM) */
.issue-module--map           { order: 1; grid-column: 1 / -1; }
.issue-module--donut         { order: 2; }   /* beside the map when present (mockup pairing) */
.issue-module--process_steps { /*! order: 3; */ grid-column: 1 / -1; margin-bottom:50px;}
.issue-module--stat_grid     { order: 4; grid-column: 1 / -1; }
/* when the donut module exists, the map shares its row instead of going full-width */
.issue-modules:has(.issue-module--donut) .issue-module--map { grid-column: span 1; }

/* stat grid */
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: .9rem; }
/* .stat-card rules are scoped under .issue-guide: admin dashboards also use
   .stat-card and must keep their own admin.css styling */
.issue-guide .stat-card { padding: 1rem 1.1rem; display: flex; flex-direction: column; gap: .25rem; }
.issue-guide .stat-card .stat-icon { color: var(--ink-soft); line-height: 0; }
.issue-guide .stat-card .stat-number { font-weight: 700; font-size: 1.7rem; line-height: 1.1; color: var(--issue-accent); overflow-wrap: anywhere; }
.issue-guide .stat-card .stat-label { font-weight: 600; color: var(--ink); line-height: 1.3; }
.issue-guide .stat-card .stat-sub { font-size: .85rem; color: var(--color-text-tertiary); line-height: 1.4; }
@media (max-width: 420px) { .stat-grid { grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); } }

/* donut cohort snapshot */
.issue-module--donut .donut-box { display: flex; flex-wrap: wrap; align-items: center; gap: 1.5rem; }
.donut-ring { position: relative; width: 180px; height: 180px; flex: 0 0 auto; }
.donut-svg { width: 180px; height: 180px; display: block; }
.donut-center { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; }
.donut-center-value { font-weight: 700; font-size: 1.4rem; line-height: 1; color: var(--issue-accent); }
.donut-center-label { font-size: .8rem; color: var(--ink-soft); }
.donut-legend { flex: 1 1 220px; min-width: 200px; display: flex; flex-direction: column; gap: .45rem; }
.donut-legend-row { display: flex; align-items: center; gap: .55rem; }
.donut-swatch { width: 14px; height: 14px; border-radius: 3px; flex: 0 0 auto; }
.donut-legend-label { flex: 1; overflow-wrap: anywhere; color: var(--ink); }
.donut-legend-pct { font-variant-numeric: tabular-nums; color: var(--ink-soft); flex: 0 0 auto; }
.donut-note { font-size: .8rem; color: var(--color-text-tertiary); margin: .6rem 0 0; line-height: 1.45; }
@media (max-width: 480px) { .issue-module--donut .donut-box { gap: 1rem; } .donut-legend { flex-basis: 100%; } }

/* 1-mile locator map */
.issue-module--map { position: relative; }   /* contains the absolutely-positioned a11y summary */
.issue-map-canvas {
  height: 320px;
  border-radius: var(--radius);
  position: relative;            /* contain Leaflet's absolutely-positioned panes */
  overflow: hidden;
  background: var(--sand);       /* neutral fill before tiles load */
  z-index: 0;
}
@media (max-width: 480px) { .issue-map-canvas { height: 240px; } }
.issue-map-canvas .leaflet-tooltip.map-marker-label {
  background: rgba(253, 251, 247, .92);
  border: 1px solid var(--sand-dark);
  color: var(--ink);
  font: 600 .72rem/1.2 'DM Sans', system-ui, sans-serif;
  padding: 1px 6px; border-radius: 5px; box-shadow: none;
}
.issue-map-canvas .leaflet-tooltip.map-marker-label::before { display: none; }
.map-callout { display: flex; flex-wrap: wrap; align-items: baseline; gap: .4rem; margin: .75rem 0 0; }
.map-callout-value { font-weight: 700; font-size: 1.4rem; line-height: 1; color: var(--issue-accent); }
.map-callout-label { color: var(--ink-soft); }
.map-open-link { display: inline-block; margin: .55rem 0 0; color: var(--issue-accent); font-weight: 600; text-decoration: underline; }
.map-note { font-size: .8rem; color: var(--color-text-tertiary); margin: .6rem 0 0; line-height: 1.45; }
.issue-map-canvas--fallback {
  height: auto; min-height: 0; overflow: visible;
  display: flex; flex-direction: column; gap: .25rem;
  padding: 1rem; border: 1px solid var(--sand-dark);
}
.map-landmark-row { color: var(--ink-soft); font-size: .9rem; }
.map-a11y-summary {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* process-steps stepper */
.process-intro { color: var(--ink-soft); margin: 0 0 1rem; line-height: 1.5; }
.process-steps { list-style: none; margin: 0; padding: 0; display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: .55rem; }
.process-step { position: relative; display: flex; flex-direction: column; align-items: flex-start; gap: .4rem; padding: .9rem .8rem; }
.process-num { display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; border-radius: 50%; background: var(--ink); color: var(--warmwhite); font-size: .72rem; font-weight: 700; flex: 0 0 auto; }
.process-icon { color: var(--ink-soft); line-height: 0; }
.process-title { font-weight: 700; color: var(--ink); line-height: 1.25; }
.process-desc { font-size: .82rem; color: var(--ink-soft); line-height: 1.4; }
.process-arrow { position: absolute; right: -.5rem; top: 50%; transform: translateY(-50%); color: var(--color-text-tertiary); font-size: 1rem; line-height: 1; padding: 0 .1rem; background: var(--warmwhite); z-index: 1; }
.process-note { font-size: .8rem; color: var(--color-text-tertiary); margin: .8rem 0 0; line-height: 1.45; font-style: italic; }

/* process step states (config.current_step) */
.pstep--done .process-title, .pstep--done .process-desc { color: var(--color-text-tertiary); }
.pstep--done .process-num { background: var(--sage); color:#fff; }
 .process-icon { font-size:3rem;}
.pstep--done .process-icon { position: relative; color: var(--color-text-tertiary); }
.pstep--done .process-icon::after { content: '✓'; position: absolute; top: 15px; right: -25px; width: 14px; height: 14px; border-radius: 50%; color: var(--sage); font-size: 25px; line-height: 14px; text-align: center; font-weight: 700; }
.pstep--current { border-color: var(--issue-accent); box-shadow: 0 0 0 1px var(--issue-accent), var(--issue-shadow); }
.pstep--current .process-num { background: var(--issue-accent); }
.pstep-here { display: inline-block; font-size: .68rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: #fff; background: var(--issue-accent); border-radius: 999px; padding: .15rem .55rem; }
.pstep--upcoming { opacity: .62; }

@media (max-width: 640px) {
  .process-steps { grid-auto-flow: row; grid-auto-columns: auto; }
  .process-arrow { display: none; }
}

/* ── full story ───────────────────────────────────────────── */
.issue-fullstory { margin: 0 0 var(--issue-section-gap); }
.issue-photos { display: flex; flex-direction: column; gap: 1rem; margin: 0 0 1rem; }
.photo-figure { margin: 0; }
.photo-figure img { width: 100%; height: auto; border-radius: 10px; display: block; }
.photo-figure figcaption { font-size: .82rem; color: var(--color-text-tertiary); margin-top: .4rem; }
.photo-placeholder { border: 1px dashed var(--sand-dark); border-radius: 10px; padding: 1.1rem; text-align: center; color: var(--color-text-tertiary); }
.photo-placeholder .ph-caption { font-size: .9rem; color: var(--ink-soft); margin: .4rem 0 .15rem; }
.photo-placeholder .ph-prompt { font-size: .8rem; font-style: italic; margin: 0; }
.issue-body { max-width: 72ch; font-size: 1.02rem; line-height: 1.75; color: var(--ink); }
.issue-body h3 { font-family: 'DM Sans', sans-serif; font-weight: 700; font-size: 1.05rem; color: var(--ink); margin: 1.6rem 0 .4rem; }
.issue-body a { color: var(--issue-accent); }

/* ── outcome ("what was decided", resolved issues only) ───── */
.issue-outcome { margin: 0 0 var(--issue-section-gap); }
.issue-outcome h3 { font-family: 'DM Sans', sans-serif; font-size: .82rem; font-weight: 700; text-transform: uppercase; letter-spacing: .07em; color: var(--ink-soft); margin: 0 0 .5rem; }

/* ── stories + related: 2-up dashboard row ────────────────── */
.issue-row-split { display: grid; grid-template-columns: 2fr 1fr; gap: 1.25rem; align-items: start; margin: 0 0 var(--issue-section-gap); }
.issue-row-split > .issue-stories, .issue-row-split > .issue-related { margin: 0; }
.issue-stories-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: var(--issue-card-gap); }
.issue-card .card-topic-badge { background: var(--sand); color: var(--ink-soft); }
.issue-card .stat-number { color: var(--ink); }
.issue-related .related-note { font-size: .82rem; color: var(--color-text-tertiary); margin: 0 0 .8rem; }
.issue-tags { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: .8rem; }
.issue-tag { background: var(--sand); border: 1px solid var(--sand-dark); color: var(--ink-soft); font-size: .82rem; padding: 3px 11px; border-radius: 8px; }
.issue-metrics { display: flex; flex-wrap: wrap; gap: 14px; }
.issue-metric { display: inline-flex; align-items: center; gap: 6px; font-size: .85rem; color: var(--ink-soft); text-decoration: none; }
.issue-metric svg { width: 16px; height: 16px; color: var(--color-text-tertiary); }
a.issue-metric:hover span, a.issue-metric:focus-visible span { color: var(--issue-accent); text-decoration: underline; }

/* ── sources + disclaimer ─────────────────────────────────── */
.issue-sources { margin: 0 0 var(--issue-section-gap); }
.sources-list { list-style: none; padding: 0; display: flex; flex-direction: column; gap: .5rem; font-size: .9rem; }
.sources-list a { color: var(--issue-accent); }
.issue-disclaimer { font-size: .82rem; color: var(--color-text-tertiary); font-style: italic; margin: 0 0 1.5rem; }

/* ── responsive: collapse every dashboard row to one column ── */
@media (max-width: 860px) {
  .issue-modules, .issue-row-split { grid-template-columns: 1fr; }
  .issue-module--map, .issue-module--donut { grid-column: 1 / -1; }
  .standing-grid { grid-template-columns: 1fr; }
}

/* ════ Hub doors — Slice A polish
   (spec: docs/superpowers/specs/2026-07-08-door-page-polish-design.md)
   Doors sit OUTSIDE .issue-guide, so the issue tokens they use are re-declared
   on .hub-door — values must track the .issue-guide block if it changes. ════ */
body.page-hub-door { background: var(--warmwhite); }

.hub-door {
  --issue-accent: #3D6B85;
  --issue-shadow: 0 1px 3px rgba(0, 0, 0, .04);
  --chip-ochre-ink: #7C6420;
  --note-bg: rgba(232, 201, 106, .18);
  --note-border: rgba(212, 168, 67, .35);
  --fa-primary-color: currentColor;
  --fa-secondary-color: var(--sage);
  --fa-secondary-opacity: .45;
  max-width: 960px; margin: 0 auto; padding: 1.5rem 1.25rem 4rem;
}

/* ── topbar: crumb + pill language toggle (issue idiom) ── */
.hub-door-topbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: .9rem; }
.hub-door-crumb { color: var(--color-text-tertiary); text-decoration: none; font-size: .85rem; }
.hub-door-lang a { display: inline-block; padding: .25rem .6rem; border: 1px solid var(--sand-dark); border-radius: 16px; margin-left: .35rem; font-size: .8rem; text-decoration: none; color: var(--ink-soft); }
.hub-door-lang a.active { background: var(--ink); color: var(--warmwhite); border-color: var(--ink); }

/* ── header ── */
.hub-door-kicker { font-family: "DM Serif Display", Georgia, serif; font-style: italic; font-size: 1.15rem; line-height: 1.5; color: var(--ink); margin: .2rem 0 .55rem; }
.hub-door-kicker a { color: var(--issue-accent); }
.hub-door-header h1 { font-family: "DM Serif Display", Georgia, serif; font-size: clamp(1.9rem, 1.4rem + 2vw, 2.3rem); line-height: 1.12; margin: .2rem 0 .5rem; }
.hub-door-dek { font-size: 1.18rem; line-height: 1.6; color: var(--ink-soft); margin: 0 0 1.3rem; }

/* ── blocks grid: live + take_part span full; past + data pair 2-up (auto-placement,
      robust when a block is missing). DOM order is live,past,data,take_part — set by
      HubDoor::get_blocks() ORDER BY FIELD (class.hub_door.php), NOT by seed sort_order;
      that adjacency is what makes past+data pair without grid-auto-flow:dense. ── */
.hub-door-blocks { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin-bottom: 1rem; }
.hub-door-block { background: #fff; border: 1px solid var(--sand-dark); border-radius: var(--radius); box-shadow: var(--issue-shadow); padding: 1.15rem 1.25rem; }
.hub-door-block.block-live, .hub-door-block.block-take_part { grid-column: 1 / -1; }

/* live block = the status band (ochre note family; milestone rendered large inside it) */
.hub-door-block.block-live { background: var(--note-bg); border-color: var(--note-border); }
.hub-door-block-head { display: flex; align-items: center; gap: .5rem; font-family: 'DM Sans', sans-serif; font-size: .82rem; font-weight: 700; text-transform: uppercase; letter-spacing: .07em; color: var(--ink-soft); margin: 0 0 .9rem; }
.hub-door-block-head .block-icon { display: inline-flex; color: var(--color-text-tertiary); }
.hub-door-block-head i { font-size: 15px; line-height: 1; flex: 0 0 auto; }
.block-live .hub-door-block-head, .block-live .hub-door-block-head .block-icon { color: var(--chip-ochre-ink); }
.hub-door-milestone { font-size: 1.15rem; line-height: 1.5; font-weight: 600; color: var(--ink); margin: 0 0 .75rem; }
.hub-door-block-body { font-size: .97rem; line-height: 1.6; color: var(--ink-soft); }
.hub-door-block-body p { margin: 0 0 .8rem; }
.hub-door-block-body p:last-child { margin-bottom: 0; }
.hub-door-block-body a { color: var(--issue-accent); }

/* ── action rows (generated: ul.door-actions) ── */
.door-actions { list-style: none; padding: 0; margin: .9rem 0 0; display: flex; flex-direction: column; gap: .6rem; }
.door-actions li { display: flex; align-items: flex-start; gap: .7rem; background: #fff; border: 1px solid var(--sand-dark); border-radius: var(--radius); box-shadow: var(--issue-shadow); padding: .7rem .9rem; }
.door-actions li > i { font-size: 22px; line-height: 1; flex: 0 0 auto; margin-top: .15rem; color: var(--issue-accent); }
.door-actions .act-phone { display: inline-block; font-size: 1.3rem; font-weight: 700; color: var(--issue-accent); }

/* ── numbered steps (generated: ol.door-steps) ── */
.door-steps { list-style: none; counter-reset: doorstep; padding: 0; margin: 1rem 0 0 0; display: flex; flex-direction: column; gap: .7rem; }
.door-steps li { counter-increment: doorstep; position: relative; padding-left: 2.4rem; }
.door-steps li::before { content: counter(doorstep); position: absolute; left: 0; top: .05rem; width: 1.7rem; height: 1.7rem; border-radius: 50%; background: var(--issue-accent); color: #fff; font-weight: 700; font-size: .9rem; display: flex; align-items: center; justify-content: center; }
.door-steps .step-label { font-weight: 700; color: var(--ink); }

/* ── stat grid (generated: ul.door-stats; denominators live in the labels) ── */
.door-stats { list-style: none; padding: 0; margin: .9rem 0 0; display: grid; grid-template-columns: 1fr 1fr; gap: .9rem .8rem; }
.door-stats li { display: flex; flex-direction: column; }
.door-stats li > i { background:var(--sand); display:inline-block; width:60px;
    height:60px; line-height:60px; border-radius:50%; text-align:center; font-size: 33px; color: var(--color-text-tertiary); margin-bottom: .3rem; }
.door-stats .stat-number { font-family: "DM Serif Display", Georgia, serif; font-size: 1.7rem; line-height: 1.1; color: var(--issue-accent); }
.door-stats .stat-label { font-size: .85rem; line-height: 1.45; color: var(--ink-soft); }

/* ── materials shelf stub ── */
.hub-door-shelf { border: 1px dashed var(--sand-dark); border-radius: var(--radius); padding: 1rem 1.25rem; margin-bottom: 1rem; background: #fff; color: var(--ink-soft); }
.hub-door-shelf-head { display: flex; align-items: center; gap: .5rem; font-size: .82rem; font-weight: 700; text-transform: uppercase; letter-spacing: .07em; color: var(--ink-soft); margin-bottom: .35rem; }
.hub-door-shelf-head i { font-size: 15px; line-height: 1; }
.hub-door-shelf-note { margin: 0; font-size: .92rem; }

/* ── network (the convergence block; drafts dimmed for admin preview) ── */
.hub-door-network { background: #fff; border: 1px solid var(--sand-dark); border-radius: var(--radius); box-shadow: var(--issue-shadow); padding: 1.15rem 1.25rem; }
.hub-door-network-head { display: flex; align-items: center; gap: .5rem; font-size: .82rem; font-weight: 700; text-transform: uppercase; letter-spacing: .07em; color: var(--ink-soft); margin: 0 0 .6rem; }
.hub-door-network-head i { font-size: 15px; line-height: 1; }
.hub-door-netrow { display: block; padding: .55rem 0; border-bottom: 1px solid var(--sand-dark); text-decoration: none; color: var(--ink); }
.hub-door-netrow:last-of-type { border-bottom: 0; }
.hub-door-netrow .netrow-label { font-weight: 700; }
.hub-door-netrow .netrow-label::after { content: ": "; font-weight: 400; color: var(--ink-soft); }
.hub-door-netrow .netrow-why { color: var(--ink-soft); }
.hub-door-netrow.row-draft { opacity: .55; }
.hub-door-netrow.row-draft .netrow-label::before { content: "draft · "; font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--color-text-tertiary); }
.hub-door-seeall { display: inline-block; margin-top: .7rem; color: var(--issue-accent); font-weight: 600; text-decoration: none; }

/* ── map zone (the hub's map module, rendered by FFModules; bare .issue-module--map /
      .issue-map-canvas / .map-* selectors style it here too — no re-scoping needed) ── */
.hub-door-map { margin-bottom: 1rem; }
.hub-door-map:empty { margin: 0; }

/* ── breadcrumb + status chip ── */
.hub-door-crumbwrap { display: flex; align-items: center; gap: .6rem; min-width: 0; }
.hub-door-crumb:hover span { color: var(--issue-accent); }
.hub-door-status-chip { font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--ink-soft); border: 1px solid var(--sand-dark); border-radius: 12px; padding: .15rem .55rem; white-space: nowrap; }

/* ── responsive: single column (door's own breakpoint; the 860px rule above is the issue page's) ── */
@media (max-width: 860px) {
  .hub-door-blocks, .door-stats { grid-template-columns: 1fr; }
}

/* ---- Launcher strip on the hub home ---- */
.matter-doors { display:grid; gap:10px; }
.matter-door { display:block; border:1px solid var(--sand-dark); border-left:3px solid var(--issue-accent); border-radius:8px;
               padding:12px 14px; text-decoration:none; color:var(--ink); transition:border-color .15s; background:#fff;}
.matter-door:hover { border-color:var(--issue-accent); }
.matter-door .matter-label { display:block; font-weight:700; }
.matter-door .matter-detail { display:block; color:var(--ink-soft); font-size:.95rem; margin-top:2px; }
.matter-door .matter-learn { display:inline-block; color:var(--issue-accent); font-weight:600; font-size:.85rem; margin-top:7px; }

/* ── Guided intro: gallery, path bar (spec 2026-07-19) ──
   The strip / pathbar rules that used to live here were scoped to v1's
   .issue-guide tree (.issue-strip, .issue-strip-line, .issue-pathbar,
   .pathbar-do, .pathbar-follow) and are unreachable now that no issue routes
   to v1 (slice 6 sweep). .issue-strip-line's replacement is the sticky bar's
   own reset in css/ffa.css (.ffa-ig-strip .issue-strip-line), the band the
   Apple-way issue guide renders a strip module in. */

/* empty-config guard: renderAll appends the wrap even when a renderer suppresses;
   this wrap carries visible box styles, so hide it when empty (template law) */
.issue-module--case_facts:empty { display: none; }

/* anchor jumps must clear the sticky nav+strip stack (strip measured up to 59px on
   mobile when its line wraps to two lines; +4rem/64px covers that plus breathing room) */
#issue-action, #issue-standing { scroll-margin-top: calc(var(--nav-h) + 4rem); }

.ig-track { display: flex; gap: .7rem; overflow-x: auto; scroll-snap-type: x mandatory; padding: .3rem 0 .2rem; scrollbar-width: none; }
.ig-track::-webkit-scrollbar { display: none; }
.ig-slide { flex: 0 0 82%; max-width: 420px; scroll-snap-align: center; margin: 0; }
.ig-art { aspect-ratio: 4 / 3; border-radius: var(--radius); overflow: hidden; background: var(--sand-dark); border: 1px solid var(--sand-dark); }
.ig-art img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ig-art--placeholder { display: flex; align-items: center; justify-content: center; }
.ig-ph-note { font-size: .75rem; color: var(--color-text-tertiary); text-transform: uppercase; letter-spacing: .06em; }
.ig-cap { font-size: .85rem; color: var(--ink-soft); padding: .45rem .15rem 0; }
.ig-cap strong { color: var(--ink); }
/* Per-slide source line (2026-07-30 readability slice). Quiet and clearly
   subordinate to the caption — the same URLs appear in full in Z7. */
.ig-src { font-size: .72rem; margin-top: .3rem; color: var(--color-text-tertiary); }
.ig-src a { color: inherit; text-decoration: underline; }
.ig-dots { display: flex; gap: .3rem; justify-content: center; padding: .5rem 0 0; }
.ig-dots i { width: 5px; height: 5px; border-radius: 50%; background: var(--sand-dark); }
.ig-dots i.on { background: var(--terracotta); }

/* record elements — navy is the record accent ONLY (spec item 7) */
.issue-module--case_facts { border: 1px solid var(--sand-dark); border-radius: var(--radius); overflow: hidden; margin: 1.1rem 0; }
.cf-head { background: var(--navy); color: #F2F5F9; font-size: .72rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; padding: .45rem .8rem; }
.cf-row { display: flex; gap: .7rem; padding: .55rem .8rem; border-top: 1px solid var(--sand); align-items: baseline; }
.cf-head + .cf-row { border-top: 0; }
.cf-k { flex: 0 0 42%; font-size: .8rem; font-weight: 700; color: var(--ink-soft); }
.cf-v { flex: 1; font-size: .86rem; }
.cf-foot { padding: .55rem .8rem; border-top: 1px solid var(--sand); background: var(--navy-soft); }
.cf-foot a { font-size: .8rem; font-weight: 700; color: var(--navy); }

/* docket shelf: sources restyled as the record shelf */
.issue-sources { background: var(--navy); border-radius: var(--radius-lg); padding: 1rem 1.1rem; border: 0; box-shadow: none; }
.issue-sources .issue-section-head { color: #F2F5F9; }
.issue-sources .section-icon i { color: #F2F5F9; }
.issue-sources .sources-list .source-item { color: #F2F5F9; }
.issue-sources .sources-list .source-item a { color: #F2F5F9; text-decoration: underline; text-underline-offset: 2px; }

/* action box (path-first) — actions stay terracotta, never navy */
.ab-help { display: block; text-align: center; font-size: .8rem; font-weight: 600; color: var(--terracotta); margin-top: .6rem; text-decoration: none; }
.ab-micro { text-align: center; font-size: .74rem; color: var(--ink-soft); margin-top: .45rem; }

/* outcomes (record accent on headers only) */
.oc-card { border: 1px solid var(--sand-dark); border-radius: var(--radius); overflow: hidden; margin-top: .7rem; }
.oc-head { background: var(--navy); color: #F2F5F9; font-size: .86rem; font-weight: 700; padding: .45rem .8rem; }
.oc-row { display: flex; gap: .7rem; padding: .5rem .8rem; border-top: 1px solid var(--sand); }
.oc-head + .oc-row { border-top: 0; }
.oc-k { flex: 0 0 42%; font-size: .78rem; font-weight: 700; color: var(--ink-soft); }
.oc-v { flex: 1; font-size: .84rem; }
.oc-fineprint { font-size: .78rem; color: var(--ink-soft); margin: .6rem .1rem 0; }

/* ── Guided intro: updates feed cards + eyebrow (Slice 4, 2026-07-20) ──
   Scope: .timeline-updates .timeline-item ONLY (the dated update entries
   inside #issue-standing) — the "what's next" milestone item is a sibling
   OUTSIDE .timeline-updates (see page/page.issue.php), so it is untouched
   by this selector and keeps its existing .timeline-item--future dashed-dot
   marker and its .timeline-body--future ochre note-card styling exactly as
   before. That is what keeps it reading as visually distinct from the
   plain feed cards below it — no changes were made to either rule.
   The rail line (.timeline-rail::before) and each item's dot marker
   (.timeline-item::before) are left in place rather than neutralized:
   both are absolutely positioned inside the rail's own left gutter
   (.timeline-rail has padding-left: 1.5rem, and the dot's `left: -1.5rem`
   pulls it back into that gutter), which sits entirely to the left of the
   card's border box — the card's background/border never overlaps the
   line or the dot. Result: a feed of dated cards strung along the
   existing rail, not a rail-vs-card hybrid. .timeline-date already reads
   as a small (.78rem) bold date line via the base rule above — no
   override needed here. */
.timeline-updates .timeline-item {
  background: var(--warmwhite);
  border: 1px solid var(--sand-dark);
  border-radius: var(--radius);
  padding: .6rem .75rem;
  margin-top: .5rem;
}

/* Eyebrow (.issue-topbar): left unchanged. The status chip and EN/ES
   toggle stay exactly as before — no topics or place labels are added
   (that data does not exist per-issue yet; inventing it would violate the
   structure-is-information rule). The back-link (`.back-link`, page/
   page.issue.php) sits in its own block AFTER .issue-topbar in the DOM,
   not as a flex child inside it, and `.back-link` is also shared with the
   story and about pages (css/style.css line ~402) — pulling it into this
   row via CSS `order` isn't reachable without either a template change
   (out of scope this slice) or scoping a new rule to `.back-link` broadly
   enough to risk bleeding into those other pages, so it was left alone. */


/* ══════════════════════════════════════════════════════════════
   Issue template v2 (.iv2-*) — the trimmed 7-zone standard
   Spec: docs/design/2026-07-21-content-structure-board.html
   Additive only: nothing above this block is touched, so the frozen
   flagship page (.issue-guide) is unaffected. Phone-first.
   ══════════════════════════════════════════════════════════════ */

.iv2-guide {
  --issue-accent: #3D6B85;                  /* same deepened --sky the flagship uses */
  --issue-shadow: 0 1px 3px rgba(0, 0, 0, .04);
  --iv2-gap: 2rem;
  --iv2-measure: 34rem;                      /* prose column; see the note below */
  /* External-link glyph, used via mask so it inherits currentColor. Keeps the
     pre-rendered link_html in class.issue.php untouched. The stroke colour in
     the data URI is irrelevant — mask uses the alpha channel only. */
  --iv2-icon-external: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14 4h6v6'/%3E%3Cpath d='M20 4 9.5 14.5'/%3E%3Cpath d='M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5'/%3E%3C/svg%3E");

  max-width: 1000px;                         /* shell width; prose is capped separately below */
  margin: 0 auto;
  padding: 1.25rem 1.15rem 4rem;
  display: flex; flex-direction: column; gap: var(--iv2-gap);
}

/* Shell is 1000px so data zones can go multi-column; prose must NOT follow it
   out. Every run of sentences is capped to a reading measure. Full-bleed
   children (module zones, action box, forms) are deliberately absent here.

   ONE shared measure, in rem, deliberately not `ch`: `ch` is the width of "0",
   which in DM Sans is ~1.5x the average glyph, so a 68ch cap measured out at
   100 characters per line (verified in-browser 2026-07-23). `ch` also scales
   with each element's own font-size, so the dek and the clock ended up with
   different max-widths and a ragged right edge. 34rem holds the dek at ~72
   characters and the clock at ~62, with one clean column edge for both. */
.iv2-dek,
.iv2-clock,
.iv2-lastchange,
.iv2-primary,
.iv2-door-q,
.iv2-door-take,
.iv2-disclaimer,
.iv2-foot p { max-width: var(--iv2-measure); }

/* Evidence-gating law: a module zone with nothing in it leaves no footprint. */
.iv2-levers:empty, .iv2-facts:empty, .iv2-gallery:empty, .iv2-outcomes:empty { display: none; }
.iv2-levers .issue-module--case_facts:empty, .iv2-facts .issue-module--case_facts:empty { display: none; }

.iv2-zone-head {
  font-size: .9rem; font-weight: 700;  text-transform: uppercase;
  color: var(--ink-soft); margin-bottom: .6rem;
}
.iv2-sub { font-size: .95rem; font-weight: 700; margin-bottom: .35rem; }
.iv2-note { font-size: .86rem; color: var(--ink-soft); }

/* ── Z1 · header ─────────────────────────────────────────────── */
.iv2-head-top { display: flex; align-items: center; justify-content: space-between; gap: 1rem; /*! margin-bottom: .9rem; */ }
.iv2-back { font-size: .82rem; color: var(--ink-soft); text-decoration: none; }
.iv2-back:hover { text-decoration: underline; }
.iv2-lang { display: flex; gap: .3rem; font-size: .74rem; font-weight: 700; letter-spacing: .05em; }
.iv2-lang a { padding: .2rem .5rem; border: 1px solid var(--sand-dark); border-radius: 999px; color: var(--ink-soft); text-decoration: none; }
.iv2-lang a.active { background: var(--navy); border-color: var(--navy); color: #fff; }

.iv2-eyebrow {
  font-size: .9rem; font-weight: 700; letter-spacing: 0em; text-transform: uppercase;
  color: var(--issue-accent); margin-bottom: .5rem;
}
.iv2-chips { display: flex; flex-wrap: wrap; gap: .4rem; margin-bottom: .7rem; }
.iv2-chip {
  display: inline-block; padding: .26rem .7rem; border-radius: 999px;
  font-size: .7rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  background: #EDE7DA; color: var(--ink-soft);
}
.iv2-chip--status.status-active     { background: rgba(164, 196, 150, .28); color: #46603C; }
.iv2-chip--status.status-monitoring { background: rgba(232, 201, 106, .30); color: #7C6420; }
.iv2-chip--status.status-resolved   { background: var(--navy-soft); color: var(--navy); }
.iv2-chip--status.status-decided    { background: var(--sky-light); color: var(--navy); }
.iv2-chip--status.status-ongoing    { background: rgba(232, 201, 106, .30); color: #7C6420; }

.iv2-h1 { font-family: 'DM Serif Display', Georgia, serif; font-size: 1.85rem; line-height: 1.2; text-wrap: balance; }
.iv2-dek { margin-top: .6rem; font-size: 1.02rem; color: var(--ink-soft); }

/* ── Z2 · where it stands (the page's ONE clock) ─────────────── */
/* Left accent rule, not a filled panel: Z2 must outrank body copy without
   competing with the filled action box in Z3. */
.iv2-stands {
  border-left: 3px solid var(--issue-accent);
  padding: .15rem 0 .15rem 1.05rem;
}

.iv2-ladder {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: .35rem .1rem; list-style: none; margin-bottom: .85rem;
}
.iv2-stage {
  display: inline-flex; align-items: center; gap: .4rem;
  font-size: .84rem; color: var(--color-text-tertiary);
}

/* Marker carries the state, so the signal is never colour-only. */
.iv2-stage::before {
  content: ''; width: .55rem; height: .55rem; border-radius: 50%;
  border: 2px solid var(--sand-dark); background: transparent; flex: 0 0 auto;
}
.iv2-stage + .iv2-stage { margin-left: .1rem; }
.iv2-stage + .iv2-stage::after {
  content: ''; order: -1; width: 1.1rem; height: 2px;
  background: var(--sand-dark); margin-right: .35rem; flex: 0 0 auto;
}
/* Done: filled but muted. Current: filled accent, ringed, bold, larger. */
.iv2-stage.is-done::before { background: var(--sand-dark); border-color: var(--sand-dark); }
.iv2-stage[data-current="1"] {
  font-weight: 700; font-size: .9rem; color: var(--issue-accent);
}
.iv2-stage[data-current="1"]::before {
  background: var(--issue-accent); border-color: var(--issue-accent);
  box-shadow: 0 0 0 3px rgba(61, 107, 133, .18);
}

.iv2-clock { font-size: 1.22rem; font-weight: 700; line-height: 1.4; color: var(--ink); }
.iv2-lastchange {
  margin-top: .7rem; padding-top: .6rem; font-size: .84rem; color: var(--ink-soft);
  border-top: 1px solid var(--sand-dark);
}
.iv2-lastchange-label { font-weight: 700; }
.iv2-lastchange-label::after { content: ':'; }
.iv2-lastchange-date { color: var(--issue-accent); font-weight: 700; margin: 0 .3rem; }

/* ── Z3 · what you can do now ────────────────────────────────── */
.iv2-action {
  background: var(--navy-soft);
  border: 1px solid rgba(42, 65, 89, .14);
  border-radius: var(--radius);
  padding: 1.1rem 1.15rem 1.25rem;
    margin:2rem 0;
}
.iv2-primary { font-size: 1rem; }
.iv2-primary p + p { margin-top: .5rem; }
.iv2-primary a { color: var(--navy); font-weight: 600; }

.iv2-follow { margin-top: 1.1rem; padding-top: 1rem; border-top: 1px solid rgba(42, 65, 89, .14); }
.iv2-field-row { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .6rem; }
.iv2-field-row input[type="email"] { flex: 1 1 12rem; min-width: 0; }

.iv2-guide input[type="email"], .iv2-guide input[type="text"], .iv2-guide textarea, .iv2-guide select {
  font: inherit; font-size: .92rem; padding: .55rem .7rem;
  border: 1px solid var(--sand-dark); border-radius: 8px; background: #fff; color: var(--ink);
  width: 100%;
}
.iv2-guide button[type="submit"] {
  font: inherit; font-size: .9rem; font-weight: 700; cursor: pointer;
  padding: .55rem 1.1rem; border: 0; border-radius: 8px;
  background: var(--navy); color: #fff;
}
.iv2-guide button[type="submit"]:disabled { opacity: .55; cursor: default; }
.iv2-label { display: block; margin-top: .7rem; font-size: .82rem; font-weight: 600; color: var(--ink-soft); }
.iv2-label input, .iv2-label textarea, .iv2-label select { margin-top: .25rem; font-weight: 400; color: var(--ink); }

/* Honeypot: off-screen rather than display:none, so bots that skip hidden
   fields still fill it. Never focusable, never announced. */
.iv2-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.iv2-form-msg:empty { display: none; }
.iv2-form-msg { margin-top: .6rem; font-size: .86rem; font-weight: 600; }
.iv2-form-msg.is-ok { color: #46603C; }
.iv2-form-msg.is-error { color: var(--brick); }

/* accordion — the four identity doors, compressed */
.iv2-acc { margin-top: 1.1rem; padding-top: 1rem; border-top: 1px solid rgba(42, 65, 89, .14); }
/* Section heading, NOT a disclosure control (owner ask 2026-07-23). It carries
   no triangle and no pointer, so nothing invites a click that does nothing.
   Sized as a peer of .iv2-sub; the doors underneath are the interactive layer. */
.iv2-acc-head {
  font-size: .95rem; font-weight: 700; color: var(--ink); margin-bottom: .5rem;
}
.iv2-ask-summary, .iv2-door-label, .iv2-deeper-summary, .iv2-more summary {
  cursor: pointer; font-weight: 700; list-style: none;
}
.iv2-ask-summary::-webkit-details-marker,
.iv2-door-label::-webkit-details-marker, .iv2-deeper-summary::-webkit-details-marker,
.iv2-more summary::-webkit-details-marker { display: none; }
.iv2-ask-summary::before, .iv2-door-label::before,
.iv2-deeper-summary::before, .iv2-more summary::before { content: '\25B8\00A0'; color: var(--issue-accent); }
.iv2-ask[open] > .iv2-ask-summary::before,
.iv2-door[open] > .iv2-door-label::before, .iv2-deeper[open] > .iv2-deeper-summary::before,
.iv2-more[open] > summary::before { content: '\25BE\00A0'; }

.iv2-door { padding: .6rem 0; border-bottom: 1px solid rgba(42, 65, 89, .10); }
.iv2-door-label { font-size: .95rem; }
.iv2-door-q { margin-top: .4rem; font-size: 1rem; font-style:italic; color: var(--ink-soft); margin-left:2rem; }
.iv2-door-take { font-size: .9rem; margin:1rem 2rem; }
.iv2-door-take a { color: var(--navy); font-weight: 600; }
.iv2-door-link { display: inline-block; margin-top: .5rem; font-size: .86rem; font-weight: 600; color: var(--navy);  margin:0 0 2rem 2rem;}
.iv2-ask { margin-top: .9rem; }
.iv2-ask-form { margin-top: .5rem; margin-left:2rem; }
.iv2-ask-form button[type="submit"] { margin-top: .8rem; }

/* ── Z6 · timeline ───────────────────────────────────────────── */
.iv2-timeline { display: flex; flex-direction: column; }
.iv2-timeline > .iv2-zone-head { order: 0; }
/* order: 1 is intentionally vacant — .iv2-ahead was removed (Z2 is the one clock). */
.iv2-updates  { order: 2; }
.iv2-more     { order: 3; margin-top: .7rem; font-size: .86rem; }
.iv2-outcomes { order: 4; }
.iv2-feed     { order: 5; margin-top: 1.2rem; }

.iv2-update {
  display: block; padding: .7rem 0; border-top: 1px solid var(--sand-dark);
  font-size: .95rem; line-height: 1.55;
}
.iv2-update-date {
  display: block; font-size: .78rem; font-weight: 700; letter-spacing: .02em;
  color: var(--issue-accent);
}
.iv2-update-body { display: block; max-width: var(--iv2-measure); }
.iv2-update-link { display: block; margin-top: .2rem; }
.iv2-update-link a {
  display: inline-flex; align-items: baseline; gap: .35rem;
  color: var(--issue-accent); font-weight: 600; font-size: .88rem;
}
/* Icon is CSS-only so the pre-rendered link_html in class.issue.php is untouched.
   mask + currentColor means it inherits the link colour, including on hover. */
.iv2-update-link a::after,
.iv2-source a::after {
  content: ''; width: .72em; height: .72em; flex: 0 0 auto;
  background-color: currentColor;
  -webkit-mask: var(--iv2-icon-external) center / contain no-repeat;
          mask: var(--iv2-icon-external) center / contain no-repeat;
}
/* Two-column at desktop: date rail + body. Shortens the measure and makes the
   chronology scannable at the wider shell. */
@media (min-width: 760px) {
  .iv2-update {
    display: grid; grid-template-columns: 7.5rem 1fr; column-gap: 1.1rem;
  }
  .iv2-update-date { grid-column: 1; padding-top: .12rem; }
  .iv2-update-body { grid-column: 2; }
  .iv2-update-link { grid-column: 2; }
}
/* Past compressed: three entries, the rest behind the toggle. The toggle sits
   BEFORE the list in source order (CSS has no previous-sibling selector) and
   flex `order` above puts it back underneath. The list template carries
   .remove-template, so clone 1 really is :nth-child(1). */
.iv2-updates .iv2-update:nth-child(n+4) { display: none; }
.iv2-more[open] ~ .iv2-updates .iv2-update:nth-child(n+4) { display: block; }
.iv2-more[open] > summary { color: var(--issue-accent); }

.iv2-feed-list { list-style: none; }
.iv2-feed-row { padding: .45rem 0; border-top: 1px solid var(--sand-dark); font-size: .88rem; }
.iv2-feed-row a { text-decoration: none; }
.iv2-feed-day { font-weight: 700; color: var(--issue-accent); margin-right: .4rem; }

/* ── Z7 · go deeper ──────────────────────────────────────────── */
.iv2-deeper { border-top: 1px solid var(--sand-dark); padding-top: 1rem; }
.iv2-shelf { margin-top: 1rem; }
.iv2-source-group + .iv2-source-group { margin-top: .9rem; }
.iv2-source-group-head {
  font-size: .74rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--ink-soft); margin-bottom: .25rem;
}
.iv2-source-count { font-weight: 400; color: var(--color-text-tertiary); }
.iv2-source-count::before { content: '('; }
.iv2-source-count::after  { content: ')'; }
.iv2-sources { list-style: none; }
.iv2-source { padding: .3rem 0; font-size: .88rem; }
.iv2-source a { color: var(--issue-accent); }
.iv2-metrics { display: flex; flex-wrap: wrap; gap: .4rem; }
.iv2-metric {
  font-size: .8rem; padding: .3rem .7rem; border: 1px solid var(--sand-dark);
  border-radius: 999px; text-decoration: none; color: var(--ink-soft);
}
.iv2-stories { list-style: none; }
.iv2-story { padding: .3rem 0; font-size: .9rem; }
.iv2-story a { color: var(--issue-accent); }
.iv2-disclaimer { margin-top: 1rem; font-size: .8rem; color: var(--color-text-tertiary); }

.iv2-foot { border-top: 1px solid var(--sand-dark); padding-top: 1rem; font-size: .82rem; color: var(--ink-soft); }
.iv2-foot a { color: var(--issue-accent); font-weight: 600; white-space: nowrap; }

/* ── Z4 · the numbers (merged) ───────────────────────────────
   The shared panel recipe near the top of this file is scoped
   `.issue-guide .stat-card`, which the v2 page is NOT — so before this block a
   public visitor saw these cards with zero padding, no border, transparent
   background and a 17px number. It only ever LOOKED styled to signed-in admins,
   because admin.css carries a bare `.stat-card` rule that bleeds onto the page
   for them (verified 2026-07-23 by disabling the admin sheets in-browser).
   Re-declared here rather than widening the shared selector, which the frozen
   flagship page depends on. */
.iv2-guide .stat-card {
  background: #fff; border: 1px solid var(--sand-dark); border-radius: var(--radius);
  box-shadow: var(--issue-shadow);
  padding: 1rem 1.1rem; display: flex; flex-direction: column; gap: .25rem;
}
.iv2-guide .stat-card .stat-icon   { color: var(--ink-soft); line-height: 0; font-size:2.5rem; margin:0.5rem 0;}
.iv2-guide .stat-card .stat-number { font-weight: 700; font-size: 1.7rem; line-height: 1.1; color: var(--issue-accent); overflow-wrap: anywhere; }
.iv2-guide .stat-card .stat-label  { font-weight: 600; color: var(--ink); line-height: 1.3; }
.iv2-guide .stat-card .stat-sub    { font-size: .85rem; color: var(--ink); line-height: 1.4; margin-top:0.5rem;}
.iv2-guide .stat-card .stat-note   { font-size: .9rem; line-height: 1.5; color: var(--ink); margin-top: .15rem; }
/* Attribution sits at the card foot, visually subordinate but always present:
   a large number must never read as an independently measured fact. */
.iv2-guide .stat-card .stat-attribution {
  margin-top: auto; padding-top: .5rem; font-size: .76rem; line-height: 1.4;
  color: var(--color-text-tertiary);
}
.iv2-guide .stat-card .stat-attribution a { color: var(--color-text-tertiary); text-decoration: underline; }
/* Wider minimum than the flagship's 150px: these cards now carry a sentence
   and an attribution line, not just a number. */
.iv2-facts .stat-grid { grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }

/* ── Z2b · open_decisions: what is still being decided ────────
   Cards, not a label/value table. The old two-column shape had nowhere to put
   "who decides" or "can I speak", which is what pushed authors into agency
   shorthand. Slot labels are emitted by the renderer so they cannot drift. */
.iv2-levers .od-head { margin-bottom: .8rem; }
.od-list { display: grid; gap: .8rem; }
@media (min-width: 760px) { .od-list { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); } }
.od-card {
  background: #fff; border: 1px solid var(--sand-dark); border-radius: var(--radius);
  box-shadow: var(--issue-shadow); padding: .95rem 1.05rem 1rem;
  border-left: 3px solid var(--issue-accent);
}
.od-title { font-size: 1rem; font-weight: 700; line-height: 1.3; color: var(--ink); margin-bottom: .35rem; }
.od-what  { font-size: .95rem; line-height: 1.5; color: var(--ink); margin-bottom: .55rem; }
.od-slot  { font-size: .88rem; line-height: 1.45; margin-top: .3rem; }
.od-k { font-weight: 700; color: var(--ink-soft); }
.od-k::after { content: ': '; }
.od-v { color: var(--ink); }
/* "Can you speak?" is the one slot a reader is scanning for, so it gets the

   accent — the only colour in the card that is not structural. */
.od-slot--say .od-k { color: var(--issue-accent); }
.od-ref {
  margin-top: .6rem; padding-top: .5rem; border-top: 1px solid var(--sand);
  font-size: .78rem; color: var(--color-text-tertiary);
}
.od-ref a { color: var(--color-text-tertiary); text-decoration: underline; }
.od-help {
  margin-top: .85rem; font-size: .92rem; line-height: 1.5;
  color: var(--ink); max-width: var(--iv2-measure);
}
.od-help a { color: var(--navy); font-weight: 600; }

/* ── meter: one quantity against an allowed limit ─────────────
   Same-ramp track (sky-light) + fill (issue accent). Mark spec: track capped at
   20px (<=24px), 4px rounded data-end, square at the baseline where the fill
   starts from zero. No legend — one series, and the caption names it. Both
   figures are visible text, which is the required relief for the light track's
   1.69:1 contrast against the surface. */
.ff-meter { margin: 0; }
.meter-head { margin-bottom: .75rem; }
.meter-track {
  position: relative; height: 20px; border-radius: 0 4px 4px 0;
  background: var(--sky-light); overflow: hidden;
}
.meter-fill {
  position: absolute; inset: 0 auto 0 0; height: 100%;
  border-radius: 0 4px 4px 0; background: var(--issue-accent);
}
/* A cap already exceeded is a real state and must not look like a full-but-fine
   bar: the fill switches to the warning hue and the track keeps its own colour. */
.ff-meter.is-over .meter-fill { background: var(--brick); }

.meter-side { display: flex; flex-wrap: wrap; align-items: baseline; gap: .1rem .5rem; }
.meter-actual { margin-bottom: .4rem; }
.meter-limit  { margin-top: .4rem; }
.meter-value  { font-size: 1.15rem; font-weight: 700; color: var(--ink); }
.meter-label  { font-size: .9rem; color: var(--ink-soft); }
/* Text never wears the data colour — the mark beside it carries identity. */
.meter-attribution { flex: 1 0 100%; font-size: .76rem; line-height: 1.4; color: var(--color-text-tertiary); }
.meter-attribution a { color: var(--color-text-tertiary); text-decoration: underline; }
.meter-note {
  margin-top: .7rem; font-size: .9rem; line-height: 1.5; color: var(--ink);
  max-width: var(--iv2-measure);
}

@media (min-width: 700px) {
  .iv2-guide { padding: 2rem 1.5rem 5rem; }
  .iv2-h1 { font-size: 2.25rem; }
}


/* -- Question spine (slice 1, design doc S2) --------------------------------
   The question REPLACES the module heading (js/issue-modules.js emits it and
   passes suppress_title to the renderer). Sized between .iv2-zone-head (the
   small uppercase part label) and .issue-section-head, so the four parts still
   read as the coarser structure. */
.issue-question {
    font-family: 'DM Serif Display', serif;
    font-size: 1.45rem;
    line-height: 1.25;
    color: var(--ink);
    margin: 2.25rem 0 .85rem;
}
.issue-question:first-child { margin-top: 0; }
@media (max-width: 768px) {
    .issue-question { font-size: 1.25rem; margin: 1.75rem 0 .7rem; }
}
/* -- Outcomes comparison table (slice 5, design doc S6) ---------------------
   Replaces three stacked navy card-tables with one: columns are the outcomes,
   rows are the labels they share. Same seeded copy, a third of the chrome.
   The renderer falls back to .oc-card when the labels diverge, so both sets of
   styles have to keep working. */
.oc-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; margin: 0 0 .6rem; }
.oc-table {
    width: 100%; min-width: 32rem; border-collapse: collapse;
    font-size: .92rem; line-height: 1.5;
}
.oc-table thead th {
    background: var(--navy); color: #fff; text-align: left; vertical-align: bottom;
    font-size: .86rem; font-weight: 700; padding: .6rem .8rem;
    border-right: 1px solid rgba(255,255,255,.14);
}
.oc-table thead th:last-child { border-right: 0; }
.oc-table thead th.oc-corner { width: 11rem; background: var(--navy); }
.oc-table tbody th {
    background: var(--sand); text-align: left; vertical-align: top; font-weight: 700;
    font-size: .8rem; color: var(--ink-soft); padding: .65rem .8rem;
    border-bottom: 1px solid var(--sand-dark); width: 11rem;
}
.oc-table tbody td {
    vertical-align: top; padding: .65rem .8rem; color: var(--ink);
    border-bottom: 1px solid var(--sand-dark); border-left: 1px solid var(--sand-dark);
}
.oc-table tbody tr:last-child th, .oc-table tbody tr:last-child td { border-bottom: 0; }
.oc-fineprint { font-style: italic; font-size: .86rem; color: var(--color-text-tertiary); margin: 0; }
/* -- Effort tiers, cost-first (slice 4, design doc S7) ----------------------
   cost | label (+ hoisted help). The cost column is read FIRST: the question
   these answer is "how much of me does this need", which is a different
   question from the doors' "who am I". Phone collapses to one column with
   the cost still leading. Rows are divs, not links (8b de-linking) — the
   third grid track only ever gets a child on the one row that embeds the
   follow form (.ab-tier--follow .ab-tier-formslot); every other row leaves
   it empty, and an untenanted "auto" track sizes to 0 (verified via
   getBoundingClientRect at 375px and desktop, slice 6 sweep), so it is not a
   layout bug. */
.ab-tier {
    display: grid; grid-template-columns: 9.5rem 1fr auto; align-items: baseline;
    gap: .35rem .9rem; padding: .8rem .95rem;
    border: 1px solid var(--sand-dark); border-radius: var(--radius);
    background: var(--warmwhite); margin-top: .5rem; margin-bottom: .5rem;
}
.ab-tier--formal { border-color: var(--terracotta); border-width: 1.5px; }
.ab-cost {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: .74rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
    color: var(--terracotta);
}
.ab-tier-body { display: block; min-width: 0; }
.ab-tier-label { display: block; font-weight: 700; font-size: .85rem; color: var(--ink); line-height: 1.35; }
.ab-tier-help { display: block; font-size: .84rem; color: var(--ink-soft); margin-top: .2rem; }
.ab-micro { font-size: .8rem; color: var(--color-text-tertiary); margin: 0 0 1.1rem; }

@media (max-width: 560px) {
    .ab-tier { grid-template-columns: 1fr auto; }
    .ab-cost { grid-column: 1 / -1; }
}


/* The composition bar (donut "style":"bar"). Same palette as the ring, same
   value-labelled legend; only a dominant segment carries its label inline,
   in white on the deepened slot-0 hue (owner 2026-07-28; 4.7:1). The legend
   always carries every exact value. */
.ffbar-track { display: flex; gap: 2px; height: 26px; border-radius: 4px; overflow: hidden; margin: .35rem 0 .5rem; }
.ffbar-seg { min-width: 3px; display: flex; align-items: center; }
.ffbar-seg-label { font-size: .72rem; font-weight: 700; color: #Fff; padding-left: .5rem; white-space: nowrap; }

/* ============================================================================
   Anchored jumps (7c, consolidation review)
   The v3 shell this block dressed is gone (Apple-way slice 5): the
   microcopy link, the on-page nav and the record anchor went with it. What
   is left is the one rule that still has readers — the question headings
   every issue page renders, and page.issue-std.php's #iv2-action.
   ========================================================================== */
.issue-question, #iv2-action { scroll-margin-top: calc(var(--nav-h) + 1rem); }

/* ============================================================================
   7d - GALLERY THUMBNAIL RAIL (consolidation review U3)
   Desktop swaps the dots for labelled thumbs (the PDP pattern); phones keep
   the dots and swipe. Both live in the DOM; the 900px shell decides.
   ========================================================================== */
.ig-thumbs { display: none; }
@media (min-width: 900px) {
  .ig-dots { display: none; }
  .ig-thumbs { display: flex; gap: .45rem; padding: .55rem 0 0; }
  .ig-thumb {
    flex: 1 1 0; min-width: 0; background: none; border: 0; padding: 0;
    cursor: pointer; font: inherit; color: var(--ink-soft); text-align: center;
  }
  .ig-thumb-art {
    display: flex; align-items: center; justify-content: center;
    aspect-ratio: 1 / 1; border: 1.5px solid var(--sand-dark); border-radius: 6px;
    background: var(--sand); overflow: hidden;
  }
  .ig-thumb-art img { width: 100%; height: 100%; object-fit: cover; display: block; }
  .ig-thumb-n { font-family: 'DM Serif Display', Georgia, serif; font-size: 1.05rem; color: var(--ink-soft); }
  .ig-thumb.on .ig-thumb-art { border-color: var(--terracotta); box-shadow: 0 0 0 1px var(--terracotta); background: #fff; }
  .ig-thumb.on { color: var(--ink); }
  .ig-thumb:focus-visible .ig-thumb-art { outline: 2px solid var(--terracotta); outline-offset: 2px; }
  /* Two lines, not one (2026-07-30). A thumb is ~51px wide at 8 slides; even the
     short `thumb` labels need 54-88px on a single line, so nowrap ellipsized all
     but one of them. Clamping at two lines fits every label and costs ~12px of
     rail height. Galleries with no `thumb` field (Marathon) keep their full title
     here and simply show two lines of it instead of one. */
  .ig-thumb-t {
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
    font-size: .62rem; line-height: 1.25; margin-top: .3rem;
    overflow: hidden; overflow-wrap: break-word;
  }
}

/* R5: tier 1 IS the follow form. The row is a div (not a link), the embedded
   form drops its own heading and note (the cost + label already say it), and
   the field row rides in the third grid column - full-width on phones. */
.ab-tier--follow .ab-tier-formslot { min-width: 0; }
@media (max-width: 700px) {
  .ab-tier--follow .ab-tier-formslot { grid-column: 1 / -1; }
}

/* ============================================================================
   8b - TIER DE-LINKING (owner note n4, 2026-07-28)
   The effort-tier rows are divs, not links: a row-wide tap that dialled a
   phone is hostile on a handset, and the row hover state was inviting a click
   that did nothing useful. The only tappable things inside the box are tier
   1's form and this number, so the number has to look tappable on its own --
   it no longer inherits any affordance from its row.
   ASCII-only in this block, per the escape convention at the ladder markers.
   ========================================================================== */
.ab-tier-tel { color: var(--terracotta); font-weight: 700; text-decoration: none; }
/* Two standalone rules, never one selector list: a browser that cannot parse
   :focus-visible drops the WHOLE rule it appears in, and the hover state would
   go down with it. Split, each survives on its own. */
.ab-tier-tel:hover { text-decoration: underline; }
.ab-tier-tel:focus-visible { text-decoration: underline; }

/* ── The agenda item's old shell (Phase 3 Stage A) ────────────────────────
   Phone-first. Chips, cards and the lang toggle reuse the existing iv2-*
   tokens; .issue-map-canvas already sizes the map mount, so nothing here
   restates it. `.ai-*` = the single item page.

   The `tw-*` half of this block — the whole weekly screen, from `tw-screen` to
   `tw-foot` — was DELETED by the Apple-way rewrite of /this-week and /meetings
   (slice 3, 2026-09-13): those were its only two readers and both now render
   the `ffa-` vocabulary in css/ffa.css. The item-page half is NOT retired with
   it. page/page.case.php (:224 `ai-screen`, :609 `ai-missing`, the comment at
   :219 that says `.cs-*` deliberately borrows this layer) and
   page/page.meeting-transcript.php (`ai-screen`, `ai-crumbs`,
   `ai-crumbs-here`, `ai-title`, `ai-missing`) still read every rule below, and
   restyling those two pages is a later slice's job, not this one's. */

/* Two body classes left this rule with the Apple-way rewrites of slice 3
   (2026-09-13): `.page-agenda-item` with the item page, and `.page-this-week`
   with /this-week — which /meetings used to borrow and now names itself
   `page-meetings`, because an index of every meeting we have is not this week.
   Their grounds now alternate warm white · sand · near-black per section
   (house rule 3), and a body painted sand can only flatten them — a
   `.ffa-sand` section on a sand body is not a section break at all. The
   classes themselves stay on those pages; what moved is the ground.
   What is LEFT here is the one template that still wants a sand page: the
   transcript reader, which is one long run of spoken text rather than a set of
   bands, and whose `.tr-unint` colour below (:3551) is contrast-checked against
   this exact ground. page.case.php was never affected (it has its own
   `.page-case` rule at :3188). */
.page-transcript { background: var(--sand); }

.ai-screen {
    margin: 0 auto;
    padding: 1.5rem 1rem 3rem;
}
/* Split 2026-08-14: the item page's two-column bands need the wider screen.
   (The 720px `tw-screen` that shared this rule went with the weekly list.) */
.ai-screen { max-width: 1100px; }

/* ── Single agenda item ── */
.ai-back { margin: 0 0 1rem; font-size: .9rem; }
.ai-chips { display: flex; flex-wrap: wrap; gap: .35rem; margin: 0 0 .75rem; }
.ai-chip-issue { text-decoration: none; background: var(--navy-soft); }
.ai-title {
    /* Officialese runs long; the full text lives in .ai-official below. */
    display: -webkit-box;
    -webkit-line-clamp: 4;
    -webkit-box-orient: vertical;
    overflow: hidden;
    font-size: 1.35rem;
    line-height: 1.3;
    margin: 0 0 .6rem;
}
.ai-meta { color: var(--ink-soft); font-size: .9rem; margin: 0 0 .2rem; }
.ai-itemno { color: var(--color-text-tertiary); font-size: .8125rem; margin: 0 0 1.25rem; }

.ai-official {
    background: var(--warmwhite);
    border: 1px solid var(--sand-dark);
    border-radius: var(--radius);
    padding: .75rem 1rem;
    margin: 0 0 1.5rem;
}
.ai-official > summary { cursor: pointer; font-size: .9rem; color: var(--ink-soft); }
.ai-official-text { white-space: pre-wrap; font-size: .9rem; line-height: 1.5; margin: .75rem 0 0; }

/* ── Staff-report analysis (slice 3) ── */
.ai-report {
    background: var(--warmwhite);
    border: 1px solid var(--sand-dark);
    border-radius: var(--radius);
    padding: 1.1rem 1.15rem;
    margin: 0 0 1.75rem;
}
/* pre-line preserves the model's paragraph breaks (clean_text keeps newlines
   for exactly this reason) without collapsing them like normal white-space. */
.ai-report-summary { font-size: .95rem; line-height: 1.55; margin: 0 0 .85rem; white-space: pre-line; }

/* The amber "guardrail" tone — a caution note, not an error. */
.ai-report-draft {
    display: inline-block;
    background: var(--ochre-soft, #FBF3DE);
    border: 1px solid #EFDFB4;
    border-radius: 999px;
    padding: .3rem .75rem;
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: #8A6B18;
    margin: 0 0 .85rem;
}

.ai-report-facts { list-style: none; margin: 0 0 1rem; padding: 0; }
.ai-report-facts li {
    display: flex;
    gap: .6rem;
    padding: .5rem 0;
    border-bottom: 1px solid var(--sand-dark);
    font-size: .9rem;
}
.ai-report-facts li:last-child { border-bottom: none; }
.ai-report-facts li > span:first-child {
    flex: 0 0 auto;
    min-width: 5.5rem;
    color: var(--ink-soft);
}

.ai-h3 { font-size: .95rem; margin: 0 0 .6rem; }
.ai-report-notes { margin: 0 0 1rem; }
.ai-note-list { list-style: none; margin: 0; padding: 0; }
.ai-note {
    padding: .6rem 0;
    border-bottom: 1px solid var(--sand-dark);
    font-size: .9rem;
    line-height: 1.5;
    white-space: pre-line;
}
.ai-note:last-child { border-bottom: none; }

.ai-siteplan { margin: 0 0 1rem; }
.ai-siteplan-link { display: block; }
.ai-siteplan-canvas {
    display: block;
    max-width: 100%;
    border: 1px solid var(--sand-dark);
    border-radius: 8px;
}

.ai-report-note { font-size: .8125rem; line-height: 1.5; color: var(--color-text-tertiary); margin: 0; }
.ai-report-note a { margin-left: .35rem; }

.ai-rel-list { list-style: none; margin: 0; padding: 0; }
.ai-rel {
    display: flex;
    flex-wrap: wrap; /* status+year metadata drops below the title on narrow screens */
    justify-content: space-between;
    align-items: baseline;
    gap: .25rem .75rem;
    padding: .6rem 0;
    border-bottom: 1px solid var(--sand-dark);
    font-size: .9rem;
}
.ai-rel > a {
    flex: 1 1 12rem; /* title claims the line first; meta wraps below when tight */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.ai-rel-date { flex: 0 0 auto; font-size: .8125rem; color: var(--color-text-tertiary); white-space: nowrap; }

.ai-map { margin: 0 0 1.75rem; }

.ai-h2 { font-size: 1.05rem; margin: 0 0 .75rem; }
.ai-stats { margin: 0 0 1.75rem; }
.ai-stat-list { list-style: none; margin: 0 0 .6rem; padding: 0; }
.ai-stat {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    padding: .6rem 0;
    border-bottom: 1px solid var(--sand-dark);
}
.ai-stat-label { color: var(--ink-soft); }
.ai-stat-value { font-weight: 600; white-space: nowrap; }
.ai-stats-note { font-size: .8125rem; color: var(--color-text-tertiary); margin: 0; }

.ai-docs { margin: 0 0 1.75rem; }
.ai-doc-list { list-style: none; margin: 0; padding: 0; }
.ai-doc {
    padding: .6rem 0;
    border-bottom: 1px solid var(--sand-dark);
    font-size: .9rem;
}
.ai-doc-orig { margin-left: .35rem; font-size: .8125rem; color: var(--color-text-tertiary); }

.ai-act {
    background: var(--warmwhite);
    border: 1px solid var(--sand-dark);
    border-radius: var(--radius);
    padding: 1.1rem 1.15rem;
    margin: 0 0 1.5rem;
}
.ai-act-when { margin: 0 0 .75rem; font-size: .95rem; }
.ai-act-links { list-style: none; margin: 0; padding: 0; }
.ai-act-links li { margin: 0 0 .4rem; }

.ai-related { margin: 0 0 1.75rem; }

.ai-provenance {
    border-top: 1px solid var(--sand-dark);
    padding-top: 1rem;
    font-size: .8125rem;
    color: var(--color-text-tertiary);
}
.ai-provenance a { margin-left: .5rem; }

.ai-missing {
    background: var(--warmwhite);
    border: 1px dashed var(--sand-dark);
    border-radius: var(--radius);
    padding: 1.25rem;
    color: var(--ink-soft);
}

/* ── Agenda item redesign (owner mockup, 2026-08-14) ───────────────────────
   Phone-first: everything stacks in source order until 900px, where the header
   and the two content bands become grids. Cards reuse the site recipe
   (--warmwhite on --sand-dark, --radius). Icons are decorative — the template
   carries aria-hidden on every one. */

.ai-crumbs { font-size: .8125rem; color: var(--ink-soft); margin: 0 0 1rem; }
.ai-crumbs a { color: var(--ink-soft); }
.ai-crumbs span[aria-hidden] { margin: 0 .15rem; color: var(--color-text-tertiary); }
.ai-crumbs-here { color: var(--color-text-tertiary); }

/* ── Header: title zone (left) + meeting card (right) ── */
.ai-header { margin: 0 0 1.25rem; }
/* min-width:0 — an unbroken officialese string must not blow out its grid track. */
.ai-header-main { min-width: 0; }

.ai-title { font-size: 1.75rem; }
.ai-title--long { font-size: 1.3rem; }
.ai-h2 > i { color: var(--navy); margin-right: .4rem; }

/* Sage fill to match the mockup's green ON THE AGENDA chip. Ink stays dark:
   never sage text on a sage field. */
.ai-chip-status { background: var(--sage-light); border-color: var(--sage-light); color: var(--ink); }

/* Short-title variant: the officialese IS the summary — clamped to 4 lines
   closed, released on open. The chevron is an affordance glyph on the details
   element itself, so it can't be eaten by the clamp box. */
.ai-official--inline { padding: .65rem .9rem; }
.ai-official-clamp {
    display: -webkit-box;
    -webkit-line-clamp: 4;
    -webkit-box-orient: vertical;
    overflow: hidden;
    cursor: pointer;
    font-size: .875rem;
    line-height: 1.5;
    color: var(--ink-soft);
    list-style: none;
}
.ai-official-clamp::-webkit-details-marker { display: none; }
.ai-official--inline[open] .ai-official-clamp { -webkit-line-clamp: unset; overflow: visible; }
.ai-official--inline::after {
    content: '\25BE';
    display: block;
    margin-top: .25rem;
    font-size: .75rem;
    color: var(--navy);
}
.ai-official--inline[open]::after { content: '\25B4'; }

/* ── Meeting card ── */
.ai-meetcard {
    background: var(--warmwhite);
    border: 1px solid var(--sand-dark);
    border-radius: var(--radius);
    padding: 0;
    /* clips the navy block to the card's own radius */
    overflow: hidden;
    margin: 1rem 0 0;
    align-self: start;
}
.ai-meetcard-rows { list-style: none; margin: 0; padding: .9rem 1rem; }
.ai-meetcard-rows li {
    display: flex;
    gap: .55rem;
    align-items: baseline;
    font-size: .875rem;
    line-height: 1.45;
    margin: 0 0 .5rem;
}
.ai-meetcard-rows li:last-child { margin-bottom: 0; }
.ai-meetcard-rows i { flex: 0 0 1.25rem; color: var(--navy); text-align: center; }

.ai-itembox { background: var(--navy); color: var(--warmwhite); padding: .85rem 1rem 1rem; }
.ai-itembox-no {
    margin: 0 0 .6rem;
    font-size: .8125rem;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
}
.ai-itembox-btn {
    display: inline-block;
    border: 1px solid var(--warmwhite);
    border-radius: 999px;
    padding: .4rem .85rem;
    font-size: .8125rem;
    line-height: 1.3;
    color: var(--warmwhite);
    text-decoration: none;
}
.ai-itembox-btn:hover { background: var(--warmwhite); color: var(--navy); }

/* ── Staff-report facts strip ── */
.ai-facts {
    background: var(--warmwhite);
    border: 1px solid var(--sand-dark);
    border-radius: var(--radius);
    padding: 1rem 1.15rem;
    margin: 0 0 1rem;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 1rem;
}
.ai-fact { display: grid; grid-template-columns: 1.25rem 1fr; column-gap: .5rem; row-gap: .15rem; }
.ai-fact > i { grid-row: 1 / span 2; color: var(--navy); font-size: .95rem; padding-top: .15rem; text-align: center; }
.ai-fact-label {
    font-size: .75rem;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--ink-soft);
}
/* anywhere, not break-all: a staff-contact email must wrap rather than widen
   the whole grid track. */
.ai-fact-value { font-size: .9rem; line-height: 1.4; color: var(--ink); overflow-wrap: anywhere; }

/* ── Public input callout ── */
.ai-pubinput {
    /* Flat rgba first for engines without color-mix (older Safari), then the
       token-derived tint. Body text stays --ink — never sage on sage. */
    background: rgba(122, 154, 109, .16);
    background: color-mix(in srgb, var(--sage-light) 30%, var(--warmwhite));
    border-radius: var(--radius);
    padding: .85rem 1rem;
    margin: 0 0 1.5rem;
    font-size: .9rem;
    line-height: 1.5;
    color: var(--ink);
}
.ai-pubinput > i { color: #4E6B43; margin-right: .45rem; }

/* ── Two-column bands ── */
.ai-cols-main, .ai-cols-side { min-width: 0; }

.ai-notes-card {
    background: var(--warmwhite);
    border: 1px solid var(--sand-dark);
    border-radius: var(--radius);
    padding: 1.1rem 1.15rem;
    margin: 0 0 1.75rem;
}
/* white-space resets to normal on the flex row and back to pre-line on the
   text body, so the markup's inter-element newline can't become a stray item. */
.ai-note { display: flex; gap: .7rem; align-items: flex-start; white-space: normal; }
.ai-note-icon {
    flex: 0 0 2.25rem;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 50%;
    background: var(--sage-light);
    color: #3F5836;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: .85rem;
}
.ai-note-body { min-width: 0; white-space: pre-line; }

/* ── Map + stats band ── */
.ai-mapcard { margin: 0 0 1.75rem; }
.ai-mapcard .ai-map { margin-bottom: 0; }
.ai-stats {
    background: var(--warmwhite);
    border: 1px solid var(--sand-dark);
    border-radius: var(--radius);
    padding: 1.1rem 1.15rem;
}
.ai-stat-label > i { color: var(--navy); margin-right: .4rem; }

/* ── Documents ── */
.ai-docs {
    background: var(--warmwhite);
    border: 1px solid var(--sand-dark);
    border-radius: var(--radius);
    padding: 1.1rem 1.15rem;
}
.ai-doc > i { color: var(--navy); margin-right: .45rem; }

/* ── Weigh-in: heading + tile grid, no longer one card ── */
.ai-act { background: none; border: none; padding: 0; }
.ai-act-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: .75rem;
}
.ai-act-tile {
    display: flex;
    flex-direction: column;
    gap: .3rem;
    background: var(--warmwhite);
    border: 1px solid var(--sand-dark);
    border-radius: var(--radius);
    padding: .9rem 1rem;
    font-size: .875rem;
    color: var(--ink);
    text-decoration: none;
}
a.ai-act-tile:hover { border-color: var(--navy); }
.ai-act-tile > i { color: var(--navy); font-size: 1.05rem; }
.ai-act-tile--meeting { border-color: var(--navy); }
.ai-act-tile-label { font-weight: 600; }
.ai-act-tile-text { color: var(--ink-soft); font-size: .8125rem; line-height: 1.4; }

.ai-provenance > i { margin-right: .35rem; }

@media (min-width: 900px) {
    .ai-header { display: grid; grid-template-columns: 2fr 2fr; gap: 1.25rem; align-items: start; }
    .ai-meetcard { margin-top: 0; }
    .ai-cols { display: grid; grid-template-columns: 3fr 2fr; gap: 1.25rem; align-items: start; }
    .ai-provenance { display: flex; flex-wrap: wrap; align-items: baseline; }
    .ai-provenance-ask { margin-left: auto; }
}

/* ── Context stats: value + comparisons (2026-08-17) ──────────────────────
   The card sits in the narrow side column, so each metric stacks instead of
   forming a four-column table: headline row, then the county/national
   comparison, then where the tract falls among county tracts. Every
   comparison cell is gated server-side — an absent figure removes its cell
   rather than printing a placeholder. */
.ai-stat { display: block; }
.ai-stat-head { display: flex; justify-content: space-between; gap: .75rem; align-items: baseline; }
.ai-stat-cmp { display: flex; flex-wrap: wrap; gap: .35rem .9rem; margin-top: .3rem; }
.ai-stat-cmp-cell { display: inline-flex; gap: .3rem; align-items: baseline; font-size: .8125rem; }
.ai-stat-cmp-label { color: var(--color-text-tertiary); }
.ai-stat-cmp-value { color: var(--ink-soft); font-weight: 600; }
.ai-stat-pct {
    display: block;
    margin-top: .2rem;
    font-size: .75rem;
    line-height: 1.4;
    color: var(--color-text-tertiary);
}
.ai-stats-source {
    margin: .5rem 0 0;
    padding-top: .5rem;
    border-top: 1px solid var(--sand-dark);
    font-size: .75rem;
    line-height: 1.45;
    color: var(--color-text-tertiary);
}

/* ── Meeting page (/item/{date}/{body}) ────────────────────────────────────
   The page itself is the Apple-way vocabulary now (css/ffa.css, .ffa-am-*),
   and its old `.am-*` layer — header, glance tiles, agenda cards, doc list,
   band collapses — was deleted with slice 3 once page.agenda-meeting.php
   stopped rendering a single one of those classes.

   What is left here is NOT the meeting page's: js/issue-modules.js writes
   .issue-map-canvas.am-map-canvas and .am-legend / .am-legend-item for EVERY
   module map on the site, so the issue guides and page.case.php (:3567, the
   .cs-map override) draw them too. The meeting page's map is one caller of
   that module among several; css/ffa.css restyles only its shell. Renaming
   these three belongs to whichever slice restyles the module itself.        */
/* Current crumb: one step darker than the tertiary set at ~2825 so "you are
   here" doesn't read as a disabled link. Appended override, not an edit.
   .ai-* is still live on page.case.php and page.meeting-transcript.php. */
.ai-crumbs-here[aria-current] { color: var(--ink-soft); }

/* Sites map (the pin_map module's shell). The pins themselves are
   css/ffa.css's since 2026-09-27 (week and maps, the owner's R8): a numbered
   teardrop, 30x38, anchored at its point — no longer a disc here. */
.issue-module--pin_map { position: relative; }   /* parity with .issue-module--map at ~1119: contains the absolutely-positioned a11y summary */
.am-map-canvas { height: 380px; }
/* The venue's PERMANENT label carries a raw Legistar location string — let it wrap instead of clipping. */
.am-map-canvas .leaflet-tooltip.map-marker-label { max-width: 220px; white-space: normal; }
.am-legend { margin: .6rem 0 0; font-size: .8125rem; color: var(--ink-soft); display: flex; flex-wrap: wrap; gap: 1rem; }
.am-legend-item { display: inline-flex; align-items: center; gap: .3rem; }

@media (max-width: 480px) {
    .am-map-canvas { height: 260px; }   /* the appended rule would otherwise outrank the 240px phone rule at ~1128 */
}
/* Leaflet unreachable → the text fallback list. Must outrank BOTH .am-map-canvas
   heights above, or the fallback rows are trapped in a fixed-height box. */
.am-map-canvas.issue-map-canvas--fallback { height: auto; overflow: visible; }

/* ── /meetings ────────────────────────────────────────────────────────────
   The `mt-*` block that sat here — `mt-screen`, `mt-section`, `mt-months`,
   `mt-month`, `mt-month-head`, `mt-all` — was DELETED with the Apple-way rewrite
   of the meetings index (slice 3, 2026-09-13). page/page.meetings.php was its
   only reader; it now draws the grouped-list vocabulary from css/ffa.css.
   The crumb nudge `mt-screen .ai-crumbs` went with it — it only ever moved the
   crumbs INSIDE the deleted screen — while the four rules it leaned on are
   untouched above (:2761-2764) for page.case.php and the transcript reader. */

/* ── Meeting transcript reader (/item/{date}/{body}/transcript) ────────────
   Server-rendered, not PageMVC — see the header comment in
   page/page.meeting-transcript.php. It borrows the item page's shell
   (body_class="page-agenda-item") but narrows the column back to a reading
   measure: this is one long run of spoken text, not the item page's bands. */
.tr-screen { max-width: 820px; }

.tr-disclaimer {
    background: var(--warmwhite);
    border: 1px solid var(--sand-dark);
    border-radius: var(--radius);
    padding: .75rem 1rem;
    /* 3rem, not 1.5rem: it is also the clearance .tr-stickynote's upward
       box-shadow needs (see there), so the shadow only ever paints over empty
       page background at rest. */
    margin: 0 0 3rem;
    font-size: .8125rem;
    line-height: 1.55;
    color: var(--ink-soft);
}
.tr-disclaimer > i { color: var(--navy); margin-right: .35rem; }
.tr-disclaimer a { color: var(--navy); margin-left: .35rem; }

/* Pinned machine-transcription notice. Deep-linking is the dominant arrival on
   this page, and it lands far below the disclaimer card — so the short form
   travels with the reader. Sits UNDER .site-nav (z-index 100) in the stack. */
.tr-stickynote {
    position: sticky;
    top: var(--nav-h);
    z-index: 90;
    margin: 0 0 1.25rem;
    padding: .45rem .75rem;
    background: var(--warmwhite);
    border: 1px solid var(--sand-dark);
    border-radius: var(--radius);
    font-size: .75rem;
    line-height: 1.4;
    color: var(--ink-soft);
    /* --nav-h is now one declared 48px at every width, so the stepped token no
       longer over-reports and there is no band of slack between the two fixed
       bars for record text to scroll through. The box-shadow stays as belt and
       braces: it takes no layout space, travels with the sticky box, and paints
       page background over anything that would otherwise show above the note.
       .tr-disclaimer's 3rem bottom margin is the matching clearance so nothing
       but empty background sits under it at rest. */
    box-shadow: 0 -3rem 0 0 var(--sand);
}
.tr-stickynote > i { color: #47799A; margin-right: .35rem; }
.tr-stickynote a { color: var(--navy); margin-left: .4rem; white-space: nowrap; }

.tr-segments { list-style: none; margin: 0 0 2rem; padding: 0; }
.tr-seg {
    padding: .9rem 0;
    border-bottom: 1px solid var(--sand-dark);
    /* #seg-{id} arrivals must clear the sticky nav + notice stack, or the link
       lands on the speaker/timestamp row and hides the very thing it cited.
       Same idiom and same +4rem allowance as #issue-action above, which stacks
       under the identical pair. --nav-h is one value at every width, so this
       tracks the phone nav too. tabindex="-1" makes it a focus target, and
       :focus-visible is suppressed because arrival is programmatic, not a tab. */
    scroll-margin-top: calc(var(--nav-h) + 4rem);
}
.tr-seg:last-child { border-bottom: 0; }
.tr-seg:focus { outline: none; }
/* Arriving from a case-page excerpt's "full transcript ↗" link. The tint alone
   was 1.03:1 against --sand — invisible in grayscale and short of WCAG 1.4.11's
   3:1 for a non-text indicator — so the accent bar carries the signal (4.1:1)
   and the tint merely supports it. Negative margins cancel the added padding
   AND the border, so the highlighted segment does not jump sideways under the
   eye exactly where the deep link put it. */
.tr-seg:target {
    background: var(--navy-soft);
    border-left: 4px solid #47799A;
    border-radius: var(--radius);
    padding-left: .75rem;
    padding-right: .75rem;
    margin-left: calc(-.75rem - 4px);
    margin-right: -.75rem;
}

.tr-seg-head {
    display: flex;
    flex-wrap: wrap;        /* phone: the ▶ chip drops below a long speaker line */
    align-items: baseline;
    gap: .35rem .5rem;
    margin: 0 0 .35rem;
}
.tr-who { min-width: 0; font-size: .875rem; font-weight: 600; color: var(--ink-soft); }
.tr-role { font-weight: 400; color: var(--color-text-tertiary); }
/* #47799A is the mockup's ▶ chip (spec §13 — excerpt-anatomy.html and
   full-mockup.html both specify background:#47799A;color:#fff). It is not a
   :root token, but it IS a project colour: the deepened sky from the owner's
   2026-07-28 palette ruling, kept as DONUT_PALETTE[0] in js/issue-modules.js
   and chosen there for exactly this case — it holds WHITE text at 4.7:1 where
   --sky (#6B9DB8) sat at 2.9:1. Written as a literal because tokenising it
   would mean editing :root, and this block is append-only; raw hex is already
   the idiom here (27 other colour declarations in this file use it). */
.tr-ts {
    margin-left: auto;
    background: #47799A;
    color: #fff;
    border-radius: 4px;
    padding: 2px 8px;
    font-size: .75rem;
    text-decoration: none;
    white-space: nowrap;
}
/* No deep link available (no video_url, or a host whose time syntax we cannot
   vouch for). It must NOT wear the solid chip: that reads as interactive and
   this is inert text. Outlined and muted says "reference, not control". */
.tr-ts--plain {
    background: transparent;
    color: var(--ink-soft);
    border: 1px solid var(--sand-dark);
}
/* overflow-wrap: machine transcription can emit one unbroken token; a phone
   must wrap it rather than give the whole page a horizontal scrollbar. */
.tr-text { margin: 0; line-height: 1.6; overflow-wrap: anywhere; }

/* ── Case study (/case/{slug}) ─────────────────────────────────────────────
   page/page.case.php. Phone-first single scroll in spec §6 order; at 900px
   .cs-cols turns the last four zones into the owner's right rail (D9) using
   grid template areas, so the DOM never has to leave reading order.

   Colour note — same reasoning as the .tr-* block above: the mockups specify
   raw hex for the case-study accents and this block is append-only, so they
   are written as literals rather than :root tokens.
     #b0672a #faf3ec #8a4f1d #e8d9c8 #fdf8f2 — the amber "not in the record"
       family (full-mockup.html, full-mockup-v2.html)
     #47799A #eef3f6 #ccd8e0 #33586e #e8eef2 #f2f7fa — the record/excerpt blue
       (already in this file as .tr-ts; DONUT_PALETTE[0])
     #2e5d43 #f2f8f4 — approved-outcome / written-comment green

   Layout note — several zones aggregate independently gated children and the
   loader has no single has_* key for "any of them". page.js REMOVES a failed
   data-show_if element, so ":has() no element children" is exactly "no
   content", and that is what collapses those frames instead of printing a
   heading over nothing (spec §9). Browsers without :has() keep the heading;
   nothing breaks. */

.page-case { background: var(--sand); }

/* Flex column, not margins: a removed zone takes its gap with it. */
.cs-case { display: flex; flex-direction: column; gap: 2rem; }

/* The small uppercase label the mockups print above every zone. */
.cs-eyebrow {
    font-size: .72rem;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--ink-soft);
    font-weight: 700;
    margin: 0 0 .6rem;
}

.cs-draft {
    background: rgba(212, 168, 67, .18);
    border: 1px solid var(--ochre);
    border-radius: var(--radius);
    padding: .6rem .9rem;
    font-size: .85rem;
    color: var(--ink-soft);
}
.cs-draft > i { margin-right: .4rem; color: #8A6A16; }

/* ── 1 · Hero ── */
.cs-hero { border-bottom: 1px solid var(--sand-dark); padding-bottom: 1.5rem; }
.cs-hero-main { min-width: 0; }
.cs-kicker {
    font-size: .72rem; letter-spacing: .12em; text-transform: uppercase;
    color: #b0672a; font-weight: 700; margin: 0 0 .5rem;
}
.cs-title {
    font-family: 'DM Serif Display', Georgia, serif;
    font-size: 1.85rem; line-height: 1.2; text-wrap: balance; margin: 0 0 .5rem;
}
.cs-dek { color: var(--ink-soft); font-size: 1.05rem; line-height: 1.55; margin: 0 0 .9rem; max-width: 62ch; }
/* .cs-hero-chips, not .cs-chips: the exhibit chip LIST further down owns that
   name, and at equal specificity the later rule silently won — the hero row was
   inheriting the list's margin-top and gap. */
.cs-hero-chips { display: flex; flex-wrap: wrap; gap: .4rem; margin: 0; }
.cs-chip {
    display: inline-block; padding: .2rem .65rem; border-radius: 999px;
    background: #EDE7DA; color: var(--ink-soft); font-size: .75rem; font-weight: 600;
}
.cs-chip--outcome { background: #2e5d43; color: #fff; }

/* Photo strip: CSS scroll-snap, no carousel JS. One image looks intentional,
   ten scroll. Captions carry the meaning, so the <img> is alt="". */
.cs-hero-media { min-width: 0; }
.cs-carousel {
    list-style: none; margin: 0; padding: 0;
    display: flex; gap: .5rem; overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
}
.cs-slide { flex: 0 0 100%; scroll-snap-align: start; min-width: 0; }
.cs-slide-fig { margin: 0; }
.cs-slide-fig img {
    display: block; width: 100%; height: 200px; object-fit: cover;
    border-radius: var(--radius); background: var(--sand-dark);
}
.cs-slide-cap { font-size: .75rem; color: var(--color-text-tertiary); margin-top: .35rem; line-height: 1.4; }
/* An image with no caption must not spend the caption's margin. :empty is the
   right test HERE (and on .cs-metric-admits) because the element's whole
   content is one placeholder: substituting '' leaves no child nodes at all. It
   would NOT work on a zone whose children page.js removed — that leaves
   whitespace text nodes behind, which is why .cs-rail below uses :has(). */
.cs-slide-cap:empty { display: none; }

/* ── 2 · The case in 60 seconds ── */
.cs-glance:not(:has(.cs-glance-grid > *)) { display: none; }
.cs-glance-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: .6rem; }
.cs-tile {
    display: flex; flex-direction: column; gap: .25rem;
    border: 1px solid var(--sand-dark); border-radius: var(--radius);
    background: var(--warmwhite); padding: .8rem .9rem;
    color: var(--ink); text-decoration: none;
}
.cs-tile-l { font-size: .68rem; text-transform: uppercase; letter-spacing: .05em; color: var(--color-text-tertiary); }
.cs-tile-v { font-size: .9rem; font-weight: 600; line-height: 1.4; }
.cs-tile--omit { border: 1.5px solid #b0672a; background: #faf3ec; }
.cs-tile--omit .cs-tile-l { color: #b0672a; }
.cs-tile--omit .cs-tile-v { color: #8a4f1d; }
.cs-tile-jump { font-weight: 400; white-space: nowrap; }

/* ── 3 · Why this case matters (D3) ──
   The frame is a template fixture; the lesson and the numbered list are each
   gated, and the frame collapses when both are gone. */
.cs-why:not(:has(.cs-why-body > *)) { display: none; }
.cs-why {
    border: 1.5px solid #b0672a; border-radius: var(--radius); overflow: hidden;
    scroll-margin-top: calc(var(--nav-h) + 1rem);
}
.cs-why-h {
    background: #b0672a; color: #fff; margin: 0;
    padding: .5rem 1rem; font-size: .78rem; font-weight: 700;
    letter-spacing: .06em; text-transform: uppercase;
}
.cs-why-body { background: #fdf8f2; padding: 1rem 1.05rem; }
.cs-lesson { margin: 0; font-size: 1rem; line-height: 1.6; }
.cs-omit-wrap { margin-top: .9rem; }
.cs-omit-h {
    font-size: .7rem; letter-spacing: .06em; text-transform: uppercase;
    color: #b0672a; font-weight: 700; margin: 0 0 .5rem;
}
.cs-omit-list { list-style: none; margin: 0; padding: 0; display: grid; gap: .4rem; }
.cs-omit {
    background: var(--warmwhite); border: 1px solid #e8d9c8; border-radius: 8px;
    padding: .55rem .8rem; font-size: .9rem; line-height: 1.5;
}
.cs-omit-no { margin-right: .3rem; }
.cs-omit-jump { color: #b0672a; font-size: .78rem; white-space: nowrap; margin-left: .35rem; }

/* ── 4 · How a rezoning moves (D4) ──
   Bespoke markup in the process-steps VISUAL idiom, not an FFModules mount. */
.cs-strip-p { margin: 0 0 .8rem; color: var(--ink-soft); font-size: .95rem; line-height: 1.55; max-width: 70ch; }
.cs-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .4rem; }
.cs-step-box {
    flex: 1 1 150px; min-width: 0;
    border: 1px solid var(--sand-dark); border-radius: 8px;
    background: var(--warmwhite); padding: .5rem .65rem;
    font-size: .8rem; line-height: 1.35;
    display: flex; flex-direction: column; gap: .15rem;
}
.cs-step-name { font-weight: 600; }
.cs-step-sub { color: var(--ink-soft); font-size: .74rem; }
.cs-step-sub--notice { color: #8a4f1d; }
.cs-step-box--write { border: 2px solid #2e5d43; background: #f2f8f4; }
.cs-step-box--write .cs-step-sub { color: #2e5d43; }
.cs-step-box--speak { border: 2px solid #47799A; background: #f2f7fa; }
.cs-step-box--speak .cs-step-sub { color: #33586e; }

/* ── 5 · Timeline ── */
.cs-timeline { list-style: none; margin: 0; padding: 0; }
.cs-event { border-left: 2px solid var(--sand-dark); padding: 0 0 1.4rem 1.1rem; }
.cs-event:last-child { padding-bottom: 0; }
.cs-event-date {
    margin: 0; font-size: .78rem; letter-spacing: .04em; text-transform: uppercase;
    color: var(--ink-soft); font-weight: 700;
}
.cs-event-date i { color: var(--navy); margin-right: .35rem; }
.cs-event-title { font-size: 1.05rem; line-height: 1.35; margin: .15rem 0 .35rem; }
.cs-event-body { color: var(--ink-soft); line-height: 1.6; font-size: .95rem; }
.cs-event-meeting { margin: .6rem 0 0; font-size: .8rem; }
.cs-event-meeting > i { color: var(--navy); margin-right: .35rem; }
.cs-event-meeting a { color: var(--navy); }
.cs-event-transcript { margin-left: .6rem; }

.cs-anns { list-style: none; margin: 0; padding: 0; }
.cs-ann { margin-top: .7rem; }
.cs-ann-body { line-height: 1.6; font-size: .95rem; color: var(--ink-soft); }

/* Exhibit chips under a narrative or a callout. An exhibit whose URL the
   loader refused renders as the same chip WITHOUT an <a> — the citation stays
   readable, only the dead link is withheld. */
.cs-chips { list-style: none; margin: .5rem 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: .35rem; }
.cs-chip-li { display: inline-flex; flex-wrap: wrap; gap: .25rem; }
.cs-doc-chip {
    display: inline-block; background: #E8E8E4; border-radius: 4px;
    padding: .1rem .5rem; font-size: .75rem; color: var(--ink-soft); text-decoration: none;
}
.cs-doc-chip > i { margin-right: .25rem; }
a.cs-doc-chip { color: var(--navy); }
a.cs-doc-chip:hover { text-decoration: underline; }
.cs-doc-chip--pending { background: #FBE9E9; color: #A0342E; }
/* Admin-only: a stored URL the loader's guard refused, naming the column. The
   public bundle carries neither key, so this element is gated away before a
   reader ever sees it. */
.cs-url-flag {
    display: inline-block; background: #FBE9E9; color: #A0342E;
    border-radius: 4px; padding: .1rem .5rem; font-size: .72rem; line-height: 1.5;
}
.cs-url-flag > i { margin-right: .25rem; }

/* The amber callout — the template's signature move (D2). */
.cs-callout {
    border-left: 4px solid #b0672a;
    background: #faf3ec;
    border-radius: 0 8px 8px 0;
    padding: .7rem .9rem;
    margin-top: .7rem;
    /* Landing from a "↓ in the timeline" jump. --nav-h is the bar's declared
       height at every width, so this clears it exactly; the +4rem is the same
       allowance .tr-seg uses for the sticky nav + notice stack. */
    scroll-margin-top: calc(var(--nav-h) + 4rem);
}
.cs-callout-label {
    margin: 0; font-size: .68rem; letter-spacing: .06em; text-transform: uppercase;
    color: #b0672a; font-weight: 700;
}
.cs-callout-body { margin-top: .35rem; line-height: 1.6; font-size: .95rem; }
/* Same reasoning as .tr-seg:target — a tint this light is not a 3:1 non-text
   indicator on its own, so the thickened accent bar carries the signal. */
.cs-callout:target { border-left-width: 8px; background: #F6EAD9; }
/* Record annotations became addressable as #ann-{id} in the same slice that
   gave the callout its #omit-{id}. Without this they land at rectTop 0 —
   a full --nav-h UNDER the sticky nav, first line hidden — because scroll-margin-top
   defaults to 0. Same allowance and same reasoning as .cs-callout above; the
   two anchor kinds come off the same loader key and must land alike. */
.cs-ann-record { scroll-margin-top: calc(var(--nav-h) + 4rem); }

/* Transcript excerpt (excerpt-anatomy.html). */
.cs-excerpt {
    margin: .7rem 0 0;
    border: 1px solid #ccd8e0; border-radius: 8px; overflow: hidden;
    background: var(--warmwhite);
}
.cs-excerpt-head {
    background: #eef3f6; padding: .4rem .7rem;
    display: flex; justify-content: space-between; align-items: center;
    flex-wrap: wrap; gap: .4rem; font-size: .82rem;
}
.cs-excerpt-who { min-width: 0; }
.cs-excerpt-role { color: var(--ink-soft); font-weight: 400; }
.cs-excerpt-links { display: flex; flex-wrap: wrap; gap: .35rem; }
.cs-watch {
    background: #47799A; color: #fff; border-radius: 4px;
    padding: .1rem .5rem; font-size: .75rem; text-decoration: none; white-space: nowrap;
}
/* No deep link available (no video, or a host whose time syntax we cannot
   vouch for): inert text must not wear the chip that reads as a control. */
.cs-watch--plain { background: transparent; color: var(--ink-soft); border: 1px solid var(--sand-dark); }
.cs-full {
    background: #e8eef2; color: #33586e; border-radius: 4px;
    padding: .1rem .5rem; font-size: .75rem; text-decoration: none; white-space: nowrap;
}
.cs-quote {
    margin: 0; padding: .6rem .85rem; font-style: italic; color: var(--ink-soft);
    line-height: 1.6; overflow-wrap: anywhere;
}
.cs-excerpt-cap { padding: 0 .85rem .6rem; font-size: .72rem; line-height: 1.45; color: var(--color-text-tertiary); }
.cs-excerpt-meeting { font-weight: 600; color: var(--ink-soft); }
.cs-excerpt-meeting::after { content: " · "; font-weight: 400; }
.cs-excerpt-cap > i { color: #47799A; margin-right: .3rem; }

/* ── 6 · Who lives with this decision (D8) ──
   stat_grid VISUAL idiom, bespoke markup. admits_* is the fine print because
   the admissibility claim belongs on the tile it licenses (spec §9). */
.cs-met-intro { margin: 0 0 .8rem; color: var(--ink-soft); font-size: .92rem; line-height: 1.55; max-width: 70ch; }
.cs-metric-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: .6rem; }
.cs-metric {
    display: flex; flex-direction: column; gap: .1rem;
    border: 1px solid var(--sand-dark); border-radius: var(--radius);
    background: var(--warmwhite); padding: .8rem .9rem;
}
.cs-metric-label { font-size: .68rem; text-transform: uppercase; letter-spacing: .05em; color: var(--color-text-tertiary); }
.cs-metric-value { font-size: 1.5rem; font-weight: 700; line-height: 1.15; }
.cs-metric-sub { font-size: .78rem; color: var(--ink-soft); line-height: 1.4; }
.cs-metric-admits {
    margin-top: .35rem; padding-top: .35rem; border-top: 1px solid var(--sand-dark);
    font-size: .72rem; line-height: 1.45; color: var(--color-text-tertiary);
}
/* D8 makes admits_* required, so this should be unreachable — but an empty one
   would render as a 7px strip whose border-top reads as a divider under
   nothing. Only ever show the rule when it is separating real text. */
.cs-metric-admits:empty { display: none; }

/* ── 7 · Ground-truth map ── */
.cs-map { margin: 0 0 .5rem; }
/* pin_map's canvas is .issue-map-canvas.am-map-canvas (380px); the rail is
   narrower than the meeting page's map band, so it comes down a notch. */
.cs-map .am-map-canvas { height: 300px; }
.cs-map-explore { margin: 0; font-size: .82rem; }
.cs-map-explore a { color: var(--navy); }

/* ── 8 · Who appears in this story (D10) ── */
.cs-who-note { margin: -.25rem 0 .6rem; font-size: .8rem; line-height: 1.45; color: var(--color-text-tertiary); }
.cs-people { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: .5rem; }
.cs-person {
    display: flex; flex-direction: column; gap: .1rem;
    border: 1px solid var(--sand-dark); border-radius: var(--radius);
    background: var(--warmwhite); padding: .65rem .8rem; font-size: .85rem;
}
.cs-person-role, .cs-person-org { color: var(--ink-soft); line-height: 1.45; }
.cs-person-note { font-size: .78rem; line-height: 1.45; color: var(--color-text-tertiary); }

/* ── 9 · Documents shelf ── */
.cs-doc-list { list-style: none; margin: 0; padding: 0; }
.cs-doc { padding: .45rem 0; border-bottom: 1px solid var(--sand-dark); font-size: .85rem; line-height: 1.45; }
.cs-doc:last-child { border-bottom: 0; }
.cs-doc-icon > i { color: var(--navy); margin-right: .4rem; }
.cs-doc-link { color: var(--navy); }
.cs-doc-date { color: var(--color-text-tertiary); font-size: .78rem; margin-left: .35rem; }
.cs-doc-date::before { content: "· "; }
.cs-doc-orig { color: var(--color-text-tertiary); font-size: .78rem; margin-left: .3rem; }
.cs-pend-note { margin: -.25rem 0 .5rem; font-size: .78rem; line-height: 1.45; color: var(--color-text-tertiary); }
.cs-pending-zone .cs-doc-chip { margin-left: .35rem; }

/* ── 10 · Methodology ── */
.cs-meth-body { font-size: .85rem; line-height: 1.6; color: var(--ink-soft); }

/* ── 11 · Funnel CTA ── */
.cs-cta {
    background: #f2f7fa; border: 1px solid #ccd8e0; border-radius: var(--radius);
    padding: 1.1rem 1.2rem;
}
.cs-cta-h { font-size: 1.1rem; margin: 0 0 .4rem; }
.cs-cta-p { margin: 0 0 .9rem; color: var(--ink-soft); line-height: 1.6; font-size: .95rem; }
.cs-cta-btns { display: flex; flex-wrap: wrap; gap: .5rem; margin: 0; }
.cs-btn {
    display: inline-block; border-radius: 6px; padding: .5rem .9rem;
    font-size: .88rem; text-decoration: none;
    border: 1px solid #47799A; color: #33586e; background: transparent;
}
.cs-btn--primary { background: #47799A; color: #fff; border-color: #47799A; }

/* ── The two-column shell (D9) ──
   Phones: one column, source order. 900px: grid template AREAS put the rail on
   the right without the DOM ever leaving reading order. */
.cs-cols { display: flex; flex-direction: column; gap: 2rem; }
.cs-rail { display: flex; flex-direction: column; gap: 1.75rem; min-width: 0; }

@media (min-width: 900px) {
    .cs-hero { display: grid; grid-template-columns: 1.2fr .8fr; gap: 1.5rem; align-items: start; }
    /* No photos → no empty .8fr track beside the headline. */
    .cs-hero:not(:has(.cs-hero-media)) { display: block; }

    .cs-cols {
        display: grid;
        grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
        grid-template-areas:
            "timeline rail"
            "metrics  rail";
        gap: 1.5rem;
        align-items: start;
    }
    .cs-timeline-zone { grid-area: timeline; }
    .cs-metrics-zone  { grid-area: metrics; }
    .cs-rail          { grid-area: rail; }
    /* Either track empty → one column, rather than stranding the surviving
       zones in a 3fr or 2fr strip beside dead space. The MAIN track is the
       reachable one: a case with no timeline and no metrics leaves only the
       rail. (The rail track cannot empty — the methodology fixture is
       unconditional — but the test asks about the TRACK, not about today's
       zone list, so it keeps holding if that ever changes.)
       align-items must be restated: "start" above is a grid alignment, but it
       survives the switch to flex, where it means flex-start on the CROSS axis
       — measured at 1280px it shrank a lone timeline to its 251px content
       width. */
    .cs-cols:not(:has(.cs-timeline-zone, .cs-metrics-zone)),
    .cs-cols:not(:has(.cs-rail > *)) {
        display: flex; flex-direction: column; align-items: stretch;
    }
}

/* ── Transcript pipeline, public side (spec 2026-09-02 §9) ────────────────
   Appended rather than woven into the .tr-* block above so the slice reads —
   and reverts — in one place. Same append-only rule and same raw-hex idiom as
   the two blocks before it. */

/* "[unintelligible]" is written into segment text by the parser and by the
   corrections stage; the reader wraps every occurrence in this span. Muted and
   italic rather than hidden: it IS part of the record — the honest statement
   that the audio was unclear and nobody guessed — so it should read as a note
   about the recording, not as speech.

   ⚠ Colour deviation, reported: the plan specifies #8a6d3b. This page's
   background is --sand (#F5F0E8, via .page-agenda-item), where that measures
   4.27:1 — short of WCAG AA's 4.5:1 for body text, which this is. The same
   amber hue darkened to #7a5f31 measures 5.28:1 on --sand and 5.8:1 on
   --warmwhite, so the plan's intent (the case study's amber family, #8a4f1d /
   #b0672a above) survives and the ratio passes. */
.tr-unint { color: #7a5f31; font-style: italic; }

/* Section jump-list. Sits between the sticky note and the segment list so it
   scrolls away instead of competing with the pinned strip for the top of the
   viewport. Wrapping chips, not a bulleted column: a CPC meeting runs to ~11
   sections and Council to more, and a vertical list of those would push the
   first words of the record off a phone screen. The <ol> is semantic (the
   sections ARE ordered); its numbers are suppressed because the labels already
   carry the agenda's own numbering. */
.tr-sections {
    margin: 0 0 1.5rem;
    padding: .6rem .85rem;
    background: var(--warmwhite);
    border: 1px solid var(--sand-dark);
    border-radius: var(--radius);
}
.tr-sections ol {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: .3rem .5rem;
}
.tr-sections li { min-width: 0; }
.tr-sections a {
    display: inline-block;
    max-width: 100%;
    padding: .2rem .5rem;
    border: 1px solid var(--sand-dark);
    border-radius: 4px;
    font-size: .8125rem;
    line-height: 1.35;
    color: var(--navy);
    text-decoration: none;
    /* A label is up to 300 characters out of Pass S. The chip clamps it rather
       than letting one section own the whole strip; the full text stays in the
       heading the link lands on. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.tr-sections a:hover,
.tr-sections a:focus-visible { background: var(--navy-soft); }
.tr-sec-dot  { color: var(--color-text-tertiary); }
.tr-sec-time { color: var(--ink-soft); font-variant-numeric: tabular-nums; }
/* The #sec-{id} target: an empty marker inside the first segment of the
   section, because that <li> already owns id="seg-{id}" and an element has one
   id. It paints nothing and takes no height, but it needs .tr-seg's clearance
   so a jump lands below the sticky nav + notice rather than under them. */
.tr-sec-anchor {
    display: block;
    height: 0;
    scroll-margin-top: calc(var(--nav-h) + 4rem);
}

/* Admin-only draft banner. The reader's query gate means no member of the
   public can reach a page carrying this. #fdecec / #a33 is the DRAFT chip from
   the pipeline-page mockup, so the two surfaces read as one status (5.69:1). */
.tr-draftnote {
    margin: 0 0 1rem;
    padding: .55rem .85rem;
    background: #fdecec;
    border: 1px solid #f3cccc;
    border-radius: var(--radius);
    font-size: .8125rem;
    line-height: 1.5;
    font-weight: 600;
    color: #a33;
}

/* .tr-sec-label had no rule of its own while both its siblings did, which read
   as an oversight. It is not decorative — it is the half of the chip that
   carries meaning, and it is the half that can be 300 characters long out of
   Pass S. Clamping HERE rather than only on the <a> is what keeps a runaway
   label from eating the clock: the anchor's ellipsis would otherwise consume
   the whole chip end-first and take "1:02:03" with it, leaving a link that
   says nothing about where it goes. inline-block is what makes max-width and
   text-overflow apply to a span at all; vertical-align keeps the clamped box
   on the same line as the "·" and the time beside it. */
.tr-sec-label {
    display: inline-block;
    max-width: 18rem;
    overflow: hidden;
    text-overflow: ellipsis;
    vertical-align: bottom;
    font-weight: 600;
}

/* tr-sec-label phone clamp. Measured, not guessed: at a 320px and a 375px
   viewport an 18rem label plus the "·" is wider than the anchor's content box,
   so the clock got clipped away and the chip said nothing about where it went
   — the exact failure the clamp above exists to prevent, just moved from "long
   label" to "narrow screen". Verified with the DOM: .tr-sec-time's right edge
   sat outside its <a> at 320 and 375, inside at 414. 11rem restores it at every
   width down to 320. A media query rather than min(18rem, 50vw) because the
   breakpoint is where the measurement actually changes sign. */
@media (max-width: 480px) {
    .tr-sec-label { max-width: 11rem; }
}
