/**
 * SnS dashboard — shared styles.
 *
 * Extracted Session 44 (2026-04-26) from the inline <style> blocks of
 * supply.html, pnl.html, sales.html, which were byte-identical (~1,010 lines
 * each, ~67 KB). De-duplication: ~135 KB removed from disk; one source of
 * truth for chip palette, card layouts, topbar, accordions, sparklines, etc.
 *
 * Also linked from index.html (mirrors pnl.html — Cloudflare Pages serves /),
 * calculator.html, and procurement-form.html.
 *
 * Aside-nav specific styles live in lib/aside-nav.css and remain separate.
 *
 * Order: load this BEFORE aside-nav.css so the aside CSS can override the
 * .app grid track.
 *
 * Stripped during extraction:
 *   · Legacy 64px gradient aside (.aside / .aside-brand / .aside-items /
 *     .aside-foot / .aside-item rules) — replaced by aside-nav.css
 *   · Mobile @media `.aside { display: none }` — replaced by aside-nav.css
 *
 * Token system: dark mode oklch palette + chip palette (tier-*, band-*,
 * prov-*, amber-*) per Session 38–40. Do not edit inline; edit here.
 */

:root {
  /* Base — shadcn preset b3ktYMKdk DARK variant (Session 38). Near-black
     background, deeper burnt-orange primary, brighter destructive red for
     dark-bg legibility. */
  --background:       oklch(0.145 0 0);                /* near-black ~#252525 */
  --foreground:       oklch(0.985 0 0);                /* near-white ~#fafafa */
  --card:             oklch(0.205 0 0);                /* lifted card surface */
  --card-foreground:  oklch(0.985 0 0);
  --popover:          oklch(0.205 0 0);
  --popover-foreground: oklch(0.985 0 0);
  --muted:            oklch(0.269 0 0);                /* tint surface */
  --muted-foreground: oklch(0.708 0 0);                /* mid-grey ~#b5b5b5 */
  --border:           oklch(1 0 0 / 10%);              /* white@10% hairline */
  --input:            oklch(1 0 0 / 15%);
  --ring:             oklch(0.556 0 0);

  /* Burnt-orange primary (deeper in dark for warmth without glare). */
  --primary:            oklch(0.47 0.157 37.304);
  --primary-foreground: oklch(0.98 0.016 73.684);
  --secondary:          oklch(0.274 0.006 286.033);
  --secondary-foreground: oklch(0.985 0 0);
  --accent:             oklch(0.269 0 0);
  --accent-foreground:  oklch(0.985 0 0);
  --destructive:        oklch(0.704 0.191 22.216);     /* brighter red for dark */

  /* Chart ramp — preset's 5-step orange. Used by the trend chart series. */
  --chart-1: oklch(0.837 0.128 66.29);    /* lightest tan */
  --chart-2: oklch(0.705 0.213 47.604);   /* orange */
  --chart-3: oklch(0.646 0.222 41.116);   /* deep orange */
  --chart-4: oklch(0.553 0.195 38.402);   /* burnt — same as primary */
  --chart-5: oklch(0.47 0.157 37.304);    /* brick */

  /* ─── Strict preset adherence (Session 38) ────────────────────────────────
     Every custom token below is now an alias onto a preset token. Preserves
     the same token names so no downstream CSS rules need editing — only
     :root values change. Semantic colour encoding (sage/amber/emerald/violet)
     collapses into preset's vocabulary. */

  /* Tiers — Session 40: normal/watch restored to green tint (was collapsed to
     muted chrome). Warning amber + critical red already correct. */
  --tier-normal:    #96bfa0;  --tier-normal-bg:    #1e2a1f;  --tier-normal-border:    rgba(150, 191, 160, 0.25);
  --tier-watch:     #96bfa0;  --tier-watch-bg:     #1e2a1f;  --tier-watch-border:     rgba(150, 191, 160, 0.25);
  --tier-warning:   #f5b878;  --tier-warning-bg:   #2e2010;  --tier-warning-border:   rgba(245, 184, 120, 0.30);
  --tier-critical:  #f87171;  --tier-critical-bg:  #2e1414;  --tier-critical-border:  rgba(248, 113, 113, 0.30);
  --tier-unknown:   var(--muted-foreground);  --tier-unknown-bg:   #2a2a2a;  --tier-unknown-border:  var(--border);

  /* Bands — Session 40: green restored to actual green tint (was collapsed to
     muted-foreground = grey, indistinguishable from gray). Gray gets proper bg. */
  --band-green:     #9dc4a8;  --band-green-bg:     #1e2e22;  --band-green-border:     rgba(157, 196, 168, 0.28);
  --band-amber:     #f5b878;  --band-amber-bg:     #2e2010;  --band-amber-border:     rgba(245, 184, 120, 0.30);
  --band-red:       #f87171;  --band-red-bg:       #2e1414;  --band-red-border:       rgba(248, 113, 113, 0.30);
  --band-gray:      var(--muted-foreground);  --band-gray-bg:      #2a2a2a;  --band-gray-border:      var(--border);

  /* Seasonal bands — restored (rose / sand / olive / grey) in dark equivalents.
     Paper tints invert: original light hue becomes deep hue tint on near-black,
     dark ink inverts to pale pastel of same hue. */
  --season-monsoon:    #3a2622;  --season-monsoon-ink:    #f4d4cc;
  --season-wintering:  #3a2f1e;  --season-wintering-ink:  #f5dab5;
  --season-peak:       #232a22;  --season-peak-ink:       #c5d4b8;
  --season-transition: #2a2a28;  --season-transition-ink: #d6d4d0;

  /* Chart series — onto preset's chart ramp */
  --series-mre:     var(--chart-4);   /* burnt orange — primary line */
  --series-sicom:   var(--chart-1);   /* light tan */
  --series-blended: var(--chart-2);   /* orange */

  --font-sans: 'Geist', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-mono: 'Geist Mono', ui-monospace, 'SF Mono', monospace;

  /* Radii — preset uses 0.45rem; keep our existing scale alignment via calc */
  --radius: 0.45rem;
  --radius-sm: calc(var(--radius) * 0.6);
  --radius-md: calc(var(--radius) * 0.8);
  --radius-lg: var(--radius);

  /* Shadows — flattened. Hairlines carry the weight. */
  --shadow-xs: none;
  --shadow-sm: 0 1px 0 rgb(0 0 0 / 0.03);
  --shadow-md: 0 1px 2px 0 rgb(0 0 0 / 0.04);

  /* Surface tokens — onto preset chrome */
  --surface-raised:  var(--card);
  --surface-sunken:  var(--muted);
  --chip-bg:         var(--muted);
  --chip-border:     var(--border);
  --chip-fg:         var(--muted-foreground);
  --grid-line:       var(--border);
  --axis-line:       var(--border);
  --on-accent:       var(--primary-foreground);

  /* Sell floor — collapse sage onto primary (orange = "good/clear floor") */
  --floor-bg:        var(--muted);
  --floor-border:    var(--border);
  --floor-k:         var(--muted-foreground);
  --floor-v:         var(--foreground);
  --floor-v-strong:  var(--primary);

  /* Amber-tone — Session 40: restored to dark amber tint (was collapsed to
     muted bg + primary text → burnt orange on dark grey, ~1.9:1, unreadable). */
  --amber-bg:        #2e2010;
  --amber-border:    rgba(245, 184, 120, 0.30);
  --amber-fg:        #f5b878;
  --amber-meta:      #f5b878;

  /* Pending / disabled wa-btn */
  --pending-bg:      var(--muted);
  --pending-fg:      var(--muted-foreground);
  --pending-border:  var(--border);

  /* Skeleton loader shimmer — dark equivalents. Without these, .skel falls
     through to its hardcoded #f1f5f9/#e2e8f0 slate defaults and renders as
     bright-white blocks on the dark cards. */
  --skel-a:          oklch(0.269 0 0);   /* base — same as --muted */
  --skel-b:          oklch(0.34 0 0);    /* shimmer crest — slightly lifted */

  /* ENSO — onto preset chrome */
  --enso-bg:         var(--muted);
  --enso-fg:         var(--foreground);
  --enso-border:     var(--border);
  --enso-tip-bg:     var(--foreground);
  --enso-tip-fg:     var(--background);

  /* Provenance tiers — LIVE emerald / DEMO amber / KL violet.
     Session 40: nudged bg deeper + fg slightly brighter for each. */
  --prov-live-bg:     #1c3828;
  --prov-live-fg:     #b2ddb8;
  --prov-live-border: rgba(178, 221, 184, 0.32);
  --prov-demo-bg:     #38301e;
  --prov-demo-fg:     #fce8c4;
  --prov-demo-border: rgba(252, 232, 196, 0.30);
  --prov-kl-bg:       #2e2240;
  --prov-kl-fg:       #d0c0e8;
  --prov-kl-border:   rgba(208, 192, 232, 0.30);

  color-scheme: dark;
}

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

