/* =========================================================================
   Market Watch — stylesheet
   =========================================================================

   POINT OF VIEW
   The morning front page of an Indian financial daily, set by someone who
   respects your time. Ink on warm paper, one ruled column of headlines,
   tabular figures, and an ink-blue rail marking what came from the regulator
   itself rather than from someone reporting on the regulator.

   There are no prices, no charts and no tickers here, and that is the point:
   this is the market app that is not trying to make you trade. So it reads as
   calm, primary-source and slightly institutional — closer to a well-set
   newspaper than to a broker dashboard.

   SYSTEM
   7 type sizes. A 4px spacing grid in px, so the text-size slider stays a
   *text* control and does not inflate layout. One structural accent
   (ink-blue) and one hot accent reserved strictly for recency. Green and red
   are reserved for price direction and used nowhere else.
   ========================================================================= */

/* ---------------------------------------------------------------- */
/* Tokens                                                            */
/* ---------------------------------------------------------------- */

:root {
  --ts: 100%;

  /* Type — 7 sizes, ~1.18 ratio, one deliberate jump at the headline. */
  --t-micro:   0.6875rem;   /* 11px — uppercase labels only */
  --t-meta:    0.8125rem;   /* 13px — all metadata */
  --t-body:    0.9375rem;   /* 15px — excerpts */
  --t-base:    1rem;        /* 16px — UI default */
  --t-head:    1.1875rem;   /* 19px — feed headline */
  --t-head-lg: 1.375rem;    /* 22px — panel titles */
  --t-display: 1.75rem;     /* 28px — onboarding hero */

  --lh-flat:  1.2;
  --lh-tight: 1.26;
  --lh-snug:  1.4;
  --lh-body:  1.55;

  --tr-tight: -0.011em;     /* 22px and above only */
  --tr-none:  0;
  --tr-label: 0.07em;       /* uppercase --t-micro only */

  /* Space — 4px grid, in px on purpose (see SYSTEM above). */
  --s-1: 4px;   --s-2: 8px;   --s-3: 12px;  --s-4: 16px;
  --s-5: 20px;  --s-6: 24px;  --s-8: 32px;  --s-10: 40px;
  --s-12: 48px; --s-16: 64px;

  --r-sm: 6px; --r-md: 10px; --r-lg: 12px; --r-pill: 999px;

  /* Light — warm paper, not blue-grey. */
  --paper:        #fbfaf7;
  --surface:      #ffffff;
  --surface-sunk: #f2f0ea;
  --rule:         #dcd7cc;   /* decorative hairlines */
  --rule-strong:  #98917f;   /* control boundaries, clears 3:1 */

  --text:   #15181c;         /* 15.9:1 on paper */
  --text-2: #4e545c;         /*  7.9:1 */
  /* 5.31:1 on paper and 4.86:1 on the sunk surface used by :hover, so card
     metadata keeps passing AA when a card is hovered or selected. */
  --text-3: #64696f;

  --brand:      #1b3a6b;     /* ink-blue: institutional, 9.8:1 */
  --brand-ink:  #ffffff;
  --brand-soft: #e9eef7;
  --brand-line: #a9bcdb;

  --hot:      #b3310f;       /* vermilion: NEW and LIVE only */
  --hot-ink:  #ffffff;
  --hot-soft: #fceee8;
  --hot-line: #e8b8a4;

  /* Reserved for price direction. There are no prices in this app, so these
     are intentionally unused; --ok below is the semantic "working" green. */
  --up:   #0b7a4b;
  --down: #c0281a;
  --warn: #8a5a00;
  --bad:  #a3281f;
  --ok:   #0b7a4b;

  --sh-1: 0 1px 1px rgba(14,17,22,.04), 0 1px 3px rgba(14,17,22,.07);
  --sh-2: 0 2px 4px rgba(14,17,22,.05), 0 14px 32px -16px rgba(14,17,22,.24);

  --sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, "Cascadia Mono", "SF Mono", Menlo, Consolas, monospace;

  --maxw: 1360px;
  --feed-max: 44rem;
  --rail-w: 232px;
  --side-w: 300px;
  /* Real fallback; JS overwrites it from the measured topbar height. The
     previous value was smaller than the actual header, which left the sticky
     columns clipped behind it. */
  --topbar-h: 104px;
}

/*
 * Dark is defined ONCE, keyed off a class that render() sets from the
 * resolved theme. Two parallel selector blocks had already drifted apart, so
 * people on "Auto" were getting different, older values from people who had
 * explicitly chosen Dark.
 */
:root { color-scheme: light; }
:root.is-dark { color-scheme: dark; }

.is-dark {
  --paper:        #0d1014;
  --surface:      #15191f;
  --surface-sunk: #0a0d10;
  --rule:         #262c34;
  /* Was #4a535d: 2.26:1 on --surface, failing 1.4.11 for every button,
     input and chip border in dark mode. */
  --rule-strong:  #656e78;

  --text:   #edeae4;         /* warm off-white: reads as paper, not an LCD */
  --text-2: #a9afb8;
  --text-3: #8a9199;

  --brand:      #8fb4f0;
  --brand-ink:  #0a1626;
  --brand-soft: #16233a;
  --brand-line: #31486e;

  --hot:      #ff8a5b;
  --hot-ink:  #2a0f06;
  --hot-soft: #2a1711;
  --hot-line: #5c3020;

  --up:   #4bc98a;
  --down: #ff7a68;
  --warn: #e9b765;
  --bad:  #ff8a7a;
  --ok:   #4bc98a;

  --sh-1: none;
  --sh-2: 0 16px 40px -20px rgba(0,0,0,.8);
}

/* ---------------------------------------------------------------- */
/* Base                                                              */
/* ---------------------------------------------------------------- */

* { box-sizing: border-box; }

/* `hidden` is only a UA-stylesheet rule, so any author rule that sets
   `display` silently defeats it. Keep it authoritative. */
[hidden] { display: none !important; }

/* No -webkit-text-size-adjust: that would disable Chrome on Android's text
   autosizer, which is how many people apply their system font size. */
html { font-size: var(--ts); }

body {
  margin: 0;
  background: var(--paper);
  color: var(--text);
  font-family: var(--sans);
  font-size: var(--t-base);
  line-height: var(--lh-snug);
  -webkit-font-smoothing: antialiased;
  overflow-wrap: break-word;
}

h1, h2, h3 { margin: 0; line-height: var(--lh-tight); letter-spacing: var(--tr-none); }
button, input, select { font: inherit; color: inherit; }
a { color: var(--brand); text-underline-offset: 2px; }

:where(a, button, input, select, [tabindex]):focus-visible {
  outline: 2.5px solid var(--brand);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--brand); color: var(--brand-ink);
  padding: var(--s-2) var(--s-4); border-radius: 0 0 var(--r-md) 0;
}
.skip:focus { left: 0; }

