/* SBF Annual Business Sentiments 2025 — Dashboard */
:root {
  /* SBF corporate palette, read from the theme of
     "SBF Corporate PPT Template_20241018 (1).pptx" (ppt/theme/theme1.xml).
     Primary pair is cyan + red (accent1/accent2); navy, green, coral and
     forest are the secondary set. */
  --sbf-navy: #0E2147;        /* dk2 / accent3 */
  --sbf-cyan: #00AED5;        /* accent1 — primary */
  --sbf-cyan-deep: #0089A8;
  --sbf-red: #EF3340;         /* accent2 — primary */
  --sbf-red-deep: #A50C20;    /* folHlink — the theme's deep red, 7.86:1 on white */
  --sbf-pale: #E4F0F5;        /* lt2 */
  --sbf-green: #10C27A;       /* accent4 */
  --sbf-coral: #FF5E49;       /* accent5 */
  --sbf-coral-soft: #FF9686;
  --sbf-forest: #00443A;      /* accent6 */

  --bg: #FFFFFF;
  --bg-warm: var(--sbf-pale);
  --bg-deep: var(--sbf-navy);
  --ink: var(--sbf-navy);
  --ink-soft: #4A5B78;
  --ink-mute: #8496AF;
  --line: rgba(14,33,71,0.12);
  --line-strong: rgba(14,33,71,0.26);

  /* Ink scale for panel content. Ground-agnostic since the dark panels were
     retired — every `rgba(var(--ink-rgb), a)` step is navy on a light ground. */
  --ink-rgb: 14, 33, 71;

  /* Chart palette. Cyan reads 6.03:1 on the navy ground and red only 3.93:1,
     so negatives use coral (5.24:1) wherever they sit on dark. */
  --chart-pos: var(--sbf-cyan);
  --chart-pos-glow: #4FD3EE;   /* light ink on a dark ground — hero video only */
  /* Tone pair for content on the light/tinted grounds. */
  --tone-pos: #0089A8;         /* 4.08:1 on white */
  --tone-neg: var(--chart-neg);/* #EF3340, 4.02:1 */
  --tone-neu: #7286A3;         /* 3.20:1 on the pale ground, 3.71:1 on white */
  --chart-neu: #CBD6E2;
  --chart-neg: var(--sbf-red);
  /* Literal, not var(--sbf-coral): tweaks.js writes --sbf-coral as an inline
     style on :root, which outranks this sheet and would quietly resolve the
     dark-ground negative back to the 3.93:1 red this token exists to avoid. */
  --chart-series-3: var(--sbf-green);

  --serif: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --mono: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}

* { box-sizing: border-box; margin: 0; padding: 0; }
/* No italics anywhere in this project — covers the <em>/<i> UA defaults too. */
em, i, cite, dfn, address, var { font-style: normal; }
html, body { background: var(--bg); color: var(--ink); font-family: var(--sans); font-weight: 400; -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; }
body { overflow-x: hidden; }
a { color: inherit; }

::selection { background: var(--sbf-cyan); color: white; }

/* ---------- Nav ---------- */
.nav {
  --navT: 0;
  position: fixed; top: 0; left: 0; right: 0; z-index: 50;
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 36px;
  background: rgba(255,255,255, calc(0.86 * var(--navT)));
  backdrop-filter: blur(calc(12px * var(--navT)));
  -webkit-backdrop-filter: blur(calc(12px * var(--navT)));
  border-bottom: 1px solid rgba(0,0,0, calc(0.08 * var(--navT)));
  box-shadow: 0 1px 0 rgba(31,31,29, calc(0.04 * var(--navT)));
}
/* Logo always visible at its final size/position, original colors. */
.nav__logo img {
  height: 40px;
  display: block;
}
.nav__filterSlot {
  display: flex;
  align-items: center;
  min-height: 1px;
  opacity: var(--navT);
  pointer-events: auto;
}
.nav--ghost .nav__filterSlot { pointer-events: none; }
.nav__links { display: flex; gap: 28px; }
.nav__links a { font-size: 14px; color: var(--ink-soft); text-decoration: none; font-weight: 500; letter-spacing: 0.01em; transition: color .2s; }
.nav__links a:hover { color: var(--sbf-cyan-deep); }
.nav__meta { display: flex; gap: 12px; }
.nav__pill { font-family: var(--mono); font-size: 12px; padding: 7px 14px; border: 1px solid var(--line-strong); border-radius: 999px; color: var(--ink-soft); letter-spacing: 0.02em; }

@media (max-width: 900px) { .nav__links { display: none; } }

/* ---------- Hero ---------- */
.hero {
  min-height: 100vh;
  padding: 88px 64px 36px;
  display: flex; flex-direction: column; justify-content: center;
  max-width: 1600px; margin: 0 auto;
  position: relative;
}

/* Hero with video background */
.hero--video {
  max-width: none;
  padding-left: 0;
  padding-right: 0;
  overflow: hidden;
  isolation: isolate;
  color: #fff;
}
/* Left edge matches the fixed nav's padding so the copy lines up with the logo.
   Full width, so the stats row below can centre itself on the page. */
.hero--video .hero__inner {
  width: 100%;
  margin: 0;
  padding: 0 36px;
  position: relative;
  z-index: 2;
}
/* While the first screen loads (see the script in index.html's head) the page is
   held back on the hero's dark ground, then shown complete in one step. */
html.is-loading { background: #0B1018; }
html.is-loading body { visibility: hidden; }
.hero__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  background: #0B1018;
}
.hero__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  filter: saturate(0.92) contrast(1.02);
}
.hero__scrim {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, rgba(8,12,20,0.55) 0%, rgba(8,12,20,0.28) 35%, rgba(8,12,20,0.55) 75%, rgba(8,12,20,0.85) 100%),
    linear-gradient(90deg, rgba(8,12,20,0.55) 0%, rgba(8,12,20,0.10) 50%, rgba(8,12,20,0.20) 100%);
}