body {
  font-family: var(--font-sans);
  background: var(--background);
  color: var(--foreground);
  min-height: 100vh;
  line-height: 1.5;
  font-size: 14px;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* ─── Password gate ──────────────────────────────────────────────────────── */
#gate {
  display: none; position: fixed; inset: 0; background: var(--background);
  z-index: 9999; align-items: center; justify-content: center;
}
#gate.show { display: flex; }
.gate-inner { width: 100%; max-width: 400px; padding: 40px 24px; text-align: center; }
.gate-logo { margin-bottom: 12px; font: 600 22px/1 var(--font-sans); letter-spacing: -0.02em; }
.gate-logo .dot { color: var(--primary); }
.gate-sub { font-size: 13px; color: var(--muted-foreground); margin-bottom: 36px; }
.gate-label { display: block; font-size: 11px; font-weight: 500; color: var(--muted-foreground); text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: 8px; text-align: left; }
.gate-input { width: 100%; padding: 12px 14px; font: 400 14px/1.2 var(--font-sans); background: var(--card); border: 1px solid var(--border); border-radius: var(--radius-sm); outline: none; color: var(--foreground); }
.gate-input:focus { border-color: var(--primary); box-shadow: 0 0 0 3px rgb(24 24 27 / 0.12); }
.gate-btn { width: 100%; margin-top: 16px; padding: 12px 16px; background: var(--primary); color: var(--primary-foreground); border: 0; border-radius: var(--radius-sm); font: 500 14px/1 var(--font-sans); cursor: pointer; transition: filter 0.15s; }
.gate-btn:hover { filter: brightness(1.06); }
.gate-err { margin-top: 12px; color: var(--tier-critical); font-size: 12px; min-height: 16px; text-align: left; }

/* ─── App shell — grid (aside + main) ────────────────────────────────────── */
.app { display: none; min-height: 100vh; }
.app.show { display: grid; grid-template-columns: 64px 1fr; min-height: 100vh; }

/* ─── Main column ─────────────────────────────────────────────────────────── */
.main { display: flex; flex-direction: column; min-width: 0; }

/* ─── Topbar — crumb + live status + actions ─────────────────────────────── */
.topbar {
  display: flex; align-items: center; gap: 20px;
  padding: 14px 28px;
  border-bottom: 1px solid var(--border);
  background: var(--background);
  /* top offset is bumped by JS when the demo banner is visible (TAT-028). */
  position: sticky; top: var(--banner-offset, 0px); z-index: 10;
  flex-wrap: wrap;
}
.topbar-crumb { display: flex; align-items: baseline; gap: 8px; font: 400 13px/1 var(--font-sans); }
.topbar-crumb .root    { color: var(--muted-foreground); }
.topbar-crumb .sep     { color: var(--muted-foreground); }
.topbar-crumb .current { color: var(--foreground); font-weight: 500; }

.topbar-status {
  display: flex; align-items: center; gap: 12px;
  font: 400 12px/1 var(--font-mono);
  color: var(--muted-foreground);
  flex: 1; min-width: 0; flex-wrap: wrap;
}
.pulse-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--tier-normal); flex: 0 0 8px;
  animation: pulse 2.2s ease-in-out infinite;
}
@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.35; } }
.status-live { color: var(--foreground); font-weight: 500; letter-spacing: 0.02em; }
.status-sep  { color: var(--muted-foreground); opacity: 0.45; }
.status-time { color: var(--muted-foreground); }

.topbar-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.icon-btn {
  width: 36px; height: 36px;
  display: grid; place-items: center;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  color: var(--muted-foreground); cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.icon-btn:hover { background: var(--muted); color: var(--foreground); border-color: var(--input); }
.icon-btn svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }

.user-chip {
  width: 36px; height: 36px;
  display: grid; place-items: center;
  background: var(--primary); color: var(--primary-foreground);
  font: 500 12px/1 var(--font-sans); letter-spacing: 0.04em;
  border-radius: var(--radius-md);
}

/* ─── Content ────────────────────────────────────────────────────────────── */
.content {
  padding: 28px 32px 80px;
  max-width: 1200px; width: 100%; margin: 0;
}

/* ─── Mobile shell ────────────────────────────────────────────────────────── */
@media (max-width: 880px) {
  .app.show { grid-template-columns: 1fr; }
  .topbar { padding: 12px 18px; gap: 12px; }
  .topbar-status { font-size: 11px; gap: 8px; }
  .content { padding: 20px 18px 80px; }
}

/* ─── WhatsApp Kee Long button ───────────────────────────────────────────── */
.wa-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px; border-radius: 999px;
  font: 500 12px/1 var(--font-sans);
  background: #25d366; color: #fff; border: 0; text-decoration: none;
  cursor: pointer; transition: filter 0.15s, background 0.15s;
  white-space: nowrap;
}
.wa-btn:hover { filter: brightness(0.94); }
.wa-btn[data-state="pending"] {
  background: var(--pending-bg); color: var(--pending-fg); border: 1px dashed var(--pending-border); cursor: not-allowed;
}
.wa-btn .icon { width: 14px; height: 14px; fill: currentColor; }

/* ─── Section ────────────────────────────────────────────────────────────── */
.sec { margin-top: 44px; }
.sec h2 { font: 500 26px/1.2 var(--font-sans); letter-spacing: -0.015em; color: var(--foreground); margin-bottom: 4px; text-transform: none; }
.sec .sec-note { font: 400 13px/1.6 var(--font-sans); color: var(--muted-foreground); margin-bottom: 20px; max-width: 64ch; }

/* ─── Nested-section accordion (seasonal outlook, etc.) ─── */
.sec-accordion { margin-top: 20px; border-top: 1px solid var(--border); }
.sec-accordion > summary {
  list-style: none;
  cursor: pointer;
  padding: 14px 12px;
  margin: 4px -8px 0;
  border-radius: 6px;
  display: flex; align-items: baseline; gap: 12px;
  font: 500 15px/1.3 var(--font-sans);
  color: var(--foreground);
  user-select: none;
  transition: background 0.15s ease;
}
.sec-accordion > summary::-webkit-details-marker { display: none; }
.sec-accordion > summary::before {
  content: "▸";
  font-size: 15px;
  font-weight: 700;
  color: var(--foreground);
  transition: transform 0.15s ease;
  display: inline-block;
  width: 16px;
  line-height: 1;
  transform-origin: center;
}
.sec-accordion[open] > summary::before { transform: rotate(90deg); }
.sec-accordion > summary .acc-title { font-weight: 500; }
.sec-accordion > summary .acc-sub {
  font: 400 12px/1.5 var(--font-sans);
  color: var(--muted-foreground);
  letter-spacing: 0;
}
/* Trailing "Tap to expand / Collapse" pill — explicit affordance so the
   accordion reads as interactive even when the caret alone is missed. */
.sec-accordion > summary::after {
  content: "Tap to expand";
  margin-left: auto;
  font: 600 10px/1 var(--font-mono);
  color: var(--muted-foreground);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: 5px 12px;
  border: 1px solid var(--border);
  border-radius: 999px;
  white-space: nowrap;
  transition: border-color 0.15s ease, color 0.15s ease;
}
.sec-accordion[open] > summary::after { content: "Collapse"; }
.sec-accordion > summary:hover { background: var(--surface-sunken); }
.sec-accordion > summary:hover::after { border-color: var(--primary); color: var(--primary); }
.sec-accordion > summary:hover .acc-title { color: var(--primary); }
.sec-accordion[open] > .phase1 { margin-top: 4px; }

/* ─── Section card modifiers (preview · Session 38) ────────────────────────
   Each top-level section becomes a tinted, bordered container. Paper-grade
   chroma only — tokens reused from the seasonal / floor families so we stay
   inside the existing palette grammar. Trend stays neutral (white) because
   the SVG already carries the chart palette and would clash with a tint.
   Inner cards (.phase1, .tcm-*-card, .intel-card-item) keep their existing
   white / sunken backgrounds, so they pop as tiles sitting on tinted paper.
   ───────────────────────────────────────────────────────────────────────── */
.sec--card {
  padding: 22px 18px 24px;
  border: 1px solid var(--border);
  border-radius: 12px;
  margin-top: 32px;
}
@media (min-width: 720px) {
  .sec--card { padding: 32px 32px 36px; }
}
/* Section tints — strict preset adherence (Session 38). All sections share
   --muted background; differentiation now comes from border + spacing only,
   not from per-section hue. The chart-1..5 ramp could give five oranges if
   we want hue back, but that breaks "follow the palette exactly." */
.sec--field { background: var(--muted); border-color: var(--border); }
.sec--pnl   { background: var(--muted); border-color: var(--border); }
.sec--sales { background: var(--muted); border-color: var(--border); }
.sec--trend { background: var(--card);  border-color: var(--border); }
.sec--intel { background: var(--muted); border-color: var(--border); }

/* ─── Card base ──────────────────────────────────────────────────────────── */
.card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 20px 22px;
  box-shadow: var(--shadow-sm);
  display: flex; flex-direction: column;
}
.card + .card { margin-top: 14px; }