.hint { color: var(--text-3); font-size: var(--t-meta); margin: var(--s-2) 0 0; }
.opt  { color: var(--text-3); font-weight: 400; font-size: .8em; }

.noscript {
  max-width: 34rem; margin: var(--s-12) auto; padding: var(--s-6);
  border: 1px solid var(--rule); border-radius: var(--r-lg); background: var(--surface);
}
.noscript h1 { font-size: var(--t-head-lg); margin-bottom: var(--s-2); }

/* ---------------------------------------------------------------- */
/* Controls                                                          */
/* ---------------------------------------------------------------- */

.btn {
  background: var(--surface); color: var(--text);
  border: 1px solid var(--rule-strong); border-radius: var(--r-md);
  padding: var(--s-3) var(--s-4); font-weight: 600; cursor: pointer;
  min-height: 44px; transition: background .14s, border-color .14s;
}
.btn:hover { background: var(--surface-sunk); }
.btn-sm { padding: var(--s-2) var(--s-3); font-size: var(--t-meta); min-height: 40px; }
.btn-block { display: block; width: 100%; }
.btn-primary {
  background: var(--brand); color: var(--brand-ink); border-color: transparent;
  padding: var(--s-4); font-size: var(--t-base); min-height: 52px;
}
.btn-primary:hover { background: var(--brand); filter: brightness(1.12); }
.btn-danger { color: var(--bad); border-color: var(--bad); background: transparent; }

.textbtn {
  background: none; border: 0; cursor: pointer;
  color: var(--brand); font-weight: 600; font-size: var(--t-meta);
  min-height: 44px; padding: var(--s-2) var(--s-3);
  display: inline-flex; align-items: center; border-radius: var(--r-sm);
}
.textbtn:hover { background: var(--surface-sunk); }

.iconbtn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  background: var(--surface); border: 1px solid var(--rule-strong);
  border-radius: var(--r-md); padding: var(--s-2) var(--s-3); cursor: pointer;
  font-size: var(--t-meta); font-weight: 600;
  min-height: 40px; min-width: 40px;
}
.iconbtn:hover { background: var(--surface-sunk); }
.iconbtn-label { display: none; }
@media (min-width: 820px) { .iconbtn-label { display: inline; } }
.iconbtn-cta { background: var(--brand); color: var(--brand-ink); border-color: transparent; }
.iconbtn-cta:hover { background: var(--brand); filter: brightness(1.12); }
.iconbtn-cta span:not([class^="i-"]) { display: inline; }