/* Title + content adapted for video */
.hero--video .hero__eyebrow { color: rgba(255,255,255,0.82); }
.hero--video .dot--cyan { background: var(--sbf-cyan); box-shadow: 0 0 0 4px rgba(0,174,213,0.30); }
.hero--video .hero__title {
  color: #fff;
  text-shadow: 0 2px 30px rgba(0,0,0,0.35), 0 1px 2px rgba(0,0,0,0.25);
}
.hero--video .hero__italic { color: var(--sbf-cyan); }
.hero--video .hero__accent { color: var(--sbf-red); }
.hero--video .hero__lede { color: rgba(255,255,255,0.86); text-shadow: 0 1px 14px rgba(0,0,0,0.35); }
.hero--video .hero__stats { border-top-color: rgba(255,255,255,0.18); border-bottom-color: rgba(255,255,255,0.18); }
.hero--video .stat__num { color: #fff; }
.hero--video .stat__lbl { color: rgba(255,255,255,0.7); }
.hero--video .hero__scroll { color: rgba(255,255,255,0.78); }

/* Filter bar over video — translucent dark */
.hero--video .filters {
  background: rgba(18,22,30,0.55);
  backdrop-filter: blur(14px) saturate(1.2);
  -webkit-backdrop-filter: blur(14px) saturate(1.2);
  border-color: rgba(255,255,255,0.14);
}
.hero--video .filters__label { color: #fff; }
.hero--video .filters__cap { color: rgba(255,255,255,0.7); }
.hero--video .chip { color: #fff; border-color: rgba(255,255,255,0.30); }
.hero--video .chip:hover { border-color: #fff; }
.hero--video .chip--active { background: #fff; color: #111; border-color: #fff; }
.hero--video .filters__n { color: rgba(255,255,255,0.72); }

@media (prefers-reduced-motion: reduce) {
  /* image hero is static; keep it visible */
}
.hero__eyebrow { display: inline-flex; align-items: center; gap: 10px; font-size: 13px; color: var(--ink-soft); font-weight: 500; margin-bottom: 20px; }
.dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
.dot--cyan { background: var(--sbf-cyan); box-shadow: 0 0 0 4px rgba(0,174,213,0.18); }
.hero__title {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(40px, 6.4vw, 96px);
  line-height: 0.98;
  letter-spacing: -0.02em;
  display: flex; flex-direction: column;
  text-wrap: pretty;
  margin-bottom: 24px;
}
/* The headline pair is the logo pair, sampled from assets/sbf-logo.png.
   Named for the original italic treatment; the emphasis is now carried by
   colour alone. tweaks.js:formatHeadline() generates this class, so the name
   is kept in step with that. */
.hero__italic { color: var(--sbf-cyan); }
.hero__accent { color: var(--sbf-red); }
/* Three-tier headline: cyan kicker, bold all-caps title, light all-caps subtitle,
   with the organisation name set small above it. */
.hero__org {
  font-size: clamp(15px, 1.4vw, 20px);
  font-weight: 600;
  letter-spacing: 0.01em;
  margin-bottom: 0.6em;
}
.hero__kicker {
  color: var(--sbf-cyan);
  font-size: clamp(22px, 2.6vw, 40px);
  font-weight: 500;
  letter-spacing: 0;
  margin-bottom: 0.25em;
}
.hero__main {
  text-transform: uppercase;
  font-weight: 800;
  letter-spacing: 0.01em;
}
.hero__sub {
  text-transform: uppercase;
  font-size: clamp(22px, 2.8vw, 42px);
  font-weight: 400;
  letter-spacing: 0.01em;
  margin-top: 0.3em;
}
.hero__lede {
  font-size: clamp(16px, 1.25vw, 19px);
  line-height: 1.5;
  max-width: 620px;
  color: var(--ink-soft);
  margin-bottom: 32px;
}
/* Centred on the page (rules included) while the copy above stays left-aligned. */
.hero__stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 32px; padding: 22px 0; max-width: 1600px; margin-left: auto; margin-right: auto; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
@media (max-width: 720px) { .hero__stats { grid-template-columns: repeat(2, 1fr); } }
.stat__num { font-family: var(--serif); font-size: clamp(30px, 3vw, 46px); line-height: 1; color: var(--ink); font-variant-numeric: tabular-nums; display: inline-flex; align-items: baseline; gap: 0; }
.stat__year { display: inline-block; }
.stat__qtr {
  display: inline-block;
  font-family: var(--serif);
  font-size: 1em;
  font-style: normal;
  font-weight: inherit;
  color: inherit;
  letter-spacing: inherit;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.5s cubic-bezier(.2,.7,.2,1), transform 0.6s cubic-bezier(.2,.7,.2,1);
}
.stat__sep {
  display: inline-block;
  margin: 0 0.22em;
  font-family: var(--serif);
  color: inherit;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.5s cubic-bezier(.2,.7,.2,1), transform 0.6s cubic-bezier(.2,.7,.2,1);
}
.hero--video .stat__qtr,
.hero--video .stat__sep { color: #fff; }
.stat__qtr--in,
.stat__sep--in { opacity: 1; transform: translateY(0); }
/* Sits above the number without pushing it down, so numbers stay level across columns. */
.stat { position: relative; text-align: center; }
.stat__pre { position: absolute; bottom: 100%; left: 0; right: 0; margin-bottom: 4px; font-size: 12px; text-transform: uppercase; letter-spacing: 0.12em; color: var(--ink-mute); }
.hero--video .stat__pre { color: rgba(255,255,255,0.7); }
.hero__stats:has(.stat__pre) { padding-top: 36px; }
.stat__num--text { white-space: nowrap; }
@media (max-width: 720px) {
  .stat:has(.stat__num--text) { grid-column: 1 / -1; }
  .stat__num--text { font-size: clamp(24px, 7vw, 34px); }
}
.stat__lbl { font-size: 12px; text-transform: uppercase; letter-spacing: 0.12em; color: var(--ink-mute); margin-top: 8px; }
.hero__scroll { position: absolute; bottom: 32px; right: 64px; display: flex; align-items: center; gap: 12px; font-size: 12px; color: var(--ink-mute); text-transform: uppercase; letter-spacing: 0.14em; }

/* Filter bar */
.filters { margin-top: 48px; display: flex; align-items: center; gap: 32px; flex-wrap: wrap; padding: 24px; background: #FAFAF8; border: 1px solid var(--line); border-radius: 4px; }
.filters__label { font-family: var(--serif); font-size: 20px; color: var(--ink); }
.filters__group { display: flex; align-items: center; gap: 12px; }
.filters__cap { font-size: 11px; text-transform: uppercase; letter-spacing: 0.12em; color: var(--ink-mute); }
.filters__chips { display: flex; gap: 6px; }
.chip { border: 1px solid var(--line-strong); background: transparent; color: var(--ink); font: 500 13px var(--sans); padding: 8px 14px; border-radius: 999px; cursor: pointer; transition: all .18s; }
.chip:hover { border-color: var(--ink); }
.chip--active { background: var(--ink); color: var(--bg); border-color: var(--ink); }
.filters__n { margin-left: auto; font-family: var(--mono); font-size: 12px; color: var(--ink-mute); }

/* ---------- Compact in-section filter strip ---------- */
.fstrip {
  display: flex; align-items: center; gap: 20px; flex-wrap: wrap;
  padding: 14px 18px;
  background: #FAFAF8;
  border: 1px solid var(--line);
  border-radius: 999px;
  margin-bottom: 56px;
  font-size: 12px;
}
.fstrip__cap {
  font: 500 10px var(--mono);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--ink-mute);
  padding-left: 4px;
}
.fstrip__group { display: flex; align-items: center; gap: 8px; }
.fstrip__chips { display: flex; gap: 4px; }
.fstrip .chip {
  padding: 5px 12px;
  font-size: 12px;
  border-radius: 999px;
  white-space: nowrap;
}
.fstrip__sep {
  width: 1px; height: 20px;
  background: var(--line-strong);
  opacity: 0.5;
}




@media (max-width: 720px) {
  .fstrip { padding: 12px; gap: 10px; border-radius: 14px; }
  .fstrip__sep { display: none; }
}

/* ---------- Panels ---------- */
.panel {
  padding: 140px 64px;
  max-width: 1600px; margin: 0 auto;
  position: relative;
}
.panel__kicker {
  display: flex; align-items: baseline; gap: 16px;
  font-size: 13px; text-transform: uppercase; letter-spacing: 0.16em; color: var(--ink-soft);
  margin-bottom: 56px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--line);
  width: 100%;
}
.kicker__num { font-family: var(--mono); font-size: 11px; color: var(--sbf-red-deep); letter-spacing: 0.08em; }
.panel__grid { display: grid; grid-template-columns: 1fr 1.4fr; gap: 80px; align-items: start; }
.panel__grid--reverse { grid-template-columns: 1.4fr 1fr; }
.panel__grid--reverse .panel__copy { order: 2; }
.panel__grid--reverse .panel__viz { order: 1; }
@media (max-width: 980px) { .panel__grid, .panel__grid--reverse { grid-template-columns: 1fr; gap: 48px; } .panel__grid--reverse .panel__copy, .panel__grid--reverse .panel__viz { order: initial; } }
.panel__title { font-family: var(--serif); font-weight: 400; font-size: clamp(36px, 4.4vw, 64px); line-height: 1.02; letter-spacing: -0.015em; margin-bottom: 24px; text-wrap: pretty; }
.panel__title em { color: var(--sbf-cyan-deep); }
.panel__desc { font-size: 17px; line-height: 1.55; color: var(--ink-soft); max-width: 480px; margin-bottom: 28px; }

/* Reveal animation */
.reveal { opacity: 0; transform: translateY(28px); transition: opacity .9s cubic-bezier(.2,.7,.2,1), transform .9s cubic-bezier(.2,.7,.2,1); }
.reveal.in { opacity: 1; transform: none; }
.reveal[data-delay="1"] { transition-delay: .08s; }
.reveal[data-delay="2"] { transition-delay: .16s; }
.reveal[data-delay="3"] { transition-delay: .24s; }

/* ---------- Q1 viz ---------- */
.legend { list-style: none; display: flex; flex-direction: column; gap: 10px; font-size: 14px; color: var(--ink-soft); }
.legend .sw { display: inline-block; width: 14px; height: 14px; border-radius: 2px; margin-right: 10px; vertical-align: -2px; }
.seg { transition: width 1s cubic-bezier(.2,.7,.2,1); width: 0%; }
.seg--pos { background: var(--chart-pos); }
.seg--neu { background: var(--chart-neu); }
.seg--neg { background: var(--chart-neg); }

/* ---------- Q2 outlook viz ---------- */
.outlook__key { display: flex; flex-direction: column; gap: 10px; font-size: 14px; color: var(--ink-soft); }
.arrow { display: inline-block; width: 22px; font-family: var(--mono); font-weight: 600; }
.arrow--up { color: var(--chart-pos); }
.arrow--flat { color: var(--ink-mute); }
.arrow--down { color: var(--chart-neg); }
.panel__viz--outlook { background: transparent; border: none; border-radius: 0; padding: 0; }
.flowChart { width: 100%; height: auto; }
.flowChart .axisLbl { font: 600 11px var(--mono); fill: var(--ink); text-transform: uppercase; letter-spacing: 0.08em; }
/* The net row is secondary to the wave label it sits under. */
.flowChart .axisLbl--net { font-weight: 500; fill: var(--ink-mute); }
.flowChart .title { font: 600 13px var(--sans); fill: var(--ink); }
.flowChart .ribbon { transition: fill-opacity .18s ease, opacity .18s ease, stroke-width .18s ease; }
.flowChart .percLbl { font: 700 14px var(--mono); }
.flowChart .catLbl { font: 500 13px var(--sans); fill: var(--ink); }

.bsiCard__hint { color: var(--ink-mute); font-size: 11px; }

/* Dark panels and the BSI intro */
.panel--ink > * { max-width: 1600px; margin-left: auto; margin-right: auto; padding-left: 64px; padding-right: 64px; }

/* Black ground for sections 02 and 04. Everything below is a token override:
   the ink ladder is already `rgba(var(--ink-rgb), a)` at 29 sites, so flipping
   that one triplet to white re-points all of them at once — the boosted alphas
   land between 5.58:1 and 17.63:1 on black, so they need no retuning. */
.panel--ink {
  --ink-rgb: 255, 255, 255;
  --ink: #FFFFFF;                    /* 21:1 */
  --ink-soft: rgba(255,255,255,0.78);/* 12.41:1 */
  --ink-mute: rgba(255,255,255,0.60);/* 7.37:1 */
  --line: rgba(255,255,255,0.16);
  --line-strong: rgba(255,255,255,0.32);
  --bg: #000000;
  --spark-halo: #000000;
  /* The tone pair inverts: on white the deeper #0089A8 was needed, but on black
     plain cyan is 8.02:1 against its 5.14:1. Literals, not var(--sbf-*), because
     tweaks.js rewrites those inline on :root. */
  --tone-pos: #00AED5;               /* 8.02:1 */
  --tone-neg: #EF3340;               /* 5.22:1 */
  --tone-neu: #9AA3AD;               /* 8.22:1 */
  --sbf-red-deep: #FF8A7E;           /* the kicker number; #A50C20 is 2.67:1 here */
  background: #000000; color: #FFFFFF;
  max-width: none; padding: 140px 0;
}

.panel--bsiIntro {
  /* Explicit: `.panel--tint > *` used to supply the horizontal padding. */
  padding: 96px 64px 56px;
}
.panel--bsiIntro .bsi__header {
  position: relative;
  padding-bottom: 40px;
  border-bottom: 1px solid var(--line);
}
.panel--bsiIntro + .panel { padding-top: 64px; }
.bsi__darkGrid { display: grid; grid-template-columns: 1fr 1.1fr; gap: 48px; align-items: stretch; }
@media (max-width: 1100px) { .bsi__darkGrid { grid-template-columns: 1fr; } }

/* Comparison */
.cmp__head { max-width: 760px; margin-bottom: 36px; }
.cmp__controls { display: flex; align-items: end; gap: 16px; flex-wrap: wrap; margin-bottom: 32px; background: #F7FBFC; border: 1px solid var(--line); border-radius: 8px; padding: 20px; }
.cmp__ctrl { display: flex; flex-direction: column; gap: 6px; }
.cmp__cap { font: 500 10px var(--mono); text-transform: uppercase; letter-spacing: 0.14em; color: var(--ink-mute); }
.cmp__title { font-family: var(--serif); font-size: 28px; margin-bottom: 20px; color: var(--ink); }
.cmp__hint { color: var(--ink-mute); font-size: 16px; }
@media (max-width: 900px) { .cmp__panel { grid-template-columns: 1fr; } }
.cmp__side { background: #FFFFFF; border: 1px solid var(--line); border-radius: 8px; padding: 24px; }
.cmp__side--a { border-color: rgba(0,174,213,0.4); }
.cmp__side--b { border-color: rgba(239,51,64,0.4); }
.cmp__head2 { display: flex; align-items: center; gap: 10px; font-size: 14px; color: var(--ink); }
.cmp__head2 strong { font-size: 16px; }
.cmp__dot { width: 10px; height: 10px; border-radius: 50%; }
.cmp__dot--a { background: var(--tone-pos); }
.cmp__dot--b { background: var(--chart-neg); }
.cmp__dot--all { background: var(--sbf-navy); }
@media (max-width: 900px) { .cmp__desc { white-space: normal; } }

/* ---------- BSI ---------- */
.bsi__header { margin-bottom: 72px; }
.bsi__header .panel__title, .bsi__header .panel__desc { max-width: 760px; }
.bsi__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 12px; margin-bottom: 96px; }
@media (max-width: 1100px) { .bsi__grid { grid-template-columns: repeat(4, 1fr); } }
@media (max-width: 640px) { .bsi__grid { grid-template-columns: repeat(2, 1fr); } }

/* ---------- Notes ---------- */
.panel--notes { padding-bottom: 80px; }
.notes__grid { display: grid; grid-template-columns: repeat(3,1fr); gap: 48px; padding-top: 64px; border-top: 1px solid var(--line); }
@media (max-width: 820px) { .notes__grid { grid-template-columns: 1fr; } }
.notes__kicker { font-family: var(--mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.14em; color: var(--sbf-red-deep); margin-bottom: 14px; }
.notes__grid p { font-size: 15px; line-height: 1.55; color: var(--ink-soft); }

/* ---------- Footer ---------- */
/* SBF cyan footer, matching sbf.org.sg. White on #00AED5 is 2.62:1 —
   below the AA minimum, and a deliberate brand match. */
/* Bottom padding clears the fixed "Ask the data" button, which sits over this corner at the end of the page. */
.foot { background: var(--sbf-cyan); color: #FFFFFF; padding: 64px 64px 112px; }
.foot__row { display: flex; justify-content: flex-end; align-items: center; }
/* Logo and credit are one link, so the whole lockup is the click target. */
.foot__brand { display: inline-flex; flex-direction: column; align-items: flex-end; gap: 12px; color: #FFFFFF !important; text-decoration: none; }
.foot__logo { display: block; width: 56px; height: 56px; }
.foot__site { font-size: 13px; color: #FFFFFF; }
.foot__name { border-bottom: 1px solid rgba(255,255,255,0.55); padding-bottom: 2px; transition: border-color .2s; }
.foot__brand:hover .foot__name { border-color: #FFFFFF; }

/* ---------- Chat ---------- */
.chatFab {
  position: fixed; bottom: 28px; right: 28px; z-index: 100;
  display: flex; align-items: center; gap: 10px;
  background: var(--ink); color: var(--bg);
  border: none; padding: 14px 20px; border-radius: 999px;
  font: 600 14px var(--sans); cursor: pointer;
  box-shadow: 0 12px 30px rgba(0,0,0,0.18);
  transition: transform .22s, background .2s, opacity .35s ease;
  /* Hidden until the top banner materializes */
  opacity: 0;
  transform: translateY(8px) scale(0.92);
  pointer-events: none;
}
.chatFab--in {
  opacity: 1;
  transform: translateY(0) scale(1);
  pointer-events: auto;
  animation: chatFabPop .55s cubic-bezier(.2,.7,.2,1.4) both;
}
.chatFab svg { transition: transform .35s cubic-bezier(.2,.7,.2,1.4); }
.chatFab span {
  display: inline-block;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity .28s ease, transform .35s cubic-bezier(.2,.7,.2,1.4);
}
.chatFab--in span {
  opacity: 1;
  transform: translateY(0);
  /* Text "jumps out" after the logo settles */
  transition-delay: .28s;
}
@keyframes chatFabPop {
  0%   { transform: translateY(8px) scale(0.92); }
  60%  { transform: translateY(-2px) scale(1.06); }
  100% { transform: translateY(0) scale(1); }
}
.chatFab:hover { transform: translateY(-2px); background: var(--sbf-cyan-deep); }
.chat {
  position: fixed; bottom: 28px; right: 28px; z-index: 100;
  width: 400px; max-width: calc(100vw - 32px); height: 580px; max-height: calc(100vh - 60px);
  background: white; border-radius: 12px;
  box-shadow: 0 24px 60px rgba(0,0,0,0.24);
  display: flex; flex-direction: column;
  transform: translateY(20px) scale(.96); opacity: 0; pointer-events: none;
  transition: all .26s cubic-bezier(.2,.7,.2,1);
  overflow: hidden;
}
.chat.open { opacity: 1; transform: none; pointer-events: auto; }
.chat__head { display: flex; justify-content: space-between; align-items: center; padding: 18px 20px; border-bottom: 1px solid var(--line); }
.chat__title { display: flex; align-items: center; gap: 12px; }
.chat__dot { width: 10px; height: 10px; border-radius: 50%; background: var(--sbf-cyan); box-shadow: 0 0 0 4px rgba(0,174,213,.2); }
.chat__title strong { font-size: 15px; }
.chat__sub { font-size: 11px; color: var(--ink-mute); font-family: var(--mono); }
.chat__close { background: none; border: none; font-size: 26px; color: var(--ink-soft); cursor: pointer; line-height: 1; padding: 0 6px; }
.sugg { text-align: left; background: white; border: 1px solid var(--line); border-radius: 8px; padding: 8px 12px; font: 500 13px var(--sans); color: var(--ink); cursor: pointer; width: 100%; transition: all .18s; }
.sugg:hover { border-color: var(--sbf-cyan); color: var(--sbf-cyan-deep); }

/* Responsive */
@media (max-width: 720px) {
  .panel, .hero { padding-left: 24px; padding-right: 24px; }
  .nav { padding: 14px 20px; }
  .hero--video { padding-left: 0; padding-right: 0; }
  .hero--video .hero__inner { padding: 0 20px; }
  .hero__scroll { display: none; }
  .foot { padding: 40px 24px; }
}

/* ============================================================
   Wave trendlines, the overall-index tile, and the wave-flow
   outlook layout. Added with the Q1 2025 – Q2 2026 data swap.
   Colours come only from existing custom properties, so the
   Tweaks palette presets keep working.
   ============================================================ */

.spark { width: 100%; height: auto; display: block; color: var(--ink-mute); overflow: visible; }
.spark__tick { font: 500 9px var(--mono); fill: currentColor; letter-spacing: 0.06em; opacity: 0.75; }
.spark__end { font: 600 11px var(--mono); font-variant-numeric: tabular-nums; }
.spark__val {
  /* The per-wave average is the headline stat on the BSI cards and the index
     chart, so it is sized and weighted to be read first, and takes full
     contrast against the ground rather than the series tint. */
  font: 700 14px var(--mono); font-variant-numeric: tabular-nums;
  fill: var(--sbf-navy); letter-spacing: -0.01em;
  /* Knockout halo: the dip test keeps labels off the line at a local minimum,
     but a steep monotonic run can still put a label on the incoming segment. */
  paint-order: stroke; stroke: var(--spark-halo, transparent);
  stroke-width: 3; stroke-linejoin: round;
}
.panel:not(.panel--ink), .cmp__stage--light { --spark-halo: #FFFFFF; }
#bsiIndex .spark__val { fill: var(--sbf-navy); }
.panel--ink .spark__val { fill: #FFFFFF; }
.cmp__stage--light .spark__val { fill: var(--sbf-navy); }
#bsiIndexChart .spark__val { font-size: 22px; letter-spacing: -0.02em; stroke-width: 4; }
#bsiIndexChart .spark__tick { font-size: 11px; opacity: 1; }
#bsiIndexChart .spark { color: rgba(var(--ink-rgb),0.782); }

/* ---------- Wave focus ----------
   Hovering a wave on any chart focuses that wave on every chart. Author rules
   beat SVG presentation attributes, so the marks restyle without !important. */
.spark__hit { cursor: crosshair; }
.spark__guide { stroke: currentColor; stroke-width: 1; stroke-opacity: 0; stroke-dasharray: 2 3; }
.spark__guide.is-focus { stroke-opacity: 0.38; }
.spark__dot { transition: r .18s ease, fill-opacity .18s ease; }
.spark__val, .spark__line, .spark__area, .spark__tick, .spark__guide { transition: opacity .18s ease, stroke-opacity .18s ease; }

/* Everything that is not the focused wave recedes. */
.spark.is-focused .spark__dot { r: 1.8; fill-opacity: 0.35; }
.spark.is-focused .spark__val { opacity: 0.22; }
.spark.is-focused .spark__line { opacity: 0.45; }
.spark.is-focused .spark__area { opacity: 0.35; }
.spark.is-focused .spark__tick { opacity: 0.35; }
/* ...and the focused one comes forward. */
.spark.is-focused .spark__dot.is-focus {
  r: 6; fill-opacity: 1;
  stroke: var(--spark-halo, #fff); stroke-width: 2.5; paint-order: stroke;
}
.spark.is-focused .spark__val.is-focus { opacity: 1; }
.spark.is-focused .spark__tick.is-focus { opacity: 1; }

/* The focused wave's value stands in for the card's resting mean. */
.bsiCard .bsiCard__score.is-waveValue { color: var(--tone-pos); }
/* The delta badge is a fixed last-wave-vs-previous figure. Beside a score that
   has been swapped to another wave it would read as that wave's change, so it
   recedes while a wave is focused. */
.bsiCard__score.is-waveValue + .bsiCard__move { opacity: 0.25; }
/* K. the movement chips key off the same wave. */
[data-wavechip].is-focus { border-color: var(--tone-pos); background: rgba(0,174,213,0.10); }

/* Index readout */
.idxRead { margin-top: 22px; padding-top: 16px; min-height: 78px;
           border-top: 1px solid var(--line); }
.idxRead__hint { font: 500 10px var(--mono); text-transform: uppercase; letter-spacing: 0.14em;
                 color: rgba(var(--ink-rgb),0.516); }
.idxRead__cols { display: flex; flex-wrap: wrap; gap: 14px 40px; align-items: flex-start; }
.idxRead__col { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.idxRead__col b { font: 600 18px var(--mono); font-variant-numeric: tabular-nums; color: var(--sbf-navy); }
.idxRead__col:empty, .idxRead__col b:empty { display: none; }
.idxRead__cap { font: 500 9px var(--mono); text-transform: uppercase; letter-spacing: 0.14em;
                color: rgba(var(--ink-rgb),0.61); }
.idxRead__col--lead b.idxRead__big { font-size: 32px; font-weight: 700; letter-spacing: -0.02em;
                                     color: var(--tone-pos); }
.idxRead__delta { font: 600 11px var(--mono); letter-spacing: 0.04em; color: rgba(var(--ink-rgb),0.688); }
.idxRead__delta--pos { color: var(--tone-pos); }
.idxRead__delta--neg { color: var(--tone-neg); }
.idxRead__delta--neu { color: rgba(var(--ink-rgb),0.766); }

/* ---------- Flow chart focus ----------
   Two independent axes: a band (category) traced across every column, and a
   wave (column). Hovering a bar sets both; the legend sets the band alone. */
.flow__hit { cursor: crosshair; }
.flowChart .percLbl, .flowChart .axisLbl { transition: opacity .18s ease; }

/* Band trace — the reading a stacked chart normally hides. */
.flowChart.is-bandFocus .ribbon:not(.is-band),
.flowChart.is-bandFocus .percLbl:not(.is-band) { opacity: 0.15; }
.flowChart.is-bandFocus .ribbon--link.is-band { fill-opacity: 0.45; }

/* Wave focus — one column forward, the rest back. */
.flowChart.is-focused:not(.is-bandFocus) .ribbon--bar:not(.is-focus),
.flowChart.is-focused:not(.is-bandFocus) .percLbl:not(.is-focus) { opacity: 0.38; }
.flowChart.is-focused:not(.is-bandFocus) .ribbon--link { opacity: 0.35; }
.flowChart.is-focused .axisLbl:not(.is-focus) { opacity: 0.35; }
.flowChart.is-focused .axisLbl.is-focus { font-weight: 700; }
/* Both at once: outline the exact band under the pointer. */
.flowChart.is-bandFocus .ribbon--bar.is-band.is-focus {
  stroke: var(--spark-halo, #fff); stroke-width: 2.5;
}

/* 18% of a brand hue reads as a pale wash on white but is near-black on black. */
.panel--ink .flowChart .ribbon--link { fill-opacity: 0.30; }

/* Legend entries are controls now. */
.legend li[data-band-legend], .outlook__key div[data-band-legend] { cursor: crosshair; transition: opacity .18s ease; }

/* Flow readout */
.flowRead { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line); min-height: 46px; }
.flowRead__hint { font: 500 10px var(--mono); text-transform: uppercase; letter-spacing: 0.14em; color: var(--ink-mute); }
.flowRead__lead { display: block; font: 700 15px var(--mono); letter-spacing: 0.02em; color: var(--ink); }
.flowRead__detail { display: block; margin-top: 4px; font: 500 12px var(--mono); color: var(--ink-soft); font-variant-numeric: tabular-nums; }

@media (prefers-reduced-motion: reduce) {
  .spark__dot, .spark__val, .spark__line, .spark__area, .spark__tick, .spark__guide,
  .flowChart .ribbon, .flowChart .percLbl, .flowChart .axisLbl { transition: none; }
}

.sparkWrap { margin-top: 18px; }
.sparkWrap__cap { font: 500 9px var(--mono); text-transform: uppercase; letter-spacing: 0.14em;
                  color: var(--ink-mute); margin-bottom: 6px; }

/* Dark surfaces: the sparkline inherits `currentColor` for its rules and ticks */
#bsiIndex .spark,
.cmp__stage .spark { color: rgba(var(--ink-rgb),0.61); }
#bsiIndex .sparkWrap__cap, .cmp__stage .sparkWrap__cap { color: rgba(var(--ink-rgb),0.571); }
.cmp__stage--light .spark { color: var(--ink-mute); }
.cmp__stage--light .sparkWrap__cap { color: var(--ink-mute); }

/* Overall index tile */
/* Unboxed: section 04 is all cards, so the index band reads better as plain
   figures on the dark ground than as one more card. */
.idxTile { display: flex; flex-direction: column; justify-content: center; padding-right: 40px; }
.idxTile__cap { font: 500 11px var(--mono); text-transform: uppercase; letter-spacing: 0.14em;
                color: rgba(var(--ink-rgb),0.649); }
.idxTile__score--pos { color: var(--tone-pos); }
.idxTile__score--neg { color: var(--tone-neg); }
.idxTile__score--neu { color: var(--tone-neu); }
.idxTile__score { font-family: var(--serif); font-size: clamp(76px, 8.4vw, 124px); font-weight: 700;
                  line-height: 1; margin-top: 14px; font-variant-numeric: tabular-nums; letter-spacing: -0.04em; }
.idxTile__delta { font: 500 12px var(--mono); letter-spacing: 0.04em; margin-top: 10px;
                  color: rgba(var(--ink-rgb),0.688); font-variant-numeric: tabular-nums; }
.idxTile__meta { display: flex; flex-wrap: wrap; gap: 20px; margin-top: 18px; padding-top: 16px;
                 border-top: 1px solid var(--line);
                 font: 500 11px var(--mono); letter-spacing: 0.06em; color: rgba(var(--ink-rgb),0.61); }
.idxTile__meta b { color: var(--sbf-navy); font-variant-numeric: tabular-nums; }
.idxTile .spark { margin-top: 26px; }
.idxTile__note { font-size: 13px; line-height: 1.55; color: rgba(var(--ink-rgb),0.688); margin-top: 16px; }

/* ---------- Section 03, the marquee ---------- */
/* Two adjacent tinted blocks each carry 140px of vertical padding, so the
   index chart used to be followed by 280px of empty navy before section 04's
   kicker. They now meet on a rule instead. */
#bsiIndex { padding-bottom: 88px; }
#bsiDims { padding-top: 88px; border-top: 1px solid var(--line); }
.idxHead { max-width: 760px; margin-bottom: 44px; }

/* Wave-over-wave movement, filling the space under the chart. */
.idxMoves { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 22px; }
.idxMove {
  display: inline-flex; align-items: baseline; gap: 7px;
  padding: 7px 11px; border-radius: 999px;
  border: 1px solid var(--line); background: #FFFFFF;
  font: 500 10px var(--mono); letter-spacing: 0.08em; text-transform: uppercase;
  color: rgba(var(--ink-rgb),0.704);
}
.idxMove b { font-size: 13px; letter-spacing: 0; font-variant-numeric: tabular-nums; }
.idxMove--pos { border-color: rgba(0,174,213,0.42); }
.idxMove--pos b { color: var(--tone-pos); }
.idxMove--neg { border-color: rgba(239,51,64,0.38); }
.idxMove--neg b { color: var(--tone-neg); }
.idxMove--neu b { color: rgba(var(--ink-rgb),0.844); }
.spark__neutralLbl { font: 600 9px var(--mono); letter-spacing: 0.14em; fill: currentColor; opacity: 0.85; }


@media (max-width: 900px) {
  .idxTile { padding: 32px 24px; }
  .idxTile__meta { gap: 14px; }
}
.q1flow__title { font-family: var(--serif); font-size: 26px; margin-bottom: 8px; }

/* ---------- Section 01 — Singapore card, regional context below ---------- */
#climate > .panel__title, #regional > .panel__title, #outlook .panel__title, #bsiIndex > .panel__title, #bsiDims .panel__title { font-size: clamp(32px, 3.4vw, 52px); font-weight: 700; max-width: 1000px; margin-bottom: 16px; }
.hl--red { color: var(--sbf-red); }
.sg__desc { max-width: 760px; margin-bottom: 36px; }
.sg__desc:has(+ .sg__desc) { margin-bottom: 12px; }
.sgCard {
  display: grid; grid-template-columns: minmax(220px, 0.4fr) 1fr; gap: 48px; align-items: center;
}
.sgKpi__name { font-size: 20px; font-weight: 700; color: var(--ink); }
.sgKpi__num {
  font-size: clamp(64px, 7vw, 112px); font-weight: 800; line-height: 1; letter-spacing: -0.03em;
  color: var(--ink); font-variant-numeric: tabular-nums; margin: 6px 0 10px;
}
.sgKpi__cap { font-size: 14px; color: var(--ink-soft); }
.sgKpi__move {
  margin-top: 14px; font-size: 13px; color: var(--ink-soft);
}
.sgKpi__move[hidden] { display: none; }
.sgKpi__move b { font-weight: 700; margin-right: 4px; color: var(--ink); }
.sgKpi__move--pos b { color: var(--tone-pos); }
.sgKpi__move--neg b { color: var(--tone-neg); }
.legend--row { flex-direction: row; flex-wrap: wrap; justify-content: center; gap: 10px 24px; margin-top: 20px; }
@media (max-width: 860px) {
  .sgCard { grid-template-columns: 1fr; gap: 24px; }
}

/* ---------- Section 02 — ASEAN and global side by side ---------- */
#regional > .panel__title { margin-bottom: 48px; }
.geoPair { display: grid; grid-template-columns: 1fr 1fr; gap: 56px; }
.geoKpi { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; margin-bottom: 20px; }
.geoKpi__num { font-size: 40px; font-weight: 800; line-height: 1; letter-spacing: -0.02em; color: var(--ink); font-variant-numeric: tabular-nums; }
.geoKpi__cap { font-size: 14px; color: var(--ink-soft); }
.geoKpi .sgKpi__move { flex-basis: 100%; margin-top: 2px; }
@media (max-width: 980px) {
  .geoPair { grid-template-columns: 1fr; gap: 48px; }
}

/* ============================================================
   Section 04 — the seven dimensions as a dark card grid.
   ============================================================ */
/* .panel--ink > * gets auto side margins, which would centre a narrow header;
   keep the block full-width and cap the text inside it instead. */
.dims__head { margin-bottom: 44px; }
.dims__head .panel__title, .dims__head .panel__desc, .dims__head .legend { max-width: 860px; }
.bsi__grid--4 { grid-template-columns: repeat(4, 1fr); gap: 20px; margin-bottom: 0; }
@media (max-width: 1200px) { .bsi__grid--4 { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 900px)  { .bsi__grid--4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 620px)  { .bsi__grid--4 { grid-template-columns: 1fr; } }

.bsiCard {
  /* Fixed row track so the score and sparkline line up across every card
     regardless of how the name/hint wrap. The trailing 1fr absorbs the slack
     so all eight tiles stay the same height. */
  display: grid;
  grid-template-rows: auto auto auto 1fr;
  background: #FFFFFF;
  border: 1px solid var(--line);
  border-radius: 10px; padding: 22px 20px 18px;
  transition: border-color .25s, transform .25s, box-shadow .25s;
}
.bsiCard:hover { border-color: rgba(14,33,71,0.28); transform: translateY(-2px); box-shadow: 0 10px 26px rgba(14,33,71,0.10); }

.bsiCard__hd { display: flex; gap: 11px; align-items: flex-start; min-height: 76px; }
.bsiCard__idx {
  flex: 0 0 22px; height: 22px; border-radius: 6px; margin-top: 1px;
  display: grid; place-items: center;
  background: rgba(14,33,71,0.07); color: rgba(var(--ink-rgb),0.844);
  font: 600 11px var(--mono); font-variant-numeric: tabular-nums;
}
.bsiCard--pos .bsiCard__idx { background: rgba(0,174,213,0.14); color: var(--tone-pos); }
.bsiCard--neg .bsiCard__idx { background: rgba(239,51,64,0.10); color: var(--tone-neg); }
.bsiCard__names { min-width: 0; }
.bsiCard__name {
  font: 600 12px var(--sans); text-transform: uppercase; letter-spacing: 0.09em;
  color: var(--sbf-navy); line-height: 1.3;
}
.bsiCard__hint {
  font-size: 11.5px; line-height: 1.42; color: rgba(var(--ink-rgb),0.61); margin-top: 5px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

.bsiCard__figure { display: flex; align-items: baseline; gap: 10px; margin-top: 14px; }
.bsiCard__score {
  font-family: var(--serif); font-size: 44px; font-weight: 300; line-height: 1;
  letter-spacing: -0.03em; font-variant-numeric: tabular-nums; color: var(--sbf-navy);
}
.bsiCard--pos .bsiCard__score { color: var(--tone-pos); }
.bsiCard--neg .bsiCard__score { color: var(--tone-neg); }
.bsiCard__move {
  font: 600 11px var(--mono); font-variant-numeric: tabular-nums;
  padding: 3px 8px; border-radius: 999px; background: rgba(14,33,71,0.06);
  color: rgba(var(--ink-rgb),0.688); white-space: nowrap;
}
.bsiCard__move--pos { background: rgba(0,174,213,0.12); color: var(--tone-pos); }
.bsiCard__move--neg { background: rgba(239,51,64,0.09); color: var(--tone-neg); }

.bsiCard__cap {
  font: 500 9px var(--mono); text-transform: uppercase; letter-spacing: 0.12em;
  color: rgba(var(--ink-rgb),0.548); margin-top: 8px;
}

.bsiCard__spark { margin-top: 16px; }
.bsiCard__spark .spark { color: rgba(var(--ink-rgb),0.7); }
.bsiCard__sparkFoot {
  display: flex; justify-content: space-between; margin-top: 2px;
  font: 500 9px var(--mono); text-transform: uppercase; letter-spacing: 0.1em;
  color: rgba(var(--ink-rgb),0.516);
}

/* Eighth tile — the reading guide, filling the 4x2 grid */
.bsiCard--guide { background: transparent; border-style: dashed; grid-template-rows: auto auto 1fr; }
.bsiCard--guide:hover { transform: none; box-shadow: none; }
.bsiCard__idx--guide { background: rgba(14,33,71,0.07); color: rgba(var(--ink-rgb),0.649); }

/* ---------- Card surfaces on the black ground ----------
   The navy-alpha fills above are dark-on-dark here, and a white card against
   #000 is far too stark, so the whole surface layer is restated in white alpha. */
.panel--ink .bsiCard { background: rgba(255,255,255,0.045); border-color: rgba(255,255,255,0.14); }
.panel--ink .bsiCard:hover { border-color: rgba(255,255,255,0.30); box-shadow: 0 10px 30px rgba(0,0,0,0.5); }
.panel--ink .bsiCard--guide { background: transparent; border-color: rgba(255,255,255,0.18); }
.panel--ink .bsiCard__idx { background: rgba(255,255,255,0.10); }
.panel--ink .bsiCard__idx--guide { background: rgba(255,255,255,0.10); }
.panel--ink .bsiCard__move { background: rgba(255,255,255,0.09); }
.panel--ink .bsiCard--pos .bsiCard__idx { background: rgba(0,174,213,0.22); }
.panel--ink .bsiCard--neg .bsiCard__idx { background: rgba(239,51,64,0.22); }
.panel--ink .bsiCard__move--pos { background: rgba(0,174,213,0.20); }
.panel--ink .bsiCard__move--neg { background: rgba(239,51,64,0.20); }
.guide { display: grid; grid-template-columns: 34px 1fr; gap: 12px 10px; margin-top: 16px; align-items: start; }
.guide dt { display: flex; justify-content: center; padding-top: 1px; }
.guide dd { font-size: 11.5px; line-height: 1.45; color: rgba(var(--ink-rgb),0.688); }
.guide__num { font: 600 12px var(--mono); color: rgba(var(--ink-rgb),0.883); font-variant-numeric: tabular-nums; }
.guide__arrow { font-size: 10px; letter-spacing: 1px; color: rgba(var(--ink-rgb),0.766); }
.guide__note { align-self: end; margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--line); font-size: 10.5px; line-height: 1.45; color: rgba(var(--ink-rgb),0.548); }

/* Section 05 — build your own view */
.bld__note { font: 500 11px var(--mono); letter-spacing: 0.04em; color: var(--ink-mute); margin: -12px 0 20px; min-height: 14px; }
.bld__panel { display: grid; grid-template-columns: 1fr; gap: 24px; }
.bld__panel--two { grid-template-columns: 1fr 1fr; }
.bld__panel--three { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 1000px) { .bld__panel--two, .bld__panel--three { grid-template-columns: 1fr; } }
.cmp__side--solo { border-color: var(--line); }
#builder .flowChart { margin-top: 8px; }
.ans__scope { font: 500 9px var(--mono); text-transform: uppercase; letter-spacing: 0.12em; color: var(--ink-mute); margin-bottom: 10px; }
.ans__head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }
.ans__big { font-family: var(--serif); font-size: 38px; line-height: 1; font-variant-numeric: tabular-nums; color: var(--ink); }
.ans__sub { font: 500 10px var(--mono); text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-mute); }
.ans__rows { list-style: none; margin: 10px 0 0; display: flex; flex-direction: column; gap: 6px; }
.ans__rows li { display: flex; justify-content: space-between; gap: 14px; font-size: 12px; color: var(--ink-soft); border-bottom: 1px solid var(--line); padding-bottom: 5px; }
.ans__rows li b { color: var(--ink); font-variant-numeric: tabular-nums; text-align: right; flex: 0 0 auto; }
.ans__note { font-size: 12px; line-height: 1.5; color: var(--ink-soft); margin-top: 12px; }
.ansCard__body .spark { margin: 4px 0 6px; color: var(--ink-mute); }
.bld__desc { max-width: 780px; }
/* The question list — needs its own list reset now that it isn't inside a bubble. */
.msg__chips { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }

/* Section 03 — index band: figures left, wave chart right */
.bsi__darkGrid { grid-template-columns: 1fr 1.5fr; align-items: center; }
.idxChart { min-width: 0; }
.idxChart__cap { font: 500 9px var(--mono); text-transform: uppercase; letter-spacing: 0.14em; color: rgba(var(--ink-rgb),0.571); margin-bottom: 6px; }
.idxChart .spark { color: rgba(var(--ink-rgb),0.61); }
@media (max-width: 1100px) { .bsi__darkGrid { grid-template-columns: 1fr; } }

/* Sections 01 / 02 — copy column beside the charts */
.panel__copy { max-width: 520px; }
/* .panel__title is clamped against the VIEWPORT (4.4vw), which overflows a 1fr
   column. Scope it down inside the two-column grid. */
.panel__grid .panel__title { font-size: clamp(32px, 3.4vw, 52px); }
.panel__grid .panel__desc { max-width: none; }
.panel__grid .legend { margin-bottom: 4px; }

.summary { margin-top: 34px; padding-top: 24px; border-top: 1px solid var(--line); }
.summary__cap {
  font: 500 10px var(--mono); text-transform: uppercase; letter-spacing: 0.16em;
  color: var(--sbf-red-deep); margin-bottom: 14px;
}
.summary__p { font-size: 14.5px; line-height: 1.6; color: var(--ink-soft); margin-bottom: 12px; }
.summary__p:last-child { margin-bottom: 0; }
@media (max-width: 980px) { .panel__copy { max-width: none; } .summary { margin-top: 28px; } }

/* Region-by-region breakdown — section 01 copy column only (renderClimateSummary
   is the sole emitter, so section 02's .summary is untouched). */
.regions { margin-top: 30px; padding-top: 24px; border-top: 1px solid var(--line); }
.region + .region { margin-top: 22px; padding-top: 22px; border-top: 1px solid var(--line); }
.region__head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.region__name { font-family: var(--serif); font-size: 19px; color: var(--ink); }
.region__figure {
  font: 600 20px var(--mono); font-variant-numeric: tabular-nums;
  color: var(--chart-pos); letter-spacing: -0.01em;
}
.region__stats { display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 8px; }
.region__stat {
  font: 500 11px var(--mono); letter-spacing: 0.03em; color: var(--ink-mute);
  display: inline-flex; align-items: center; gap: 6px;
}
/* The swatch must match the chart band it refers to; the label colour is chosen
   for legibility, so the two are set separately. */
.region__stat::before { content: ''; width: 8px; height: 8px; border-radius: 2px; background: var(--sw); }
.region__stat--pos { color: var(--chart-pos); --sw: var(--chart-pos); }
.region__stat--neu { color: var(--ink-mute); --sw: var(--chart-neu); }
.region__stat--neg { color: var(--chart-neg); --sw: var(--chart-neg); }
.region__note { font-size: 13.5px; line-height: 1.55; color: var(--ink-soft); margin-top: 10px; }

/* ============================================================
   Custom dropdown. A native <select> hands its open list to the
   OS, so it can't be styled; this one we own end to end.
   ============================================================ */
.dd { position: relative; }
.dd__btn {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; min-width: 220px;
  border: 1px solid var(--line-strong); background: white; color: var(--ink);
  font: 500 13px var(--sans); text-align: left;
  padding: 8px 14px; border-radius: 999px; cursor: pointer;
  transition: border-color .18s, box-shadow .18s;
}
.dd__btn:hover { border-color: var(--ink); }
.dd__btn:focus-visible { outline: none; border-color: var(--sbf-cyan); box-shadow: 0 0 0 3px rgba(0,174,213,0.18); }
.dd__btn svg { width: 10px; height: 6px; color: var(--ink-soft); flex: 0 0 auto; transition: transform .2s; }
.dd--open .dd__btn { border-color: var(--ink); }
.dd--open .dd__btn svg { transform: rotate(180deg); }
.dd__value { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.dd__panel {
  position: absolute; z-index: 60; top: calc(100% + 6px); left: 0;
  min-width: 100%; width: max-content; max-width: 320px;
  max-height: 340px; overflow-y: auto;
  background: white; border: 1px solid var(--line-strong); border-radius: 10px;
  box-shadow: 0 16px 40px rgba(31,31,29,0.16); padding: 6px;
  opacity: 0; transform: translateY(-6px); pointer-events: none;
  transition: opacity .16s ease, transform .16s cubic-bezier(.2,.7,.2,1);
}
.dd--open .dd__panel { opacity: 1; transform: none; pointer-events: auto; }

.dd__group {
  font: 500 9px var(--mono); text-transform: uppercase; letter-spacing: 0.14em;
  color: var(--ink-mute); padding: 10px 10px 6px;
}
.dd__group:first-child { padding-top: 4px; }
.dd__opt {
  display: block; width: 100%; text-align: left;
  border: 0; background: none; cursor: pointer;
  font: 500 13px var(--sans); color: var(--ink);
  padding: 7px 10px 7px 26px; border-radius: 6px; position: relative;
}
.dd__opt:hover { background: var(--bg-warm); }
.dd__opt:focus-visible { outline: none; background: var(--bg-warm); box-shadow: inset 0 0 0 1px var(--sbf-cyan); }
.dd__opt--sel { color: var(--sbf-cyan-deep); }
.dd__opt--sel::before {
  content: '✓'; position: absolute; left: 9px; top: 50%; transform: translateY(-50%);
  font-size: 11px; color: var(--sbf-cyan-deep);
}
.dd__opt--disabled { color: var(--ink-mute); opacity: 0.55; cursor: not-allowed; }
.dd__opt--disabled:hover { background: none; }

/* Ask the data — two views: question list and answer thread. Both stay mounted
   and crossfade, following the #ffilter pattern. */
.chat__views { position: relative; flex: 1; min-height: 0; }
/* A descendant's `pointer-events: auto` re-enables hit-testing even under an
   ancestor set to `none`, so while the panel is closed its views would still
   swallow clicks — right on top of the FAB. Gate them on .open. */
.chat:not(.open) .chat__view { pointer-events: none; }
.chat__view {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  opacity: 0; pointer-events: none; transform: translateX(-8px);
  transition: opacity .22s ease, transform .22s cubic-bezier(.2,.7,.2,1);
}
.chat__view--list { opacity: 1; pointer-events: auto; transform: none; }
.chat--answer .chat__view--list { opacity: 0; pointer-events: none; transform: translateX(-8px); }
.chat--answer .chat__view--answer { opacity: 1; pointer-events: auto; transform: none; }
.chat__view--answer { transform: translateX(8px); }

.chat__scroll { flex: 1; min-height: 0; overflow-y: auto; padding: 16px 16px 8px; }
.chat__menuCap { font: 500 9px var(--mono); text-transform: uppercase; letter-spacing: 0.14em; color: var(--ink-mute); margin-bottom: 10px; }
.chat__resume {
  flex: 0 0 auto; margin: 0 16px 16px; padding: 10px 14px;
  border: 1px solid var(--line); border-radius: 8px; background: #FAFAF8; cursor: pointer;
  font: 500 12px var(--sans); color: var(--sbf-cyan-deep); text-align: left;
  transition: border-color .18s, background .18s;
}
.chat__resume:hover { border-color: var(--sbf-cyan); background: white; }

.chat__bar {
  flex: 0 0 auto; display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 12px 16px; border-bottom: 1px solid var(--line);
}
.chat__back, .chat__reset {
  border: 1px solid var(--line); background: white; border-radius: 999px; cursor: pointer;
  font: 500 11.5px var(--sans); padding: 6px 12px; color: var(--ink);
  transition: border-color .18s, color .18s;
}
.chat__back:hover { border-color: var(--sbf-cyan); color: var(--sbf-cyan-deep); }
.chat__reset { color: var(--ink-mute); }
.chat__reset:hover { border-color: var(--sbf-red-deep); color: var(--sbf-red-deep); }

.chat__thread { flex: 1; min-height: 0; overflow-y: auto; padding: 16px; display: flex; flex-direction: column; gap: 18px; }
.ansCard { display: flex; flex-direction: column; gap: 8px; }
.ansCard + .ansCard { padding-top: 18px; border-top: 1px solid var(--line); }
.ansCard__q { font: 600 13px var(--sans); color: var(--ink); line-height: 1.35; }
.ansCard__body { font-size: 13.5px; line-height: 1.5; color: var(--ink); }

/* ============================================================
   Section 04 — Business Sentiment Index: figure and commentary
   left, index by wave right, hover card on the points.
   ============================================================ */
.idx__desc { max-width: 960px; margin-bottom: 56px; }
.idxGrid { display: grid; grid-template-columns: minmax(280px, 0.8fr) 1.5fr; gap: 56px; align-items: center; }
@media (max-width: 980px) { .idxGrid { grid-template-columns: 1fr; gap: 40px; } }
#bsiIndex .idxTile { padding: 0; }
.idxTile__fig { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 16px; margin-top: 10px; }
#bsiIndex .idxTile__score {
  color: var(--ink); font-size: clamp(64px, 7vw, 104px); font-weight: 800; line-height: 1; letter-spacing: -0.03em;
}
#bsiIndex .idxTile__delta { margin: 0; font: 600 14px var(--sans); letter-spacing: 0; color: var(--ink-mute); }
#bsiIndex .idxTile__delta--pos { color: var(--tone-pos); }
#bsiIndex .idxTile__delta--neg { color: var(--tone-neg); }
.idxNote { margin-top: 28px; padding-top: 24px; border-top: 1px solid var(--line); }
.idxNote p { font-size: 15px; line-height: 1.6; color: var(--ink-soft); }
.idxNote p + p { margin-top: 12px; }

#bsiIndex .idxChart { position: relative; }
.spark--index .spark__dot { r: 4; }
.spark--index .spark__val { fill: var(--ink); }
/* The focused point becomes a ring, as in the reference, with the dashed guide under it. */
.spark--index.is-focused .spark__dot.is-focus {
  r: 7; fill: #FFFFFF; fill-opacity: 1; stroke: var(--tone-pos); stroke-width: 2.5;
}

.idxTip {
  position: absolute; z-index: 5; pointer-events: none; min-width: 190px;
  padding: 12px 14px; background: #FFFFFF; border: 1px solid var(--line-strong); border-radius: 10px;
  box-shadow: 0 8px 24px rgba(14,33,71,0.14);
}
.idxTip[hidden] { display: none; }
.idxTip__wave { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.12em; color: var(--ink-mute); }
.idxTip__score { margin-top: 4px; font-size: 28px; font-weight: 800; line-height: 1.1; color: var(--ink); font-variant-numeric: tabular-nums; }
.idxTip__delta { display: block; margin-top: 2px; font-size: 12px; font-weight: 600; color: var(--ink-mute); }
.idxTip__delta--pos { color: var(--tone-pos); }
.idxTip__delta--neg { color: var(--tone-neg); }
.idxTip__split {
  display: grid; grid-template-columns: auto auto; gap: 4px 16px; margin-top: 10px; padding-top: 10px;
  border-top: 1px solid var(--line); font-size: 12px;
}
.idxTip__split dt { color: var(--ink-soft); }
.idxTip__split dd { text-align: right; font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }
.spark--index .spark__tick { font-size: 13px; font-weight: 600; fill: var(--ink-soft); }

/* ---------- Section 05 — component cards, one shared colour ---------- */
#bsiDims .bsiCard__hd { min-height: 36px; }
#bsiDims .bsiCard:hover { position: relative; z-index: 2; border-color: var(--sbf-cyan); }
.bsiCard__spark { position: relative; }
.idxTip--sm { min-width: 160px; padding: 10px 12px; }
.idxTip--sm .idxTip__score { font-size: 22px; }
#bsiDims .bsiCard__name { font-size: 15px; font-weight: 700; text-transform: none; letter-spacing: 0; }
#bsiDims .spark__tick { font-size: 10px; font-weight: 600; }

/* ---------- Section 06 — explore the findings ---------- */
#builder .panel__title { font-size: clamp(32px, 3.4vw, 52px); font-weight: 700; }
.bld__key { margin-top: 12px; }
#builder .spark__tick { font-size: 12px; font-weight: 600; }
/* Multi-select dropdown: a checkbox per option instead of the single-pick tick. */
.dd--multi .dd__opt { padding-left: 30px; }
.dd--multi .dd__opt::before {
  content: ''; position: absolute; left: 9px; top: 50%; transform: translateY(-50%);
  width: 13px; height: 13px; box-sizing: border-box; border: 1.5px solid var(--line-strong); border-radius: 3px; background: #FFFFFF;
}
.dd--multi .dd__opt--sel { color: var(--ink); }
.dd--multi .dd__opt--sel::before {
  content: '✓'; display: grid; place-items: center; font-size: 9px; line-height: 1; font-weight: 700;
  background: var(--sbf-navy); border-color: var(--sbf-navy); color: #FFFFFF;
}