.card-row { display: grid; grid-template-columns: 1fr; gap: 14px; align-items: stretch; }
@media (min-width: 880px) { .card-row.two { grid-template-columns: 1fr 1fr; } }

/* ─── Reusable 2-col row within a section ───────────────────────────────── */
.row-split { display: grid; grid-template-columns: 1fr; gap: 20px; align-items: stretch; }
@media (min-width: 980px) {
  .row-split.wide-left  { grid-template-columns: 1.5fr 1fr; }
  .row-split.equal      { grid-template-columns: 1fr 1fr; }
  .row-split.wide-right { grid-template-columns: 1fr 1.5fr; }
}

/* ─── Phase 1 · Editorial block (no wrapper card) ────────────────────────── */
.phase1 { margin-bottom: 22px; }
.phase1-head { display: flex; align-items: baseline; gap: 16px; margin-bottom: 14px; flex-wrap: wrap; }
/* Reorder eyebrow row: prov-chip(s) first, then title, then right-side meta.
   margin-left:auto on the meta pushes it to the end (replaces space-between). */
.phase1-head > .prov-chip { order: 1; margin-left: 0; }
.phase1-head > .phase1-eyebrow { order: 2; margin-left: 0; }
.phase1-head > :not(.prov-chip):not(.phase1-eyebrow) { order: 3; margin-left: auto; }
.phase1-eyebrow { font: 500 10px/1 var(--font-mono); text-transform: uppercase; letter-spacing: 0.14em; color: var(--muted-foreground); }

/* Phase 1 interior 2-col: hero + floor on the left, stat cards on the right */
.phase1-split { display: grid; grid-template-columns: 1fr; gap: 20px; margin-bottom: 18px; align-items: stretch; }
@media (min-width: 880px) { .phase1-split { grid-template-columns: 1.25fr 1fr; gap: 28px; } }
.phase1-col { display: flex; flex-direction: column; min-width: 0; }
.phase1-col-primary { justify-content: flex-start; }
.phase1-col-stats { gap: 10px; justify-content: center; }

.phase1-hero { display: flex; align-items: baseline; gap: 14px; margin-bottom: 6px; flex-wrap: wrap; }
.inv-number { font: 500 72px/1 var(--font-sans); letter-spacing: -0.035em; font-variant-numeric: tabular-nums; color: var(--foreground); }
.inv-number.null { color: var(--muted-foreground); font-weight: 400; font-size: 44px; }
.phase1-hero-unit { font: 400 15px/1.3 var(--font-sans); color: var(--muted-foreground); }
.phase1-hero-unit em { font-style: normal; color: var(--muted-foreground); }

.phase1-sub { font: 400 13px/1.55 var(--font-sans); color: var(--muted-foreground); margin-bottom: 22px; max-width: 64ch; }
.phase1-sub strong { color: var(--foreground); font-weight: 500; font-variant-numeric: tabular-nums; }

/* Mini-KPI grid — 2-up on desktop, stacks on mobile; floor spans full width */
.kpi-row { display: grid; grid-template-columns: 1fr; gap: 10px; margin-bottom: 10px; }
@media (min-width: 720px) { .kpi-row { grid-template-columns: 1fr 1fr; } }
/* TAT-029 Session 26 — 4-tile variant for the Sales pipeline card. */
@media (min-width: 1040px) { .kpi-row-4 { grid-template-columns: repeat(4, 1fr); } }

.kpi {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 14px 16px;
  display: flex; flex-direction: column; gap: 6px;
}
.kpi-k { font: 500 10px/1 var(--font-mono); text-transform: uppercase; letter-spacing: 0.12em; color: var(--muted-foreground); }
.kpi-v { font: 500 26px/1.15 var(--font-sans); letter-spacing: -0.015em; color: var(--foreground); font-variant-numeric: tabular-nums; display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; }
.kpi-v .val { color: var(--foreground); font-weight: 600; }
.kpi-v .unit { font: 500 10px/1.2 var(--font-mono); color: var(--muted-foreground); text-transform: uppercase; letter-spacing: 0.08em; font-weight: 500; }

/* Sell floor — the commercial "go" card. Subtle warm sage tint. */
.kpi-floor {
  background: var(--floor-bg);
  border-color: var(--floor-border);
  margin-bottom: 14px;
  padding: 14px 16px;
}
.kpi-floor .kpi-k { color: var(--floor-k); }
.kpi-floor .kpi-v { font: 500 16px/1.5 var(--font-sans); color: var(--floor-v); letter-spacing: 0; }
.kpi-floor .kpi-v strong { font-weight: 700; color: var(--floor-v-strong); }
.kpi-floor .kpi-v em { font-style: normal; font: 400 11px/1.4 var(--font-mono); color: var(--muted-foreground); }
.kpi-floor .kpi-v.none { color: var(--muted-foreground); font-style: italic; font-size: 13px; font-weight: 400; }

/* Tertiary context — latest buy + source */
.phase1-context { padding-top: 12px; border-top: 1px dashed var(--border); display: flex; flex-direction: column; gap: 4px; font: 400 12px/1.55 var(--font-sans); color: var(--muted-foreground); }
.phase1-context .context-k { font: 500 10px/1 var(--font-mono); text-transform: uppercase; letter-spacing: 0.12em; color: var(--muted-foreground); margin-right: 4px; }
.phase1-context .context-v { color: var(--foreground); }
.phase1-context .context-v.none { color: var(--muted-foreground); font-style: italic; font-weight: 400; opacity: 0.75; }
.phase1-context .context-v strong { color: var(--foreground); font-weight: 500; }
.phase1-context .context-foot { font: 400 11px/1.4 var(--font-mono); color: var(--muted-foreground); margin-top: 2px; }

@media (max-width: 560px) {
  .inv-number { font-size: 52px; }
  .kpi-v { font-size: 22px; }
}

/* ─── FL 7-day ledger (TAT-042) ──────────────────────────────────────────
 * Sits under the rolling-stock block. 3-up summary of buys-in-window + a
 * light list of rows. No wrapper card — it's an editorial block that rides
 * the same .phase1 rhythm.
 */
.fl-ledger-summary { display: grid; grid-template-columns: 1fr; gap: 10px; margin-bottom: 14px; }
@media (min-width: 720px) { .fl-ledger-summary { grid-template-columns: repeat(3, 1fr); } }

.fl-ledger-list { display: flex; flex-direction: column; gap: 0; }
.fl-ledger-row {
  display: grid;
  grid-template-columns: 96px 1fr auto;
  gap: 12px;
  align-items: baseline;
  padding: 10px 0;
  border-top: 1px dashed var(--border);
  font: 400 13px/1.5 var(--font-sans);
  color: var(--foreground);
}
.fl-ledger-row:first-child { border-top: 1px solid var(--border); }
.fl-ledger-row .fl-date { font: 500 11px/1.2 var(--font-mono); color: var(--muted-foreground); text-transform: uppercase; letter-spacing: 0.06em; }
.fl-ledger-row .fl-body strong { font-weight: 500; color: var(--foreground); font-variant-numeric: tabular-nums; }
.fl-ledger-row .fl-body .fl-supplier { color: var(--muted-foreground); }
.fl-ledger-row .fl-body .fl-note { display: block; margin-top: 2px; font: 400 11px/1.4 var(--font-mono); color: var(--muted-foreground); }
.fl-ledger-row .fl-cost { font: 500 13px/1.3 var(--font-sans); font-variant-numeric: tabular-nums; color: var(--foreground); white-space: nowrap; }
.fl-ledger-row .fl-cost .unit { font: 500 10px/1 var(--font-mono); color: var(--muted-foreground); text-transform: uppercase; letter-spacing: 0.08em; margin-left: 4px; }

.fl-ledger-empty {
  padding: 14px 16px;
  border: 1px dashed var(--border); border-radius: var(--radius-md);
  font: 400 12.5px/1.55 var(--font-sans); color: var(--muted-foreground);
}
.fl-ledger-empty strong { color: var(--foreground); font-weight: 500; }

@media (max-width: 560px) {
  .fl-ledger-row { grid-template-columns: 80px 1fr; }
  .fl-ledger-row .fl-cost { grid-column: 1 / -1; padding-left: 92px; }
}

/* ─── Supply signal (Phase 4, editorial block) ────────────────────────── */
.supply-tier { display: inline-flex; align-items: center; gap: 6px; padding: 5px 12px; border-radius: 999px; font: 600 10px/1 var(--font-mono); letter-spacing: 0.08em; text-transform: uppercase; }
.supply[data-tier="NORMAL"]   .supply-tier { background: var(--tier-normal-bg);   color: var(--tier-normal);   border: 1px solid var(--tier-normal-border); }
.supply[data-tier="WATCH"]    .supply-tier { background: var(--tier-watch-bg);    color: var(--tier-watch);    border: 1px solid var(--tier-watch-border); }
.supply[data-tier="WARNING"]  .supply-tier { background: var(--tier-warning-bg);  color: var(--tier-warning);  border: 1px solid var(--tier-warning-border); }
.supply[data-tier="CRITICAL"] .supply-tier { background: var(--tier-critical-bg); color: var(--tier-critical); border: 1px solid var(--tier-critical-border); }
.supply[data-tier="UNKNOWN"]  .supply-tier { background: var(--tier-unknown-bg);  color: var(--tier-unknown);  border: 1px solid var(--tier-unknown-border); }
.supply-tier .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; opacity: 0.85; }