/* Icons are CSS masks: no icon font, no network request, CSP-clean. */
[class^="i-"] {
  width: 1.05em; height: 1.05em; display: inline-block; flex: 0 0 auto;
  background: currentColor;
  -webkit-mask: var(--svg) center / contain no-repeat;
          mask: var(--svg) center / contain no-repeat;
}
.i-refresh { --svg: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2.2" stroke-linecap="round"><path d="M21 12a9 9 0 1 1-3.2-6.9"/><path d="M21 3v6h-6"/></svg>'); }
.i-gear    { --svg: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2.2" stroke-linecap="round"><circle cx="12" cy="12" r="3.2"/><path d="M12 2v3M12 19v3M4.2 4.2l2.1 2.1M17.7 17.7l2.1 2.1M2 12h3M19 12h3M4.2 19.8l2.1-2.1M17.7 6.3l2.1-2.1"/></svg>'); }
.i-x       { --svg: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2.4" stroke-linecap="round"><path d="M5 5l14 14M19 5L5 19"/></svg>'); }
.i-tag     { --svg: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2.2" stroke-linecap="round"><path d="M20.6 13.4 12 22l-9-9 8.6-8.6L21 4z"/><circle cx="16" cy="8" r="1.4" fill="black"/></svg>'); }
.i-new     { --svg: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3l2.4 5.2 5.6.7-4.1 3.9 1.1 5.6L12 15.8 6.9 18.4 8 12.8 4 8.9l5.6-.7z"/></svg>'); }
.i-feed    { --svg: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2.2" stroke-linecap="round"><path d="M4 6h16M4 12h16M4 18h10"/></svg>'); }
.i-save    { --svg: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 3h12v18l-6-4.5L6 21z"/></svg>'); }
.i-more    { --svg: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="black"><circle cx="5" cy="12" r="1.8"/><circle cx="12" cy="12" r="1.8"/><circle cx="19" cy="12" r="1.8"/></svg>'); }
.i-up      { --svg: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2.2" stroke-linecap="round"><path d="M12 20V5"/><path d="M5 12l7-7 7 7"/></svg>'); }
.i-install { --svg: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3v12"/><path d="M7 10l5 5 5-5"/><path d="M4 20h16"/></svg>'); }

input[type="text"], input[type="search"], select {
  background: var(--surface); border: 1px solid var(--rule-strong);
  border-radius: var(--r-md); padding: var(--s-3); width: 100%; min-height: 44px;
}
input::placeholder { color: var(--text-3); }

.row { display: flex; gap: var(--s-2); align-items: center; }
.row input[type="text"], .row input[type="search"] { flex: 1 1 auto; min-width: 0; }

.chipwrap { display: flex; flex-wrap: wrap; gap: var(--s-2); }

.chip {
  display: inline-flex; align-items: center; gap: var(--s-1);
  background: var(--surface); border: 1px solid var(--rule-strong);
  border-radius: var(--r-pill); padding: var(--s-2) var(--s-4);
  min-height: 40px; cursor: pointer;
  font-size: var(--t-meta); font-weight: 500; color: var(--text-2);
  transition: background .13s, color .13s, border-color .13s;
}
.chip:hover { background: var(--surface-sunk); }
.chip[aria-pressed="true"] {
  background: var(--brand); border-color: var(--brand);
  color: var(--brand-ink); font-weight: 600;
}
.chip-x {
  border: 0; background: none; cursor: pointer; color: inherit;
  min-width: 40px; min-height: 40px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 1.05em; line-height: 1; opacity: .8;
}
.chip-x:hover { opacity: 1; background: var(--surface-sunk); }

/* ---------------------------------------------------------------- */
/* Onboarding                                                        */
/* ---------------------------------------------------------------- */

.onboarding {
  min-height: 100dvh; display: grid; place-items: start center;
  padding: clamp(16px, 4vw, 48px) var(--s-4) var(--s-12);
  background: var(--paper);
}
.ob-card {
  width: 100%; max-width: 40rem; background: var(--surface);
  border: 1px solid var(--rule); border-radius: var(--r-lg);
  padding: clamp(20px, 4vw, 36px); box-shadow: var(--sh-1);
}
.ob-kicker {
  margin: 0 0 var(--s-2); font-size: var(--t-micro); font-weight: 700;
  letter-spacing: var(--tr-label); text-transform: uppercase; color: var(--brand);
}
.ob-by { color: var(--text-3); font-weight: 500; }
#ob-title { font-size: clamp(1.5rem, 5vw, 1.75rem); letter-spacing: var(--tr-tight); }
.ob-lede { color: var(--text-2); margin: var(--s-3) 0 var(--s-6); font-size: var(--t-base); line-height: var(--lh-body); }
.ob-step { margin-bottom: var(--s-6); }
.ob-step h2 {
  font-size: var(--t-micro); text-transform: uppercase; letter-spacing: var(--tr-label);
  color: var(--text-3); margin-bottom: var(--s-3); font-weight: 700;
}
.ob-foot { color: var(--text-3); font-size: var(--t-meta); text-align: center; margin: var(--s-4) 0 0; }

/* ---------------------------------------------------------------- */
/* App shell                                                         */
/* ---------------------------------------------------------------- */

.app { min-height: 100dvh; display: flex; flex-direction: column; }

/*
 * Two chrome rows, not four. The market clock sits beside the wordmark; the
 * feed's own status moved into the feed column, where it describes the thing
 * it is next to. Previously ~250px of app furniture preceded the first
 * headline.
 */
.topbar {
  position: sticky; top: 0; z-index: 30;
  background: color-mix(in srgb, var(--surface) 94%, transparent);
  backdrop-filter: saturate(140%) blur(10px);
  border-bottom: 1px solid var(--rule);
  padding: 0 clamp(12px, 2.5vw, 20px);
}
.topbar-main {
  display: flex; align-items: center; gap: var(--s-3);
  max-width: var(--maxw); margin: 0 auto; width: 100%; min-height: 52px;
}
.brand { display: flex; align-items: center; gap: var(--s-2); flex: 0 0 auto; }
.brand-mark { width: 14px; height: 14px; border-radius: 3px; background: var(--brand); }
.brand-text { display: flex; flex-direction: column; line-height: 1.1; min-width: 0; }
.brand-name { font-size: var(--t-base); font-weight: 700; letter-spacing: var(--tr-none); }
.brand-by {
  font-size: var(--t-micro); font-weight: 500; color: var(--text-3);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.topbar-actions { display: flex; gap: var(--s-2); margin-left: auto; flex: 0 0 auto; }

/* Market clock, inline with the brand. */
.marketbar {
  display: flex; align-items: center; gap: var(--s-2);
  font-size: var(--t-meta); min-width: 0; overflow: hidden;
}
.mkt { display: inline-flex; align-items: center; gap: var(--s-2); white-space: nowrap; font-weight: 600; }
.mkt strong { font-weight: 600; }
.mkt-detail { color: var(--text-3); font-weight: 400; font-variant-numeric: tabular-nums; }
.mkt-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--text-3); flex: 0 0 auto; }
.mkt-open .mkt-dot, .mkt-special .mkt-dot { background: var(--ok); }
.mkt-pre-open .mkt-dot, .mkt-closing-auction .mkt-dot { background: var(--warn); }
/* Calendar events live in the side column, not the header. */
.marketbar .mkt-ev { display: none; }

/* The rail carries the app's central editorial claim, so it has to be named.
   Undisclosed colour is decoration. */
.railkey {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-1) var(--s-4);
  margin: 0 0 var(--s-4); font-size: var(--t-micro); color: var(--text-3);
  text-transform: uppercase; letter-spacing: var(--tr-label); font-weight: 700;
}
.rk {
  display: inline-block; width: 3px; height: 12px; border-radius: 3px;
  margin-right: var(--s-1); vertical-align: -1px;
}
.rk-reg { background: var(--brand); }
.rk-new { background: var(--hot); }

/* Market status on the phone, where the side column does not exist. */
.marketbar-phone {
  display: none; align-items: center; flex-wrap: wrap; gap: var(--s-1) var(--s-3);
  font-size: var(--t-meta); padding-bottom: var(--s-3);
  border-bottom: 1px solid var(--rule); margin-bottom: var(--s-3);
}
.marketbar-phone .mkt-ev { color: var(--text-3); font-variant-numeric: tabular-nums; }
@media (max-width: 899px) { .marketbar-phone { display: flex; } }
@media (max-width: 899px) { .marketbar .mkt-detail { display: none; } }
@media (max-width: 560px) { .marketbar { display: none; } }

.viewtabs {
  display: flex; gap: var(--s-1); max-width: var(--maxw); margin: 0 auto;
  width: 100%; flex-wrap: wrap;
}
.vt {
  background: none; border: 0; border-bottom: 2px solid transparent;
  padding: var(--s-3); min-height: 44px; cursor: pointer; white-space: nowrap;
  color: var(--text-3); font-weight: 600; font-size: var(--t-meta);
}
.vt[aria-pressed="true"] { color: var(--text); border-bottom-color: var(--brand); }
.vt-count {
  font-variant-numeric: tabular-nums; font-size: var(--t-micro);
  background: var(--surface-sunk); border-radius: var(--r-pill);
  padding: 1px 6px; margin-left: var(--s-1); color: var(--text-3);
}
.vt[aria-pressed="true"] .vt-count { background: var(--brand-soft); color: var(--brand); }
.vt-count:empty { display: none; }

/* ---------------------------------------------------------------- */
/* Layout                                                            */
/* ---------------------------------------------------------------- */

.layout {
  flex: 1 1 auto; width: 100%; max-width: var(--maxw); margin: 0 auto;
  display: grid; grid-template-columns: 1fr;
  padding: 0 clamp(12px, 2.5vw, 20px);
}
.feedcol { min-width: 0; padding: var(--s-4) 0 var(--s-16); }
/* The bar is 57px plus up to ~34px of safe-area inset, so 64px was not enough
   and the colophon slid underneath it. */
@media (max-width: 899px) {
  .feedcol { padding-bottom: calc(96px + env(safe-area-inset-bottom)); }
}
.side, .rail { display: none; }

@media (min-width: 900px) {
  /* Cap the reading measure: an uncapped column ran ~90 characters a line. */
  .layout {
    grid-template-columns: var(--rail-w) minmax(0, var(--feed-max));
    gap: var(--s-8); justify-content: center;
  }
  .feedcol { padding-bottom: var(--s-12); }
  .rail {
    display: block; position: sticky; top: calc(var(--topbar-h) + var(--s-3));
    align-self: start; max-height: calc(100dvh - var(--topbar-h) - var(--s-6));
    padding: var(--s-4) 0; overflow: hidden;
  }
  .rail-scroll { overflow-y: auto; max-height: calc(100dvh - var(--topbar-h) - var(--s-12)); padding-right: var(--s-1); }
}
@media (min-width: 1280px) {
  .layout { grid-template-columns: var(--rail-w) minmax(0, var(--feed-max)) var(--side-w); }
  .side {
    display: block; padding: var(--s-4) 0 var(--s-12);
    position: sticky; top: calc(var(--topbar-h) + var(--s-3)); align-self: start;
    max-height: calc(100dvh - var(--topbar-h) - var(--s-6)); overflow-y: auto;
  }
}

/* ---------------------------------------------------------------- */
/* Topics rail                                                       */
/* ---------------------------------------------------------------- */

.rail-head h2, .rail-custom h3, .tgroup h3, .side h2 {
  font-size: var(--t-micro); text-transform: uppercase; letter-spacing: var(--tr-label);
  color: var(--text-3); font-weight: 700; margin-bottom: var(--s-2);
}
.rail-actions { display: flex; gap: var(--s-3); margin-bottom: var(--s-2); }
.tgroup { margin-bottom: var(--s-5); }
.rail-custom { border-top: 1px solid var(--rule); padding-top: var(--s-4); margin-top: var(--s-2); }
.customlist { display: flex; flex-direction: column; gap: var(--s-2); margin-top: var(--s-3); }
.customrow {
  display: flex; align-items: center; gap: var(--s-3); font-size: var(--t-meta);
  background: var(--surface); border: 1px solid var(--rule);
  border-radius: var(--r-md); padding: var(--s-1) var(--s-2);
}
.customrow b { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; font-weight: 600; }
.customrow .al { color: var(--text-3); font-size: var(--t-micro); }

/* Phone: the rail becomes a bottom sheet. */
@media (max-width: 899px) {
  .rail[data-open="1"] {
    display: flex; flex-direction: column;
    position: fixed; inset: auto 0 0 0; z-index: 60;
    background: var(--surface); border-top: 1px solid var(--rule-strong);
    border-radius: var(--r-lg) var(--r-lg) 0 0;
    box-shadow: var(--sh-2); max-height: 82dvh;
    padding: var(--s-2) var(--s-4) var(--s-4);
    animation: sheetup .2s ease-out;
  }
  .rail[data-open="1"] .rail-head {
    display: flex; align-items: center; justify-content: space-between;
    padding: var(--s-1) 0 var(--s-2); border-bottom: 1px solid var(--rule);
  }
  .rail[data-open="1"] .rail-head h2 {
    font-size: var(--t-base); text-transform: none; letter-spacing: 0; color: var(--text);
  }
  .rail[data-open="1"] .rail-scroll {
    overflow-y: auto; padding-top: var(--s-3);
    padding-bottom: max(var(--s-4), env(safe-area-inset-bottom));
  }
}
@keyframes sheetup { from { transform: translateY(14%); opacity: .4; } to { transform: none; opacity: 1; } }

/*
 * Explicit per-element display. `revert-layer` in the author origin with no
 * @layer declared reverts to the UA value, which broke #rail-close: it has
 * the same specificity as .textbtn but comes later, so the Done button lost
 * its inline-flex and rendered top-aligned inside its 44px box.
 */
.only-phone { display: none; }
@media (max-width: 899px) {
  .bottombar.only-phone { display: grid; }
  .textbtn.only-phone { display: inline-flex; }
}

/* ---------------------------------------------------------------- */
/* Feed status and filters                                           */
/* ---------------------------------------------------------------- */

.statusline {
  display: flex; flex-wrap: wrap; gap: var(--s-3); align-items: baseline;
  font-size: var(--t-meta); color: var(--text-3);
  padding: 0 0 var(--s-3); border-bottom: 1px solid var(--rule); margin-bottom: var(--s-4);
}
/* Same bug .feedstate had: an always-present empty element still renders its
   padding, border and margin. */
.statusline:empty { display: none; padding: 0; margin: 0; border: 0; }
.statusline b { font-weight: 600; color: var(--text-2); }
.statusline .dot { width: 7px; height: 7px; border-radius: 50%; display: inline-block; margin-right: var(--s-1); }
.dot-ok { background: var(--ok); } .dot-warn { background: var(--warn); } .dot-bad { background: var(--bad); }
.statusline time, .statusline .num { font-variant-numeric: tabular-nums; }

.filterbar { margin: 0 0 var(--s-4); }
.filterbar-row { display: flex; gap: var(--s-2); flex-wrap: wrap; }
.filterbar-row #q { flex: 1 1 14rem; min-width: 0; }
.adv-only { display: none; }
body[data-mode="advanced"] .adv-only { display: block; }
body[data-mode="advanced"] .adv-only select { width: auto; min-width: 9rem; }
.activefilters { display: flex; flex-wrap: wrap; gap: var(--s-1); margin-top: var(--s-2); }
.activefilters:empty { margin-top: 0; }
.ftag {
  font-size: var(--t-micro); color: var(--text-3);
  border: 1px solid var(--rule); border-radius: var(--r-pill); padding: 2px 8px;
}

/* ---------------------------------------------------------------- */
/* Banners                                                           */
/* ---------------------------------------------------------------- */

.banner {
  border-radius: var(--r-md); padding: var(--s-3) var(--s-4); margin-bottom: var(--s-4);
  font-size: var(--t-meta); line-height: var(--lh-snug);
  border: 1px solid var(--rule); background: var(--surface);
  display: flex; gap: var(--s-2); align-items: flex-start;
}
.banner strong { display: block; font-weight: 700; }
.banner-warn { background: var(--hot-soft); border-color: var(--hot-line); color: var(--warn); }
.banner-bad  { background: var(--hot-soft); border-color: var(--hot); color: var(--bad); }
.banner-info { background: var(--brand-soft); border-color: var(--brand-line); color: var(--brand); }
.banner .textbtn { color: inherit; text-decoration: underline; min-height: 0; padding: 0 4px; }

/* ---------------------------------------------------------------- */
/* The feed — a ruled column, not a stack of boxes                   */
/* ---------------------------------------------------------------- */

.feed { list-style: none; margin: 0; padding: 0; }

.card {
  position: relative; list-style: none;
  /* The rail below is positioned from these, so they must be variables: the
     first card and Advanced mode both override the padding, and a hard-coded
     rail was short at the top in both cases. */
  --card-pt: var(--s-5);
  --card-pb: var(--s-4);
  padding: var(--card-pt) 0 var(--card-pb) var(--s-5);
  border-bottom: 1px solid var(--rule);
  transition: background .16s ease, box-shadow .16s ease;
}
.card:first-child { --card-pt: var(--s-2); }

/*
 * One 2px rail carries provenance. Two rules previously set border-left at
 * the same specificity, so a NEW REGULATOR story silently lost its new
 * marker to the tier rule — and those are the stories most likely to be new.
 */
.card::before {
  content: ''; position: absolute; left: 0;
  top: var(--card-pt); bottom: var(--card-pb);
  width: 3px; border-radius: 3px; background: transparent;
}
.card[data-tier="regulator"]::before { background: var(--brand); }
/* Recency stops the moment the story has been read, so the loudest colour in
   the feed is never attached to something already dealt with. */
.card[data-new="1"]:not([data-read="1"])::before { background: var(--hot); }
/* Both facts: alternating bands over the full height. The previous rule put
   both gradient stops at 14px, so it interpolated nothing and read as an
   antialiasing artefact rather than a second state. */
.card[data-new="1"][data-tier="regulator"]:not([data-read="1"])::before {
  background: repeating-linear-gradient(var(--hot) 0 6px, var(--brand) 6px 12px);
}
.card[data-read="1"] .newflag { display: none; }

.card:hover,
.card[aria-current="true"] {
  background: var(--surface-sunk);
  box-shadow: 0 0 0 var(--s-4) var(--surface-sunk);
}
.card[data-read="1"] .card-title { color: var(--text-2); font-weight: 600; }
/* Dim, do not delete: markReadOnOpen fires while the card is still on screen,
   so removing the excerpt shifted everything below it as the user looked. */
.card[data-read="1"] .card-x { color: var(--text-3); -webkit-line-clamp: 1; }

/*
 * The headline is a link, but it must read as a headline: ink-coloured and
 * undecorated until hover. Left to the browser default it renders blue and
 * underlined, which makes a column of headlines look like a page of
 * selected text.
 */
.card-title a,
.card-link { color: inherit; text-decoration: none; display: inline; }
.card-link { display: block; }
.card-title a:hover,
.card-link:hover .card-title {
  text-decoration: underline; text-decoration-thickness: 1.5px;
  text-underline-offset: 3px; text-decoration-color: var(--brand);
}
.card-title a:focus-visible { outline-offset: 3px; }

.card-meta {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-1) var(--s-2);
  /* Was --s-1, the same as the row's own gap, so a wrapped meta line and the
     headline were equidistant and nothing grouped. */
  margin-bottom: var(--s-2); line-height: var(--lh-flat);
}
.pub { font-size: var(--t-meta); font-weight: 500; color: var(--text-2); }
.newflag {
  order: -1; font-size: var(--t-micro); font-weight: 700; text-transform: uppercase;
  letter-spacing: var(--tr-label); color: var(--hot-ink); background: var(--hot);
  border-radius: var(--r-sm); padding: 2px 5px;
}
.doctype {
  font-size: var(--t-micro); font-weight: 600; text-transform: uppercase;
  letter-spacing: var(--tr-label); color: var(--brand); background: var(--brand-soft);
  border-radius: var(--r-sm); padding: 2px 5px;
}
.kindtag {
  font-size: var(--t-micro); font-weight: 600; color: var(--text-3);
  border: 1px solid var(--rule); border-radius: var(--r-sm); padding: 1px 5px;
}
/* Kind, not recency. Vermilion is reserved for "new". */
.kind-live { color: var(--text-2); border-color: var(--rule-strong); }
/* The ink-blue rail plus the document label already say "official"; a third
   signal for the same fact is noise. */
.tier { display: none; }

.card-title {
  margin: 0; font-size: var(--t-head); font-weight: 700;
  line-height: var(--lh-tight); letter-spacing: var(--tr-none); color: var(--text);
  /* A handful of regulator notices run to 300 characters. Clamp so no single
     item can own the screen; Details shows the full text. */
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.card-x {
  margin: var(--s-2) 0 0; font-size: var(--t-body); line-height: var(--lh-body);
  color: var(--text-2);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

.age { font-size: var(--t-meta); color: var(--text-3); font-variant-numeric: tabular-nums; }
.age-unknown { color: var(--warn); font-style: italic; }
.exact, .delaytag { display: none; }     /* operator detail: Advanced + Details only */
body[data-mode="advanced"] .exact {
  display: inline; font-family: var(--mono); font-size: var(--t-micro); color: var(--text-3);
}
body[data-mode="advanced"] .delaytag {
  display: inline; font-size: var(--t-micro); color: var(--text-3);
  font-variant-numeric: tabular-nums;
}

/* Matched topics as interpuncted text, not a row of bordered pills. */
.card-topics { display: flex; flex-wrap: wrap; gap: var(--s-1); min-width: 0; }
.tchip { font-size: var(--t-meta); font-weight: 500; color: var(--text-3); }
/* The separator is what makes this read as a list rather than a grey phrase,
   so it cannot be the faintest thing on the card. */
.tchip::before { content: '· '; color: var(--text-3); }
.tchip-title { color: var(--brand); font-weight: 600; }
.tchip-custom { color: var(--brand); font-weight: 600; }

/* The match evidence is debug grammar; by default it lives in Details. */
.card-why { display: none; }
body[data-mode="advanced"] .card-why {
  display: block; font-size: var(--t-micro); color: var(--text-3); margin-top: var(--s-1);
}
.card-why code { font-family: var(--mono); }

.alsoline { font-size: var(--t-meta); color: var(--text-3); margin-top: var(--s-1); }
.alsoline a { color: var(--text-2); }

.card-foot { display: flex; align-items: center; gap: var(--s-2); margin-top: var(--s-3); min-height: 36px; flex-wrap: wrap; }
.card-foot .textbtn { color: var(--text-3); font-weight: 500; }
.card-foot .textbtn:hover { color: var(--text); }
.card-spacer { flex: 1 1 auto; }
.savebtn[aria-pressed="true"] { color: var(--brand); font-weight: 600; }

/* Advanced is a density change, not a metadata dump. */
body[data-mode="advanced"] .card { --card-pt: var(--s-3); --card-pb: var(--s-3); }
body[data-mode="advanced"] .card-title { font-size: var(--t-base); -webkit-line-clamp: 2; }
body[data-mode="advanced"] .card-x { display: none; }
body[data-mode="advanced"] .card-foot { margin-top: var(--s-2); }

/* ---------------------------------------------------------------- */
/* Folded groups                                                     */
/* ---------------------------------------------------------------- */

.foldrow { list-style: none; }
.foldbtn {
  width: 100%; text-align: left; cursor: pointer;
  background: none; border: 0;
  border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule);
  padding: var(--s-4) var(--s-4) var(--s-4) 0; margin: var(--s-1) 0;
  display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 2px var(--s-3);
}
.foldbtn:hover { background: var(--surface-sunk); }
.foldcount { display: none; }   /* the count reads better inside the label */
.foldlabel { grid-column: 1; font-size: var(--t-base); font-weight: 600; color: var(--text); }
.foldnote { grid-column: 1; font-size: var(--t-meta); color: var(--text-3); }
.foldbtn::after {
  content: ''; grid-column: 2; grid-row: 1 / span 2;
  width: 8px; height: 8px;
  border-right: 2px solid var(--text-3); border-bottom: 2px solid var(--text-3);
  transform: rotate(-45deg);
}

/* ---------------------------------------------------------------- */
/* States                                                            */
/* ---------------------------------------------------------------- */

/* Left-aligned and railed, like the cards it stands among. A centred block at
   headline size read as a 404 page inside a left-ruled column. */
.feedstate {
  position: relative; padding: var(--s-8) 0 var(--s-8) var(--s-5);
  text-align: left; color: var(--text-3);
}
.feedstate::before {
  content: ''; position: absolute; left: 0; top: var(--s-8); bottom: var(--s-8);
  width: 3px; border-radius: 3px; background: var(--rule-strong);
}
/* An always-present empty div still renders its padding: this was 80px of
   dead space under every feed. */
.feedstate:empty { display: none; padding: 0; }
.feedstate h3 { font-size: var(--t-base); margin-bottom: var(--s-2); color: var(--text); }
.feedstate p { margin: var(--s-1) 0; max-width: 34rem; font-size: var(--t-meta); line-height: var(--lh-body); }
.feedstate .btn { margin-top: var(--s-4); display: inline-block; width: auto; }

.sk { padding: var(--s-5) 0 var(--s-4); border-bottom: 1px solid var(--rule); }
.sk span {
  display: block; height: 11px; border-radius: 3px; margin-bottom: var(--s-2);
  background: linear-gradient(90deg, var(--surface-sunk) 25%, var(--rule) 37%, var(--surface-sunk) 63%);
  background-size: 400% 100%; animation: shimmer 1.4s ease-in-out infinite;
}
.sk span:nth-child(1) { width: 22%; }
.sk span:nth-child(2) { width: 92%; height: 17px; }
.sk span:nth-child(3) { width: 64%; height: 17px; }
.sk span:last-child { width: 38%; margin-bottom: 0; }
@keyframes shimmer { 0% { background-position: 100% 0; } 100% { background-position: 0 0; } }

/* ---------------------------------------------------------------- */
/* Side column — what a reader wants, not operator telemetry         */
/* ---------------------------------------------------------------- */

.sidecard { border-top: 1px solid var(--rule); padding: var(--s-4) 0; }
.sidecard:first-child { border-top: 0; padding-top: 0; }
.sidecard h2 { margin-bottom: var(--s-3); }

.digest { font-size: var(--t-meta); color: var(--text-2); line-height: var(--lh-body); }
.digest b {
  font-size: var(--t-head-lg); font-weight: 700; color: var(--text);
  display: block; letter-spacing: var(--tr-tight);
}
.digest-list { list-style: none; margin: var(--s-2) 0 0; padding: 0; }
.digest-list li { display: flex; justify-content: space-between; gap: var(--s-2); padding: 3px 0; }
.digest-list .n { font-variant-numeric: tabular-nums; color: var(--text-3); }

.cal { list-style: none; margin: 0; padding: 0; font-size: var(--t-meta); }
.cal li {
  display: flex; justify-content: space-between; gap: var(--s-2);
  padding: var(--s-2) 0; border-top: 1px solid var(--rule);
}
.cal li:first-child { border-top: 0; }
.cal .when { color: var(--text-3); font-variant-numeric: tabular-nums; white-space: nowrap; }

.detail:empty { display: none; }
.detail { font-size: var(--t-meta); }
.detail h3 {
  font-size: var(--t-micro); text-transform: uppercase; letter-spacing: var(--tr-label);
  color: var(--text-3); margin: var(--s-4) 0 var(--s-2);
}
.detail h3:first-child {
  margin-top: 0; font-size: var(--t-body); text-transform: none; letter-spacing: 0;
  color: var(--text); font-weight: 700; line-height: var(--lh-tight);
}
.detail .btn { display: inline-block; width: auto; margin-top: var(--s-3); text-decoration: none; }

.health-summary { font-size: var(--t-meta); color: var(--text-3); margin: 0 0 var(--s-2); }
.health-list { list-style: none; margin: 0; padding: 0; font-size: var(--t-meta); }
.health-list li { display: flex; align-items: center; gap: var(--s-2); padding: 4px 0; border-top: 1px solid var(--rule); }
.health-list li:first-child { border-top: 0; }
.health-list .dot { width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto; }
.health-list .hname { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.health-list .hwhen { color: var(--text-3); font-variant-numeric: tabular-nums; font-size: var(--t-micro); }

.kv { display: grid; grid-template-columns: auto 1fr; gap: var(--s-1) var(--s-3); font-size: var(--t-meta); margin: var(--s-2) 0 0; }
.kv dt { color: var(--text-3); }
.kv dd { margin: 0; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }

/* Inline details below 1280px, where there is no side column. */
.card-detail { margin-top: var(--s-3); padding-top: var(--s-3); border-top: 1px solid var(--rule); }
@media (min-width: 1280px) { .card-detail { display: none; } }

/* ---------------------------------------------------------------- */
/* Colophon — attribution with dignity                               */
/* ---------------------------------------------------------------- */

.colophon {
  margin: var(--s-12) 0 0; padding-top: var(--s-5);
  border-top: 1px solid var(--rule);
  font-size: var(--t-meta); line-height: var(--lh-body); color: var(--text-3);
}
.colophon b { font-weight: 600; color: var(--text-2); }

/* ---------------------------------------------------------------- */
/* Phone bottom bar — views, not utilities                           */
/* ---------------------------------------------------------------- */

.bottombar {
  position: fixed; inset: auto 0 0 0; z-index: 40;
  background: color-mix(in srgb, var(--surface) 96%, transparent);
  backdrop-filter: blur(10px); border-top: 1px solid var(--rule);
  padding: var(--s-1) var(--s-1) max(var(--s-1), env(safe-area-inset-bottom));
}
@media (max-width: 899px) {
  .bottombar { display: grid; grid-template-columns: repeat(4, 1fr); }
  .viewtabs { display: none; }       /* the bar owns views on phone */
}
.bb {
  position: relative; background: none; border: 0; cursor: pointer; color: var(--text-3);
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: var(--s-2) var(--s-1); font-size: var(--t-micro); font-weight: 600;
  border-radius: var(--r-md); min-height: 52px;
}
.bb [class^="i-"] { width: 20px; height: 20px; }
.bb[aria-pressed="true"] { color: var(--brand); }
.bb:active { background: var(--surface-sunk); }
.bb-badge {
  position: absolute; top: 4px; left: 50%; margin-left: 5px;
  min-width: 16px; height: 16px; padding: 0 4px; border-radius: var(--r-pill);
  background: var(--hot); color: var(--hot-ink);
  font-size: 10px; line-height: 16px; font-variant-numeric: tabular-nums;
}
.bb-badge:empty { display: none; }

/* ---------------------------------------------------------------- */
/* Settings sheet                                                    */
/* ---------------------------------------------------------------- */

.sheet { position: fixed; inset: 0; z-index: 80; background: rgba(8,12,18,.52); display: grid; }
.sheet-panel {
  background: var(--paper); width: 100%; max-width: 34rem; margin-left: auto;
  height: 100dvh; overflow-y: auto; border-left: 1px solid var(--rule);
  animation: slidein .2s ease-out;
}
@media (max-width: 600px) {
  .sheet-panel {
    max-width: none; margin: auto 0 0; height: 94dvh;
    border-radius: var(--r-lg) var(--r-lg) 0 0; border-left: 0;
  }
}
@keyframes slidein { from { transform: translateX(4%); opacity: .6; } to { transform: none; opacity: 1; } }

.sheet-head {
  position: sticky; top: 0; background: var(--paper); z-index: 2;
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--s-4); border-bottom: 1px solid var(--rule);
}
.sheet-head h2 { font-size: var(--t-head-lg); letter-spacing: var(--tr-tight); }
.sheet-body { padding: var(--s-4) var(--s-4) max(var(--s-12), env(safe-area-inset-bottom)); }

.fs { border: 0; padding: 0; margin: 0 0 var(--s-8); }
.fs legend, .fs h3 {
  font-size: var(--t-micro); text-transform: uppercase; letter-spacing: var(--tr-label);
  color: var(--text-3); font-weight: 700; padding: 0; margin-bottom: var(--s-3);
}

.segmented { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-2); }
.segmented-3 { grid-template-columns: repeat(3, 1fr); }
.seg {
  background: var(--surface); border: 1.5px solid var(--rule-strong);
  border-radius: var(--r-md); padding: var(--s-3); cursor: pointer;
  text-align: left; display: flex; flex-direction: column; gap: 2px; min-height: 56px;
}
.seg strong { font-size: var(--t-meta); font-weight: 700; }
.seg span { font-size: var(--t-micro); color: var(--text-3); }
.seg[aria-checked="true"] { border-color: var(--brand); background: var(--brand-soft); }
.seg[aria-checked="true"] strong { color: var(--brand); }
.segmented-3 .seg { align-items: center; text-align: center; }

.field { display: block; margin-top: var(--s-4); font-size: var(--t-meta); }
.field > span { display: flex; justify-content: space-between; margin-bottom: var(--s-2); color: var(--text-3); }
.field output { font-variant-numeric: tabular-nums; font-weight: 700; color: var(--text); }
input[type="range"] { width: 100%; accent-color: var(--brand); min-height: 44px; }

.check {
  display: flex; gap: var(--s-3); align-items: flex-start; font-size: var(--t-meta);
  cursor: pointer; min-height: 44px; padding: var(--s-2) 0;
}
.check input { margin-top: 3px; width: 18px; height: 18px; accent-color: var(--brand); flex: 0 0 auto; }
.check em { display: block; font-size: var(--t-micro); color: var(--text-3); font-style: normal; }

.gl { border-top: 1px solid var(--rule); padding: var(--s-3) 0; }
.gl:first-child { border-top: 0; }
.gl dt { font-weight: 700; font-size: var(--t-meta); }
.gl dd { margin: 2px 0 0; font-size: var(--t-meta); color: var(--text-2); line-height: var(--lh-body); }

/* ---------------------------------------------------------------- */
/* Loading vocabulary                                                */
/* ---------------------------------------------------------------- */

.spinner {
  width: 1em; height: 1em; flex: 0 0 auto; display: inline-block; vertical-align: -.15em;
  border: 2px solid color-mix(in srgb, currentColor 22%, transparent);
  border-top-color: currentColor; border-radius: 50%;
  animation: spin .7s linear infinite;
}
.spinner-lg { width: 2.4rem; height: 2.4rem; border-width: 3px; color: var(--brand); }
@keyframes spin { to { transform: rotate(360deg); } }

.btn-spinner { display: none; }
[aria-busy="true"] > .btn-spinner { display: inline-block; }
[aria-busy="true"] > .i-refresh { display: none; }
.iconbtn[aria-busy="true"], .bb[aria-busy="true"] { cursor: progress; }
.btn[aria-busy="true"] { opacity: .75; pointer-events: none; }

.progress {
  position: fixed; inset: 0 0 auto 0; height: 2px; z-index: 100;
  background: transparent; overflow: hidden; opacity: 0; transition: opacity .2s; pointer-events: none;
}
.progress[data-on="1"] { opacity: 1; }
.progress > span {
  display: block; height: 100%; width: 40%;
  background: linear-gradient(90deg, transparent, var(--brand), transparent);
  animation: slide 1.1s ease-in-out infinite;
}
@keyframes slide { 0% { transform: translateX(-100%); } 100% { transform: translateX(350%); } }

.fullscreen-loader {
  position: fixed; inset: 0; z-index: 120; display: grid; place-items: center;
  background: var(--paper); transition: opacity .28s ease, visibility .28s;
}
.fullscreen-loader[data-done="1"] { opacity: 0; visibility: hidden; }
.fl-inner { text-align: center; display: grid; justify-items: center; gap: var(--s-3); }
.fl-title { font-size: var(--t-head); font-weight: 700; margin: var(--s-1) 0 0; }
.fl-sub { font-size: var(--t-meta); color: var(--text-3); margin: 0; }

.pulse { position: relative; }
.pulse::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  background: inherit; animation: pulsering 1.8s ease-out infinite;
}
@keyframes pulsering {
  0% { transform: scale(1); opacity: .6; }
  70%, 100% { transform: scale(2.6); opacity: 0; }
}

.ptr {
  display: flex; align-items: center; justify-content: center; gap: var(--s-2);
  height: 0; overflow: hidden; font-size: var(--t-meta); color: var(--text-3);
  transition: height .18s ease;
}
.ptr[data-pull="1"] { height: var(--ptr-h, 48px); }
.ptr[data-busy="1"] { height: 48px; }
.ptr-circle {
  width: 26px; height: 26px; border-radius: 50%; border: 1px solid var(--rule-strong);
  display: grid; place-items: center; background: var(--surface);
}
.ptr-arrow {
  width: 9px; height: 9px;
  border-left: 2px solid var(--brand); border-bottom: 2px solid var(--brand);
  transform: rotate(-45deg) translate(1px, -1px); transition: transform .18s ease;
}
.ptr[data-ready="1"] .ptr-arrow { transform: rotate(135deg) translate(1px, -1px); }
.ptr[data-busy="1"] .ptr-arrow { display: none; }
.ptr[data-busy="1"] .spinner { display: inline-block !important; color: var(--brand); }
@media (min-width: 900px) { .ptr { display: none; } }

.infinite {
  display: flex; align-items: center; justify-content: center; gap: var(--s-2);
  padding: var(--s-5) var(--s-4); color: var(--text-3); font-size: var(--t-meta);
}
.sentinel { height: 1px; }

/* Toast visibility is a data attribute, never `hidden`: a live region that is
   display:none when its text changes is not announced. */
.toast {
  position: fixed; left: 50%; bottom: 72px; transform: translateX(-50%) translateY(6px);
  background: var(--text); color: var(--paper);
  padding: var(--s-2) var(--s-4); border-radius: var(--r-pill);
  font-size: var(--t-meta); z-index: 90; box-shadow: var(--sh-2);
  max-width: calc(100vw - 32px); text-align: center;
  opacity: 0; pointer-events: none; transition: opacity .18s, transform .18s;
}
.toast[data-show="1"] { opacity: 1; transform: translateX(-50%); }
@media (max-width: 899px) { .toast { bottom: calc(72px + env(safe-area-inset-bottom)); } }
@media (min-width: 900px) { .toast { bottom: var(--s-6); } }

/* ---------------------------------------------------------------- */
/* Optional backdrop                                                 */
/* ---------------------------------------------------------------- */

.gradient-canvas {
  position: fixed; inset: 0; width: 100%; height: 100%;
  z-index: -2; pointer-events: none; display: block;
}
:root[data-fx="off"] .gradient-canvas,
:root[data-fx="subtle"] .gradient-canvas { display: none; }

/* "Off" must mean off: these blurs sit on sticky, scroll-repainted elements
   and are the most expensive thing in the app on a mid-range GPU. */
:root[data-fx="off"] .pulse::after { animation: none; opacity: 0; }
:root[data-fx="off"] .topbar,
:root[data-fx="off"] .bottombar {
  -webkit-backdrop-filter: none; backdrop-filter: none; background: var(--surface);
}

/* ---------------------------------------------------------------- */
/* Preference and accessibility overrides                            */
/* ---------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .spinner { animation: none; opacity: .85; }
  .progress > span { animation: none; width: 100%; opacity: .7; }
  .pulse::after { animation: none; opacity: 0; }
  .sk span { animation: none; }
  .fullscreen-loader, .ptr, .toast { transition: none; }
  .rail[data-open="1"], .sheet-panel { animation: none; }
}

@media (prefers-contrast: more) {
  :root { --rule: #000; --rule-strong: #000; --text-2: #22262b; --text-3: #2b2b2b; }
  .is-dark { --rule: #fff; --rule-strong: #fff; --text-2: #f2f5f9; --text-3: #e3e9f0; }
  .card { border-bottom-width: 1.5px; }
  .gradient-canvas { display: none; }
}

@media (forced-colors: active) {
  .gradient-canvas { display: none; }
  .chip, .btn, .iconbtn, .seg { border: 1px solid CanvasText; }
  .chip[aria-pressed="true"], .seg[aria-checked="true"] { outline: 2px solid Highlight; }
  .card::before { background: CanvasText !important; }
}

@media (prefers-reduced-transparency: reduce) {
  .gradient-canvas { display: none; }
  .topbar, .bottombar, .sheet-panel {
    -webkit-backdrop-filter: none !important; backdrop-filter: none !important;
    background: var(--surface) !important;
  }
}

@media print {
  .topbar, .bottombar, .rail, .side, .filterbar, .card-foot, .toast, .progress { display: none; }
  .card { break-inside: avoid; }
}

/* ---------------------------------------------------------------- */
/* Side-column objects that are controls, not read-outs              */
/* ---------------------------------------------------------------- */

.digest-lead {
  display: block; width: 100%; text-align: left;
  background: none; border: 0; padding: 0; cursor: pointer;
  font-size: var(--t-head-lg); font-weight: 700; color: var(--text);
  letter-spacing: var(--tr-tight); line-height: var(--lh-flat);
}
.digest-lead:hover { color: var(--brand); }
.digest-sub { margin: var(--s-1) 0 0; font-size: var(--t-meta); color: var(--text-3); }
.digest-list li { border-top: 1px solid var(--rule); align-items: baseline; }
.digest-list li:first-child { border-top: 0; }
.digest-row {
  flex: 1 1 auto; min-width: 0; text-align: left;
  background: none; border: 0; cursor: pointer;
  padding: var(--s-2) 0; min-height: 40px;
  font-size: var(--t-meta); font-weight: 500; color: var(--text-2);
}
.digest-row:hover { color: var(--brand); }
/* The counts are the point of the panel, so they are not the quietest thing
   in it. */
.digest-list .n { font-weight: 700; color: var(--text); }

/* A rate decision and a public holiday must not look identical. */
.cal li { padding-left: var(--s-3); position: relative; align-items: baseline; }
.cal li::before {
  content: ''; position: absolute; left: 0; top: var(--s-2); bottom: var(--s-2);
  width: 3px; border-radius: 3px; background: var(--brand);
}
.cal li[data-kind="closed"]::before { background: var(--rule-strong); }
.cal li[data-kind="closed"] .ev { color: var(--text-3); }
.cal .ev { flex: 1 1 auto; min-width: 0; color: var(--text); font-weight: 500; }
.cal .when { flex: 0 0 auto; text-align: right; }
.cal .when b {
  display: block; font-weight: 700; font-size: var(--t-meta);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.cal .when i {
  display: block; font-style: normal; font-size: var(--t-micro);
  color: var(--text-3); font-variant-numeric: tabular-nums; white-space: nowrap;
}

/* The detail panel's story title should not be smaller than the headline it
   came from. */
.detail h3:first-child { font-size: var(--t-base); }

/* Inline alias field, replacing a native prompt(). */
.aliasinput {
  flex: 1 1 100%; margin-top: var(--s-2);
  font-size: var(--t-meta); min-height: 40px; padding: var(--s-1) var(--s-2);
}

/* ---------------------------------------------------------------- */
/* Per-story actions: two icons in the meta row, one shared menu     */
/* ---------------------------------------------------------------- */

.card-meta { min-height: 40px; }
.card-spacer { flex: 1 1 auto; min-width: var(--s-2); }

.act {
  display: inline-grid; place-items: center; flex: 0 0 auto;
  width: 40px; height: 40px;
  background: none; border: 0; border-radius: var(--r-sm);
  color: var(--text-3); cursor: pointer;
  transition: background .14s, color .14s;
}
.act [class^="i-"] { width: 18px; height: 18px; }
.act:hover { background: var(--surface-sunk); color: var(--text); }
.act[aria-expanded="true"] { background: var(--brand-soft); color: var(--brand); }

/* The card footer now holds nothing but the "also reported by" line. */
.card-foot:empty { display: none; }

.cardmenu {
  position: absolute; z-index: 70; min-width: 14rem; padding: var(--s-1);
  background: var(--surface); border: 1px solid var(--rule-strong);
  border-radius: var(--r-md); box-shadow: var(--sh-2);
}
.cm {
  display: flex; align-items: center; width: 100%;
  min-height: 44px; padding: 0 var(--s-3);
  background: none; border: 0; border-radius: var(--r-sm);
  color: var(--text); font-size: var(--t-meta); font-weight: 500;
  text-align: left; text-decoration: none; cursor: pointer;
}
.cm:hover, .cm:focus-visible { background: var(--surface-sunk); }

.scrim { position: fixed; inset: 0; z-index: 65; background: transparent; }

/* Touch: the same sheet grammar as the Topics rail, so a card at the top of
   the screen never throws its menu out of thumb reach. */
@media (max-width: 560px) {
  .cardmenu {
    position: fixed; inset: auto 0 0 0; min-width: 0;
    border-radius: var(--r-lg) var(--r-lg) 0 0; border-left: 0; border-right: 0;
    padding: var(--s-2) var(--s-2) max(var(--s-2), env(safe-area-inset-bottom));
    animation: sheetup .2s ease-out;
  }
  .cm { min-height: 52px; font-size: var(--t-base); }
  .scrim { background: rgba(8, 12, 18, .42); }
}
@media (prefers-reduced-motion: reduce) { .cardmenu { animation: none; } }