.supply-number { font: 500 48px/1 var(--font-sans); letter-spacing: -0.025em; color: var(--foreground); font-variant-numeric: tabular-nums; }

.supply-compare { display: flex; align-items: baseline; gap: 8px; font: 400 13px/1.55 var(--font-sans); color: var(--muted-foreground); margin: 0 0 16px; flex-wrap: wrap; max-width: 64ch; }
.supply-delta { font-weight: 500; font-variant-numeric: tabular-nums; color: var(--foreground); }
.supply-delta.pos { color: var(--tier-watch); }
.supply-delta.neg { color: var(--tier-warning); }

.supply-signal { background: var(--surface-sunken); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 10px 12px; font: 400 12.5px/1.55 var(--font-sans); color: var(--foreground); margin-bottom: 16px; }
.supply-signal .prefix { font-weight: 500; color: var(--primary); }

.supply-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; font: 400 11px/1.4 var(--font-mono); color: var(--muted-foreground); }
.supply-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }

/* ─── Staleness pill ─────────────────────────────────────────────────────── */
.stale { display: inline-flex; align-items: center; gap: 6px; padding: 5px 12px; border-radius: 999px; font: 500 10px/1 var(--font-mono); text-transform: uppercase; letter-spacing: 0.08em; }
.stale[data-state="fresh"]   { background: var(--tier-normal-bg); color: var(--tier-normal); border: 1px solid var(--tier-normal-border); }
.stale[data-state="amber"]   { background: var(--amber-bg); color: var(--amber-meta); border: 1px solid var(--amber-border); }
.stale[data-state="red"]     { background: var(--tier-critical-bg); color: var(--tier-critical); border: 1px solid var(--tier-critical-border); }
.stale[data-state="missing"] { background: var(--chip-bg); color: var(--chip-fg); border: 1px solid var(--chip-border); }
.stale[data-state="unknown"] { background: var(--chip-bg); color: var(--chip-fg); border: 1px solid var(--chip-border); }
.stale .dot { width: 5px; height: 5px; border-radius: 50%; background: currentColor; }

/* ─── Forward-compression banner ─────────────────────────────────────────── */
.forward-banner { display: none; background: var(--amber-bg); border: 1px solid var(--amber-border); border-radius: var(--radius-md); padding: 12px 16px; margin-bottom: 16px; font: 400 13px/1.55 var(--font-sans); color: var(--amber-fg); }
.forward-banner.show { display: block; }
.forward-banner strong { color: var(--tier-warning); font-weight: 600; }
.forward-banner .meta { display: block; margin-top: 4px; font: 400 11px/1.4 var(--font-mono); color: var(--amber-meta); }

/* ─── ENSO badge ─────────────────────────────────────────────────────────── */
.enso { position: relative; display: inline-flex; align-items: center; gap: 6px; padding: 5px 12px; border-radius: 999px; font: 500 10px/1 var(--font-mono); letter-spacing: 0.08em; text-transform: uppercase; background: var(--enso-bg); color: var(--enso-fg); border: 1px solid var(--enso-border); cursor: help; transition: background 0.15s; }
.enso[data-phase="El Niño"] { background: var(--amber-bg); color: var(--amber-meta); border-color: var(--amber-border); }
.enso[data-phase="La Niña"] { background: var(--tier-watch-bg); color: var(--tier-watch); border-color: var(--tier-watch-border); }
.enso[data-phase="Neutral"] { background: var(--enso-bg); color: var(--enso-fg); border-color: var(--enso-border); }
.enso .swatch { width: 8px; height: 8px; border-radius: 50%; background: currentColor; }
.enso .anom { font: 500 10px/1 var(--font-mono); opacity: 0.7; }
.enso-tip { position: absolute; right: 0; top: calc(100% + 6px); z-index: 100; max-width: 280px; padding: 10px 12px; background: var(--enso-tip-bg); color: var(--enso-tip-fg); font: 400 12px/1.5 var(--font-sans); border-radius: var(--radius-sm); box-shadow: var(--shadow-md); opacity: 0; pointer-events: none; transform: translateY(-4px); transition: opacity 0.15s, transform 0.15s; }
.enso:hover .enso-tip { opacity: 1; transform: translateY(0); }
@media (max-width: 560px) { .enso-tip { right: 0; left: auto; max-width: 240px; } }

/* ─── FX chip ────────────────────────────────────────────────────────────── */
.fx-chip { display: inline-flex; align-items: center; gap: 6px; padding: 5px 12px; border-radius: 999px; font: 600 10px/1 var(--font-mono); letter-spacing: 0.08em; text-transform: uppercase; background: var(--chip-bg); color: var(--foreground); border: 1.5px solid var(--chip-border); }
.fx-chip[data-available="true"]  { background: var(--tier-normal-bg); color: var(--tier-normal); border-color: var(--tier-normal-border); }
.fx-chip[data-available="false"] { background: var(--tier-critical-bg); color: var(--tier-critical); border-color: var(--tier-critical-border); }

/* TAT-029 Session 26 — xe / BNM redundancy badge (next to #fx-chip) */
.fx-redundancy { display: inline-flex; align-items: center; gap: 6px; padding: 5px 12px; border-radius: 999px; font: 500 10px/1 var(--font-mono); letter-spacing: 0.08em; text-transform: uppercase; background: var(--chip-bg); color: var(--muted-foreground); border: 1px solid var(--chip-border); }
.fx-redundancy .swatch { width: 7px; height: 7px; border-radius: 999px; background: currentColor; }
.fx-redundancy[data-status="agree"]    { background: var(--tier-normal-bg);   color: var(--tier-normal);   border-color: var(--tier-normal-border); }
.fx-redundancy[data-status="watch"]    { background: var(--band-amber-bg);    color: var(--band-amber);    border-color: var(--band-amber); }
.fx-redundancy[data-status="disagree"] { background: var(--tier-critical-bg); color: var(--tier-critical); border-color: var(--tier-critical-border); }
.fx-redundancy[data-status="awaiting"] { opacity: 0.7; }

/* ─── Reusable meta bar (right side of phase1-head) ──────────────────────── */
.edblock-meta { font: 400 11px/1 var(--font-mono); color: var(--muted-foreground); }
.edblock-meta strong { color: var(--foreground); font-weight: 500; font-variant-numeric: tabular-nums; }

/* ─── Provenance chips (TAT-028) ─────────────────────────────────────────── */
/* Inline tags that sit next to data-carrying fields or in phase1-eyebrow rows.
 * Rhythm matches .edblock-meta and .stale — 10px Geist Mono, uppercase, thin
 * border matching fg at 30% opacity. Three variants: live/demo/kl. */
.prov-chip {
  display: inline-flex; align-items: center;
  padding: 5px 12px; border-radius: var(--radius-sm);
  font: 500 10px/1 var(--font-mono); text-transform: uppercase; letter-spacing: 0.08em;
  border: 1px solid transparent;
  vertical-align: middle;
}
.prov-chip.live { background: var(--prov-live-bg); color: var(--prov-live-fg); border-color: var(--prov-live-border); }
.prov-chip.demo { background: var(--prov-demo-bg); color: var(--prov-demo-fg); border-color: var(--prov-demo-border); }
.prov-chip.kl   { background: var(--prov-kl-bg);   color: var(--prov-kl-fg);   border-color: var(--prov-kl-border); }
/* When a chip sits next to a value, give it a hair of breathing room. */
.prov-chip + .prov-chip,
.edblock-meta + .prov-chip,
.phase1-eyebrow + .prov-chip { margin-left: 8px; }
/* Eyebrow chips ride the baseline with the rest of the phase label. */
.phase1-eyebrow .prov-chip { margin-left: 8px; }

/* ─── Demo banner (persistent top strip while DEMO chips are on screen) ──── */
.demo-banner {
  display: none; /* JS flips to flex when any .prov-chip.demo is in viewport */
  position: sticky; top: 0; z-index: 50;
  gap: 12px; align-items: center; justify-content: space-between;
  padding: 8px 16px;
  background: var(--amber-bg); border-bottom: 1px solid var(--amber-border);
  color: var(--amber-fg);
  font: 400 12px/1.45 var(--font-sans);
}
.demo-banner.show { display: flex; }
.demo-banner .demo-banner-copy { flex: 1; min-width: 0; }
.demo-banner .demo-banner-copy strong { color: var(--amber-meta); font-weight: 600; letter-spacing: 0.02em; }
.demo-banner .demo-banner-copy .sep { margin: 0 6px; color: var(--amber-border); }
.demo-banner .demo-banner-dismiss {
  flex: 0 0 auto;
  background: transparent; border: 1px solid var(--amber-border); color: var(--amber-fg);
  padding: 4px 10px; border-radius: var(--radius-sm);
  font: 500 10px/1 var(--font-mono); text-transform: uppercase; letter-spacing: 0.1em;
  cursor: pointer;
}
.demo-banner .demo-banner-dismiss:hover { background: rgba(120, 53, 15, 0.08); }
.demo-banner .demo-banner-dismiss:focus-visible { outline: 2px solid var(--amber-meta); outline-offset: 2px; }
@media (max-width: 375px) {
  .demo-banner { padding: 6px 12px; font-size: 11px; }
  .demo-banner .demo-banner-copy .sep,
  .demo-banner .demo-banner-copy .detail { display: none; }
}

/* ─── Price strip (now inside editorial block — no wrapper card) ────────── */
.strip-row { display: grid; grid-template-columns: 1fr; gap: 10px; }
@media (min-width: 720px) { .strip-row { grid-template-columns: repeat(3, 1fr); gap: 12px; } }

.tile { position: relative; background: var(--surface-raised); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 14px 16px; min-height: 104px; display: flex; flex-direction: column; justify-content: space-between; }
.tile[data-colour="green"] { background: linear-gradient(180deg, var(--band-green-bg) 0%, var(--surface-raised) 60%); }
.tile[data-colour="red"]   { background: linear-gradient(180deg, var(--band-red-bg)   0%, var(--surface-raised) 60%); }
.tile[data-colour="gray"]  { background: var(--surface-sunken); }
/* ref — reference-only tile (e.g. SICOM dry rubber): dimmed, no blended-cost colouring */
.tile[data-colour="ref"]   { background: var(--surface-sunken); opacity: 0.6; }
.tile[data-colour="ref"] .tile-price .val { color: var(--muted-foreground); }
.tile[data-colour="ref"] .tile-label .src { opacity: 0.7; }

.tile-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; margin-bottom: 10px; }
.tile-label { font: 500 12px/1.35 var(--font-sans); color: var(--foreground); }
.tile-label .src { font: 500 10px/1 var(--font-mono); text-transform: uppercase; letter-spacing: 0.12em; color: var(--muted-foreground); display: block; margin-bottom: 3px; }

.tile-price { font: 600 22px/1 var(--font-sans); letter-spacing: -0.01em; font-variant-numeric: tabular-nums; }
.tile-price .cur { font: 500 10px/1 var(--font-mono); color: var(--muted-foreground); margin-right: 4px; text-transform: uppercase; letter-spacing: 0.1em; }
.tile-price .val { color: var(--foreground); }
.tile-price .unit { font: 500 11px/1 var(--font-mono); color: var(--muted-foreground); margin-left: 4px; }
.tile-price.null { color: var(--muted-foreground); font-weight: 400; font-size: 14px; letter-spacing: 0; }

.tile-native { margin-top: 4px; font: 400 11px/1.4 var(--font-mono); color: var(--muted-foreground); font-variant-numeric: tabular-nums; }

.tile-foot { margin-top: 10px; display: flex; align-items: center; justify-content: space-between; gap: 8px; font: 400 11px/1.4 var(--font-mono); color: var(--muted-foreground); }

.tile-fallback { margin-top: 10px; padding: 8px 10px; background: var(--band-amber-bg); border: 1px dashed var(--band-amber-border); border-radius: var(--radius-sm); font: 400 11px/1.4 var(--font-mono); color: var(--amber-meta); }
.tile-fallback strong { font-weight: 600; color: var(--band-amber); }

/* Inline source-provenance disclosure — always visible, no hover required.
   Used on tiles whose price is scraped via a one-hop republisher rather than
   directly from the exchange (SICOM via RTAS). Cathedral "honesty on display"
   pattern — disclosure shouldn't hide behind a tap on a mobile-first surface. */
.tile-note { margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--border); font: 400 10.5px/1.45 var(--font-mono); color: var(--muted-foreground); }

.fx-missing { font: 500 10px/1 var(--font-mono); color: var(--tier-critical); text-transform: uppercase; letter-spacing: 0.1em; }

/* ─── Spread widget (now an editorial block — band signal carried by pill) ─ */
.spread-pill { display: inline-flex; align-items: center; gap: 6px; padding: 5px 12px; border-radius: 999px; font: 600 10px/1 var(--font-mono); letter-spacing: 0.08em; text-transform: uppercase; background: var(--band-gray-bg); color: var(--band-gray); border: 1px solid var(--band-gray-border); }
#spread-card[data-band="green"] .spread-pill { background: var(--band-green-bg); color: var(--band-green); border-color: var(--band-green-border); }
#spread-card[data-band="amber"] .spread-pill { background: var(--band-amber-bg); color: var(--band-amber); border-color: var(--band-amber-border); }
#spread-card[data-band="red"]   .spread-pill { background: var(--band-red-bg);   color: var(--band-red);   border-color: var(--band-red-border); }
.spread-pill .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; opacity: 0.85; }

.spread-number { font: 500 48px/1 var(--font-sans); letter-spacing: -0.025em; font-variant-numeric: tabular-nums; color: var(--foreground); }
.spread-number.null { color: var(--muted-foreground); font-weight: 400; font-size: 28px; }
.spread-number .sign { font-weight: 500; }

.context-sep { color: var(--muted-foreground); opacity: 0.5; }

/* ─── Trend chart (now inside editorial block — no wrapper card) ────────── */
.trend-legend { display: flex; flex-wrap: wrap; gap: 10px 16px; margin: 14px 0 10px; font: 400 11px/1.4 var(--font-mono); color: var(--muted-foreground); }
.trend-legend .sw { display: inline-block; width: 14px; height: 2px; vertical-align: middle; margin-right: 6px; border-radius: 1px; }
.trend-legend .sw.mre { background: var(--series-mre); }
.trend-legend .sw.sicom { background: var(--series-sicom); }
.trend-legend .sw.blended { background: var(--series-blended); height: 0; border-top: 2px dashed var(--series-blended); }

.trend-svg-wrap { width: 100%; background: var(--surface-sunken); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 8px 8px 4px; overflow-x: auto; }
.trend-svg { display: block; width: 100%; height: 260px; min-width: 320px; overflow: visible; }
.trend-svg .axis-line { stroke: var(--axis-line); stroke-width: 1; }
.trend-svg .gridline  { stroke: var(--grid-line); stroke-width: 1; stroke-dasharray: 2 3; }
.trend-svg .axis-label { fill: var(--muted-foreground); font: 400 10px/1 var(--font-mono); }
.trend-svg .series { fill: none; stroke-width: 1.8; stroke-linejoin: round; stroke-linecap: round; }
.trend-svg .series.mre    { stroke: var(--series-mre); }
.trend-svg .series.sicom  { stroke: var(--series-sicom); stroke-width: 1.4; opacity: 0.8; }
.trend-svg .blended       { stroke: var(--series-blended); stroke-width: 1.6; stroke-dasharray: 6 4; fill: none; }
.trend-svg .blended-label { fill: var(--series-blended); font: 500 10px/1 var(--font-mono); }

/* Seasonal context bands — Thai rubber calendar for southern (Sadao) tapping */
.trend-svg .season-band             { opacity: 0.45; }
.trend-svg .season-band.wintering   { fill: var(--season-wintering); } /* paper ochre — defoliation, supply tight */
.trend-svg .season-band.peak        { fill: var(--season-peak); } /* muted moss — peak tapping, supply abundant */
.trend-svg .season-band.monsoon     { fill: var(--season-monsoon); } /* paper brick — rain disruption */
.trend-svg .season-band.transition  { fill: var(--season-transition); opacity: 0.3; } /* neutral paper — shoulder months, no strong signal */
.trend-svg .season-label {
  fill: var(--muted-foreground); font: 500 9px/1 var(--font-mono);
  letter-spacing: 0.08em; text-transform: uppercase;
}

.season-legend { display: flex; flex-wrap: wrap; gap: 8px 14px; margin-top: 8px; font: 400 10.5px/1.4 var(--font-mono); color: var(--muted-foreground); }
.season-legend .sw { display: inline-block; width: 12px; height: 8px; border-radius: 2px; margin-right: 5px; vertical-align: middle; opacity: 0.7; }
.season-legend .sw.wintering  { background: var(--season-wintering); }
.season-legend .sw.peak       { background: var(--season-peak); }
.season-legend .sw.monsoon    { background: var(--season-monsoon); }
.season-legend .sw.transition { background: var(--season-transition); }
.season-legend .src-tag { margin-left: auto; font-size: 10px; opacity: 0.7; } /* "live · NASA POWER" vs "fallback · static" */

/* .trend-foot — removed; replaced by .phase1-context in the editorial block */

/* ─── Seasonal calendar (now inside editorial block — no wrapper card) ──── */
.season-strip { position: relative; display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 4px; height: 72px; background: var(--chip-bg); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 6px; overflow: hidden; }
.season-cell { position: relative; border-radius: var(--radius-sm); padding: 6px 4px; display: flex; flex-direction: column; justify-content: space-between; align-items: center; font: 500 10px/1 var(--font-mono); text-align: center; letter-spacing: 0.05em; cursor: help; }
.season-cell .m  { text-transform: uppercase; opacity: 0.8; }
.season-cell .mm { font: 500 10px/1 var(--font-mono); opacity: 0.7; font-variant-numeric: tabular-nums; }
.season-cell[data-band="monsoon"]    { background: var(--season-monsoon);    color: var(--season-monsoon-ink); }
.season-cell[data-band="wintering"]  { background: var(--season-wintering);  color: var(--season-wintering-ink); }
.season-cell[data-band="peak"]       { background: var(--season-peak);       color: var(--season-peak-ink); }
.season-cell[data-band="transition"] { background: var(--season-transition); color: var(--season-transition-ink); }
.season-cell.now { outline: 2px solid var(--primary); outline-offset: -2px; }
.season-cell .tip { position: absolute; left: 50%; transform: translate(-50%, -8px); bottom: calc(100% + 6px); max-width: 220px; padding: 8px 10px; background: var(--enso-tip-bg); color: var(--enso-tip-fg); font: 400 11px/1.4 var(--font-sans); border-radius: var(--radius-sm); box-shadow: var(--shadow-md); opacity: 0; pointer-events: none; transition: opacity 0.15s, transform 0.15s; white-space: normal; text-align: left; z-index: 20; }
.season-cell:hover .tip { opacity: 1; transform: translate(-50%, 0); }

.season-legend { display: flex; flex-wrap: wrap; gap: 12px 18px; margin-top: 12px; font: 400 12px/1.4 var(--font-sans); color: var(--muted-foreground); }
.season-legend .sw { display: inline-block; width: 10px; height: 10px; border-radius: 2px; vertical-align: middle; margin-right: 6px; }
.season-legend .m { background: var(--season-monsoon); }
.season-legend .w { background: var(--season-wintering); }
.season-legend .p { background: var(--season-peak); }
.season-legend .t { background: var(--season-transition); }

/* .season-overlay now sits inside .phase1-context which already provides the dashed top rule */
.season-overlay { font: 400 12px/1.55 var(--font-sans); color: var(--muted-foreground); }
.season-overlay strong { color: var(--foreground); font-weight: 500; }

@media (max-width: 560px) { .season-cell .mm { display: none; } .season-strip { height: 56px; } }

/* ─── Rainfall block (TMD spatial + our overlay + threshold + sparkline) */
.rain-grid {
  display: grid; grid-template-columns: 1fr; gap: 18px;
}
@media (min-width: 880px) {
  .rain-grid { grid-template-columns: 300px 1fr; gap: 28px; align-items: stretch; }
}

/* Left column — TMD thumbnail with SVG overlay */
.rain-thumb-wrap {
  position: relative; width: 100%; max-width: 300px;
  background: var(--chip-bg); border: 1px solid var(--border); border-radius: var(--radius-md);
  overflow: hidden; aspect-ratio: 350 / 720;
}
.rain-thumb-img { display: block; width: 100%; height: 100%; object-fit: cover; background: var(--chip-bg); }
.rain-thumb-img.hidden { display: none; }
.rain-thumb-overlay {
  position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none;
}
.rain-thumb-fallback {
  display: none; position: absolute; inset: 0; align-items: center; justify-content: center;
  text-align: center; padding: 16px; color: var(--muted-foreground);
  font: 400 11px/1.5 var(--font-mono); background: var(--chip-bg);
}
.rain-thumb-fallback.show { display: flex; }
.rain-thumb-fallback strong { display: block; font-weight: 500; color: var(--foreground); margin-bottom: 6px; font-family: var(--font-sans); font-size: 12px; letter-spacing: 0.02em; }
.rain-thumb-caption {
  margin-top: 6px; font: 400 10.5px/1.4 var(--font-mono); color: var(--muted-foreground);
  display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap;
}
.rain-thumb-caption .date { color: var(--foreground); font-weight: 500; }

/* SVG overlay — Sadao pin + 100km ring */
.rain-overlay .ring { fill: none; stroke: var(--primary); stroke-width: 1.25; stroke-dasharray: 3 3; opacity: 0.9; }
.rain-overlay .ring-halo { fill: var(--primary); opacity: 0.08; }
.rain-overlay .pin-dot { fill: var(--primary); stroke: #fff; stroke-width: 1.5; }
.rain-overlay .pin-label { fill: var(--foreground); font: 600 10px/1 var(--font-sans); letter-spacing: 0.02em; paint-order: stroke fill; stroke: #fff; stroke-width: 3; stroke-linejoin: round; }

/* Right column — today at Sadao + sparkline */
.rain-right { display: flex; flex-direction: column; gap: 16px; }

.rain-today-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 8px; }
.rain-today-head .label { font: 500 10px/1 var(--font-mono); text-transform: uppercase; letter-spacing: 0.14em; color: var(--muted-foreground); }
.rain-today-head .date { font: 400 11px/1 var(--font-mono); color: var(--muted-foreground); }

.rain-today-value { display: flex; align-items: baseline; gap: 10px; margin-bottom: 10px; flex-wrap: wrap; }
.rain-today-mm { font: 600 30px/1 var(--font-sans); letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.rain-today-unit { font: 500 12px/1 var(--font-mono); color: var(--muted-foreground); }
.rain-today-tag { display: inline-flex; align-items: center; gap: 6px; padding: 5px 12px; border-radius: 999px; font: 600 10px/1 var(--font-mono); letter-spacing: 0.08em; text-transform: uppercase; border: 1px solid transparent; }
.rain-today-tag[data-band="normal"]       { background: var(--band-green-bg); color: var(--band-green); border-color: var(--band-green-border); }
.rain-today-tag[data-band="impractical"]  { background: var(--band-amber-bg); color: var(--band-amber); border-color: var(--band-amber-border); }
.rain-today-tag[data-band="impossible"]   { background: var(--band-red-bg);   color: var(--band-red);   border-color: var(--band-red-border); }
.rain-today-tag[data-band="unknown"]      { background: var(--band-gray-bg);  color: var(--band-gray);  border-color: var(--band-gray-border); }
.rain-today-tag .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; opacity: 0.85; }

/* Threshold gauge — horizontal bar with three bands + marker */
.rain-gauge { position: relative; width: 100%; height: 22px; background: linear-gradient(to right, var(--band-green-bg) 0%, var(--band-green-bg) var(--p1, 26%), var(--band-amber-bg) var(--p1, 26%), var(--band-amber-bg) var(--p2, 72%), var(--band-red-bg) var(--p2, 72%), var(--band-red-bg) 100%); border: 1px solid var(--border); border-radius: 999px; margin: 8px 0 6px; overflow: visible; }
.rain-gauge .rail-tick { position: absolute; top: -4px; bottom: -4px; width: 1px; background: var(--border); opacity: 0.7; }
.rain-gauge .rail-marker { position: absolute; top: -6px; bottom: -6px; width: 12px; margin-left: -6px; background: var(--primary); border: 2px solid var(--card); border-radius: 3px; box-shadow: var(--shadow-sm); transition: left 0.35s ease; }
.rain-gauge-legend { display: flex; align-items: center; justify-content: space-between; font: 400 10.5px/1.3 var(--font-mono); color: var(--muted-foreground); gap: 8px; }
.rain-gauge-legend span { display: flex; flex-direction: column; gap: 1px; }
.rain-gauge-legend .v { color: var(--foreground); font-weight: 500; font-variant-numeric: tabular-nums; }
.rain-gauge-legend .k { font-size: 9.5px; text-transform: uppercase; letter-spacing: 0.08em; }

/* 14-day sparkline */
.rain-spark-wrap { background: var(--surface-sunken); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 10px 12px 12px; }
.rain-spark-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 8px; }
.rain-spark-head .label { font: 500 10px/1 var(--font-mono); text-transform: uppercase; letter-spacing: 0.14em; color: var(--muted-foreground); }
.rain-spark-head .range { font: 400 10.5px/1 var(--font-mono); color: var(--muted-foreground); font-variant-numeric: tabular-nums; }
.rain-spark-svg { display: block; width: 100%; height: 110px; overflow: visible; }

/* Session 37 — rainfall sparkline stretches to match TMD thumbnail height on
   desktop. On mobile (<880px) the grid is single-column and the chart stays at
   its default 110px. On desktop the grid stretches both columns to the same
   row height, so the sparkline wrap absorbs whatever vertical space remains
   below the today-value + gauge + legend. Dynamic viewBox is set at draw time
   (see renderRainfall) so bars/thresholds compute against actual clientHeight. */
@media (min-width: 880px) {
  .rain-spark-wrap { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 280px; }
  .rain-spark-wrap .rain-spark-head { flex: 0 0 auto; }
  #rain-spark-svg { flex: 1 1 auto; height: auto; min-height: 260px; }
}

/* TAT-045 — Thai Central Market · Field Latex card specifics */
#tcm-card .phase1-hero .supply-number { color: var(--primary, inherit); }
#tcm-card .tcm-dod { display: inline-flex; align-items: center; gap: 4px; font: 500 11px/1 var(--font-mono); font-variant-numeric: tabular-nums; }
#tcm-card .tcm-dod .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--muted-foreground); display: inline-block; }
#tcm-card .tcm-dod[data-band="up"]   .dot { background: var(--band-green, #1e8a4c); }
#tcm-card .tcm-dod[data-band="down"] .dot { background: var(--band-red, #c4432b); }
#tcm-card .tcm-dod[data-band="flat"] .dot { background: var(--muted-foreground); }

/* 2×2 grid layout (Session 35 hotfix — Kenneth's layout steer):
   C1R1 big weighted settlement · C2R1 14-day sparkline
   C1R2 EUDR card               · C2R2 Non-EUDR card
   Mobile stacks to 1-col single-row-each; desktop breakpoint at 720px. */
.tcm-grid { display: grid; grid-template-columns: 1fr; gap: 16px; margin-bottom: 16px; align-items: stretch; }
@media (min-width: 720px) { .tcm-grid { grid-template-columns: 1fr 1fr; gap: 18px; } }

.tcm-hero-card {
  background: var(--surface-sunken);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 16px 18px;
  display: flex; flex-direction: column; justify-content: center; gap: 6px;
  min-height: 140px;
}
.tcm-hero-card .phase1-hero { margin-bottom: 2px; }
.tcm-hero-card .phase1-sub { margin: 0; }

.tcm-kpi-card {
  background: var(--surface-sunken);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 14px 16px;
  display: flex; flex-direction: column; gap: 8px; justify-content: center;
  min-height: 84px;
}
.tcm-kpi-card .tcm-kpi-label {
  font: 500 10px/1 var(--font-mono);
  color: var(--muted-foreground);
  text-transform: uppercase;
  letter-spacing: 0.14em;
}
.tcm-kpi-card .tcm-kpi-value {
  display: flex; align-items: baseline; gap: 6px;
  font: 600 22px/1.1 var(--font-sans);
  font-variant-numeric: tabular-nums;
  color: var(--foreground);
}
.tcm-kpi-card .tcm-kpi-value .unit {
  font: 500 10.5px/1 var(--font-mono);
  color: var(--muted-foreground);
  letter-spacing: 0.02em;
}
.tcm-kpi-card.tcm-kpi-eudr .tcm-kpi-value .val { color: var(--band-green, #1e8a4c); }

/* Sparkline overrides inside #tcm-card — narrower grid cell stretches viewBox
   less horizontally, so the line appears steeper naturally. Session 37 —
   bumped to 140 (was 130) alongside the drawTcmSparkline refinement:
   finer stroke, softer area fill, target-style last-point marker, faint
   baseline, reduced-opacity axis labels. Taller canvas lets the line breathe. */
#tcm-card .rain-spark-wrap { min-height: 152px; display: flex; flex-direction: column; }
#tcm-card .rain-spark-svg { flex: 1 1 auto; height: 140px; }
.tcm-regions { display: flex; flex-direction: column; gap: 2px; margin-top: 8px; font: 500 11.5px/1.3 var(--font-mono); }
.tcm-region-head { display: grid; grid-template-columns: 1.6fr 0.7fr 0.7fr; gap: 10px; padding: 6px 8px; background: var(--surface-sunken); border-radius: 4px; color: var(--muted-foreground); font-size: 10.5px; letter-spacing: 0.04em; text-transform: uppercase; }
/* Right-align the numeric header cells (Non-EUDR, EUDR) so they sit over the
   right-aligned .tcm-region-val values below. Without this, headers default
   to left-align while values stay right-aligned — the visual drift makes each
   value look like it sits under the *next* column's header. */
.tcm-region-head span + span { text-align: right; }
.tcm-region-row  { display: grid; grid-template-columns: 1.6fr 0.7fr 0.7fr; gap: 10px; padding: 6px 8px; border-bottom: 1px dashed var(--border, #e5e5e5); align-items: baseline; }
.tcm-region-row:last-child { border-bottom: none; }
.tcm-region-name { color: var(--foreground); }
.tcm-region-name .region-hint { color: var(--muted-foreground); font-style: normal; font-size: 10px; letter-spacing: 0.02em; }
.tcm-region-val  { text-align: right; font-variant-numeric: tabular-nums; }
.tcm-region-val[data-class="eudr"]     { color: var(--band-green, #1e8a4c); }
.tcm-region-val[data-class="non-eudr"] { color: var(--foreground); }
.rain-spark-svg .spark-threshold { stroke: var(--band-amber); stroke-width: 1; stroke-dasharray: 2 3; opacity: 0.55; }
.rain-spark-svg .spark-threshold-critical { stroke: var(--band-red); stroke-width: 1; stroke-dasharray: 2 3; opacity: 0.55; }
.rain-spark-svg .spark-threshold-label { fill: var(--muted-foreground); font: 500 9px/1 var(--font-mono); letter-spacing: 0.04em; }
.rain-spark-svg .spark-bar { fill: var(--primary); opacity: 0.85; }
.rain-spark-svg .spark-bar.impractical { fill: var(--band-amber); }
.rain-spark-svg .spark-bar.impossible  { fill: var(--band-red); }
.rain-spark-svg .spark-axis-label { fill: var(--muted-foreground); font: 500 9px/1 var(--font-mono); letter-spacing: 0.04em; }
.rain-spark-svg .spark-value-label { fill: var(--foreground); font: 500 9.5px/1 var(--font-mono); font-variant-numeric: tabular-nums; }

/* Supply-zone region context — balances the tall TMD thumb on desktop */
.rain-region { margin-top: 2px; }
.rain-region-head { margin-bottom: 8px; }
.rain-region-head .label { font: 500 10px/1 var(--font-mono); text-transform: uppercase; letter-spacing: 0.14em; color: var(--muted-foreground); }
.rain-region-grid { margin: 0; padding: 10px 12px; background: var(--surface-sunken); border: 1px solid var(--border); border-radius: var(--radius-md); display: grid; grid-template-columns: 1fr; gap: 6px; }
.rain-region-grid > div { display: grid; grid-template-columns: 72px 1fr; gap: 10px; align-items: baseline; }
.rain-region-grid dt { font: 500 10px/1.35 var(--font-mono); text-transform: uppercase; letter-spacing: 0.1em; color: var(--muted-foreground); margin: 0; }
.rain-region-grid dd { margin: 0; font: 400 12px/1.35 var(--font-sans); color: var(--foreground); font-variant-numeric: tabular-nums; }

.rain-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
}
.rain-foot .context-foot { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.rain-link {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px; border-radius: 999px; font: 500 11px/1 var(--font-sans);
  color: var(--primary); background: var(--accent); border: 1px solid var(--border);
  text-decoration: none; white-space: nowrap; transition: background 0.15s;
}
.rain-link:hover { background: var(--muted); border-color: var(--input); }
.rain-link .arrow { font: 500 11px/1 var(--font-mono); }

@media (max-width: 560px) {
  .rain-today-mm { font-size: 24px; }
  .rain-thumb-wrap { max-width: 240px; margin: 0 auto; }
}

/* ─── TAT-029 Session 26 — Sales pipeline + Market intelligence cards ──── */
/* Sales top-buyers list (inline rows — buyer, country tier, volume share). */
.sales-top-buyers { display: flex; flex-direction: column; gap: 4px; }
.sales-top-buyers .row { display: flex; align-items: baseline; gap: 8px; font: 400 12px/1.5 var(--font-sans); color: var(--foreground); }
.sales-top-buyers .row .buyer { font-weight: 500; }
.sales-top-buyers .row .meta { font: 400 11px/1.4 var(--font-mono); color: var(--muted-foreground); margin-left: auto; font-variant-numeric: tabular-nums; }
.sales-outliers { display: flex; align-items: baseline; gap: 8px; font: 400 12px/1.5 var(--font-sans); color: var(--foreground); flex-wrap: wrap; }
.sales-outliers .val { font-variant-numeric: tabular-nums; font-weight: 500; }
.sales-outliers .val.loss { color: var(--tier-critical); }
.sales-outliers .val.fx { color: var(--band-amber); }
.sales-outliers .val.ok { color: var(--tier-normal); }
/* Intel card — 2-column contact grid on desktop, 1-column on mobile. */
.intel-grid { display: grid; grid-template-columns: 1fr; gap: 12px; margin-bottom: 8px; }
@media (min-width: 720px) { .intel-grid { grid-template-columns: 1fr 1fr; } }
.intel-card-item { border: 1px solid var(--border); border-radius: var(--radius-md); padding: 12px 14px; background: var(--background); display: flex; flex-direction: column; gap: 8px; }
.intel-card-item .ici-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
.intel-card-item .ici-name { font: 600 14px/1.2 var(--font-sans); color: var(--foreground); letter-spacing: -0.005em; }
.intel-card-item .ici-company { font: 400 12px/1.4 var(--font-sans); color: var(--muted-foreground); }
.intel-card-item .ici-meta { font: 400 10.5px/1.3 var(--font-mono); color: var(--muted-foreground); text-transform: uppercase; letter-spacing: 0.06em; }
.intel-card-item .ici-archetype { font: 500 10px/1 var(--font-mono); text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted-foreground); padding: 5px 12px; border: 1px solid var(--chip-border); border-radius: var(--radius-sm); background: var(--chip-bg); }
.intel-card-item .ici-reliability { font: 500 10px/1 var(--font-mono); color: var(--muted-foreground); font-variant-numeric: tabular-nums; }
.intel-card-item .ici-reliability strong { color: var(--foreground); font-weight: 600; }
.intel-card-item .ici-signals { display: flex; flex-direction: column; gap: 4px; border-top: 1px dashed var(--border); padding-top: 6px; }
.intel-card-item .ici-sig { display: flex; gap: 8px; align-items: baseline; font: 400 12px/1.45 var(--font-sans); color: var(--foreground); }
.intel-card-item .ici-sig .sig-date { font: 400 10.5px/1.3 var(--font-mono); color: var(--muted-foreground); font-variant-numeric: tabular-nums; flex-shrink: 0; width: 54px; }
.intel-card-item .ici-sig .sig-dir { font: 500 10px/1 var(--font-mono); text-transform: uppercase; letter-spacing: 0.08em; padding: 1px 4px; border-radius: var(--radius-sm); flex-shrink: 0; }
.intel-card-item .ici-sig .sig-dir.up { background: var(--tier-normal-bg); color: var(--tier-normal); }
.intel-card-item .ici-sig .sig-dir.down { background: var(--tier-critical-bg); color: var(--tier-critical); }
.intel-card-item .ici-sig .sig-dir.neutral { background: var(--chip-bg); color: var(--muted-foreground); }
.intel-card-item .ici-sig .sig-summary { color: var(--foreground); }
.intel-card-item .ici-empty { font: 400 12px/1.5 var(--font-sans); color: var(--muted-foreground); font-style: italic; padding: 4px 0; }
/* NOTIFICATIONS OFF chip — muted variant of .prov-chip. */
.prov-chip[data-prov="off"] { background: var(--chip-bg); color: var(--muted-foreground); border-color: var(--chip-border); opacity: 0.75; }
.skel-block { display: block; width: 100%; min-height: 60px; padding: 12px; font: 400 11px/1.4 var(--font-mono); color: var(--muted-foreground); }

/* ─── Error state + loading skeleton ─────────────────────────────────────── */
.err-state { display: none; background: var(--tier-critical-bg); border: 1px solid var(--tier-critical-border); color: var(--tier-critical); padding: 10px 14px; border-radius: var(--radius-md); font: 400 12px/1.5 var(--font-sans); margin-bottom: 14px; }
.err-state.show { display: block; }
.skel { display: inline-block; background: linear-gradient(90deg, var(--skel-a, #f1f5f9), var(--skel-b, #e2e8f0), var(--skel-a, #f1f5f9)); background-size: 200% 100%; animation: shimmer 1.4s ease-in-out infinite; border-radius: 4px; height: 1em; min-width: 2em; color: transparent; }
@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }

/* ─── Footnote ───────────────────────────────────────────────────────────── */
.footnote { margin-top: 40px; padding-top: 20px; border-top: 1px solid var(--border); font: 400 11px/1.5 var(--font-mono); color: var(--muted-foreground); display: flex; flex-wrap: wrap; justify-content: space-between; gap: 10px; }
.footnote a { color: var(--muted-foreground); text-decoration: none; }
.footnote a:hover { color: var(--primary); }

@media (max-width: 560px) {
  .content { padding: 16px 14px 64px; }
  .card { padding: 16px 16px; }
  .supply-number { font-size: 28px; }
  .inv-number { font-size: 44px; }
  .tile-price { font-size: 20px; }
  .spread-number { font-size: 26px; }
  .trend-svg { height: 220px; }
}

/* === Password visibility toggle (SnS gate) === */
.pw-wrap { position: relative; }
.pw-wrap > .gate-input { padding-right: 44px; }
.pw-toggle {
  position: absolute; top: 50%; right: 8px; transform: translateY(-50%);
  background: transparent; border: 0; padding: 6px; cursor: pointer;
  color: var(--muted-foreground); display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--radius-sm); transition: color 0.15s, background 0.15s;
}
.pw-toggle:hover { color: var(--foreground); background: rgba(0,0,0,0.04); }
.pw-toggle:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.pw-toggle svg { width: 18px; height: 18px; display: block; }

/* ─── Sub-page header (TAT-055 — shared by calculator + procurement-form) ─
   For top-level <h1> on a sub-page (Calculator, Log a buy, future settings/etc.).
   Distinct from .sec h2 (26px), which heads sections WITHIN a page.
   No element qualifier — works on h1, h2, etc. (per Codex F6, 28 Apr 2026). */
.page-title { font: 500 24px/1.2 var(--font-sans); letter-spacing: -0.02em; margin-bottom: 8px; color: var(--foreground); }
.page-lede { font-size: 13px; color: var(--muted-foreground); margin-bottom: 28px; max-width: 64ch; line-height: 1.6; }
.page-lede code { font-family: var(--font-mono); font-size: 12px; background: var(--muted); padding: 2px 6px; border-radius: var(--radius-sm); color: var(--foreground); }

/* ─── Form field (TAT-055 — canonical form pattern) ───────────────────────
   Used by procurement-form (Log a buy) + future log-a-sale, settings, etc.
   Calculator uses a different field pattern (.calc-field) — not interchangeable. */
.field { display: flex; flex-direction: column; gap: 6px; }
.field > label { font-size: 12px; font-weight: 500; color: var(--muted-foreground); text-transform: uppercase; letter-spacing: 0.06em; }
.field > input,
.field > select,
.field > textarea {
  padding: 11px 14px; font: 400 15px/1.2 var(--font-sans);
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius-sm);
  outline: none; color: var(--foreground); width: 100%;
}
.field > input[type="number"] { font-variant-numeric: tabular-nums; font-family: var(--font-mono); font-size: 16px; }
.field > input:focus, .field > select:focus, .field > textarea:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px rgb(255 255 255 / 0.08);
}
.field > textarea { min-height: 60px; resize: vertical; font-family: var(--font-sans); }
.field-hint { font-size: 11px; color: var(--muted-foreground); font-weight: 400; }
.field-err { font-size: 12px; color: var(--tier-critical); font-weight: 500; display: none; }
.field.has-err > input, .field.has-err > select { border-color: var(--tier-critical); }
.field.has-err > .field-err { display: block; }

/* ─── Segmented radio control (TAT-055) ───────────────────────────────────
   Three- or two-segment radio group. Used by procurement-form for currency / DRC mode. */
.segmented {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 0;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius-sm);
  overflow: hidden;
}
.segmented.two { grid-template-columns: repeat(2, 1fr); }
.segmented input[type="radio"] { position: absolute; opacity: 0; pointer-events: none; }
.segmented label {
  display: block; padding: 10px 8px; font: 500 13px/1 var(--font-sans);
  text-align: center; cursor: pointer; transition: all 0.15s; color: var(--muted-foreground);
  border-right: 1px solid var(--border);
}
.segmented label:last-of-type { border-right: 0; }
.segmented input[type="radio"]:checked + label { background: var(--primary); color: var(--primary-foreground); }
.segmented input[type="radio"]:focus-visible + label { outline: 2px solid var(--primary); outline-offset: -2px; }

/* ─── Two-column row (TAT-055) ────────────────────────────────────────────
   Generic 1fr 1fr row that collapses to 1 column on mobile. */
.row-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
@media (max-width: 480px) { .row-2 { grid-template-columns: 1fr; } }

/* ─── Buttons (TAT-055) ───────────────────────────────────────────────────
   Primary = filled brand colour; secondary = bordered, neutral. */
.btn-primary {
  padding: 14px 16px; font: 500 15px/1 var(--font-sans);
  background: var(--primary); color: var(--primary-foreground); border: 0; border-radius: var(--radius-sm);
  cursor: pointer; transition: filter 0.15s;
}
.btn-primary:hover:not(:disabled) { filter: brightness(1.06); }
.btn-primary:disabled { background: var(--muted); color: var(--muted-foreground); cursor: not-allowed; }
.btn-secondary {
  padding: 10px 14px; font: 500 13px/1 var(--font-sans);
  background: var(--card); color: var(--foreground);
  border: 1px solid var(--border); border-radius: var(--radius-sm); cursor: pointer;
  text-decoration: none;
}
.btn-secondary:hover { border-color: var(--primary); color: var(--primary); }
