/* EQSIS Pulse: pulse.css, built by the render asset step from public/pulse/assets/pulse.css.d/ (12 parts, in name order). Edit the parts, never this file. */

/* ===== part 00-tokens.css ===== */
/* =====================================================================
   EQSIS Pulse: pulse.css, part 00 (tokens). Owner: foundation.
   ---------------------------------------------------------------------
   pulse.css is ONE served file (.claude/rules/frontend.md), built by the
   render asset step from the parts in public/pulse/assets/pulse.css.d/,
   concatenated in file-name order (docs/design/BUILD-V2.md, "CSS"). Each
   package owns its own part; nobody edits another package's part. It loads
   after the site's fonts.css, bootstrap.min.css and eqsis.css (which
   carries tokens.css), and it may only:
     - alias existing site tokens to new roles (never a new colour value:
       no hex, rgb() or hsl() anywhere; make check fails on one),
     - add Pulse's type, space and layout scales (rem, plus the reviewed
       fluid clamp() exception of DESIGN-SYSTEM.md 15.1),
     - lay out Pulse's own pieces.
   Theming is the site's: dark values only under :root[data-theme="dark"],
   every one restated under :root[data-theme="dark"][data-contrast="high"];
   never a prefers-color-scheme query. Every --a11y-scale use carries the
   ", 1" fallback (make check lints it): the site sets the property only
   when the reader picks a text size.

   Breakpoint constants (DESIGN-SYSTEM.md 14.6; a custom property cannot sit
   inside @media, so they are written here once). They decide CHROME ONLY:
     min-width   576px  768px  992px  1200px
     max-width   575.98px  767.98px  991.98px
     short       max-height: 26rem (fixed bars return to the flow)
   Page and component layout switch on named containers, in rem:
     pulse-page 44rem 58rem | pulse-strip 30rem 52rem | pulse-stamp 30rem 40rem
     pulse-number 22rem 30rem | pulse-item 30rem 40rem | pulse-tile 30rem 52rem
     pulse-end 40rem | pulse-ex 27.5rem 42.5rem 60rem
   ===================================================================== */

:root {
  /* ---- Market direction: the site's own roles. Always with a direction
     mark and a sign, never colour alone. */
  --pulse-up:            var(--green-700);
  --pulse-down:          var(--danger);
  --pulse-flat:          var(--ink-soft);
  --pulse-up-bg:         var(--green-100);

  /* ---- Deep surface. Never --blue-900 as a background: it becomes a text
     colour in dark mode. --surface-deep arrives through HANDOFF row 4;
     --pulse-stamp-bg reads it with the interim --pulse-deep-bg fallback, so
     the HANDOFF needs no Pulse deploy. */
  --pulse-deep-bg:       var(--blue-800);
  --pulse-on-deep:       var(--surface);
  --pulse-on-deep-soft:  var(--blue-100);
  --pulse-up-on-deep:    var(--green-100);
  --pulse-down-on-deep:  var(--surface);
  --pulse-stamp-bg:      var(--surface-deep, var(--pulse-deep-bg));
  --pulse-stamp-fg:      var(--pulse-on-deep);
  --pulse-band-edge:     transparent;
  --pulse-deep-line:     var(--blue-700);

  /* ---- Prototype banner, status markers, rules, meta. */
  --pulse-banner-bg:     var(--blue-100);
  --pulse-banner-fg:     var(--ink);
  --pulse-banner-rule:   var(--blue-600);
  --pulse-status-bg:     var(--surface);
  --pulse-status-fg:     var(--ink);
  --pulse-status-border: var(--field-border);
  --pulse-nav-current:   var(--blue-600);
  --pulse-rule:          var(--line);
  --pulse-meta:          var(--ink-soft);

  /* ---- v2 colour roles (DESIGN-SYSTEM.md 14.3), all aliases. */
  --pulse-split-a:         var(--eq-green);
  --pulse-split-b:         var(--eq-blue);
  --pulse-figure-ink:      var(--blue-900);
  --pulse-label:           var(--blue-600);
  --pulse-plain-label:     var(--blue-700);
  --pulse-plain-bg:        var(--surface-alt);
  --pulse-note-underline:  var(--field-border);
  --pulse-since-rule:      var(--blue-600);
  --pulse-since-pill-fg:   var(--blue-700);
  --pulse-new-bg:          var(--blue-100);
  --pulse-progress-done:   var(--blue-600);
  --pulse-progress-todo:   var(--field-border);
  --pulse-endcard-bg:      var(--surface-alt);
  --pulse-analyst-label:   var(--blue-700);
  --pulse-analyst-rule:    linear-gradient(var(--pulse-split-a) 0 40%, var(--pulse-split-b) 40% 100%);
  --pulse-split-rule:      linear-gradient(90deg, var(--pulse-split-a) 0 40%, var(--pulse-split-b) 40% 100%);
  --pulse-follow-on-bg:    var(--blue-100);
  --pulse-follow-on-fg:    var(--blue-900);

  /* ---- Chart roles (infographics.json house.colour_roles). */
  --pulse-chart-main:    var(--blue-600);
  --pulse-chart-compare: var(--ink-soft);
  --pulse-chart-ref:     var(--ink);
  --pulse-chart-quiet:   var(--field-border);
  --pulse-chart-grid:    var(--line);
  --pulse-chart-track:   var(--surface-alt);
  --pulse-chart-band:    var(--surface-alt);

  /* ---- Category accents (data/seed/categories.json accent_token): from
     the site's blue and green ramps and neutrals, never the price colours;
     a category's name is always printed as text, the accent only marks. */
  --pulse-cat-markets-today:            var(--blue-900);
  --pulse-cat-trading-desk:             var(--blue-700);
  --pulse-cat-investing:                var(--green-600);
  --pulse-cat-companies:                var(--blue-600);
  --pulse-cat-sectors-and-themes:       var(--field-border);
  --pulse-cat-economy-and-policy:       var(--ink-soft);
  --pulse-cat-global-markets:           var(--blue-800);
  --pulse-cat-commodities-and-currency: var(--field-border);
  --pulse-cat-data-desk:                var(--ink);
  --pulse-cat-data-desk-secondary:      var(--eq-green);
  --pulse-cat-learn:                    var(--green-600);

  /* ---- Fixed type steps (rem; the site's --text-* scale stays the body
     scale). --pulse-text-xs holds 12px at A- 90% (DESIGN-SYSTEM.md 5.2). */
  --pulse-text-xs:       max(12px, 0.8125rem);
  --pulse-text-sm:       0.875rem;
  --pulse-text-base:     1rem;
  --pulse-text-dek:      1.125rem;
  --pulse-text-card:     1.1875rem;
  --pulse-text-section:  1.375rem;
  --pulse-text-lead:     1.75rem;
  --pulse-text-h1:       2rem;
  --pulse-text-h1-lg:    2.5rem;
  --pulse-text-article:  1.125rem;
  --pulse-text-figure:    3.5rem;
  --pulse-text-figure-lg: 4.5rem;
  --pulse-text-figure-sm: var(--pulse-text-h1);
  --pulse-text-label:     var(--text-sm);

  /* ---- Fluid display roles (reviewed exception 15.1-1): both bounds are
     existing tokens; the vw slope follows the A+ control. */
  --pulse-fs-dek:    var(--text-base);
  --pulse-fs-1:      clamp(var(--pulse-text-card), 1.1071rem + 0.3571vw * var(--a11y-scale, 1), var(--text-xl));
  --pulse-fs-2:      clamp(var(--text-xl), 1.2143rem + 0.7143vw * var(--a11y-scale, 1), var(--text-2xl));
  --pulse-fs-3:      clamp(var(--pulse-text-lead), 1.5893rem + 0.7143vw * var(--a11y-scale, 1), var(--text-3xl));
  --pulse-fs-4:      clamp(var(--pulse-text-h1), 1.7857rem + 0.9524vw * var(--a11y-scale, 1), var(--pulse-text-h1-lg));
  --pulse-fs-figure: clamp(var(--pulse-text-figure), 3.0714rem + 1.9048vw * var(--a11y-scale, 1), var(--pulse-text-figure-lg));

  /* ---- Leading: always unitless, never "normal". */
  --pulse-leading-figure: 1;
  --pulse-leading-lead:   1.15;
  --pulse-leading-card:   1.25;
  --pulse-leading-dense:  1.45;

  /* ---- Fluid space scale (DESIGN-SYSTEM.md 6.1): one named step per job. */
  --pulse-space-2xs: var(--sp-1);
  --pulse-space-xs:  clamp(var(--sp-2), 0.3929rem + 0.4762vw * var(--a11y-scale, 1), var(--sp-3));
  --pulse-space-s:   clamp(var(--sp-4), 0.7857rem + 0.9524vw * var(--a11y-scale, 1), var(--sp-5));
  --pulse-space-m:   clamp(var(--sp-5), 1.2857rem + 0.9524vw * var(--a11y-scale, 1), var(--sp-6));
  --pulse-space-l:   clamp(var(--sp-6), 1.5714rem + 1.9048vw * var(--a11y-scale, 1), var(--sp-7));
  --pulse-space-xl:  clamp(var(--sp-7), 2.5714rem + 1.9048vw * var(--a11y-scale, 1), var(--sp-8));

  /* ---- Layout constants. The gutter equals the site's .container-eq
     padding (1.5rem) until HANDOFF row 29 changes the site below 576px. */
  --pulse-gutter:            var(--sp-5);
  --pulse-rail:              4rem;
  --pulse-measure:           34rem;
  --pulse-card-pad:          var(--pulse-space-s);
  --pulse-tap:               max(48px, 3rem);
  --pulse-tap-dense:         max(44px, 2.75rem);
  --pulse-reserve-since:     3rem;
  --pulse-reserve-progress:  3rem;
  --pulse-split-h:           0.25rem;
  --pulse-split-h-frame:     0.5rem;
  --pulse-bottombar-h:       3.5rem;
  --pulse-actionbar-h:       3.5rem;
}

/* The plain-words sentence steps up once, at the site's tablet breakpoint. */
@media (min-width: 768px) {
  :root { --pulse-fs-dek: var(--pulse-text-dek); }
}

/* ---- Dark ----
   The Stamp (the page's one feature) is LIFTED in the dark states, never sunk: the interim
   --blue-800 is 1.07:1 against --surface and HANDOFF row 4's first dark value was darker still, so
   the Stamp read flatter than the ordinary tinted bands and the hierarchy inverted. --surface-alt
   plus the 1px --pulse-band-edge (which the bands do not carry) keeps it the most present surface
   in all four states; the on-deep text roles are --ink and --ink-soft here (pairs checked in
   data/check/contrast_pairs.json). Set directly, not through --surface-deep, so the dark value
   holds whatever row 4 finally ships (docs/HANDOFF.md row 4 now proposes a lifted dark tone). */
:root[data-theme="dark"] {
  --pulse-stamp-bg:      var(--surface-alt);
  --pulse-on-deep:       var(--ink);
  --pulse-on-deep-soft:  var(--ink-soft);
  --pulse-up-on-deep:    var(--green-700);
  --pulse-down-on-deep:  var(--danger);
  --pulse-band-edge:     var(--field-border);
  --pulse-deep-line:     var(--line);
  --pulse-cat-global-markets: var(--blue-700);
  --pulse-cat-data-desk-secondary: var(--eq-green);
}

/* ---- Dark plus high contrast: restate every dark role. The site's dark+HC
   block does not restate --green-600, so its light high-contrast value leaks
   in and fails 3:1 on the dark surface; green accents switch to --eq-green. */
:root[data-theme="dark"][data-contrast="high"] {
  --pulse-stamp-bg:      var(--surface-alt);
  --pulse-on-deep:       var(--ink);
  --pulse-on-deep-soft:  var(--ink-soft);
  --pulse-up-on-deep:    var(--green-700);
  --pulse-down-on-deep:  var(--danger);
  --pulse-band-edge:     var(--field-border);
  --pulse-deep-line:     var(--line);
  --pulse-cat-global-markets: var(--blue-700);
  --pulse-cat-data-desk-secondary: var(--eq-green);
  --pulse-cat-investing: var(--eq-green);
  --pulse-cat-learn:     var(--eq-green);
}

/* ===== part 10-base.css ===== */
/* =====================================================================
   EQSIS Pulse: pulse.css, part 10 (base). Owner: foundation.
   Figures and direction, tags and status markers, the prototype banner,
   the v2 type roles, the split bar, focus on deep surfaces, motion, and
   the build stub. Every size from the scales in part 00; every colour an
   alias of a site token.
   ===================================================================== */

/* ---------- Figures and direction (DESIGN-SYSTEM.md 10.3) ---------- */
.pulse-num { font-variant-numeric: tabular-nums; }
.pulse-up { color: var(--pulse-up); }
.pulse-down { color: var(--pulse-down); }
.pulse-flat { color: var(--pulse-flat); }
.pulse-ink { color: var(--ink); }
.pulse-chg { white-space: nowrap; font-weight: var(--weight-medium); }
/* The SVG triangle: 0.7em, currentColor, aria-hidden (direction_mark.php). */
.pulse-dir { display: inline-block; width: 0.7em; height: 0.7em; vertical-align: 0.02em; }
.pulse-deep .pulse-up, .pulse-sec--feature .pulse-up { color: var(--pulse-up-on-deep); }
.pulse-deep .pulse-down, .pulse-sec--feature .pulse-down { color: var(--pulse-down-on-deep); }
.pulse-deep .pulse-flat, .pulse-sec--feature .pulse-flat { color: var(--pulse-on-deep-soft); }

/* ---------- Prototype banner, status markers, tags ---------- */
.pulse-proto {
  background: var(--pulse-banner-bg);
  color: var(--pulse-banner-fg);
  border-bottom: 3px solid var(--pulse-banner-rule);
  font-size: var(--pulse-text-sm);
}
.pulse-proto p { margin: 0; padding-block: var(--sp-2); }
/* One tag family (DESIGN-SYSTEM.md 10.3): Sample data, Pending confirmation, Provisional, Key moment,
   An EQSIS course, Next. Outlined, --radius-sm, at the 0.8125rem floor. One per module, never per line. */
.pulse-status, .pulse-tag {
  display: inline-block;
  padding: 0 var(--sp-2);
  border: 1px solid var(--pulse-status-border);
  border-radius: var(--radius-sm);
  background: var(--pulse-status-bg);
  color: var(--pulse-status-fg);
  font-family: var(--font-body);
  font-size: var(--pulse-text-xs);
  font-weight: var(--weight-semibold);
  line-height: 1.6;
  white-space: nowrap;
  vertical-align: baseline;
}
.pulse-status--placeholder { border-style: dashed; }
.pulse-copy-state { margin-top: calc(-1 * var(--sp-2)); }

/* ---------- v2 type roles (DESIGN-SYSTEM.md section 5) ----------
   Display face for headlines, labels, numerals and figures; body face for text,
   meta and controls; never a literal family; no italics; never 700 on Plex. */
.pulse-h-lead, .pulse-h-item, .pulse-h-card, .pulse-h-article {
  margin: 0;
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  color: var(--blue-900);
  text-wrap: balance;
}
.pulse-h-article { font-size: var(--pulse-fs-4); line-height: var(--pulse-leading-lead); }
.pulse-h-lead { font-size: var(--pulse-fs-3); line-height: var(--pulse-leading-lead); }
.pulse-h-item { font-size: var(--pulse-fs-2); line-height: var(--leading-tight); }
.pulse-h-card { font-size: var(--pulse-fs-1); line-height: var(--pulse-leading-card); }
.pulse-h-card a, .pulse-h-item a { color: inherit; text-decoration: none; }
.pulse-h-card a:hover, .pulse-h-item a:hover { text-decoration: underline; text-underline-offset: 3px; }
/* Unit labels ("In plain words", "What happened", "Why it matters", "What it does not tell
   you", "What it means"): Archivo 600, sentence case, never uppercase. */
.pulse-unit-label {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--pulse-text-label);
  line-height: var(--pulse-leading-dense);
  color: var(--pulse-label);
}
.pulse-dekline { font-size: var(--pulse-fs-dek); line-height: var(--pulse-leading-dense); text-wrap: pretty; }
.pulse-measure { max-width: var(--pulse-measure); }
.pulse-meta-line { margin: 0; color: var(--pulse-meta); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
.pulse-figure-num {
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-variant-numeric: tabular-nums;
  color: var(--pulse-figure-ink);
  line-height: var(--pulse-leading-figure);
}

/* ---------- The split bar: the brand mark of EQSIS authorship (DESIGN-SYSTEM.md 9) ----------
   40% EQ green, 60% SIS blue, square ends; decoration only (the label carries the meaning).
   Allowed only on the Stamp and the end card (frame, 0.5rem), share frames (0.25rem), and
   vertically at the left of an analyst's voice. Never under, beside or inside an exhibit. */
.pulse-split-top { position: relative; }
.pulse-split-top::before {
  content: ""; position: absolute; inset: 0 0 auto 0;
  height: var(--pulse-split-h-frame);
  background: var(--pulse-split-rule);
}
.pulse-split-top--thin::before { height: var(--pulse-split-h); }
.pulse-split-left { position: relative; padding-inline-start: calc(var(--pulse-split-h) + var(--pulse-space-s)); }
.pulse-split-left::before {
  content: ""; position: absolute; inset: 0 auto 0 0;
  width: var(--pulse-split-h);
  background: var(--pulse-analyst-rule);
}

/* ---------- Focus on the deep surface (DESIGN-SYSTEM.md 12) ----------
   The site's --focus-ring is 2.25:1 on the interim deep surface. Until HANDOFF rows 26 and 27 add
   these selectors to the site's dark-surface ring, the ring follows the on-deep text colour
   (11.3:1; a checked pair in data/check/contrast_pairs.json, so it cannot be dropped by accident). */
.pulse-deep :focus-visible,
.pulse-sec--feature :focus-visible,
.pulse-stamp :focus-visible { outline-color: var(--pulse-on-deep) !important; }

/* ---------- Motion (DESIGN-SYSTEM.md 11) ----------
   No motion by default. Colour and opacity transitions only, on the site's durations, which the
   site zeroes under prefers-reduced-motion and data-motion="reduce"; restated here for Pulse. */
.pulse-fade { transition: opacity var(--dur-base) var(--ease), color var(--dur-fast) var(--ease); }
@media (prefers-reduced-motion: reduce) {
  .pulse-fade { transition: none; }
}
:root[data-motion="reduce"] .pulse-fade { transition: none; }

/* ---------- Build stub (templates/components/_stub.php; fixture renders only) ---------- */
.pulse-stub {
  margin-block: var(--pulse-space-xs);
  padding: var(--pulse-space-xs) var(--pulse-space-s);
  border: 1px dashed var(--field-border);
  border-radius: var(--radius-sm);
  color: inherit;
}
.pulse-stub-label { margin: 0; font-size: var(--pulse-text-sm); }

/* ===== part 20-layout.css ===== */
/* =====================================================================
   EQSIS Pulse: pulse.css, part 20 (layout). Owner: foundation.
   The page container and grid, the hanging rail, the measure, and the
   four section treatments with their joins (DESIGN-SYSTEM.md sections 4, 6
   and 7). Page columns switch on the pulse-page CONTAINER in rem (so the
   A+ control collapses them instead of squeezing them); media queries here
   only set the band padding step at the site's 768px breakpoint.
   Compact first: unqueried CSS is the one-column phone layout.
   ===================================================================== */

/* ---------- The page container ----------
   .pulse-page sits inside .container-eq (its content box is what the 44rem and 58rem thresholds
   measure). One container per component root; never on a flex item with flex-basis auto. */
.pulse-page { container: pulse-page / inline-size; }

/* Main 8 columns and rail 4, with 1.5rem gaps, from a 58rem page container. The rail is an <aside>
   placed between the items in the DOM (so reading order equals phone order); give it
   grid-row: 1 / span N for the N main-column children it should run beside. */
@container pulse-page (min-width: 58rem) {
  .pulse-grid {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: var(--sp-5);
    align-items: start;
  }
  .pulse-grid > .pulse-col-main { grid-column: 1 / span 8; }
  .pulse-grid > .pulse-col-rail { grid-column: 9 / span 4; }
  .pulse-grid > .pulse-col-full { grid-column: 1 / -1; }
}

/* The hanging rail (4rem) from a 44rem page container: numerals, slot names, live-row times and
   kickers hang in it; the text column keeps one left edge. */
@container pulse-page (min-width: 44rem) {
  .pulse-hang {
    display: grid;
    grid-template-columns: var(--pulse-rail) minmax(0, 1fr);
    column-gap: var(--pulse-space-m);
  }
  .pulse-hang > .pulse-hang-rail { grid-column: 1; }
  .pulse-hang > :not(.pulse-hang-rail) { grid-column: 2; }
}

/* Prose, plain-words lines and deks cap at 34rem (about 68 characters of 18px Plex), in rem so
   the character count holds at every A+ step (reviewed exception 15.1-3). */
.pulse-prose-measure > p,
.pulse-prose-measure > ul,
.pulse-prose-measure > ol { max-width: var(--pulse-measure); }

/* ---------- Sections: the four treatments (DESIGN-SYSTEM.md 7.1) ----------
   flow and shift keep the white surface; band (tint) and feature (deep) change it. A surface
   never changes in the middle of a section. render_sections() prints these classes and checks
   the adjacency rules; nothing else should. */
.pulse-sec { position: relative; }
.pulse-sec-in > :first-child { margin-top: 0; }
.pulse-sec-in > :last-child { margin-bottom: 0; }

.pulse-sec--band {
  background: var(--surface-alt);
  padding-block: var(--pulse-space-l);
}
.pulse-sec--feature {
  background: var(--pulse-stamp-bg);
  color: var(--pulse-stamp-fg);
  padding-block: var(--pulse-space-l);
  /* In the dark states the deep surface is 1.05:1 against the page: a 1px edge draws it. */
  box-shadow: inset 0 0 0 1px var(--pulse-band-edge);
}
.pulse-sec--feature a { color: var(--pulse-on-deep); }
.pulse-sec--feature h2, .pulse-sec--feature h3 { color: var(--pulse-on-deep); }
@media (min-width: 768px) {
  .pulse-sec--band, .pulse-sec--feature { padding-block: var(--pulse-space-xl); }
}

/* ---------- Joins (DESIGN-SYSTEM.md 6.2 and 7.1) ----------
   first          the breadcrumb's own padding separates the first section
   continue       flow: --pulse-space-l
   series         flow member of the series above: --pulse-space-m
   shift          a new topic on white: --pulse-space-xl
   after-surface  the first white section after a band or feature: l below 768px, xl from 768px
   change         a band or feature after white: the surface edge separates, with l of white space
                  before it (xl from 768px), the same step as the band's own padding */
.pulse-join--first { margin-top: 0; }
.pulse-join--continue { margin-top: var(--pulse-space-l); }
.pulse-join--series { margin-top: var(--pulse-space-m); }
.pulse-join--shift { margin-top: var(--pulse-space-xl); }
.pulse-join--after-surface, .pulse-join--change { margin-top: var(--pulse-space-l); }
@media (min-width: 768px) {
  .pulse-join--after-surface, .pulse-join--change { margin-top: var(--pulse-space-xl); }
}

/* ---------- Placement: column (inside an existing container) ----------
   Phones and tablets: a band or feature runs full-bleed by the gutter outdent; the text keeps the
   page's one left edge. From a 58rem page container (the main and rail grid) it is a --radius-lg
   panel, and a panel pads by --pulse-card-pad on every side (DESIGN-SYSTEM.md 6.2, "Card and panel
   padding": the Stamp, the Now panel, the end card), not by the full-bleed band's xl block step,
   which put 64 px above the Stamp's first line at 1200 px and pushed its schedule band below the
   1280 x 800 fold (3.6). A panel carrying the 0.5rem split bar on its top edge (.pulse-split-top)
   adds the bar's height, so the space under the bar stays one card-pad. Placement 'page' needs none
   of this: the section is full width and holds its own .container-eq. */
.pulse-sec--column.pulse-sec--band,
.pulse-sec--column.pulse-sec--feature {
  margin-inline: calc(-1 * var(--pulse-gutter));
  padding-inline: var(--pulse-gutter);
  border-radius: 0;
}
@container pulse-page (min-width: 58rem) {
  .pulse-sec--column.pulse-sec--band,
  .pulse-sec--column.pulse-sec--feature {
    margin-inline: 0;
    padding: var(--pulse-card-pad);
    border-radius: var(--radius-lg);
  }
  .pulse-sec--column.pulse-sec--band.pulse-split-top,
  .pulse-sec--column.pulse-sec--feature.pulse-split-top {
    padding-block-start: calc(var(--pulse-card-pad) + var(--pulse-split-h-frame));
  }
}

/* ---------- Section heads (shift: rule, h2, dek; band: h2 inside the band) ---------- */
.pulse-sec-head { margin-bottom: var(--pulse-space-s); }
.pulse-sec-head--rule::before {
  content: ""; display: block;
  width: 2.5rem; height: 3px;
  margin-bottom: var(--pulse-space-xs);
  background: var(--pulse-label);
}
.pulse-sec-title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-size: var(--pulse-fs-2);
  line-height: var(--leading-tight);
  color: var(--blue-900);
  text-wrap: balance;
}
.pulse-sec-dek {
  margin: var(--pulse-space-xs) 0 0;
  max-width: var(--pulse-measure);
  color: var(--pulse-meta);
  font-size: var(--pulse-text-sm);
  line-height: var(--pulse-leading-dense);
}
@media (min-width: 768px) {
  .pulse-sec-dek { font-size: var(--text-base); }
}

/* ---------- Separation inside a section: space and hairlines before boxes ---------- */
.pulse-rule-top { border-top: 1px solid var(--pulse-rule); padding-top: var(--pulse-space-m); }
.pulse-series > * + * { margin-top: var(--pulse-space-m); padding-top: var(--pulse-space-m); border-top: 1px solid var(--pulse-rule); }

/* ===== part 30-chrome.css ===== */
/* =====================================================================
   EQSIS Pulse: pulse.css, part 30 (chrome). Owner: foundation.
   The masthead and its Pulse bar, the section navigation, the market strip
   with its phone twin, the dock (bottom bar and the article action bar)
   and the standards links in the site footer (DESIGN-SYSTEM.md 3.2 to 3.6,
   components.json chrome.*). Chrome is what media queries may decide, at
   the site's pixel breakpoints (part 00 lists them).
   Stacking order: see the header of src/publishing/render.php.
   ===================================================================== */

/* ---------- Masthead ----------
   DOM order: lockup, section nav, RA line, status. The grid places them:
   below 768   lockup | status / RA                (the nav is the bottom bar's job)
   768-991     lockup | status / RA / nav row
   992-1199    lockup | status / lockup | RA / nav row
   1200 up     the Pulse bar: lockup | nav (Search at its end) / RA | date, updated, status */
.pulse-masthead { background: var(--surface); border-bottom: 1px solid var(--pulse-rule); }
.pulse-mast {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "brand status" "ra ra";
  align-items: center;
  column-gap: var(--sp-4);
  row-gap: var(--sp-1);
  /* A tighter top step keeps the phone masthead near the 100 px DESIGN-SYSTEM.md 3.6 budgets. */
  padding-block: var(--sp-1) var(--sp-2);
}
.pulse-mast-brand { grid-area: brand; min-width: 0; }
.pulse-lockup {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  min-height: var(--pulse-tap);
  margin: 0;
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-size: var(--pulse-fs-1);
  line-height: 1;
  color: var(--ink);
  text-decoration: none;
}
/* The front page's lockup is its h1, not a link: no tap-target height to hold. */
h1.pulse-lockup { min-height: 0; }
a.pulse-lockup:hover .pulse-lockup-name { text-decoration: underline; text-underline-offset: 3px; }
.pulse-logo { display: block; width: auto; height: 1.5rem; }
.pulse-logo--dark { display: none; }
:root[data-theme="dark"] .pulse-logo--light { display: none; }
:root[data-theme="dark"] .pulse-logo--dark { display: block; }
.pulse-lockup-name { color: var(--ink); }
/* The tagline is not in the phone masthead (reviewed exception 15.1-2): it sits in the end card's
   sign-off and every share frame instead. */
.pulse-tagline { display: none; margin: 0; color: var(--pulse-meta); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
.pulse-mast-status {
  grid-area: status;
  margin: 0;
  display: flex; flex-direction: column; align-items: flex-end;
  color: var(--pulse-meta);
  font-size: var(--pulse-text-sm);
  line-height: var(--pulse-leading-dense);
  text-align: end;
  font-variant-numeric: tabular-nums;
}
.pulse-mast-date { display: none; }
.pulse-mast-market { color: var(--ink); font-weight: var(--weight-medium); }
.pulse-mast-ra {
  grid-area: ra;
  margin: 0;
  color: var(--pulse-meta);
  font-size: var(--pulse-text-xs);
  line-height: var(--pulse-leading-dense);
}
.pulse-masthead .pulse-sections { grid-area: nav; }
@media (min-width: 576px) {
  .pulse-tagline { display: block; }
}
@media (min-width: 768px) {
  .pulse-mast { grid-template-areas: "brand status" "ra ra" "nav nav"; }
  .pulse-mast-ra { font-size: var(--pulse-text-sm); }
}
@media (min-width: 992px) {
  .pulse-mast { grid-template-areas: "brand status" "brand ra" "nav nav"; row-gap: 0; }
  .pulse-mast-status { flex-direction: row; flex-wrap: wrap; justify-content: flex-end; gap: 0 var(--sp-3); }
  .pulse-mast-date { display: inline; }
  .pulse-mast-ra { text-align: end; }
  .pulse-lockup { font-size: var(--pulse-fs-2); }
  .pulse-logo { height: 1.75rem; }
}
@media (min-width: 1200px) {
  .pulse-mast {
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-areas: "brand nav" "ra status";
    row-gap: 0;
  }
  .pulse-mast-brand { display: flex; align-items: center; gap: var(--sp-4); }
  .pulse-mast-ra { text-align: start; }
  .pulse-mast-status { justify-content: flex-end; }
}

/* ---------- Section navigation (768px and up; the bottom bar below) ---------- */
.pulse-sections { display: none; }
@media (min-width: 768px) {
  .pulse-sections { display: block; border-top: 1px solid var(--pulse-rule); }
}
@media (min-width: 1200px) {
  .pulse-masthead .pulse-sections { border-top: 0; }
}
.pulse-sections-list {
  display: flex; gap: var(--sp-1);
  margin: 0; padding: 0; list-style: none;
  overflow-x: auto;
}
.pulse-sections-search { margin-inline-start: auto; }
.pulse-sections-link {
  display: inline-flex; align-items: center; gap: var(--sp-1);
  min-height: var(--pulse-tap); padding-inline: var(--sp-3);
  color: var(--ink); font-weight: var(--weight-medium); font-size: var(--pulse-text-base);
  text-decoration: none; white-space: nowrap;
}
.pulse-sections-link:hover { color: var(--blue-700); text-decoration: underline; text-underline-offset: 3px; }
/* The current item: --blue-600 at 600 and a 3px inset underline (the row height never changes),
   with aria-current; never colour alone. */
.pulse-sections-link[aria-current] {
  color: var(--pulse-nav-current); font-weight: var(--weight-semibold);
  box-shadow: inset 0 -3px 0 var(--pulse-nav-current);
}
.pulse-sections-link:focus-visible { outline-offset: -3px; }

/* ---------- Market strip (chrome.market_strip) ----------
   One copy visible per width: .pulse-strip--from-md (the chrome copy) and .pulse-strip--below-md
   (the phone twin, in the Now band or under the breadcrumb). */
.pulse-strip { container: pulse-strip / inline-size; background: var(--surface); }
.pulse-strip--chrome { border-bottom: 1px solid var(--pulse-rule); }
.pulse-strip--from-md { display: none; }
@media (min-width: 768px) {
  .pulse-strip--from-md { display: block; }
  .pulse-strip--below-md { display: none; }
}
.pulse-strip--now-band { background: transparent; }
.pulse-strip-list {
  position: relative; /* keeps the hidden up/down words inside the scroller (1.4.10) */
  display: flex; gap: var(--sp-4);
  margin: 0 calc(-1 * var(--pulse-gutter));
  padding: var(--sp-2) var(--pulse-gutter);
  list-style: none;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: var(--pulse-gutter);
}
.pulse-strip-list:focus-visible { outline-offset: -3px; }
.pulse-strip-tile {
  flex: none;
  min-inline-size: 9.5rem;
  display: grid; grid-template-columns: auto auto; justify-content: start; column-gap: var(--sp-2);
  scroll-snap-align: start;
  font-size: var(--pulse-text-sm);
  line-height: var(--pulse-leading-dense);
  white-space: nowrap;
}
.pulse-strip-name { color: var(--pulse-meta); }
.pulse-strip-level { color: var(--ink); font-weight: var(--weight-semibold); }
.pulse-strip-tile .pulse-chg { grid-column: 1 / -1; }
.pulse-strip-bar {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0 var(--sp-3);
  min-height: var(--pulse-tap);
}
.pulse-strip-asof { margin: 0; color: var(--pulse-meta); font-size: var(--pulse-text-sm); }
.pulse-strip-help > summary {
  display: inline-flex; align-items: center; min-height: var(--pulse-tap);
  color: var(--blue-600); font-size: var(--pulse-text-sm); font-weight: var(--weight-semibold);
  cursor: pointer;
}
.pulse-strip-help > summary:hover { color: var(--blue-700); text-decoration: underline; }
.pulse-strip-help[open] { flex-basis: 100%; }
.pulse-strip-help-list { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: var(--sp-1) var(--sp-3); margin: 0 0 var(--sp-2); font-size: var(--pulse-text-sm); }
.pulse-strip-help-list dt { font-weight: var(--weight-semibold); color: var(--ink); }
.pulse-strip-help-list dd { margin: 0; color: var(--ink); }
.pulse-strip-help p { margin: 0 0 var(--sp-2); font-size: var(--pulse-text-sm); color: var(--ink); max-width: var(--pulse-measure); }
.pulse-strip-pager:not([hidden]) { display: inline-flex; align-items: center; gap: var(--sp-1); margin-inline-start: auto; }
.pulse-strip-page {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: var(--pulse-tap); min-height: var(--pulse-tap);
  border: 1px solid var(--field-border); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--ink);
}
.pulse-strip-page[aria-disabled="true"] { color: var(--pulse-meta); }
.pulse-strip-pos { color: var(--pulse-meta); font-size: var(--pulse-text-sm); font-variant-numeric: tabular-nums; }
.pulse-pause {
  min-height: var(--pulse-tap); min-width: 6rem; padding: 0 var(--sp-3);
  border: 1px solid var(--field-border); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--ink);
  font-family: var(--font-body); font-size: var(--pulse-text-sm); font-weight: var(--weight-semibold);
}
.pulse-pause:hover { background: var(--surface-alt); }
[data-pulse-live][data-paused="true"] .pulse-pause { border-width: 2px; }
/* From a 30rem strip container (the tablet chrome copy, and the phone twin on a large phone) the
   tiles page by WHOLE tiles: no gutter bleed, and each tile a fixed share of the row, three across
   from 30rem and four from 42rem (DESIGN-SYSTEM.md 3.2: four whole tiles on tablet). A half-cut
   last tile read as a layout fault, not a scroller. Inside a tile the text may wrap between words
   (never inside a figure), so a wide face (the readable-font mode) or a long "unchanged" line
   grows the tile instead of spilling into its neighbour. Below 30rem the phone keeps its peek. */
@container pulse-strip (min-width: 30rem) and (max-width: 51.99rem) {
  .pulse-strip-list { margin-inline: 0; padding-inline: 0; scroll-padding-inline: 0; }
  .pulse-strip-tile {
    flex: 0 0 calc((100% - 2 * var(--sp-4)) / 3);
    min-inline-size: 0;
    white-space: normal;
  }
  .pulse-strip-tile .pulse-chg { white-space: normal; }
}
@container pulse-strip (min-width: 42rem) and (max-width: 51.99rem) {
  .pulse-strip-tile { flex-basis: calc((100% - 3 * var(--sp-4)) / 4); }
}
/* From a 52rem strip container: the six tiles in one row, beside the status cluster once the strip
   is at the full 72rem container. Each tile keeps its natural width while the row has room and
   otherwise shrinks, wrapping between words, down to its longest word (never to zero, never cut), so
   the row fits whole at every width, A+ step and font mode; it still scrolls (never the page) in the
   extreme case where even that does not fit, and pulse.js shows the pager only then. */
@container pulse-strip (min-width: 52rem) {
  .pulse-strip-in {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(11rem, 13rem);
    column-gap: var(--sp-5);
    align-items: center;
  }
  .pulse-strip-list { gap: var(--sp-3); margin-inline: 0; padding-inline: 0; scroll-padding-inline: 0; }
  /* Three short lines per tile (name, level, change), so six tiles fit beside the cluster at 72rem. */
  .pulse-strip-tile { flex: 0 1 auto; min-inline-size: auto; grid-template-columns: auto; white-space: normal; }
  .pulse-strip-tile .pulse-chg { grid-column: auto; white-space: normal; }
  .pulse-strip-level { font-size: 1.125rem; }
  .pulse-strip-bar { justify-content: flex-start; }
}
/* Below a 72rem strip (a 1024 px laptop, a wide tablet; the container is the full-bleed strip, so
   72rem is the viewport where .container-eq reaches its full width) six tiles and the cluster do not
   fit side by side: the cluster squeezed into four rows (a 140 px strip) and the sixth tile was cut
   mid-glyph. The cluster takes its own one-line row under the tiles instead, so all six show whole. */
@container pulse-strip (min-width: 52rem) and (max-width: 71.99rem) {
  .pulse-strip-in { grid-template-columns: minmax(0, 1fr); }
}

/* ---------- Dock: the bottom bar and the article action bar (below 768px) ----------
   The bar is 3.5rem only while every label fits on one line. At 320 px, at A+ 125% and 140%, and
   with WCAG 1.4.12 text spacing, "Data Desk" wraps and the bar grows (67 to 84 px), so everything
   that clears the bar reads its MEASURED height, --pulse-dock-h on <html>: the bar's border-box
   height without its safe-area padding, in px, written by pulse.js's foot-of-screen measurer (part
   9, beside --pulse-cover-bottom; its ResizeObserver already watches the bar). The 3.5rem token is
   the fallback until it is written and without JavaScript. Users: the .pulse-dock spacer, the action
   bar's offset, the consent banner's offset, the fallback scroll padding below, and the progress
   row's inset (80-interactive.css). */
.pulse-dock { display: none; }
@media (max-width: 767.98px) {
  .pulse-dock { display: block; height: calc(var(--pulse-dock-h, var(--pulse-bottombar-h)) + env(safe-area-inset-bottom)); }
  .pulse-dock:has(.pulse-actionbar) { height: calc(var(--pulse-dock-h, var(--pulse-bottombar-h)) + var(--pulse-actionbar-h) + env(safe-area-inset-bottom)); }
  .pulse-bottombar {
    position: fixed; inset-inline: 0; bottom: 0; z-index: 1035;
    min-height: var(--pulse-bottombar-h);
    background: var(--surface);
    border-top: 1px solid var(--pulse-rule);
    box-shadow: var(--shadow-raised);
    padding-bottom: env(safe-area-inset-bottom);
  }
  .pulse-bottombar-list { display: flex; margin: 0; padding: 0; list-style: none; }
  .pulse-bottombar-list > li { flex: 1 1 0; min-width: 0; }
  .pulse-bottombar-link {
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.125rem;
    /* 1px less than the bar, whose 1px top border sits inside its border-box height: while every
       label fits on one line the bar is then exactly --pulse-bottombar-h, the fallback the dock
       spacer and the consent-banner offset use until --pulse-dock-h is measured (note above). */
    min-height: calc(var(--pulse-bottombar-h) - 1px); min-width: 48px; padding: var(--sp-1) 0.125rem;
    color: var(--ink-soft); font-size: var(--pulse-text-sm); font-weight: var(--weight-medium);
    line-height: 1.15; text-align: center; text-decoration: none;
  }
  .pulse-bottombar-link svg { flex: none; }
  /* A label that must wrap breaks only between its words ("Data / Desk"), never inside one. */
  .pulse-bottombar-link span { hyphens: manual; overflow-wrap: normal; word-break: normal; }
  .pulse-bottombar-link[aria-current] { color: var(--pulse-nav-current); font-weight: var(--weight-semibold); box-shadow: inset 0 3px 0 var(--pulse-nav-current); }
  .pulse-bottombar-link:focus-visible { outline-offset: -3px; }
  .pulse-actionbar {
    position: fixed; inset-inline: 0; bottom: calc(var(--pulse-dock-h, var(--pulse-bottombar-h)) + env(safe-area-inset-bottom)); z-index: 1036;
    min-height: var(--pulse-actionbar-h);
    background: var(--surface);
    border-top: 1px solid var(--pulse-rule);
  }
  /* The site's consent banner (z-index 1050) sits above the dock, never under it. */
  body.pulse .consent-banner { bottom: calc(var(--pulse-dock-h, var(--pulse-bottombar-h)) + env(safe-area-inset-bottom)); }
  body.pulse:has(.pulse-actionbar) .consent-banner { bottom: calc(var(--pulse-dock-h, var(--pulse-bottombar-h)) + var(--pulse-actionbar-h) + env(safe-area-inset-bottom)); }
  /* Focus never lands under the fixed bars (WCAG 2.4.11, and the design's "the bottom bar never
     hides focus" at 2.4.12). With JavaScript, pulse.js measures everything covering the foot of the
     screen (consent banner, bars, the stuck progress row) into --pulse-cover-bottom and marks <html>
     .pulse-js-cover, and part 80 pads by that. These rules are the fallback without it: the bars'
     height plus a margin, and while the edition's sticky progress row is there, its reserved height
     too, so a focused "Read the full story" or Share never lands half under it. Scoped with
     :not(.pulse-js-cover) so they never outrank the measured value. */
  html:not(.pulse-js-cover) { scroll-padding-bottom: calc(var(--pulse-dock-h, var(--pulse-bottombar-h)) + var(--sp-5)); }
  html:not(.pulse-js-cover):has(.pulse-actionbar) { scroll-padding-bottom: calc(var(--pulse-dock-h, var(--pulse-bottombar-h)) + var(--pulse-actionbar-h) + var(--sp-5)); }
  html:not(.pulse-js-cover):has(.pulse-progress:not(.pulse-js-off)) { scroll-padding-bottom: calc(var(--pulse-dock-h, var(--pulse-bottombar-h)) + var(--pulse-reserve-progress) + var(--sp-5)); }
}
/* Very short viewports (landscape phones, 200-400% zoom): the bars return to the flow, as the site's
   sticky header does at the same height (1.4.10, 2.4.11). */
@media (max-width: 767.98px) and (max-height: 26rem) {
  .pulse-dock, .pulse-dock:has(.pulse-actionbar) { height: auto; }
  .pulse-bottombar, .pulse-actionbar { position: static; }
  body.pulse .consent-banner, body.pulse:has(.pulse-actionbar) .consent-banner { bottom: 0; }
  html:not(.pulse-js-cover), html:not(.pulse-js-cover):has(.pulse-actionbar), html:not(.pulse-js-cover):has(.pulse-progress:not(.pulse-js-off)) { scroll-padding-bottom: 5rem; }
}

/* ---------- Footer: Pulse standards links (inside .site-footer, above the SEBI block) ---------- */
.pulse-standards { padding-block: var(--sp-4) var(--sp-2); }
.pulse-standards-h { margin-bottom: var(--sp-1); }
.pulse-standards-list { display: flex; flex-wrap: wrap; gap: 0 var(--sp-5); margin: 0; padding: 0; list-style: none; }
.pulse-standards-list a { display: inline-flex; align-items: center; justify-content: center; min-height: 48px; min-width: 48px; }

@media print {
  .pulse-dock, .pulse-sections, .pulse-pause, .pulse-strip-pager { display: none !important; }
}

/* ===== part 40-ig.css ===== */
/* =====================================================================
   EQSIS Pulse: pulse.css, part 40 (infographics). Owner: package A
   (docs/design/BUILD-V2.md). The exhibit system of
   docs/design/INFOGRAPHICS.md: the .pulse-ex anatomy, the HTML-row forms
   (.pulse-ig-*), the SVG twins switched by the pulse-ex container (27.5rem,
   42.5rem, 60rem; compact first), the limits line (.pulse-limits*), and the
   M1 chart rules kept for src/publishing/charts.php's legacy specs until
   their callers move (minus min-width: 30rem and the sideways scroller,
   both retired, DESIGN-SYSTEM.md 15.2).
   Colour only through the chart roles of part 00 (house.colour_roles);
   never a literal colour, never a price colour on a non-price mark (C1, C2),
   never EQ green or a category colour in a chart (C4, C5).
   ===================================================================== */

/* ---------- The exhibit: open, not boxed (INFOGRAPHICS 3.9) ----------
   A hairline above the caption and planned space around it; no border, no tint, no inner padding.
   The figure is the named size container; its parts read their own width, not the device's. */
.pulse-ex {
  container: pulse-ex / inline-size;
  --pulse-ig-bg: var(--surface);
  margin: var(--pulse-space-l) 0;
  padding-top: var(--sp-3);
  border-top: 1px solid var(--pulse-rule);
  color: var(--ink);
  line-height: var(--pulse-leading-dense);
}
/* Inside the site's .container-text (article pages), its p and li sizes and bottom margins would
   win over the exhibit's class rules; this guard has the same weight and comes later, and every
   text rule below names its element, so the exhibit keeps its own type scale. */
.pulse-ex :is(p, li, dd, dt, ol, ul) { font-size: inherit; margin-bottom: 0; }
.pulse-sec--band .pulse-ex { --pulse-ig-bg: var(--surface-alt); }
.pulse-ex--mini, .pulse-ex--frame { margin: 0; padding-top: 0; border-top: 0; }
/* Today's number hosts its figure: the host's head names it and its foot keeps the one hairline,
   so the exhibit adds no rule, margin or caption gap of its own (the caption is visually hidden). */
.pulse-ex--host-todays-number { margin: 0; padding-top: 0; border-top: 0; }
.pulse-ex--host-todays-number .pulse-ex-body > :first-child { margin-top: 0; }
.pulse-ex--host-todays-number p.pulse-ig-kf-rec { padding-top: 0; border-top: 0; }

.pulse-ex-cap { display: block; max-width: var(--pulse-measure); margin: 0; }
.pulse-ex-title {
  display: block;
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--pulse-text-card);
  line-height: var(--pulse-leading-card);
  color: var(--ink);
  text-wrap: balance;
}
.pulse-ex-summary {
  display: block;
  margin-top: var(--sp-1);
  font-size: var(--pulse-text-base);
  line-height: var(--pulse-leading-dense);
  color: var(--ink);
  text-wrap: pretty;
}
.pulse-ex-meta {
  display: block;
  margin-top: var(--sp-1);
  font-size: var(--pulse-text-xs);
  font-weight: var(--weight-medium);
  line-height: var(--pulse-leading-dense);
  color: var(--pulse-meta);
}
.pulse-ex-meta .pulse-tag { margin-inline-start: var(--sp-1); }
.pulse-ex-meta .pulse-tag:first-child { margin-inline-start: 0; }
.pulse-ex-body > * { margin-top: var(--sp-3); }
.pulse-ex-body > :first-child { margin-top: var(--sp-3); }
.pulse-ex-plot { position: relative; }
.pulse-ex--mini .pulse-ex-plot, .pulse-ex--frame .pulse-ex-plot { margin: 0; }

ol.pulse-ex-notes {
  max-width: var(--pulse-measure);
  margin-bottom: 0;
  padding-inline-start: 1.5em;
  font-size: var(--pulse-text-sm);
  line-height: var(--pulse-leading-dense);
}
ol.pulse-ex-notes > li { margin: 0 0 var(--sp-1); }
ol.pulse-ex-notes > li::marker { font-family: var(--font-display); font-weight: var(--weight-semibold); color: var(--pulse-label); }

/* What it means, What it does not tell you: run-in labels, one cell each. */
.pulse-ex-words { display: grid; gap: var(--sp-2); max-width: var(--pulse-measure); }
.pulse-ex-words > p { margin: 0; font-size: var(--pulse-text-base); line-height: var(--pulse-leading-dense); }
.pulse-ex-words .pulse-unit-label { margin-inline-end: var(--sp-1); }
.pulse-ex-owner a { display: inline-flex; align-items: center; min-height: var(--pulse-tap); font-weight: var(--weight-semibold); }
p.pulse-ex-source { margin-bottom: 0; max-width: var(--pulse-measure); font-size: var(--pulse-text-xs); line-height: var(--pulse-leading-dense); color: var(--pulse-meta); }
.pulse-ex-body > p.pulse-ex-source { margin-top: var(--sp-2); }
p.pulse-ex-more { margin: var(--sp-1) 0 0; }
.pulse-ex-more a { display: inline-flex; align-items: center; min-height: var(--pulse-tap); font-weight: var(--weight-semibold); }

/* The table toggle: a real <details>, 48 px, "Show the figures as a table". */
.pulse-ex-body > .pulse-ex-data { margin-top: var(--sp-2); }
.pulse-ex-data > summary {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: var(--pulse-tap);
  color: var(--pulse-label);
  font-size: var(--pulse-text-sm);
  font-weight: var(--weight-semibold);
  cursor: pointer;
  list-style: none;
}
.pulse-ex-data > summary::-webkit-details-marker { display: none; }
.pulse-ex-data > summary::before {
  content: "";
  flex: none;
  width: 0.45em;
  height: 0.45em;
  margin-inline: 0.15em 0.1em;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(-45deg);
}
.pulse-ex-data[open] > summary::before { transform: rotate(45deg) translate(-0.1em, -0.1em); }
.pulse-ex-data > summary:hover { text-decoration: underline; text-underline-offset: 3px; }
.pulse-ex-table-wrap { margin-top: var(--sp-1); }
/* The details table that stands in only where rows give way to twins: from a 27.5rem exhibit
   (compact period rows) or from 42.5rem (flows and slope rows, which hold until the wide twin). */
.pulse-ex-data--wide, .pulse-ex-data--from-wide { display: none; }

.pulse-ex-share { margin-top: var(--sp-2); }

/* ---------- Tables: the data table and the visible row tables ---------- */
.pulse-ig-table {
  width: 100%;
  margin: 0;
  border-collapse: collapse;
  font-size: var(--pulse-text-sm);
  line-height: var(--pulse-leading-dense);
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  overflow-wrap: anywhere;
}
.pulse-ig-table caption {
  caption-side: top;
  padding: 0 0 var(--sp-1);
  text-align: start;
  font-size: var(--pulse-text-xs);
  color: var(--pulse-meta);
}
.pulse-ig-table th, .pulse-ig-table td {
  padding: var(--sp-2) var(--sp-2) var(--sp-2) 0;
  text-align: start;
  vertical-align: top;
  font-weight: var(--weight-body);
}
.pulse-ig-table th:last-child, .pulse-ig-table td:last-child { padding-inline-end: 0; }
.pulse-ig-table thead th { font-size: var(--pulse-text-xs); font-weight: var(--weight-medium); color: var(--pulse-meta); border-bottom: 1px solid var(--pulse-rule); }
.pulse-ig-table th[scope="row"], .pulse-ig-table th[scope="rowgroup"] { font-weight: var(--weight-medium); }
.pulse-ig-table tfoot th, .pulse-ig-table tfoot td { border-top: 1px solid var(--pulse-rule); font-weight: var(--weight-semibold); }
.pulse-ig-datatable tbody tr + tr > * { border-top: 1px solid var(--pulse-rule); }
.pulse-ig-table .pulse-ig-num { text-align: end; }

/* ---------- Row forms (method A): label left, the bar and its value in the value cell ----------
   One line per row from the phone up (INFOGRAPHICS 5.4: period rows 32 px, compared items 36 to
   40 px): the bar's track in column 1, the value just past the track's end in column 2. Column 2
   has one width for the whole table (.pulse-ig-vn-N, set by the renderer from the longest value in
   ch of the value's own face), so every track in a table has the same length on screen (H14). A
   table whose values are too long to sit beside a bar on a compact exhibit (pulse-ig-vstack:
   flows in words, dumbbell pairs) stacks the value over a full-width bar there instead. */
/* Automatic layout: Chromium's fixed layout ignored the label cell's width here and split the row
   50/50 (measured 13 Oct 2026), so the label column's width below is what the reader gets. The
   cell's own grid has no min-content of note (its track is minmax(0, 1fr)), so the columns hold. */
.pulse-ig-bars { table-layout: auto; }
.pulse-ig-bars .pulse-ig-rlabel {
  width: 45%;
  padding: 0.375rem var(--sp-3) 0.375rem 0;
  vertical-align: middle;
  font-size: var(--pulse-text-sm);
  font-weight: var(--weight-medium);
}
.pulse-ig-bars .pulse-ig-rval { padding: 0.375rem 0; vertical-align: middle; }
/* Period rows: a year or a month is short, so its label takes a fixed narrow column and the
   bars get the room (the ten-year shape the title promises). */
.pulse-ig-pb-rows .pulse-ig-rlabel { width: 5.5rem; }
.pulse-ig-pb-rows--short .pulse-ig-rlabel { width: 3.5rem; }
.pulse-ig-pb-rows--short-note .pulse-ig-rlabel { width: 6rem; }
.pulse-ig-pb-rows .pulse-ig-rlabel, .pulse-ig-pb-rows .pulse-ig-rval { padding-block: 0.25rem; }
.pulse-ig-cell {
  display: grid;
  grid-template-columns: minmax(0, 1fr) calc(var(--pulse-ig-vn, 8) * 1ch);
  column-gap: var(--sp-2);
  align-items: center;
  font-size: var(--pulse-text-base);
  font-weight: var(--weight-semibold);
}
.pulse-ig-cell > .pulse-ig-bar, .pulse-ig-cell > .pulse-ig-track--db { grid-column: 1; grid-row: 1; align-self: center; }
.pulse-ig-cell > .pulse-ig-v { grid-column: 2; grid-row: 1; justify-self: start; text-align: start; }
.pulse-ig-vstack .pulse-ig-cell { grid-template-columns: minmax(0, 1fr); row-gap: var(--sp-1); }
.pulse-ig-vstack .pulse-ig-cell > .pulse-ig-v { grid-column: 1; grid-row: 1; justify-self: end; text-align: end; }
.pulse-ig-vstack .pulse-ig-cell > .pulse-ig-bar, .pulse-ig-vstack .pulse-ig-cell > .pulse-ig-track--db { grid-column: 1; grid-row: 2; }
.pulse-ig-vn-4 { --pulse-ig-vn: 4; }
.pulse-ig-vn-5 { --pulse-ig-vn: 5; }
.pulse-ig-vn-6 { --pulse-ig-vn: 6; }
.pulse-ig-vn-7 { --pulse-ig-vn: 7; }
.pulse-ig-vn-8 { --pulse-ig-vn: 8; }
.pulse-ig-vn-9 { --pulse-ig-vn: 9; }
.pulse-ig-vn-10 { --pulse-ig-vn: 10; }
.pulse-ig-vn-11 { --pulse-ig-vn: 11; }
.pulse-ig-vn-12 { --pulse-ig-vn: 12; }
.pulse-ig-vn-14 { --pulse-ig-vn: 14; }
.pulse-ig-vn-16 { --pulse-ig-vn: 16; }
.pulse-ig-vn-18 { --pulse-ig-vn: 18; }
.pulse-ig-vn-20 { --pulse-ig-vn: 20; }
.pulse-ig-vn-22 { --pulse-ig-vn: 22; }
.pulse-ig-vn-24 { --pulse-ig-vn: 24; }
.pulse-ig-v { font-size: inherit; font-weight: var(--weight-semibold); font-variant-numeric: tabular-nums; }
.pulse-ig-v .pulse-chg { font-weight: var(--weight-semibold); }
.pulse-ig-ref-v { display: block; font-size: var(--pulse-text-xs); font-weight: var(--weight-medium); color: var(--pulse-meta); }
.pulse-ig-bar { display: block; width: 100%; height: 0.75rem; overflow: visible; }
.pulse-ig-row.is-hl .pulse-ig-rlabel, .pulse-ig-row.is-hl .pulse-ig-v { font-weight: var(--weight-semibold); }
.pulse-ig-row.is-hl .pulse-ig-rlabel::before {
  content: "";
  display: inline-block;
  width: 0.625rem;
  height: 0.625rem;
  margin-inline-end: var(--sp-2);
  border: 2px solid var(--pulse-chart-main);
  border-radius: 50%;
  vertical-align: 0.05em;
}
.pulse-ig-gaprow th { padding: var(--sp-1) 0; font-size: var(--pulse-text-xs); color: var(--pulse-meta); text-align: center; border-block: 1px dashed var(--pulse-rule); }
.pulse-ig-note-tag {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.25rem;
  height: 1.25rem;
  margin-inline-start: var(--sp-1);
  border: 1.5px solid var(--pulse-chart-ref);
  border-radius: 50%;
  font-size: var(--pulse-text-xs);
  font-weight: var(--weight-semibold);
  line-height: 1;
  vertical-align: 0.1em;
}
.pulse-ig-runit { display: block; font-size: var(--pulse-text-xs); font-weight: var(--weight-body); color: var(--pulse-meta); }

/* Results card: the row's own two bars, current solid over prior outlined. On a phone one block per
   measure; the prior and change columns join from 27.5rem (display: none keeps a cell out of the
   accessibility tree, so the figures are never read twice). */
.pulse-ig-rc .pulse-ig-rlabel { width: 36%; vertical-align: top; }
.pulse-ig-rc td { vertical-align: top; }
.pulse-ig-rc .pulse-ig-rc-col { display: none; }
.pulse-ig-rc-v { font-weight: var(--weight-semibold); font-size: var(--pulse-text-base); }
.pulse-ig-rc .pulse-ig-bar--pair { height: 1.125rem; margin-top: var(--sp-1); }
.pulse-ig-rc .pulse-chg { white-space: normal; }

/* Flow bars: the session as a row group, FII then DII. */
.pulse-ig-fb .pulse-ig-fb-day { width: 4rem; padding-top: var(--sp-2); vertical-align: top; font-size: var(--pulse-text-sm); }
.pulse-ig-fb .pulse-ig-fb-who { width: 2.75rem; vertical-align: middle; font-size: var(--pulse-text-sm); font-weight: var(--weight-semibold); }
.pulse-ig-fb .pulse-ig-row--first > * { border-top: 1px solid var(--pulse-rule); }
.pulse-ig-fb tbody tr:first-child > * { border-top: 0; }
p.pulse-ig-fb-mtd { margin: var(--sp-2) 0 0; font-size: var(--pulse-text-sm); color: var(--ink); }

/* Dumbbell rows (ig.slope). */
.pulse-ig-db .pulse-ig-v { font-weight: var(--weight-medium); }
.pulse-ig-db-chg { display: block; }
.pulse-ig-v .pulse-chg { white-space: normal; }
p.pulse-ig-key { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-1) var(--sp-2); margin: 0; font-size: var(--pulse-text-xs); color: var(--pulse-meta); }
.pulse-ig-key-scale { margin-inline-start: var(--sp-2); font-variant-numeric: tabular-nums; }

/* ---------- Marks: classes resolve to the chart roles; attributes stay currentColor or none ---------- */
.pulse-ig-m--main, .pulse-ig-col, .pulse-ig-col--fii { fill: var(--pulse-chart-main); }
.pulse-ig-m--main-out, .pulse-ig-col--out { fill: none; stroke: var(--pulse-chart-main); }
.pulse-ig-m--compare { fill: var(--pulse-chart-compare); }
.pulse-ig-m--compare-out { fill: none; stroke: var(--pulse-chart-compare); }
.pulse-ig-m--ref-out, .pulse-ig-col--dii { fill: none; stroke: var(--pulse-chart-ref); }
.pulse-ig-m--quiet, .pulse-ig-col--quiet { fill: var(--pulse-chart-quiet); }
.pulse-ig-m--quiet-out, .pulse-ig-m--quiet-dash { fill: none; stroke: var(--pulse-chart-quiet); }
.pulse-ig-m--track { fill: var(--pulse-chart-track); }
.pulse-ig-m--up, .pulse-ig-col--up { fill: var(--pulse-up); }
.pulse-ig-m--down, .pulse-ig-col--down { fill: var(--pulse-down); }
.pulse-ig-m--down-out { fill: none; stroke: var(--pulse-down); }
.pulse-ig-zero, .pulse-ig-reftick, .pulse-ig-tick, .pulse-ig-leader, .pulse-ig-brk { stroke: var(--pulse-chart-ref); }
.pulse-ig-gap, .pulse-ig-halo-line { stroke: var(--pulse-ig-bg); }
.pulse-ig-halo { fill: var(--pulse-ig-bg); }
.pulse-ig-grid { stroke: var(--pulse-chart-grid); }
.pulse-ig-track-line, .pulse-ig-conn--quiet { stroke: var(--pulse-chart-quiet); }
.pulse-ig-dbaxis { stroke: var(--pulse-chart-grid); }
.pulse-ig-edge { stroke: var(--pulse-chart-quiet); }
.pulse-ig-conn { stroke: var(--pulse-chart-main); }
.pulse-ig-line-main { stroke: var(--pulse-chart-main); fill: none; }
.pulse-ig-line-cmp { stroke: var(--pulse-chart-compare); fill: none; }
.pulse-ig-ref, .pulse-ig-band-edge { stroke: var(--pulse-chart-compare); }
.pulse-ig-band, .pulse-ig-quad { fill: var(--pulse-chart-band); }
.pulse-ig-dot { fill: var(--pulse-chart-main); }
.pulse-ig-dot--cmp { fill: var(--pulse-chart-compare); }
.pulse-ig-dot--ring { fill: var(--pulse-ig-bg); stroke: var(--pulse-chart-compare); }
.pulse-ig-dot--quiet { fill: none; stroke: var(--pulse-chart-ref); }
.pulse-ig-mark { fill: var(--pulse-ig-bg); stroke: var(--pulse-chart-ref); }

/* Swatches: the same shape as the mark they name (solid, outlined, dashed), never colour alone. */
.pulse-ig-sw {
  display: inline-block;
  flex: none;
  width: 0.875rem;
  height: 0.875rem;
  margin-inline-end: var(--sp-2);
  border-radius: 2px;
  vertical-align: -0.1em;
}
.pulse-ig-sw--main { background: var(--pulse-chart-main); }
.pulse-ig-sw--compare { background: var(--pulse-chart-compare); }
.pulse-ig-sw--quiet { background: var(--pulse-chart-quiet); }
.pulse-ig-sw--up { background: var(--pulse-up); }
.pulse-ig-sw--down-out { border: 2px solid var(--pulse-down); }
.pulse-ig-sw--main-out { border: 2px solid var(--pulse-chart-main); }
.pulse-ig-sw--ref-out { border: 2px solid var(--pulse-chart-ref); }
.pulse-ig-sw--compare-out { border: 1.5px solid var(--pulse-chart-compare); }
.pulse-ig-sw--quiet-out { border: 2px solid var(--pulse-chart-quiet); }
.pulse-ig-sw--quiet-dash { border: 2px dashed var(--pulse-chart-quiet); }
.pulse-ig-sw--tick { width: 3px; border-radius: 0; background: var(--pulse-chart-ref); }
.pulse-ig-sw--dot { border-radius: 50%; background: var(--pulse-chart-main); }
.pulse-ig-sw--dot-out { border-radius: 50%; border: 2px solid var(--pulse-chart-compare); }

/* ---------- SVG twins (method B): one shown, by the exhibit's own width ---------- */
.pulse-ig-svg { display: block; width: 100%; height: auto; overflow: visible; font-family: var(--font-body); font-variant-numeric: tabular-nums; }
.pulse-ig-t { fill: var(--ink); }
.pulse-ig-t--tick { fill: var(--pulse-meta); font-weight: var(--weight-body); }
.pulse-ig-t--label { font-weight: var(--weight-medium); }
.pulse-ig-t--value, .pulse-ig-t--note_letter, .pulse-ig-t--hl { font-weight: var(--weight-semibold); }
.pulse-ig-halo-t { paint-order: stroke; stroke: var(--pulse-ig-bg); stroke-width: 4px; stroke-linejoin: round; }
.pulse-ig-zone-t { fill: var(--pulse-meta); }

.pulse-ex-twin { display: none; }
.pulse-ex-twin--c { display: block; max-width: 27.625rem; }
.pulse-ex-twin--m { max-width: 42.25rem; }
.pulse-ex-twin--w { max-width: 58.5rem; }
.pulse-ex-twin--b { max-width: 89.375rem; }
/* Rows that stand in for twins below a width. */
.pulse-ex-rows--compact, .pulse-ex-rows--to-wide { display: block; }

/* Small multiples: one shared scale, a column of panels on a phone. */
.pulse-ig-sm { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--pulse-space-s) var(--pulse-space-m); }
.pulse-ig-sm-panel { min-width: 0; }
p.pulse-ig-sm-name { margin: 0 0 var(--sp-1); font-size: var(--pulse-text-sm); font-weight: var(--weight-semibold); }
.pulse-ig-sm-end { margin-inline-start: var(--sp-1); font-weight: var(--weight-semibold); color: var(--pulse-meta); }
.pulse-ig-sm .pulse-ex-twin--m, .pulse-ig-sm .pulse-ex-twin--b { max-width: 21rem; }
.pulse-ig-sm .pulse-ex-twin--w { max-width: 29.25rem; }

/* ---------- ig.key_figure: the figure, its anchor and a micro picture of the anchor ---------- */
.pulse-ig-kf { display: grid; gap: var(--sp-1); }
.pulse-ig-kf > p { margin: 0; }
p.pulse-ig-kf-label { font-size: var(--pulse-text-sm); font-weight: var(--weight-medium); color: var(--pulse-meta); line-height: var(--pulse-leading-dense); }
p.pulse-ig-kf-fig { line-height: var(--pulse-leading-figure); }
.pulse-ig-kf-num {
  display: block;
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-size: var(--pulse-fs-figure);
  font-size: min(var(--pulse-fs-figure), 20cqi);
  line-height: var(--pulse-leading-figure);
  font-variant-numeric: tabular-nums;
  color: var(--pulse-figure-ink);
}
.pulse-ig-kf-unit {
  display: block;
  margin-top: var(--sp-1);
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--pulse-fs-1);
  line-height: var(--pulse-leading-card);
  color: var(--ink);
}
.pulse-ig-kf--mini .pulse-ig-kf-num { font-size: var(--pulse-text-figure-sm); }
.pulse-ig-kf--mini .pulse-ig-kf-unit { font-size: var(--pulse-text-base); }
p.pulse-ig-kf-anchor { margin-top: var(--sp-1); font-size: var(--pulse-text-base); line-height: var(--pulse-leading-dense); }
/* The anchor sentence under a split micro keys the reference tick with the tick's own swatch. */
p.pulse-ig-kf-anchor--tick { max-width: var(--pulse-measure); }
.pulse-ig-kf-anchor--tick .pulse-ig-sw--tick { height: 1em; vertical-align: -0.15em; }
.pulse-ig-kf-micro, .pulse-ig-fr-micro {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--sp-1) var(--sp-2);
  align-items: center;
  max-width: 24rem;
  margin-top: var(--sp-2);
}
.pulse-ig-mlbl { font-size: var(--pulse-text-xs); color: var(--pulse-meta); }
.pulse-ig-bar--micro { height: 0.625rem; }
.pulse-ig-track, .pulse-ig-split, .pulse-ig-spark, .pulse-ig-mkey { grid-column: 1 / -1; }
.pulse-ig-track { display: block; width: 100%; height: 1.5rem; overflow: visible; }
.pulse-ig-split { display: block; width: 100%; height: 1.5rem; overflow: visible; }
.pulse-ig-spark { display: block; width: 100%; height: 1.5rem; }
.pulse-ig-mkey { font-size: var(--pulse-text-xs); color: var(--pulse-meta); }
p.pulse-ig-kf-spark, p.pulse-ig-kf-rec { font-size: var(--pulse-text-sm); color: var(--ink); }
p.pulse-ig-kf-rec { padding-top: var(--sp-2); border-top: 1px solid var(--pulse-rule); }

/* The label list under a split micro: every part with its word and direction mark. */
ul.pulse-ig-list { display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-4); margin: var(--sp-2) 0 0; padding: 0; list-style: none; font-size: var(--pulse-text-sm); }
li.pulse-ig-li { display: inline-flex; align-items: baseline; gap: var(--sp-1); margin: 0; }
.pulse-ig-li .pulse-ig-sw { align-self: center; margin-inline-end: 0; }
.pulse-ig-li-v { font-weight: var(--weight-semibold); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ---------- ig.figure_row: two to four unlike figures, each with its own comparison ---------- */
.pulse-ig-fr { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--pulse-space-s) var(--pulse-space-m); margin: 0; }
.pulse-ig-fr--pairs { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@container pulse-ex (min-width: 27.5rem) {
  .pulse-ig-fr { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.pulse-ig-fr-cell { min-width: 0; margin: 0; }
.pulse-ig-fr-cell dd { margin: 0; }
.pulse-ig-fr-label { font-size: var(--pulse-text-sm); font-weight: var(--weight-medium); color: var(--pulse-meta); }
dd.pulse-ig-fr-val {
  margin-top: var(--sp-1);
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-size: var(--pulse-text-figure-sm);
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
  color: var(--pulse-figure-ink);
}
.pulse-ig-fr-val .pulse-chg { font-weight: var(--weight-display); white-space: normal; }
.pulse-ig-fig-num { white-space: nowrap; }
.pulse-ig-fig-unit { display: block; margin-top: 2px; font-family: var(--font-body); font-weight: var(--weight-semibold); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); color: var(--ink); }
.pulse-ig-fr-word { font-size: var(--pulse-text-sm); font-weight: var(--weight-semibold); }
dd.pulse-ig-fr-anchor { margin-top: 2px; font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); color: var(--pulse-meta); }
.pulse-ig-fr-cell--pattern .pulse-ig-fr-val { font-size: var(--pulse-fs-1); }
.pulse-ex--mini .pulse-ig-fr-val { font-size: var(--pulse-text-card); }

/* ---------- ig.split_bar and ig.unit_grid ---------- */
.pulse-ig-sb + .pulse-ig-sb { margin-top: var(--pulse-space-s); }
p.pulse-ig-sb-label { margin: 0 0 var(--sp-1); font-size: var(--pulse-text-sm); font-weight: var(--weight-semibold); }
.pulse-ig-sb-bar { margin-bottom: var(--sp-2); }
.pulse-ig-split-table th[scope="row"] { font-weight: var(--weight-body); }
.pulse-ig-split-table td { font-weight: var(--weight-semibold); }
.pulse-ig-split-table tbody tr + tr > * { border-top: 0; }
.pulse-ig-split-table th, .pulse-ig-split-table td { padding-block: var(--sp-1); }
p.pulse-ig-ug-big { margin: 0 0 var(--sp-2); font-family: var(--font-display); font-weight: var(--weight-semibold); font-size: var(--pulse-fs-1); line-height: var(--pulse-leading-card); }
.pulse-ig-ug-k { font-weight: var(--weight-display); font-size: var(--pulse-text-figure-sm); color: var(--pulse-figure-ink); }
.pulse-ig-units { display: block; width: 100%; max-width: 16.25rem; height: auto; margin-bottom: var(--sp-2); }
.pulse-ig-units--500 { max-width: 18.75rem; }

/* ---------- ig.range_position and ig.valuation_band: a dot on a track, the values in a table ---------- */
.pulse-ig-rp + .pulse-ig-rp { margin-top: var(--pulse-space-s); }
p.pulse-ig-rp-label { margin: 0 0 var(--sp-1); font-size: var(--pulse-text-sm); font-weight: var(--weight-semibold); }
.pulse-ig-track--range { height: 3.5rem; max-width: 40rem; }
.pulse-ig-track--band { height: 4.75rem; max-width: 40rem; }
.pulse-ig-track--db { height: 1.25rem; }
.pulse-ig-tlabel { fill: var(--ink); font-size: var(--pulse-text-sm); font-weight: var(--weight-semibold); font-variant-numeric: tabular-nums; }
.pulse-ig-tick-t { fill: var(--pulse-meta); font-size: var(--pulse-text-xs); font-variant-numeric: tabular-nums; }
.pulse-ig-rp + .pulse-ig-table, .pulse-ig-rp + .pulse-ig-split-table { margin-top: var(--sp-2); }

/* ---------- ig.oi_quadrant on compact: four labelled lists in a fixed order ---------- */
.pulse-ig-oi { display: grid; gap: var(--sp-3); }
.pulse-ig-oi-group > p { margin: 0; }
p.pulse-ig-oi-head { font-family: var(--font-display); font-weight: var(--weight-semibold); font-size: var(--pulse-text-label); }
.pulse-ig-oi-sub { margin-inline-start: var(--sp-1); font-family: var(--font-body); font-weight: var(--weight-body); font-size: var(--pulse-text-xs); color: var(--pulse-meta); }
ul.pulse-ig-oi-list { margin: var(--sp-1) 0 0; padding: 0; list-style: none; font-size: var(--pulse-text-sm); }
ul.pulse-ig-oi-list > li { margin: 0 0 var(--sp-1); }
.pulse-ig-oi-name { font-weight: var(--weight-semibold); }
.pulse-ig-oi-vals { display: block; }
p.pulse-ig-oi-none { font-size: var(--pulse-text-xs); color: var(--pulse-meta); }

/* ---------- "How it works" diagrams: the --surface-alt panel marks the change of mode ----------
   Full-bleed on phones (padding equal to the gutter, so the left edge never moves); an outdented
   --radius-lg panel once the page has its main and rail grid; no second tint on a band. */
.pulse-ex-plot--diagram {
  --pulse-ig-bg: var(--surface-alt);
  margin-inline: calc(-1 * var(--pulse-gutter));
  padding: var(--pulse-space-s) var(--pulse-gutter);
  background: var(--surface-alt);
}
@container pulse-page (min-width: 58rem) {
  .pulse-ex-plot--diagram { margin-inline: 0; padding: var(--pulse-card-pad); border-radius: var(--radius-lg); }
}
.pulse-sec--band .pulse-ex-plot--diagram { margin-inline: 0; padding-inline: 0; background: none; }
.pulse-ex--mini .pulse-ex-plot--diagram, .pulse-ex--frame .pulse-ex-plot--diagram { margin-inline: 0; padding: 0; background: none; }

/* ig.transmission_map: stages as an ordered list, the mechanism and its certainty on each link. */
ol.pulse-ig-tm { display: grid; margin: 0; padding: 0; list-style: none; }
li.pulse-ig-tm-stage { margin: 0; }
p.pulse-ig-tm-name { margin: 0 0 var(--sp-1); font-family: var(--font-display); font-weight: var(--weight-semibold); font-size: var(--pulse-text-label); color: var(--ink); }
ul.pulse-ig-tm-items { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin: 0; padding: 0; list-style: none; }
li.pulse-ig-tm-item {
  margin: 0;
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--pulse-chart-quiet);
  border-radius: var(--radius-sm);
  background: var(--surface);
  font-weight: var(--weight-medium);
}
.pulse-ig-tm-item a { display: inline-flex; align-items: center; min-height: var(--pulse-tap-dense); margin-block: calc(-1 * var(--sp-2)); }
p.pulse-ig-tm-link { display: flex; align-items: center; gap: var(--sp-3); margin: var(--sp-1) 0; padding-inline-start: var(--sp-4); font-size: var(--pulse-text-sm); }
.pulse-ig-tm-arrow { position: relative; flex: none; width: 2px; height: 2.25rem; background: var(--pulse-chart-compare); }
.pulse-ig-tm-arrow::after {
  content: "";
  position: absolute;
  left: -4px;
  bottom: -2px;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 7px solid var(--pulse-chart-compare);
}
.pulse-ig-tm-cert { color: var(--pulse-meta); }

/* ig.process_steps: the list's own numerals, large, beside the actor and the action. */
ol.pulse-ig-ps { display: grid; gap: var(--pulse-space-s); margin: 0; padding-inline-start: 2.75rem; list-style: decimal; }
li.pulse-ig-ps-step { margin: 0; padding-inline-start: var(--sp-1); }
.pulse-ig-ps-step::marker { font-family: var(--font-display); font-weight: var(--weight-display); font-size: var(--pulse-text-section); color: var(--pulse-chart-main); }
.pulse-ig-ps-step > p { margin: 0; }
p.pulse-ig-ps-actor { font-weight: var(--weight-semibold); }
.pulse-ig-ps-chip { margin-inline-start: var(--sp-2); }

/* ig.timeline and ig.calendar_strip: dated rows, done filled and scheduled outlined, with the word. */
ol.pulse-ig-tl { position: relative; margin: 0; padding: 0; list-style: none; }
li.pulse-ig-tl-ev { position: relative; margin: 0; padding: 0 0 var(--pulse-space-s) calc(1rem + var(--sp-3)); }
.pulse-ig-tl-ev::before { content: ""; position: absolute; left: calc(0.5rem - 1px); top: 1.25rem; bottom: 0.125rem; width: 2px; background: var(--pulse-chart-quiet); }
.pulse-ig-tl-ev:last-child::before { display: none; }
.pulse-ig-tl-dot { position: absolute; left: 0; top: 0.25rem; width: 1rem; height: 1rem; border: 2px solid var(--pulse-chart-ref); border-radius: 50%; background: var(--pulse-ig-bg); }
.pulse-ig-tl-ev.is-done .pulse-ig-tl-dot { border-color: var(--pulse-chart-main); background: var(--pulse-chart-main); }
.pulse-ig-tl-ev > p { margin: 0; }
p.pulse-ig-tl-when { font-size: var(--pulse-text-sm); font-weight: var(--weight-semibold); font-variant-numeric: tabular-nums; }
.pulse-ig-tl-status { margin-inline-start: var(--sp-1); font-size: var(--pulse-text-xs); font-weight: var(--weight-medium); color: var(--pulse-meta); }
p.pulse-ig-tl-text { margin-top: 2px; }
.pulse-ig-tl-ent { font-weight: var(--weight-semibold); }
/* A timeline row is a dense data row: its hub link is a 44 px target (as the transmission map's). */
.pulse-ig-tl-ent a { display: inline-flex; align-items: center; min-height: var(--pulse-tap-dense); margin-block: calc(-1 * var(--sp-2)); }
p.pulse-ig-tl-note { margin-top: 2px; font-size: var(--pulse-text-sm); color: var(--pulse-meta); }
li.pulse-ig-tl-today { margin: 0 0 var(--sp-3); padding: var(--sp-1) 0 0; border-top: 1px dashed var(--pulse-chart-ref); }
.pulse-ig-tl-today > p { margin: 0; font-size: var(--pulse-text-xs); font-weight: var(--weight-semibold); }
.pulse-ig-tl--mini .pulse-ig-tl-ev { padding-bottom: var(--sp-2); }
ol.pulse-ig-cal { display: grid; gap: var(--sp-3); margin: 0; padding: 0; list-style: none; }
li.pulse-ig-cal-day { margin: 0; }
p.pulse-ig-cal-head { margin: 0 0 var(--sp-2); font-family: var(--font-display); font-weight: var(--weight-semibold); font-size: var(--pulse-text-label); color: var(--ink); }
.pulse-ig-cal--mini { gap: 0; }
.pulse-ig-cal--mini .pulse-ig-cal-day:not(:last-child) .pulse-ig-tl-ev:last-child::before { display: block; bottom: calc(-1 * var(--sp-1)); }
.pulse-ig-cal--mini .pulse-ig-tl-ev { padding-bottom: var(--sp-2); }
ol.pulse-ig-tl--cal > li.pulse-ig-tl-ev:last-child { padding-bottom: 0; }

/* ig.before_after: before above after on a phone; side by side from 27.5rem. */
.pulse-ig-ba { display: grid; gap: var(--pulse-space-s); }
.pulse-ig-ba-side > p { margin: 0; }
p.pulse-ig-ba-head { font-family: var(--font-display); font-weight: var(--weight-semibold); font-size: var(--pulse-text-label); }
.pulse-ig-blocks { display: block; width: auto; height: 1.875rem; max-width: 100%; margin: var(--sp-2) 0; }
p.pulse-ig-ba-line { font-size: var(--pulse-text-sm); }
.pulse-ig-ba + .pulse-ig-table { margin-top: var(--sp-3); }
p.pulse-ig-ba-keep, p.pulse-ig-ba-dates { margin: var(--sp-2) 0 0; font-size: var(--pulse-text-sm); }
.pulse-ig-ba-keep .pulse-unit-label { margin-inline-end: var(--sp-1); }

/* ---------- The limits line (block.what_it_does_not_tell_you): no tint, no box ---------- */
p.pulse-limits, dd.pulse-limits { margin: 0; max-width: var(--pulse-measure); font-size: var(--pulse-text-base); line-height: var(--pulse-leading-dense); }
.pulse-limits-label { margin-inline-end: var(--sp-1); }
p.pulse-limits--edition_item, dd.pulse-limits--item { padding-top: var(--sp-2); }

/* ---------- Medium: from a 27.5rem exhibit ---------- */
@container pulse-ex (min-width: 27.5rem) {
  .pulse-ex-title { font-size: var(--text-xl); line-height: var(--leading-tight); }
  .pulse-ex-summary { font-size: var(--text-base); line-height: 1.5; }
  .pulse-ex-twin--c { display: none; }
  .pulse-ex-twin--m { display: block; }
  .pulse-ex-rows--compact { display: none; }
  .pulse-ex-data--wide { display: block; }
  .pulse-ig-bars .pulse-ig-rlabel { width: 30%; font-size: var(--pulse-text-base); }
  .pulse-ig-pb-rows .pulse-ig-rlabel { width: 5.5rem; }
  .pulse-ig-pb-rows--short .pulse-ig-rlabel { width: 3.5rem; }
  .pulse-ig-pb-rows--short-note .pulse-ig-rlabel { width: 6rem; }
  .pulse-ig-cell, .pulse-ig-vstack .pulse-ig-cell { grid-template-columns: minmax(0, 1fr) calc(var(--pulse-ig-vn, 8) * 1ch); column-gap: var(--sp-3); font-size: var(--text-base); }
  .pulse-ig-vstack .pulse-ig-cell > .pulse-ig-bar, .pulse-ig-vstack .pulse-ig-cell > .pulse-ig-track--db { grid-column: 1; grid-row: 1; }
  .pulse-ig-vstack .pulse-ig-cell > .pulse-ig-v { grid-column: 2; grid-row: 1; justify-self: start; text-align: start; }
  .pulse-ig-rc .pulse-ig-rlabel { width: 28%; }
  .pulse-ig-rc .pulse-ig-rc-col { display: table-cell; }
  .pulse-ig-rc .pulse-ig-rc-compact { display: none; }
  .pulse-ig-rc .pulse-ig-rc-cur, .pulse-ig-rc .pulse-ig-rc-curh { text-align: end; }
  .pulse-ig-sm { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pulse-ig-ba { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--pulse-space-m); }
  /* A key figure beside its words, when it has them. */
  .pulse-ex--key-figure .pulse-ex-body:has(> .pulse-ex-words) { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); column-gap: var(--pulse-space-m); align-items: start; }
  .pulse-ex--key-figure .pulse-ex-body:has(> .pulse-ex-words) > * { grid-column: 1 / -1; }
  .pulse-ex--key-figure .pulse-ex-body:has(> .pulse-ex-words) > .pulse-ex-plot { grid-column: 1; grid-row: 1 / span 3; }
  .pulse-ex--key-figure .pulse-ex-body:has(> .pulse-ex-words) > .pulse-ex-words { grid-column: 2; grid-row: 1; }
  /* Today's number: the meanings start level with the numeral (the figure has no top gap). */
  .pulse-ex--host-todays-number .pulse-ex-body:has(> .pulse-ex-words) > .pulse-ex-words { margin-top: 0; }
}

/* ---------- Wide: from a 42.5rem exhibit ---------- */
@container pulse-ex (min-width: 42.5rem) {
  .pulse-ex-twin--m { display: none; }
  .pulse-ex-twin--w { display: block; }
  .pulse-ex-rows--to-wide { display: none; }
  .pulse-ex-data--from-wide { display: block; }
  ol.pulse-ex-notes, .pulse-ex-words > p, p.pulse-limits, dd.pulse-limits { font-size: var(--text-base); }
  .pulse-ex-words { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--pulse-space-m); max-width: none; }
  .pulse-ex-words > :only-child { grid-column: 1 / -1; max-width: var(--pulse-measure); }
  .pulse-ex-words > .pulse-ex-owner { grid-column: 1 / -1; }
  .pulse-ex--key-figure .pulse-ex-body:has(> .pulse-ex-words) > .pulse-ex-words { grid-template-columns: minmax(0, 1fr); }
  .pulse-ig-bar { height: 1rem; }
  .pulse-ig-bars .pulse-ig-rval { padding-block: 0.625rem; }
  .pulse-ig-fr { grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); }
  .pulse-ig-fr-cell + .pulse-ig-fr-cell { padding-inline-start: var(--pulse-space-m); border-inline-start: 1px solid var(--pulse-rule); }
  ol.pulse-ig-tm { grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); column-gap: var(--pulse-space-s); }
  p.pulse-ig-tm-link { flex-direction: column; align-items: flex-start; gap: var(--sp-1); padding-inline-start: 0; }
  .pulse-ig-tm-arrow { width: 100%; max-width: 6rem; height: 2px; }
  .pulse-ig-tm-arrow::after { left: auto; right: -2px; bottom: -4px; border-top: 5px solid transparent; border-bottom: 5px solid transparent; border-left: 7px solid var(--pulse-chart-compare); border-right: 0; }
  .pulse-ex--wide .pulse-ig-ps--3, .pulse-ex--wide .pulse-ig-ps--4, .pulse-ex--wide .pulse-ig-ps--5 { grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); column-gap: var(--pulse-space-m); }
  .pulse-ex--wide .pulse-ig-tl--2, .pulse-ex--wide .pulse-ig-tl--3, .pulse-ex--wide .pulse-ig-tl--4, .pulse-ex--wide .pulse-ig-tl--5 { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); column-gap: var(--sp-3); }
  .pulse-ex--wide .pulse-ig-tl--2 .pulse-ig-tl-ev, .pulse-ex--wide .pulse-ig-tl--3 .pulse-ig-tl-ev, .pulse-ex--wide .pulse-ig-tl--4 .pulse-ig-tl-ev, .pulse-ex--wide .pulse-ig-tl--5 .pulse-ig-tl-ev { padding: calc(1rem + var(--sp-2)) 0 0; }
  .pulse-ex--wide .pulse-ig-tl--2 .pulse-ig-tl-ev::before, .pulse-ex--wide .pulse-ig-tl--3 .pulse-ig-tl-ev::before, .pulse-ex--wide .pulse-ig-tl--4 .pulse-ig-tl-ev::before, .pulse-ex--wide .pulse-ig-tl--5 .pulse-ig-tl-ev::before { left: 1.25rem; right: calc(-1 * var(--sp-3)); top: calc(0.5rem - 1px); bottom: auto; width: auto; height: 2px; }
}

/* ---------- Breakout: from a 60rem exhibit (wide size only) ---------- */
@container pulse-ex (min-width: 60rem) {
  .pulse-ex--has-b .pulse-ex-twin--w { display: none; }
  .pulse-ex-twin--b { display: block; }
  .pulse-ex--has-b .pulse-ig-sm { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* Print: the figures print as a table outside the toggle (CSS cannot open <details> in every
   browser; where ::details-content is supported the table shows), and an exhibit never splits. */
@media print {
  .pulse-ex { break-inside: avoid; }
  .pulse-ex-data::details-content { content-visibility: visible; display: contents; }
  .pulse-ex-data > summary, .pulse-ex-share { display: none; }
}

/* ---------- M1 charts (src/publishing/charts.php legacy specs; retired with their callers) ----------
   The 560-unit SVG now scales to its column: min-width: 30rem and the focusable sideways scroller
   are gone (INFOGRAPHICS 11.1), so nothing scrolls sideways. */
.pulse-figure-plot { position: relative; max-width: 100%; padding: var(--sp-2) 0; }
.pulse-chart .up { fill: var(--pulse-up); }
.pulse-chart .down { fill: var(--pulse-down); }
.pulse-chart .line { stroke: var(--pulse-chart-main); fill: none; }
.pulse-chart .axis, .pulse-chart .grid { stroke: var(--pulse-rule); }
.pulse-chart text { fill: var(--ink-soft); font-family: var(--font-body); }
.pulse-figure { margin: var(--sp-5) 0; }
.pulse-figure-cap { display: block; margin-bottom: var(--sp-2); }
.pulse-figure-title { display: block; color: var(--blue-900); font-family: var(--font-display); font-weight: var(--weight-semibold); font-size: var(--pulse-text-base); line-height: var(--leading-tight); }
.pulse-figure-summary { display: block; margin-top: var(--sp-1); color: var(--pulse-meta); font-size: var(--pulse-text-sm); }
.pulse-chart { display: block; width: 100%; max-width: 40rem; height: auto; font-variant-numeric: tabular-nums; }
.pulse-chart text { font-variant-numeric: tabular-nums; }
.pulse-chart .zero { stroke: var(--field-border); stroke-width: 1.5; }
.pulse-chart .flat { fill: var(--pulse-flat); }
.pulse-chart .marker { stroke: var(--ink-soft); }
.pulse-chart .marker-dot { fill: var(--ink); }
.pulse-chart .marker-num, .pulse-chart .val, .pulse-chart .chg, .pulse-chart .lbl-strong,
.pulse-chart .stage, .pulse-chart .quad-lbl { fill: var(--ink); font-weight: var(--weight-semibold); }
.pulse-chart .lbl, .pulse-chart .pt-lbl { fill: var(--ink); }
.pulse-chart .axis-title, .pulse-chart .quad-sub { fill: var(--ink-soft); }
.pulse-chart .dir-up { fill: var(--pulse-up); }
.pulse-chart .dir-down { fill: var(--pulse-down); }
.pulse-chart .dir-ink { fill: var(--ink); }
.pulse-chart .quad { fill: var(--surface-alt); }
.pulse-chart .quad-lb, .pulse-chart .quad-lu { fill: var(--surface); }
.pulse-chart .pt { fill: var(--pulse-chart-main); stroke: var(--surface); stroke-width: 2; }
.pulse-chart .s1, .pulse-chart .cur { fill: var(--pulse-chart-main); }
.pulse-chart .s2, .pulse-chart .prior { fill: var(--surface); stroke: var(--ink); }
.pulse-chart .node { fill: var(--surface-alt); stroke: var(--field-border); stroke-width: 1.5; }
.pulse-chart .edge { fill: none; stroke: var(--ink-soft); }
.pulse-chart .edge-head { fill: var(--ink-soft); }
.pulse-figure .pulse-figure-source { margin: var(--sp-2) 0 0; color: var(--pulse-meta); font-size: var(--pulse-text-xs); }
.pulse-figure .pulse-chart-legend {
  display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-4);
  margin: var(--sp-2) 0 0; padding: 0; list-style: none;
  color: var(--ink); font-size: var(--pulse-text-sm);
}
.pulse-figure .pulse-chart-legend li { display: inline-flex; align-items: center; gap: var(--sp-2); margin: 0; font-size: var(--pulse-text-sm); }
.pulse-swatch { display: inline-block; flex: none; width: 1rem; height: 1rem; border-radius: 0.125rem; }
.pulse-swatch--s1, .pulse-swatch--cur { background: var(--pulse-chart-main); }
.pulse-swatch--s2, .pulse-swatch--prior { background: var(--surface); border: 2px solid var(--ink); }
.pulse-figure .pulse-chart-events { margin: var(--sp-2) 0 0; padding-inline-start: 1.5em; }
.pulse-figure .pulse-chart-events li { margin-bottom: var(--sp-1); font-size: var(--pulse-text-sm); }
.pulse-chart-data { margin-top: var(--sp-2); }
.pulse-chart-data > summary {
  min-height: 48px; padding-block: 0.75rem; line-height: 1.5rem;
  color: var(--pulse-label); font-size: var(--pulse-text-sm); font-weight: var(--weight-semibold);
  cursor: pointer;
}
.pulse-chart-data > summary:hover { color: var(--blue-700); text-decoration: underline; }
.pulse-chart-table { margin: 0; font-size: var(--pulse-text-sm); font-variant-numeric: tabular-nums; }
.pulse-chart-table caption { caption-side: top; padding-top: 0; color: var(--pulse-meta); font-size: var(--pulse-text-xs); }

/* ===== part 50-front.css ===== */
/* =====================================================================
   EQSIS Pulse: pulse.css, part 50 (front page, edition pages, category,
   Data Desk and Learn fronts). Owner: package B (docs/design/BUILD-V2.md).
   ---------------------------------------------------------------------
   The merged front page of DESIGN-SYSTEM.md 3.2 to 3.6, the edition pages
   (13), the category, Data Desk and Learn fronts, and package B's
   components: chrome.edition_stamp (with its progress row and contents
   panel), block.todays_number, block.where_things_stand, card.edition_item,
   card.story_card, card.row, card.data_tile and state.end_card.
   Prefixes: .pulse-stamp* .pulse-item* .pulse-number* .pulse-now*
   .pulse-end* .pulse-front* .pulse-card* .pulse-row* .pulse-tile*.
   Foundation classes (.pulse-sec*, .pulse-join--*, .pulse-grid,
   .pulse-hang*, .pulse-h-*, .pulse-unit-label, .pulse-split-*) are used,
   never restyled. Compact first: unqueried rules are the 360 px phone;
   wider layouts sit inside @container (pulse-page 44/58rem, pulse-stamp
   30/40rem, pulse-number 30rem, pulse-item 40rem, pulse-tile 30/52rem,
   pulse-end 40rem). Media queries only for the chrome breakpoint at 768 px
   (the Stamp's schedule band and its phone top padding, which follow the
   band padding's own 768 px switch; the phone progress row; the extra live
   rows).
   Every size from the part-00 scales; every colour an alias; no motion.
   ===================================================================== */

/* ---------- Category marker: a 0.5rem square in the category's accent, then the name ----------
   The square is decoration; the name carries the meaning (DESIGN-SYSTEM.md 10.3). */
.pulse-card-cat { display: inline-flex; align-items: center; gap: 0.375rem; }
.pulse-card-cat::before {
  content: ""; flex: none;
  width: 0.5rem; height: 0.5rem;
  background: var(--pulse-catmark, var(--pulse-label));
}
.pulse-card-cat--markets-today { --pulse-catmark: var(--pulse-cat-markets-today); }
.pulse-card-cat--trading-desk { --pulse-catmark: var(--pulse-cat-trading-desk); }
.pulse-card-cat--investing { --pulse-catmark: var(--pulse-cat-investing); }
.pulse-card-cat--companies { --pulse-catmark: var(--pulse-cat-companies); }
.pulse-card-cat--sectors-and-themes { --pulse-catmark: var(--pulse-cat-sectors-and-themes); }
.pulse-card-cat--economy-and-policy { --pulse-catmark: var(--pulse-cat-economy-and-policy); }
.pulse-card-cat--global-markets { --pulse-catmark: var(--pulse-cat-global-markets); }
.pulse-card-cat--commodities-and-currency { --pulse-catmark: var(--pulse-cat-commodities-and-currency); }
.pulse-card-cat--data-desk { --pulse-catmark: var(--pulse-cat-data-desk); }
.pulse-card-cat--learn { --pulse-catmark: var(--pulse-cat-learn); }

/* =====================================================================
   The front page grid: Part A in the 8 + 4 grid of the pulse-page container
   ===================================================================== */
/* Below the 58rem page container the Stamp joins the chrome with no extra gap: the breadcrumb's
   own padding separates them (DESIGN-SYSTEM.md 7.4), so the first headline holds y <= 300 at 360. */
.pulse-front-a { margin-top: 0; }
/* On phones the rail is simply the next block: Today's number enters with the shift join. */
.pulse-front-rail { margin-top: var(--pulse-space-xl); min-width: 0; }
.pulse-front-main { min-width: 0; }
@container pulse-page (min-width: 58rem) {
  .pulse-front-a { margin-top: var(--pulse-space-xs); }
  /* The rail spans both main rows and stretches, so the contents panel can stick inside it. */
  .pulse-front-rail { grid-row: 1 / span 2; align-self: stretch; margin-top: 0; }
  .pulse-front-main--items { grid-row: 2; }
  /* Today's number becomes the rail's one bordered card. */
  .pulse-number-sec {
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    padding: var(--pulse-card-pad);
  }
}
/* The split bar sits on a radius-lg panel from 58rem: clip its square ends. */
.pulse-front-stamp, .pulse-end-sec { overflow: hidden; }
/* The Stamp's phone exception (DESIGN-SYSTEM.md 3.6 and 6.2): below 768 px the edition name sits
   --pulse-space-s under the 0.5rem split bar, not a full band padding (l) under it, so the Stamp head
   is the 78 px the first-screen sums assume. Its foot keeps the band padding. */
@media (max-width: 767.98px) {
  .pulse-sec--feature.pulse-front-stamp { padding-top: calc(var(--pulse-split-h-frame) + var(--pulse-space-s)); }
}
.pulse-front-b { padding-bottom: var(--pulse-space-l); }

/* =====================================================================
   chrome.edition_stamp: the Stamp on the deep surface
   ===================================================================== */
.pulse-stamp { container: pulse-stamp / inline-size; }
.pulse-stamp-kicker {
  margin: 0 0 var(--pulse-space-2xs);
  color: var(--pulse-on-deep-soft);
  font-size: var(--pulse-text-sm);
  line-height: var(--pulse-leading-dense);
}
/* On the phone front page the masthead already dates the page: the kicker returns from 40rem. */
.pulse-front .pulse-stamp-kicker { display: none; }
.pulse-stamp-name {
  margin: 0;
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-size: var(--pulse-fs-3);
  line-height: var(--pulse-leading-lead);
  color: var(--pulse-stamp-fg);
}
/* The rows' own padding opens the list: no bottom margin, so the phone first screen holds the Stamp
   head plus rows 1 to 3 above the consent banner at 360 x 640 (DESIGN-SYSTEM.md 3.6 and 15.4). */
.pulse-stamp-meta {
  margin: var(--pulse-space-2xs) 0 0;
  color: var(--pulse-on-deep-soft);
  font-size: var(--pulse-text-sm);
  line-height: var(--pulse-leading-dense);
  font-variant-numeric: tabular-nums;
}
.pulse-stamp-rows { margin: 0; padding: 0; list-style: none; }
.pulse-stamp-row + .pulse-stamp-row { border-top: 1px solid var(--pulse-deep-line); }
.pulse-stamp-link {
  display: grid;
  grid-template-columns: 1.25rem minmax(0, 1fr);
  column-gap: var(--pulse-space-xs);
  align-items: baseline;
  min-height: var(--pulse-tap);
  /* A two-line row is 52 px (section 3.6's row height); a one-line row keeps the 48 px tap height. */
  padding-block: 0.25rem;
  color: var(--pulse-stamp-fg);
  text-decoration: none;
}
.pulse-stamp-link:hover .pulse-stamp-hl { text-decoration: underline; text-underline-offset: 3px; }
.pulse-stamp-n {
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-size: 1.375rem;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.pulse-stamp-text { min-width: 0; }
.pulse-stamp-slot { display: block; color: var(--pulse-on-deep-soft); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
/* Below a 30rem Stamp the slot name is read, not shown: the headline carries the row. */
.pulse-stamp-slotname {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}
.pulse-stamp-hl {
  display: block;
  font-family: var(--font-body);
  font-weight: var(--weight-semibold);
  font-size: var(--pulse-text-base);
  line-height: 1.3;
  text-wrap: pretty;
}
.pulse-stamp-since {
  min-height: var(--pulse-reserve-since);
  margin-top: var(--pulse-space-xs);
  padding-top: var(--pulse-space-2xs);
  border-top: 1px solid var(--pulse-deep-line);
}
.pulse-stamp-sched { display: none; }
@media (min-width: 768px) {
  .pulse-stamp-sched {
    display: flex; flex-wrap: wrap; gap: var(--pulse-space-2xs) var(--pulse-space-m);
    margin: var(--pulse-space-s) 0 0; padding: var(--pulse-space-xs) 0 0;
    border-top: 1px solid var(--pulse-deep-line);
    list-style: none;
    color: var(--pulse-on-deep-soft);
    font-size: var(--pulse-text-sm);
    line-height: var(--pulse-leading-dense);
    font-variant-numeric: tabular-nums;
  }
}
.pulse-stamp-sched-item { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 0 var(--pulse-space-xs); }
.pulse-stamp-sched-name { color: var(--pulse-stamp-fg); font-weight: var(--weight-semibold); }
.pulse-stamp-sched-status { display: inline-flex; align-items: center; gap: var(--pulse-space-2xs); }
.pulse-stamp-check { width: 0.75rem; height: 0.75rem; }
@container pulse-stamp (min-width: 30rem) {
  .pulse-stamp-slotname { position: static; width: auto; height: auto; overflow: visible; clip-path: none; white-space: normal; }
  .pulse-stamp-kick::before { content: " · "; }
}
@container pulse-stamp (min-width: 40rem) {
  .pulse-front .pulse-stamp-kicker { display: block; }
  .pulse-stamp-hl { font-size: var(--text-base); }
  .pulse-stamp-link { grid-template-columns: 1.75rem minmax(0, 1fr); }
}

/* The progress row and the contents panel (edition_progress.php): package E lays them out and
   drives them (.pulse-progress*, 80-interactive.css; pulse.js). B styles only its own words: the
   edition name, the panel title, the hanging numerals and the "You are here" mark. */
.pulse-stamp-progress-text { margin: 0; }
.pulse-stamp-progress-name { font-weight: var(--weight-semibold); }
.pulse-stamp-contents-title {
  margin: 0 0 var(--pulse-space-2xs);
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--pulse-text-label);
  color: var(--pulse-label);
}
.pulse-stamp-contents-n { min-inline-size: 1.25rem; font-family: var(--font-display); font-weight: var(--weight-display); color: var(--pulse-label); font-variant-numeric: tabular-nums; }
.pulse-stamp-contents-here { display: block; padding-inline-start: calc(var(--sp-3) + 3px + 1.25rem + var(--sp-2)); margin-top: calc(-1 * var(--sp-2)); padding-bottom: var(--sp-2); font-size: var(--pulse-text-sm); color: var(--pulse-meta); }
.pulse-stamp-contents-here[hidden] { display: none; }
.pulse-progress-dialog [data-pulse-dialog-close] { min-block-size: var(--pulse-tap); margin-top: var(--pulse-space-s); }

/* =====================================================================
   block.todays_number
   ===================================================================== */
.pulse-number { container: pulse-number / inline-size; }
.pulse-number-head { margin-bottom: var(--pulse-space-xs); }
.pulse-number-h {
  margin: 0;
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-size: var(--pulse-fs-2);
  line-height: var(--leading-tight);
  color: var(--blue-900);
}
.pulse-number-date { margin: var(--pulse-space-2xs) 0 0; color: var(--pulse-meta); font-size: var(--pulse-text-sm); }
.pulse-number-after { margin-top: var(--pulse-space-s); }
.pulse-number-after > * { max-width: var(--pulse-measure); }
.pulse-number-reconcile {
  margin: 0;
  color: var(--ink);
  font-size: var(--text-base);
  line-height: var(--pulse-leading-dense);
}
.pulse-number-part { white-space: nowrap; }
.pulse-number-reconcile-src { margin: var(--pulse-space-2xs) 0 0; color: var(--pulse-meta); font-size: var(--pulse-text-sm); }
.pulse-number-tie { margin: var(--pulse-space-xs) 0 0; font-size: var(--text-base); line-height: var(--pulse-leading-dense); }
.pulse-number-tie a { font-weight: var(--weight-semibold); }
/* The reconcile and tie lines print inside the key figure, right after its label list (ig_render()
   after_list), so the reader meets them with the number. */
.pulse-ig-kf > .pulse-number-reconcile,
.pulse-ig-kf > .pulse-number-reconcile-wrap { margin-top: var(--pulse-space-xs); }
.pulse-ig-kf > .pulse-number-reconcile,
.pulse-ig-kf > .pulse-number-reconcile-wrap,
.pulse-ig-kf > .pulse-number-tie { max-width: var(--pulse-measure); }
.pulse-number-signoff {
  margin: var(--pulse-space-s) 0 0;
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--pulse-text-sm);
  color: var(--ink);
}
.pulse-number-actions { margin-top: var(--pulse-space-xs); }
.pulse-number-how { margin-top: var(--pulse-space-xs); font-size: var(--pulse-text-sm); }
.pulse-number-how > summary {
  display: inline-flex; align-items: center;
  min-height: var(--pulse-tap);
  color: var(--blue-700);
  font-weight: var(--weight-semibold);
  cursor: pointer;
}
.pulse-number-how > summary:hover { text-decoration: underline; text-underline-offset: 3px; }
.pulse-number-foot {
  margin-top: var(--pulse-space-s);
  padding-top: var(--pulse-space-xs);
  border-top: 1px solid var(--pulse-rule);
}
.pulse-number-ra { margin: var(--pulse-space-2xs) 0 0; color: var(--pulse-meta); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
/* On the Morning Brief page, item 4 in place: the figure sits inside the item's body column. */
.pulse-number--in-edition .pulse-number-after { margin-top: var(--pulse-space-xs); }

/* =====================================================================
   The Now band (A4) and block.where_things_stand
   ===================================================================== */
.pulse-now-title {
  margin: 0 0 var(--pulse-space-s);
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-size: var(--pulse-fs-2);
  line-height: var(--leading-tight);
  color: var(--blue-900);
  text-wrap: balance;
}
@media (max-width: 767.98px) {
  .pulse-now-strip { margin-bottom: var(--pulse-space-s); }
}
.pulse-now-h { margin: 0 0 var(--pulse-space-s); font-family: var(--font-display); font-weight: var(--weight-display); font-size: var(--pulse-fs-2); line-height: var(--leading-tight); color: var(--blue-900); }
.pulse-now-lines { margin: 0; padding: 0; list-style: none; }
.pulse-now-line {
  position: relative;
  max-width: var(--pulse-measure);
  padding-inline-start: 1.125rem;
  font-size: var(--text-base);
  line-height: var(--leading-body);
}
.pulse-now-line + .pulse-now-line { margin-top: var(--pulse-space-xs); }
.pulse-now-line::before {
  content: ""; position: absolute; left: 0; top: 0.65em;
  width: 0.375rem; height: 0.375rem;
  background: var(--pulse-meta);
}
/* A line that links its Live entry (Live, hubs) is one whole-line 48 px target: the padding centres a
   single line in the tap height and the bullet follows the first line (it measured 20 px from 768 px). */
.pulse-now-line > a:only-child { display: block; padding-block: calc((var(--pulse-tap) - var(--leading-body) * 1em) / 2); }
.pulse-now-line:has(> a:only-child)::before { top: calc(var(--pulse-tap) / 2 - 0.1875rem); }
.pulse-now-note { display: none; margin: var(--pulse-space-xs) 0 0; color: var(--pulse-meta); font-size: var(--pulse-text-sm); }
.pulse-now-since { margin-top: var(--pulse-space-xs); }
/* Each row keeps a gap of --pulse-space-s above its text: the since bookmark (package E) is drawn
   centred on a row's top edge, inside that existing gap, so no row moves when it appears. */
.pulse-now-rows { margin: var(--pulse-space-s) 0 0; padding: 0; list-style: none; }
.pulse-now-row { padding-top: var(--pulse-space-s); }
.pulse-now-row + .pulse-now-row { margin-top: var(--pulse-space-2xs); border-top: 1px solid var(--pulse-rule); }
.pulse-now-row--extra { display: none; }
@media (min-width: 768px) {
  .pulse-now-row--extra { display: block; }
}
.pulse-now-open { margin: var(--pulse-space-s) 0 0; }
.pulse-now-live { display: flex; justify-content: center; align-items: center; width: 100%; min-height: var(--pulse-tap); }
.pulse-now-trust { margin-top: var(--pulse-space-xs); }
@container pulse-page (min-width: 44rem) {
  .pulse-now-live { display: inline-flex; width: auto; }
}
@container pulse-page (min-width: 58rem) {
  .pulse-now-title { font-size: var(--pulse-fs-1); }
  .pulse-now-note { display: block; }
  .pulse-now-line { font-size: var(--pulse-text-base); }
}

/* =====================================================================
   card.edition_item and the items list (the edition spine)
   ===================================================================== */
.pulse-items { margin: 0; padding: 0; list-style: none; }
.pulse-items-li + .pulse-items-li {
  margin-top: var(--pulse-space-m);
  padding-top: var(--pulse-space-m);
  border-top: 1px solid var(--pulse-rule);
}
.pulse-item-rail {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 var(--pulse-space-xs);
  margin: 0 0 var(--pulse-space-2xs);
}
.pulse-item-n {
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-size: var(--pulse-text-h1);
  line-height: 1;
  color: var(--pulse-label);
  font-variant-numeric: tabular-nums;
}
.pulse-item-slot { font-family: var(--font-body); font-weight: var(--weight-semibold); font-size: 0.9375rem; line-height: var(--pulse-leading-dense); color: var(--ink); }
.pulse-item-kicker { flex-basis: 100%; color: var(--pulse-analyst-label); font-size: var(--pulse-text-sm); font-weight: var(--weight-semibold); }
.pulse-item-body { container: pulse-item / inline-size; min-width: 0; }
.pulse-item-meta { margin: 0 0 var(--pulse-space-2xs); color: var(--pulse-meta); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
.pulse-item-hl a { padding-block: 0.6875rem; }
.pulse-item-plain { margin-top: var(--pulse-space-xs); max-width: var(--pulse-measure); }
.pulse-item-units { margin: var(--pulse-space-s) 0 0; max-width: var(--pulse-measure); }
.pulse-item-unit { margin: 0; font-size: var(--text-base); line-height: var(--leading-body); }
.pulse-item-unit + .pulse-item-unit { margin-top: var(--pulse-space-xs); }
/* Front density: two short run-in paragraphs, set at the dense leading so an item stays near its
   440 px budget at 360 px; the edition page keeps the body leading for its labelled units. */
.pulse-item--front .pulse-item-unit { line-height: var(--pulse-leading-dense); }
.pulse-item-units--full .pulse-item-unit + .pulse-item-unit { margin-top: var(--pulse-space-s); }
.pulse-item-units--full dt { display: block; margin-bottom: var(--pulse-space-2xs); }
.pulse-item-units--full dd { margin: 0; }
.pulse-item-note { margin-top: var(--pulse-space-s); max-width: var(--pulse-measure); }
.pulse-item-pic { margin-top: var(--pulse-space-s); }
/* Bar minis take the reading measure, so their tracks keep a usable length; a key figure or a
   timeline mini stays narrow (its numeral or its dates need no more). */
.pulse-item--front .pulse-item-pic { max-width: var(--pulse-measure); }
.pulse-item--front .pulse-item-pic--narrow { max-width: 28rem; }
.pulse-item-limits { margin: var(--pulse-space-xs) 0 0; max-width: var(--pulse-measure); }
.pulse-item-limits dd { margin: 0; }
/* Front density: the limits line is a quiet footnote to the mini (meta size), so an item stays near
   its 440 px budget at 360 px; the edition page keeps it at body size. */
.pulse-item--front .pulse-limits { font-size: var(--pulse-text-sm); }
.pulse-item-sources { margin-top: var(--pulse-space-xs); max-width: var(--pulse-measure); }
.pulse-item-actions {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--pulse-space-2xs) var(--pulse-space-s);
  margin-top: var(--pulse-space-s);
}
.pulse-item-read { display: inline-flex; align-items: center; min-height: var(--pulse-tap); font-weight: var(--weight-semibold); }
.pulse-item-save { display: inline-block; inline-size: 3rem; visibility: hidden; }
.pulse-item-trust { margin-top: var(--pulse-space-xs); }
@container pulse-page (min-width: 44rem) {
  /* The numeral and slot name hang in the 4rem rail (.pulse-hang); the text keeps one left edge. */
  .pulse-item-rail { display: block; margin: 0; }
  .pulse-item-n { display: block; font-size: 2.5rem; }
  .pulse-item-slot { display: block; margin-top: var(--pulse-space-2xs); font-size: var(--pulse-text-sm); }
  .pulse-item-kicker { display: block; margin-top: var(--pulse-space-2xs); }
}

/* =====================================================================
   card.row (story, flash, pointer, ranked, result)
   ===================================================================== */
.pulse-row { position: relative; min-height: var(--pulse-tap); }
.pulse-row-meta { margin: 0; color: var(--pulse-meta); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); font-variant-numeric: tabular-nums; }
.pulse-row-hl {
  margin: var(--pulse-space-2xs) 0 0;
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-size: var(--pulse-fs-1);
  line-height: var(--pulse-leading-card);
  color: var(--blue-900);
  text-wrap: balance;
}
.pulse-row-link { color: inherit; text-decoration: none; }
.pulse-row-link:hover { text-decoration: underline; text-underline-offset: 3px; }
/* The whole row is one link (at least 48 px); a trust strip inside stays reachable above it. */
.pulse-row--story .pulse-row-link::after,
.pulse-row--flash .pulse-row-link::after,
.pulse-row--result .pulse-row-link::after { content: ""; position: absolute; inset: 0; }
.pulse-row-trust { position: relative; z-index: 1; margin-top: var(--pulse-space-xs); }
.pulse-row-plain { margin-top: var(--pulse-space-xs); max-width: var(--pulse-measure); }
.pulse-row-text { margin: var(--pulse-space-2xs) 0 0; max-width: var(--pulse-measure); font-size: var(--text-base); line-height: var(--leading-body); }
/* flash: time first, then the update */
.pulse-row--flash { display: grid; grid-template-columns: minmax(0, 1fr); }
.pulse-row-time { margin: 0; color: var(--ink); font-weight: var(--weight-semibold); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
/* The reserved "New" slot is hidden until the since marker shows it: part 80 owns that state ([data-pulse-new]). */
.pulse-row--compact .pulse-row-hl { font-family: var(--font-body); font-weight: var(--weight-semibold); font-size: var(--text-base); line-height: var(--pulse-leading-dense); }
/* pointer: "4 · Today's number · shown above", on the spine */
.pulse-row--pointer { display: flex; align-items: baseline; gap: var(--pulse-space-xs); margin: 0; }
.pulse-row-n {
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-size: var(--pulse-text-h1);
  line-height: 1;
  color: var(--pulse-label);
  font-variant-numeric: tabular-nums;
}
.pulse-row-pointer { display: inline-block; padding-block: 0.6875rem; font-weight: var(--weight-semibold); }
.pulse-row-pointer-note { color: var(--pulse-meta); font-weight: var(--weight-body); }
/* ranked: Most read */
.pulse-row--ranked {
  display: grid; grid-template-columns: 1.5rem minmax(0, 1fr); column-gap: var(--pulse-space-xs);
  align-items: baseline; margin: 0;
}
.pulse-row-rank { color: var(--pulse-meta); font-size: var(--pulse-text-sm); }
.pulse-row--ranked .pulse-row-link { display: inline-flex; align-items: center; min-height: var(--pulse-tap); font-weight: var(--weight-semibold); color: var(--ink); }
.pulse-row-format { grid-column: 2; color: var(--pulse-meta); font-size: var(--pulse-text-sm); }
@container pulse-page (min-width: 44rem) {
  .pulse-row--pointer .pulse-row-n { font-size: 2.5rem; }
  .pulse-row--pointer { display: grid; }
  .pulse-row--flash { grid-template-columns: var(--pulse-rail) minmax(0, 1fr); column-gap: var(--pulse-space-m); }
  .pulse-row--flash .pulse-row-time { padding-top: var(--pulse-space-2xs); }
}

/* Lists of rows */
.pulse-front-rows { margin: 0; padding: 0; list-style: none; }
.pulse-front-rows > li + li { margin-top: var(--pulse-space-m); padding-top: var(--pulse-space-m); border-top: 1px solid var(--pulse-rule); }

/* =====================================================================
   card.story_card (story, lead, hub, up_next, analyst), unboxed
   ===================================================================== */
.pulse-front-cards { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--pulse-space-m); margin: 0; padding: 0; list-style: none; }
.pulse-front-cards > li + li { padding-top: var(--pulse-space-m); border-top: 1px solid var(--pulse-rule); }
.pulse-card-meta { margin: 0; color: var(--pulse-meta); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
.pulse-card-hl { margin: var(--pulse-space-2xs) 0 0; }
/* The headline link is a 48 px target whatever the font's metrics: padding on an inline link left it at 43 to 46 px. */
.pulse-card-hl a { display: inline-flex; align-items: center; min-height: var(--pulse-tap); color: inherit; text-decoration: none; }
.pulse-card-hl a:hover { text-decoration: underline; text-underline-offset: 3px; }
.pulse-card-item--lead .pulse-card-hl { max-width: 40rem; }
.pulse-card-plain { margin-top: var(--pulse-space-xs); max-width: var(--pulse-measure); }
.pulse-card-label { margin: 0; font-family: var(--font-display); font-weight: var(--weight-semibold); font-size: var(--pulse-text-label); line-height: var(--pulse-leading-dense); color: var(--pulse-analyst-label); }
.pulse-card-excerpt { margin: var(--pulse-space-s) 0 0; max-width: var(--pulse-measure); font-size: var(--pulse-fs-dek); line-height: var(--pulse-leading-dense); color: var(--ink); }
.pulse-card-excerpt p { margin: 0; }
.pulse-card-reason { margin: var(--pulse-space-xs) 0 0; color: var(--pulse-meta); font-size: var(--pulse-text-sm); }
.pulse-card-pic { margin-top: var(--pulse-space-s); }
.pulse-card-attr { margin: var(--pulse-space-xs) 0 0; color: var(--pulse-meta); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
.pulse-card-trust { margin-top: var(--pulse-space-xs); }
.pulse-card-latest { margin: var(--pulse-space-xs) 0 0; font-size: var(--text-base); line-height: var(--pulse-leading-dense); }
.pulse-card-latest-label { color: var(--pulse-meta); font-size: var(--pulse-text-sm); }
.pulse-card-item--lead .pulse-card-plain { margin-top: var(--pulse-space-s); }
@container pulse-page (min-width: 44rem) {
  .pulse-front-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--pulse-space-l); }
  .pulse-front-cards > li, .pulse-front-cards > li + li { padding-top: var(--pulse-space-m); border-top: 1px solid var(--pulse-rule); }
}
@container pulse-page (min-width: 58rem) {
  .pulse-front-cards { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* =====================================================================
   card.data_tile and the Data Desk tiles
   ===================================================================== */
.pulse-tiles-wrap { container: pulse-tile / inline-size; }
.pulse-tiles { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--pulse-space-m); margin: 0; padding: 0; list-style: none; }
.pulse-tiles > li + li { padding-top: var(--pulse-space-m); border-top: 1px solid var(--pulse-rule); }
.pulse-tiles-li--extra { display: none; }
.pulse-tile-name { margin: 0; font-family: var(--font-body); font-weight: var(--weight-semibold); font-size: var(--text-base); line-height: var(--pulse-leading-dense); }
.pulse-tile-name a { display: inline-flex; align-items: center; min-height: var(--pulse-tap); color: var(--ink); text-decoration: none; }
.pulse-tile-name a:hover { text-decoration: underline; text-underline-offset: 3px; }
.pulse-tile-pic { margin-top: var(--pulse-space-xs); }
.pulse-tile-means { margin: var(--pulse-space-xs) 0 0; font-size: var(--text-base); line-height: var(--pulse-leading-dense); }
.pulse-tile-limits { margin-top: var(--pulse-space-xs); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
.pulse-tile-asof { margin: var(--pulse-space-xs) 0 0; color: var(--pulse-meta); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
.pulse-tile-actions { margin-top: var(--pulse-space-xs); }
.pulse-tile-owner { display: inline-flex; align-items: center; min-height: var(--pulse-tap); font-weight: var(--weight-semibold); }
.pulse-tile-trust { margin-top: var(--pulse-space-xs); }
.pulse-tiles-foot { margin-top: var(--pulse-space-m); padding-top: var(--pulse-space-s); border-top: 1px solid var(--pulse-rule); }
.pulse-tiles-ra { margin: var(--pulse-space-2xs) 0 0; color: var(--pulse-meta); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
.pulse-tiles-all { margin: var(--pulse-space-xs) 0 0; }
.pulse-tiles-all a { display: inline-flex; align-items: center; min-height: var(--pulse-tap); font-weight: var(--weight-semibold); }
@container pulse-tile (min-width: 30rem) {
  .pulse-tiles-li--extra { display: block; }
  .pulse-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--pulse-space-l); }
  .pulse-tiles > li, .pulse-tiles > li + li { padding-top: var(--pulse-space-s); border-top: 1px solid var(--pulse-rule); }
}
@container pulse-tile (min-width: 52rem) {
  .pulse-tiles { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--pulse-space-l) 0; }
  .pulse-tiles > li, .pulse-tiles > li + li { padding: 0 var(--pulse-space-m); border-top: 0; border-left: 1px solid var(--pulse-rule); }
  /* Four across: the first tile of each row keeps the text edge; the last needs no right space. */
  .pulse-tiles > li:nth-child(4n+1) { padding-left: 0; border-left: 0; }
  .pulse-tiles > li:nth-child(4n) { padding-right: 0; }
}

/* =====================================================================
   state.end_card
   ===================================================================== */
.pulse-end-sec { container: pulse-end / inline-size; }
.pulse-end { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--pulse-space-s); padding-top: var(--pulse-space-xs); }
.pulse-end-kicker { margin: 0; color: var(--pulse-meta); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
.pulse-end-title {
  margin: var(--pulse-space-2xs) 0 0;
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-size: var(--pulse-fs-2);
  line-height: var(--leading-tight);
  color: var(--blue-900);
  text-wrap: balance;
}
.pulse-end-recap { margin-top: var(--pulse-space-s); max-width: var(--pulse-measure); }
.pulse-end-recap-h { margin: 0 0 var(--pulse-space-xs); font-family: var(--font-display); font-weight: var(--weight-semibold); font-size: var(--pulse-text-label); color: var(--pulse-label); }
.pulse-end-recap-list { margin: 0; padding: 0; list-style: none; }
.pulse-end-recap-list li { display: grid; grid-template-columns: 1.25rem minmax(0, 1fr); column-gap: var(--pulse-space-xs); font-size: var(--text-base); line-height: var(--pulse-leading-dense); }
.pulse-end-recap-list li + li { margin-top: var(--pulse-space-xs); }
.pulse-end-recap-list li > :not(.pulse-end-recap-n) { grid-column: 2; }
.pulse-end-recap-n { grid-row: 1 / span 3; color: var(--pulse-meta); font-variant-numeric: tabular-nums; }
.pulse-end-recap-label { font-weight: var(--weight-semibold); }
.pulse-end-next { margin-top: var(--pulse-space-s); }
.pulse-end-line { margin: 0; font-size: var(--text-base); line-height: var(--pulse-leading-dense); }
.pulse-end-line + .pulse-end-line { margin-top: var(--pulse-space-2xs); }
.pulse-end-finite { margin: var(--pulse-space-s) 0 0; color: var(--pulse-meta); font-size: var(--pulse-text-sm); }
/* The end card's parts are grid children in reading order: main (title, next edition, calendar,
   finite line), side (today's editions), actions (Share, Was this clear?), sign. */
.pulse-end-actions { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--pulse-space-s) var(--pulse-space-l); }
.pulse-end-timeline {
  margin: 0; padding: 0 0 0 var(--pulse-space-s); list-style: none;
  border-left: 2px solid var(--pulse-progress-todo);
  font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense);
  font-variant-numeric: tabular-nums;
}
.pulse-end-tl { display: flex; flex-wrap: wrap; gap: 0 var(--pulse-space-xs); }
.pulse-end-tl + .pulse-end-tl { margin-top: var(--pulse-space-xs); }
.pulse-end-tl-name { font-weight: var(--weight-semibold); color: var(--ink); }
.pulse-end-tl-status { display: inline-flex; align-items: center; gap: var(--pulse-space-2xs); }
.pulse-end-tl--now { position: relative; color: var(--pulse-label); }
.pulse-end-tl--now::before {
  content: ""; position: absolute; left: calc(-1 * var(--pulse-space-s) - 2px); top: 0; bottom: 0;
  width: 2px; background: var(--pulse-progress-done);
}
.pulse-end-tl--now .pulse-end-tl-name { color: var(--pulse-label); }
.pulse-end-check { width: 0.75rem; height: 0.75rem; }
.pulse-end-sign { padding-top: var(--pulse-space-s); border-top: 1px solid var(--pulse-rule); }
.pulse-end-signoff { margin: 0; color: var(--ink); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
.pulse-end-lockup { font-family: var(--font-display); font-weight: var(--weight-display); }
.pulse-end-ra { margin: var(--pulse-space-2xs) 0 0; color: var(--pulse-meta); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
/* list, live and visual-story variants */
.pulse-end--list { display: block; margin-top: var(--pulse-space-m); padding-top: var(--pulse-space-s); border-top: 1px solid var(--pulse-rule); }
.pulse-end-list-line { display: flex; align-items: center; gap: var(--pulse-space-xs); margin: 0; color: var(--pulse-meta); font-size: var(--pulse-text-sm); }
.pulse-end--live, .pulse-end--visual { display: block; padding-top: var(--pulse-space-s); border-top: 1px solid var(--pulse-rule); }
.pulse-end-live-title { margin: 0; font-family: var(--font-display); font-weight: var(--weight-semibold); font-size: var(--text-base); color: var(--ink); }
.pulse-end-live-line { margin: var(--pulse-space-2xs) 0 0; color: var(--pulse-meta); font-size: var(--pulse-text-sm); }
@container pulse-end (min-width: 40rem) {
  /* Two columns: the closing text over the actions on the left, the timeline beside both. Grid
     placement only, so the reading order stays the phone's. */
  .pulse-end--edition { grid-template-columns: minmax(0, 1fr) minmax(0, 15rem); column-gap: var(--pulse-space-l); }
  .pulse-end-main { grid-column: 1; grid-row: 1; }
  .pulse-end-side { grid-column: 2; grid-row: 1 / span 2; align-self: start; padding-top: var(--pulse-space-l); }
  .pulse-end-actions { grid-column: 1; grid-row: 2; }
  .pulse-end-sign { grid-column: 1 / -1; grid-row: 3; }
}

/* =====================================================================
   Part B: folds, More from today with Most read, Sections
   ===================================================================== */
/* Phones show the first rows; "Show n more" reveals rows already in the HTML. Without :has()
   every row shows and the toggle stays hidden, so nothing is ever unreachable. */
.pulse-front-fold { display: none; }
@supports selector(:has(*)) {
  @container pulse-page (max-width: 43.99rem) {
    .pulse-front-fold { display: block; margin-top: var(--pulse-space-s); }
    .pulse-front-fold-wrap:not(:has(> .pulse-front-fold[open])) .pulse-front-extra { display: none; }
  }
}
.pulse-front-fold-btn {
  display: inline-flex; align-items: center;
  min-height: var(--pulse-tap);
  padding: 0 var(--pulse-space-s);
  border: 1px solid var(--field-border);
  border-radius: var(--radius-md);
  color: var(--blue-700);
  font-weight: var(--weight-semibold);
  list-style: none;
  cursor: pointer;
}
.pulse-front-fold-btn::-webkit-details-marker { display: none; }
.pulse-front-fold-btn:hover { background: var(--surface-alt); }

.pulse-front-more-list { min-width: 0; }
.pulse-front-mostread { display: none; }
.pulse-front-mostread-h { margin: 0 0 var(--pulse-space-xs); font-family: var(--font-display); font-weight: var(--weight-semibold); font-size: var(--pulse-text-label); color: var(--pulse-label); }
.pulse-front-mostread-list { margin: 0; padding: 0; list-style: none; }
.pulse-front-mostread-list > li + li { border-top: 1px solid var(--pulse-rule); }
@container pulse-page (min-width: 44rem) {
  .pulse-front-more--with-rail { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); column-gap: var(--pulse-space-l); align-items: start; }
  .pulse-front-mostread { display: block; padding-left: var(--pulse-space-m); border-left: 1px solid var(--pulse-rule); }
}
@container pulse-page (min-width: 58rem) {
  /* More from today flows in two columns by rows: newest first reads across, then down. */
  .pulse-front-more-list > .pulse-front-rows { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--pulse-space-m) var(--pulse-space-l); }
  .pulse-front-more-list > .pulse-front-rows > li { margin-top: 0; padding-top: var(--pulse-space-m); border-top: 1px solid var(--pulse-rule); }
}

.pulse-front-chips-h { margin: 0 0 var(--pulse-space-xs); color: var(--pulse-meta); font-size: var(--pulse-text-sm); font-weight: var(--weight-semibold); }
.pulse-front-chiplist { display: flex; flex-wrap: wrap; gap: var(--pulse-space-xs); margin: 0; padding: 0; list-style: none; }
.pulse-front-chip {
  display: inline-flex; align-items: center;
  min-height: var(--pulse-tap);
  padding: 0 var(--pulse-space-s);
  border: 1px solid var(--field-border);
  border-radius: var(--radius-md);
  color: var(--ink);
  font-size: var(--pulse-text-sm);
  font-weight: var(--weight-medium);
  text-decoration: none;
}
.pulse-front-chip:hover { background: var(--surface-alt); }
.pulse-front-chip[aria-current] { font-weight: var(--weight-semibold); box-shadow: inset 0 -3px 0 var(--pulse-nav-current); }
.pulse-front-top { margin: var(--pulse-space-s) 0 0; }
.pulse-front-top a { display: inline-flex; align-items: center; min-height: var(--pulse-tap); font-weight: var(--weight-semibold); }

/* =====================================================================
   Category, Data Desk and Learn fronts; edition pages
   ===================================================================== */
.pulse-front-headwrap { padding: var(--pulse-space-xs) 0 var(--pulse-space-l); }
.pulse-front-cathead { max-width: var(--container-text); }
.pulse-front-cat-h1 { display: flex; align-items: baseline; gap: var(--pulse-space-xs); }
.pulse-front-catsq { flex: none; width: 0.75rem; height: 0.75rem; background: var(--pulse-catmark, var(--pulse-label)); }
.pulse-front-catdesc { margin: var(--pulse-space-xs) 0 0; max-width: var(--pulse-measure); color: var(--pulse-meta); font-size: var(--pulse-fs-dek); line-height: var(--pulse-leading-dense); }
.pulse-front-catcount { margin: var(--pulse-space-xs) 0 0; font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
.pulse-front-cathead--deep .pulse-front-cat-h1 { color: var(--pulse-on-deep); }
/* On the deep head the Data Desk's ink square would vanish: it takes the desk's secondary accent. */
.pulse-front-cathead--deep .pulse-front-catsq { background: var(--pulse-cat-data-desk-secondary); }
.pulse-front-cathead--deep .pulse-front-catdesc, .pulse-front-cathead--deep .pulse-front-catcount { color: var(--pulse-on-deep-soft); }
.pulse-front-empty-line { margin: 0; font-size: var(--text-base); line-height: var(--leading-body); }
.pulse-front-empty-link { margin: var(--pulse-space-2xs) 0 0; }
.pulse-front-empty-link a { display: inline-flex; align-items: center; min-height: var(--pulse-tap); font-weight: var(--weight-semibold); }

.pulse-front-ed { padding-bottom: var(--pulse-space-l); }
.pulse-front-ed-main { min-width: 0; margin-top: 0; }
@container pulse-page (min-width: 58rem) {
  .pulse-front-ed-main { margin-top: var(--pulse-space-xs); }
  .pulse-front-ed-rail { align-self: stretch; }
}

/* ---------- M5: the front page before the first issue (database renders; ADR-037) ----------
   The notice that says when the first edition comes stands where Part A would; Part B follows. */
.pulse-front-notice { padding-top: var(--pulse-space-l); }

/* ===== part 60-article.css ===== */
/* =====================================================================
   EQSIS Pulse: pulse.css, part 60 (article pages and the story blocks).
   Owner: package C (docs/design/BUILD-V2.md).
   ---------------------------------------------------------------------
   v2 first: the article page of every recipe (templates/pages/article.php),
   the visual story (templates/pages/visual_story.php) and the blocks C
   owns, wherever they appear: block.plain_words (.pulse-pw*),
   block.trust_strip (.pulse-trust*), block.takeaways and block.section
   (.pulse-art*), block.analyst_note (.pulse-anote*), block.eqsis_view
   (.pulse-view*), block.sources (.pulse-src*), block.learn (.pulse-learnblk*),
   block.word_note (.pulse-wn*), block.share (.pulse-share-btn*) and
   block.feedback (.pulse-fb*). Last, the article action bar
   (.pulse-actionbar-list, .pulse-action), kept for the dock swap.
   Rules: every colour a token or an alias of part 00; every size from the
   type and space scales (rem); tap targets through --pulse-tap; compact
   first, wider layouts inside @container pulse-page (44rem, 58rem); the
   chrome breakpoints (576/768/992) only where a site rule meets ours.
   Spacing follows DESIGN-SYSTEM.md 6.2: xs inside a block, s between
   units, m between list members, l between blocks, the section joins of
   part 20 between sections. Space and hairlines before boxes.
   ===================================================================== */

/* ---------- The page: one reading column, wide end sections ---------- */
.pulse-art-page { padding-bottom: var(--pulse-space-l); }
/* The reading column is the site's --container-text (48rem); prose inside it caps at --pulse-measure.
   Bands keep their full-bleed tint on phones and tablets: only their content takes the column. */
.pulse-art-page .pulse-sec-in { max-width: var(--container-text); }
.pulse-art-page .pulse-art-wide .pulse-sec-in { max-width: none; }
@container pulse-page (min-width: 58rem) {
  /* From the main-and-rail width a band is a --radius-lg panel (part 20): it matches the column. */
  .pulse-art .pulse-sec { max-width: var(--container-text); }
  .pulse-art .pulse-sec--band .pulse-sec-in { max-width: none; }
}
/* Blocks inside one body section are a continue join apart (--pulse-space-l). */
.pulse-art-sec--body > .pulse-sec-in > * + *,
.pulse-art-sec--diagram > .pulse-sec-in > * + *,
.pulse-art-sec--notes > .pulse-sec-in > * + * { margin-top: var(--pulse-space-l); }

/* ---------- Head (DESIGN-SYSTEM.md 13.1) ---------- */
.pulse-art-head { padding-top: var(--pulse-space-xs); }
.pulse-art-kicker {
  display: flex; flex-wrap: wrap; align-items: center;
  margin: 0 0 var(--pulse-space-xs);
  color: var(--pulse-meta);
  font-size: var(--pulse-text-sm);
  line-height: var(--pulse-leading-dense);
}
.pulse-art-kicker > span + span::before,
.pulse-trust-part + .pulse-trust-part::before,
.pulse-anote-attr > span + span::before {
  content: "";
  display: inline-block;
  width: 0.1875rem; height: 0.1875rem;
  margin-inline: var(--sp-2);
  border-radius: 50%;
  background: currentColor;
  vertical-align: 0.2em;
}
/* The category marker: a 0.5rem square in the category's accent (decoration), then its name. */
.pulse-art-cat { display: inline-flex; align-items: center; gap: var(--sp-2); color: var(--ink); font-weight: var(--weight-semibold); }
.pulse-art-cat-mark { flex: none; width: 0.5rem; height: 0.5rem; background: var(--pulse-art-cat, var(--pulse-label)); }
.pulse-art-cat--markets-today { --pulse-art-cat: var(--pulse-cat-markets-today); }
.pulse-art-cat--trading-desk { --pulse-art-cat: var(--pulse-cat-trading-desk); }
.pulse-art-cat--investing { --pulse-art-cat: var(--pulse-cat-investing); }
.pulse-art-cat--companies { --pulse-art-cat: var(--pulse-cat-companies); }
.pulse-art-cat--sectors-and-themes { --pulse-art-cat: var(--pulse-cat-sectors-and-themes); }
.pulse-art-cat--economy-and-policy { --pulse-art-cat: var(--pulse-cat-economy-and-policy); }
.pulse-art-cat--global-markets { --pulse-art-cat: var(--pulse-cat-global-markets); }
.pulse-art-cat--commodities-and-currency { --pulse-art-cat: var(--pulse-cat-commodities-and-currency); }
.pulse-art-cat--data-desk { --pulse-art-cat: var(--pulse-cat-data-desk); }
.pulse-art-cat--learn { --pulse-art-cat: var(--pulse-cat-learn); }
.pulse-art-format { color: var(--pulse-meta); }
.pulse-art-h1 { max-width: var(--container-text); }

/* ---------- In plain words (block.plain_words) ----------
   The equals mark: two 1.25rem x 0.25rem bars, EQ green over SIS blue, 0.25rem apart (decoration,
   aria-hidden; the label carries the meaning). */
.pulse-pw { margin: 0; color: var(--ink); }
.pulse-pw-mark {
  display: inline-flex; flex-direction: column; gap: 0.25rem;
  width: 1.25rem;
  margin-inline-end: var(--sp-2);
  vertical-align: 0.08em;
}
.pulse-pw-mark > span { display: block; height: 0.25rem; }
.pulse-pw-mark > span:first-child { background: var(--pulse-split-a); }
.pulse-pw-mark > span:last-child { background: var(--pulse-split-b); }
.pulse-pw-label {
  margin-inline-end: var(--sp-1);
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--pulse-text-label);
  color: var(--pulse-plain-label);
}
.pulse-pw--line, .pulse-pw--panel .pulse-pw-line {
  max-width: var(--pulse-measure);
  font-size: var(--pulse-fs-dek);
  line-height: var(--pulse-leading-dense);
  text-wrap: pretty;
}
.pulse-pw--row { max-width: var(--pulse-measure); color: var(--ink-soft); font-size: var(--text-base); line-height: var(--pulse-leading-dense); }
/* Panel: the article's one tinted shape, in the dek's slot. Full-bleed on phones (the text keeps the
   page's left edge); a --radius-md panel once the reading column stops at its 48rem width. */
.pulse-pw--panel {
  margin: var(--pulse-space-s) calc(-1 * var(--pulse-gutter)) 0;
  padding: var(--pulse-space-s) var(--pulse-gutter);
  background: var(--pulse-plain-bg);
}
.pulse-pw--panel .pulse-pw-line { margin: 0; }
@container pulse-page (min-width: 49rem) {
  .pulse-pw--panel { margin-inline: 0; padding-inline: var(--pulse-card-pad); border-radius: var(--radius-md); }
}

/* ---------- Trust strip (block.trust_strip) ---------- */
.pulse-trust {
  margin-top: var(--pulse-space-s);
  color: var(--pulse-meta);
  font-size: var(--pulse-text-sm);
  line-height: var(--pulse-leading-dense);
}
.pulse-trust-line { margin: 0; }
.pulse-trust-part { display: inline; }
.pulse-trust-format { color: var(--ink); font-weight: var(--weight-medium); }
.pulse-trust time { font-variant-numeric: tabular-nums; }
/* The AI badge: an outlined tag inside a link that stays inline text, so the badge is a one-line
   tag in the flow of the strip, never a flex item that wraps into a bordered rectangle. Its 48 px
   hit area is an overlay centred on the badge (as .pulse-frame-ai): the line never grows. Hit
   areas never overlap, because no other part of a strip is a control. */
.pulse-trust-ai { display: inline; color: var(--pulse-meta); text-decoration: none; }
.pulse-trust-ai:hover .pulse-trust-badge { text-decoration: underline; text-underline-offset: 2px; }
.pulse-trust-badge {
  position: relative;
  padding: 0 var(--sp-2);
  border: 1px solid var(--field-border);
  border-radius: var(--radius-sm);
  color: var(--ink);
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}
.pulse-trust-badge::after { content: ""; position: absolute; inset-inline: 0; inset-block: calc((100% - var(--pulse-tap)) / 2); }
/* A badge short enough to be a tag (trust_strip.php: 32 characters or fewer, such as the short form
   of a row that is not yet approved) stays on one line once the column has room for it; in a
   narrower column (320 px at A+ 140%) it may break like text rather than push the page sideways.
   A longer row is never forced onto one line. */
@container pulse-page (min-width: 18rem) {
  .pulse-trust-ai--tag .pulse-trust-badge { white-space: nowrap; }
}
/* The contribution header: who contributed, in what form, what the AI did, who approved. */
.pulse-trust--contribution {
  padding-block: var(--pulse-space-s);
  border-block: 1px solid var(--pulse-rule);
}
.pulse-trust-kicker {
  margin: 0 0 var(--pulse-space-2xs);
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--pulse-text-label);
  color: var(--pulse-analyst-label);
}
.pulse-trust--contribution .pulse-trust-line + .pulse-trust-disclosure,
.pulse-trust--contribution .pulse-trust-disclosure + .pulse-trust-line,
.pulse-trust--contribution .pulse-trust-line + .pulse-trust-line { margin-top: var(--pulse-space-xs); }
.pulse-trust-disclosure { margin: 0; color: var(--ink); }
.pulse-trust-talk { color: var(--pulse-meta); }

/* ---------- Entity chips: one quiet meta line ----------
   No outline and no box: the entities read as a meta line under the trust strip, separated by the
   kicker row's dot. An entity moves to the next line whole (a flex item), and breaks inside only
   when it is longer than the column; the dot ends a line rather than starting one. The follow
   chip's width is reserved once, at the end of the row, and only while the personal layer is on
   (article_chips.php), so nothing shifts when it lands. */
.pulse-art-chips {
  display: flex; flex-wrap: wrap; align-items: baseline;
  margin: var(--pulse-space-xs) 0 0; padding: 0;
  list-style: none;
  color: var(--ink);
  font-size: var(--pulse-text-sm);
  line-height: var(--pulse-leading-dense);
}
.pulse-art-chip { margin: 0; }
.pulse-art-chip:has(+ .pulse-art-chip)::after {
  content: "";
  display: inline-block;
  width: 0.1875rem; height: 0.1875rem;
  margin-inline: var(--sp-2);
  border-radius: 50%;
  background: var(--pulse-meta);
  vertical-align: 0.2em;
}
.pulse-art-chip-kind { color: var(--pulse-meta); }
.pulse-art-chip-name { font-weight: var(--weight-medium); }
.pulse-art-chip-follow { display: block; inline-size: 3rem; block-size: 1px; margin: 0 0 0 var(--sp-2); visibility: hidden; }

/* ---------- Takeaways (block.takeaways) ---------- */
.pulse-art-tk { margin-top: var(--pulse-space-m); padding-top: var(--pulse-space-m); border-top: 1px solid var(--pulse-rule); }
.pulse-art-tk-h {
  margin: 0 0 var(--pulse-space-xs);
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--pulse-text-label);
  line-height: var(--pulse-leading-dense);
  color: var(--pulse-label);
}
.pulse-art-tk-list { counter-reset: pulse-tk; max-width: var(--pulse-measure); margin: 0; padding: 0; list-style: none; }
.pulse-art-tk-list > li {
  counter-increment: pulse-tk;
  position: relative;
  margin: 0;
  padding-inline-start: 1.75rem;
  color: var(--ink);
  font-size: var(--text-base);
  line-height: 1.55;
}
.pulse-art-tk-list > li + li { margin-top: var(--pulse-space-xs); }
.pulse-art-tk-list > li::before {
  content: counter(pulse-tk);
  position: absolute; inset-inline-start: 0; top: 0;
  color: var(--pulse-meta);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
}

/* ---------- Body sections (block.section) ---------- */
.pulse-art-sec-h {
  margin: 0 0 var(--pulse-space-xs);
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-size: var(--pulse-fs-2);
  line-height: var(--leading-tight);
  color: var(--blue-900);
  text-wrap: balance;
}
.pulse-art-sec-check { width: 0.85em; height: 0.85em; margin-inline-end: var(--sp-2); vertical-align: -0.05em; color: var(--pulse-label); }
.pulse-art-p {
  max-width: var(--pulse-measure);
  margin: 0;
  color: var(--ink);
  font-size: var(--text-base);
  line-height: var(--leading-body);
  text-wrap: pretty;
}
.pulse-art-p + .pulse-art-p { margin-top: var(--pulse-space-s); }
.pulse-art-list { max-width: var(--pulse-measure); margin: var(--pulse-space-s) 0 0; padding-inline-start: 1.25em; }
.pulse-art-list li { color: var(--ink); line-height: var(--leading-body); }
@media (min-width: 992px) {
  .pulse-art-p, .pulse-art-list li { font-size: var(--pulse-text-article); }
}
/* Run-in and labelled forms (edition items, cards). */
.pulse-art-runin { max-width: var(--pulse-measure); margin: 0; line-height: var(--leading-body); }
.pulse-art-runin + .pulse-art-runin { margin-top: var(--pulse-space-xs); }
.pulse-art-runin > .pulse-unit-label { margin-inline-end: var(--sp-1); }
.pulse-art-unit { margin: 0; }
.pulse-art-unit > dt { margin: 0 0 var(--pulse-space-2xs); }
.pulse-art-unit > dd { margin: 0; }
.pulse-art-unit > dd > p { max-width: var(--pulse-measure); margin: 0; }
.pulse-art-unit + .pulse-art-unit { margin-top: var(--pulse-space-s); }
/* Inserts after a paragraph: an exhibit sits --pulse-space-l from the text around it (unboxed; its
   own hairline sits above its caption), an analyst note --pulse-space-m, a word note right under its
   paragraph. */
.pulse-art-sec-unit > .pulse-art-ex,
.pulse-art-rq > .pulse-art-ex { margin-block: var(--pulse-space-l); }
.pulse-art-ex + .pulse-art-p { margin-top: 0; }
.pulse-art-limits { max-width: var(--pulse-measure); }

/* ---------- Word notes (block.word_note): <details>, tap to open, in place ----------
   The term in the paragraph (span.pulse-wn-term, block.section) is plain text: without the script
   the control is the note's own <summary> under the paragraph, and a dotted underline on a word
   that does nothing would promise a tap that never comes. The dotted underline belongs to the
   wired toggle only: <button class="pulse-wn-term" aria-expanded aria-controls>, which pulse.js
   prints in its place (package E; data-pulse-note-term). It is a target inside a sentence (the
   WCAG 2.5.8 inline exception), so it takes no overlay that could cover a link on the next line;
   the 48 px <summary> under the paragraph stays the full-size control. With the word-notes switch
   off the toggle reads as plain text again. */
button.pulse-wn-term {
  display: inline;
  margin: 0; padding: 0;
  border: 0; border-radius: 0;
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
  text-align: inherit;
  text-decoration-line: underline;
  text-decoration-style: dotted;
  text-decoration-color: var(--pulse-note-underline);
  text-decoration-thickness: 0.125rem;
  text-underline-offset: 0.2em;
}
button.pulse-wn-term[aria-expanded="true"] { text-decoration-style: solid; text-decoration-color: currentColor; }
.pulse-js-notes-off button.pulse-wn-term { text-decoration: none; cursor: auto; }
.pulse-wn { max-width: var(--pulse-measure); margin: var(--pulse-space-2xs) 0 var(--pulse-space-s); }
.pulse-wn-sum {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  min-height: var(--pulse-tap);
  cursor: pointer;
  list-style: none;
  color: var(--pulse-label);
  font-size: var(--pulse-text-sm);
  font-weight: var(--weight-semibold);
}
.pulse-wn-sum::-webkit-details-marker { display: none; }
.pulse-wn-sum::marker { content: ""; }
.pulse-wn-plus { position: relative; flex: none; width: 1.125rem; height: 1.125rem; border: 0.125rem solid currentColor; border-radius: 50%; }
.pulse-wn-plus::before, .pulse-wn-plus::after {
  content: ""; position: absolute; left: 50%; top: 50%;
  width: 0.5rem; height: 0.125rem;
  margin: -0.0625rem 0 0 -0.25rem;
  background: currentColor;
}
.pulse-wn-plus::after { transform: rotate(90deg); }
.pulse-wn[open] .pulse-wn-plus::after { display: none; }
.pulse-wn-sum:hover .pulse-wn-name { text-decoration: underline; text-underline-offset: 2px; }
.pulse-wn-body {
  padding: var(--pulse-card-pad);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink);
}
.pulse-wn-body > p { margin: 0; line-height: var(--pulse-leading-dense); }
.pulse-wn-body > p + p { margin-top: var(--pulse-space-xs); }
.pulse-wn-def dfn { font-style: normal; font-weight: var(--weight-semibold); }
.pulse-wn-ex, .pulse-wn-owner { font-size: var(--pulse-text-sm); }
.pulse-wn-ex-label { color: var(--pulse-label); font-weight: var(--weight-semibold); }
.pulse-wn-owner a { display: inline-flex; align-items: center; min-height: var(--pulse-tap); font-weight: var(--weight-semibold); }

/* ---------- Analyst note (block.analyst_note): the analyst's own voice ----------
   The vertical split bar is the foundation's .pulse-split-left; no tint, no box. From a 44rem page
   container the bar hangs in the gutter so the words keep the column's left edge. */
.pulse-anote { max-width: var(--pulse-measure); margin: var(--pulse-space-m) 0; padding-block: var(--pulse-space-2xs); }
.pulse-anote-label {
  margin: 0 0 var(--pulse-space-2xs);
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--pulse-text-label);
  line-height: var(--pulse-leading-dense);
  color: var(--pulse-analyst-label);
}
.pulse-anote-q { margin: 0 0 var(--pulse-space-xs); color: var(--pulse-meta); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
.pulse-anote-text, .pulse-anote-text > p {
  margin: 0;
  color: var(--ink);
  font-size: var(--pulse-fs-dek);
  line-height: var(--pulse-leading-dense);
  text-wrap: pretty;
}
.pulse-anote--quote .pulse-anote-text { margin: 0; padding: 0; border: 0; }
.pulse-anote-attr { margin: var(--pulse-space-xs) 0 0; color: var(--pulse-meta); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
@container pulse-page (min-width: 44rem) {
  .pulse-anote.pulse-split-left { padding-inline-start: 0; }
  .pulse-anote.pulse-split-left::before { inset-inline-start: calc(-1 * (var(--pulse-split-h) + var(--pulse-space-s))); }
}

/* ---------- What to watch (block.what_to_watch) ---------- */
.pulse-art-watch-list { max-width: var(--pulse-measure); margin: var(--pulse-space-xs) 0 0; padding: 0; list-style: none; }
.pulse-art-watch-item { margin: 0; padding-block: var(--pulse-space-xs); border-top: 1px solid var(--pulse-rule); line-height: var(--pulse-leading-dense); }
.pulse-art-watch-list { border-bottom: 1px solid var(--pulse-rule); }
.pulse-art-watch:last-child .pulse-art-watch-list { border-bottom: 0; }
.pulse-art-watch-when { display: block; color: var(--blue-900); font-size: var(--pulse-text-sm); font-weight: var(--weight-semibold); }
.pulse-art-watch-what { color: var(--ink); }
@container pulse-page (min-width: 44rem) {
  .pulse-art-watch-item { display: grid; grid-template-columns: var(--pulse-rail) minmax(0, 1fr); column-gap: var(--pulse-space-m); align-items: baseline; }
}

/* ---------- EQSIS View (block.eqsis_view), on its band ---------- */
.pulse-view-h {
  margin: 0 0 var(--pulse-space-xs);
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-size: var(--pulse-fs-1);
  line-height: var(--pulse-leading-card);
  color: var(--blue-900);
}
.pulse-view-text { max-width: var(--pulse-measure); margin: 0; color: var(--ink); font-size: var(--pulse-fs-dek); line-height: var(--pulse-leading-dense); }
.pulse-view-disclosure { max-width: var(--pulse-measure); margin-top: var(--pulse-space-s); padding-top: var(--pulse-space-s); border-top: 1px solid var(--line); color: var(--ink); font-size: var(--pulse-text-sm); }
.pulse-view-disclosure p { margin: 0 0 var(--pulse-space-xs); }

/* ---------- Share (block.share) ---------- */
/* One control: the sheet form's button carries its own label ("Share this story"); no rules. */
.pulse-share-btn { padding-block: var(--pulse-space-s); scroll-margin-top: calc(var(--header-h) + var(--sp-4)); }
.pulse-share-btn--compact { padding-block: 0; }

/* ---------- Sources and notes (block.sources) ---------- */
.pulse-src-row { max-width: var(--pulse-measure); margin: 0; color: var(--pulse-meta); font-size: var(--pulse-text-sm); font-weight: var(--weight-medium); line-height: var(--pulse-leading-dense); }
.pulse-src-h { font-size: var(--pulse-fs-1); line-height: var(--pulse-leading-card); }
.pulse-src-list { max-width: var(--pulse-measure); margin: var(--pulse-space-xs) 0 0; padding-inline-start: 1.25em; color: var(--ink); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
.pulse-src-list > li + li { margin-top: var(--pulse-space-2xs); }
.pulse-src-title { font-weight: var(--weight-medium); }
.pulse-src-time { color: var(--pulse-meta); }
.pulse-src-disclaimer, .pulse-src-tier2 { max-width: var(--pulse-measure); margin-top: var(--pulse-space-s); color: var(--ink); font-size: var(--pulse-text-sm); }
.pulse-src-disclaimer p, .pulse-src-tier2 p { margin: 0 0 var(--pulse-space-2xs); }

/* ---------- Learn (block.learn): the idea row and the one course block ---------- */
.pulse-learnblk { display: grid; gap: var(--pulse-space-m); align-items: start; }
@container pulse-page (min-width: 44rem) {
  .pulse-learnblk:has(> .pulse-learnblk-idea) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.pulse-learnblk-idea {
  display: grid; gap: var(--pulse-space-2xs);
  min-height: var(--pulse-tap);
  padding-block: var(--pulse-space-s);
  border-block: 1px solid var(--pulse-rule);
  color: var(--ink);
  text-decoration: none;
}
.pulse-learnblk-kind { font-family: var(--font-display); font-weight: var(--weight-semibold); font-size: var(--pulse-text-label); color: var(--pulse-label); }
.pulse-learnblk-title { font-family: var(--font-display); font-weight: var(--weight-display); font-size: var(--pulse-fs-1); line-height: var(--pulse-leading-card); color: var(--blue-900); }
.pulse-learnblk-idea:hover .pulse-learnblk-title { text-decoration: underline; text-underline-offset: 3px; }
.pulse-learnblk-meta { color: var(--pulse-meta); font-size: var(--pulse-text-sm); }
.pulse-learnblk-course { max-width: var(--container-text); padding: var(--pulse-card-pad); border-radius: var(--radius-md); background: var(--surface-alt); }
.pulse-learnblk--on-band .pulse-learnblk-course { background: var(--surface); }
.pulse-learnblk-tag { margin: 0 0 var(--pulse-space-xs); }
.pulse-learnblk-name { margin: 0; font-family: var(--font-display); font-weight: var(--weight-display); font-size: var(--pulse-fs-1); line-height: var(--pulse-leading-card); color: var(--blue-900); }
.pulse-learnblk-line { max-width: var(--pulse-measure); margin: var(--pulse-space-xs) 0 0; color: var(--ink); line-height: var(--pulse-leading-dense); }
.pulse-learnblk-btn { display: flex; align-items: center; justify-content: center; width: 100%; min-height: var(--pulse-tap); margin-top: var(--pulse-space-s); }
@container pulse-page (min-width: 44rem) {
  .pulse-learnblk-btn { display: inline-flex; width: auto; }
}

/* ---------- Up next (card.story_card from package B): one column, two, then three ---------- */
.pulse-art-next { display: grid; gap: var(--pulse-space-m); margin: 0; padding: 0; list-style: none; }
.pulse-art-next-item { margin: 0; min-width: 0; }
@container pulse-page (min-width: 44rem) {
  .pulse-art-next { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--pulse-space-l); }
}
@container pulse-page (min-width: 58rem) {
  .pulse-art-next { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ---------- Reader feedback (block.feedback): one quiet question ---------- */
.pulse-fb { padding-top: var(--pulse-space-s); scroll-margin-top: calc(var(--header-h) + var(--sp-4)); }
.pulse-fb-h {
  margin: 0 0 var(--pulse-space-xs);
  font-family: var(--font-body);
  font-weight: var(--weight-semibold);
  font-size: var(--pulse-text-base);
  line-height: var(--pulse-leading-dense);
  color: var(--ink);
}
.pulse-fb-form { margin: 0; }
.pulse-fb-buttons { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
/* A label never breaks inside its button. Each button is at least as wide as its label (a button
   narrower than its words would spill them over its border) and the row wraps between buttons
   only when the labels themselves do not fit, which at 360 px they do. */
.pulse-fb-btn { min-height: var(--pulse-tap); min-width: max-content; padding-inline: var(--sp-3); white-space: nowrap; }
.pulse-fb-buttons > .pulse-fb-btn { flex: 1 1 0; }
/* "Yes" and "Not yet": two equal outlined buttons, each as wide as the wider label (never stretched
   across the column), whether the block has the column (explainers) or sits as a shrink-to-fit
   item beside Share (the end card). */
.pulse-fb--clear .pulse-fb-buttons { display: inline-grid; grid-auto-flow: column; grid-auto-columns: 1fr; }
.pulse-fb--clear .pulse-fb-btn { min-width: 6rem; }
/* The reactions: three quiet text buttons separated by space, not three outlined boxes. Each is a
   48 px tall target; its words keep the column's left edge. */
.pulse-fb--reactions .pulse-fb-buttons { gap: 0 var(--pulse-space-m); }
.pulse-fb--reactions .pulse-fb-buttons > .pulse-fb-btn { flex: 0 0 auto; }
.pulse-fb-btn--text {
  display: inline-flex; align-items: center;
  margin: 0; padding: 0;
  border: 0; border-radius: var(--radius-sm);
  background: transparent;
  color: var(--blue-700);
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  line-height: var(--pulse-leading-dense);
  text-decoration: none;
  cursor: pointer;
}
.pulse-fb-btn--text:hover { color: var(--blue-900); text-decoration: underline; text-underline-offset: 0.2em; }
.pulse-fb-btn[aria-pressed="true"] { text-decoration: underline; text-decoration-thickness: 0.125rem; text-underline-offset: 0.2em; }
.pulse-fb-btn--text[aria-pressed="true"] { color: var(--ink); }
.pulse-fb-help { max-width: var(--pulse-measure); margin-top: var(--pulse-space-s); padding: var(--pulse-card-pad); border: 1px solid var(--line); border-radius: var(--radius-md); }
.pulse-fb-help-lead { margin: 0; color: var(--ink); font-weight: var(--weight-semibold); }
.pulse-fb-help-list { margin: var(--pulse-space-2xs) 0 0; padding: 0; list-style: none; }
.pulse-fb-help-list a { display: inline-flex; align-items: center; min-height: var(--pulse-tap); }
.pulse-fb-status { margin: var(--pulse-space-xs) 0 0; color: var(--ink); font-size: var(--pulse-text-sm); }
.pulse-fb-status:empty { margin: 0; }

/* ---------- The pillar's reader questions (block.reader_question, proposed) ---------- */
.pulse-art-questions > .pulse-art-sec-h { margin-bottom: 0; }
.pulse-art-rq { margin-top: var(--pulse-space-m); padding-top: var(--pulse-space-m); border-top: 1px solid var(--pulse-rule); }
.pulse-art-rq-label { margin: 0 0 var(--pulse-space-2xs); color: var(--pulse-meta); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
.pulse-art-rq-q {
  max-width: var(--pulse-measure);
  margin: 0 0 var(--pulse-space-xs);
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-size: var(--pulse-fs-1);
  line-height: var(--pulse-leading-card);
  color: var(--blue-900);
  text-wrap: balance;
}
.pulse-art-rq > .pulse-pw--line { margin-bottom: var(--pulse-space-s); }
.pulse-art-rq-head { margin: 0 0 var(--pulse-space-xs); color: var(--ink); font-family: var(--font-display); font-size: var(--pulse-fs-1); }

/* ---------- The visual story (templates/pages/visual_story.php): frames as HTML ----------
   Each card is package E's frame preview (share_frame.php, html mode; its styles are part 80);
   this part lays the cards out: one a screen on phones, two from 44rem, three from 58rem, each
   then the List twin in a <details> (the frame's own top row carries "N of M"). */
.pulse-art-vs-intro { max-width: var(--pulse-measure); margin: var(--pulse-space-xs) 0 0; color: var(--ink); font-size: var(--pulse-fs-dek); line-height: var(--pulse-leading-dense); }
.pulse-art-vs-intro a, .pulse-art-vs-jump a { display: inline-flex; align-items: center; min-height: var(--pulse-tap); font-weight: var(--weight-semibold); }
.pulse-art-vs-jump { margin: 0; font-size: var(--pulse-text-sm); }
.pulse-art-vs-cards { display: grid; gap: var(--pulse-space-l); margin: 0; padding: 0; list-style: none; }
.pulse-art-vs-item { margin: 0; min-width: 0; }
@container pulse-page (min-width: 44rem) {
  .pulse-art-vs-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--pulse-space-m); }
}
@container pulse-page (min-width: 58rem) {
  .pulse-art-vs-cards { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.pulse-art-vs-list-sum {
  display: inline-flex; align-items: center;
  min-height: var(--pulse-tap);
  cursor: pointer;
  color: var(--pulse-label);
  font-weight: var(--weight-semibold);
}
/* The list's numbers are the list's own: small plain numerals in --pulse-meta from a CSS counter,
   as the takeaways (never typed into the text, so nothing is read twice). */
.pulse-art-vs-list-ol { counter-reset: pulse-vs; max-width: var(--pulse-measure); margin: var(--pulse-space-xs) 0 0; padding: 0; list-style: none; }
.pulse-art-vs-list-ol > li {
  counter-increment: pulse-vs;
  position: relative;
  margin: 0;
  padding-block: var(--pulse-space-xs);
  padding-inline-start: 1.75rem;
  border-top: 1px solid var(--pulse-rule);
  color: var(--ink);
  line-height: var(--pulse-leading-dense);
}
.pulse-art-vs-list-ol > li::before {
  content: counter(pulse-vs) ".";
  position: absolute; inset-inline-start: 0; top: var(--pulse-space-xs);
  color: var(--pulse-meta);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
}
.pulse-art-vs-list-slot { color: var(--pulse-label); font-weight: var(--weight-semibold); }
.pulse-art-vs-list-h { font-weight: var(--weight-semibold); }
.pulse-art-vs-list-plain { display: block; color: var(--ink-soft); }

/* ---------- Print: the words, the sources and the disclosures; no controls ---------- */
@media print {
  .pulse-share-btn, .pulse-fb, #art-next, .pulse-art-chip-follow, .pulse-wn-sum { display: none !important; }
  .pulse-wn-body { border: 0; padding: 0; }
  .pulse-art-vs-item { break-inside: avoid; }
}

/* =====================================================================
   The article action bar (templates/components/article_actionbar.php;
   bottom_bar.php docks it). Off on v2 article pages until the dock-swap
   hook lands (package C open issue); the M1 article rules that stood here
   went at the v2 integration (13 October 2026): nothing printed them.
   ===================================================================== */
/* The sticky action bar (positioned by section 9; shown under 768 px only, as .pulse-dock is). The
   items mirror the bottom bar: 1px less than the bar, whose 1px top border sits inside its
   border-box height, so the bar is exactly --pulse-actionbar-h, the height the dock spacer, the
   consent-banner offset and the scroll padding assume (2.4.11). */
.pulse-actionbar-list { display: flex; margin: 0; padding: 0; list-style: none; }
.pulse-actionbar-list > li { flex: 1 1 0; min-width: 0; }
.pulse-action {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.125rem;
  width: 100%; min-height: calc(var(--pulse-actionbar-h) - 1px); min-width: 48px; padding: var(--sp-1) 0.125rem;
  border: 0; background: transparent; color: var(--ink-soft);
  font-family: var(--font-body); font-size: var(--pulse-text-xs); font-weight: var(--weight-medium);
  line-height: 1.2; text-align: center; text-decoration: none;
}
.pulse-action svg { flex: none; }
.pulse-action:hover { color: var(--blue-700); }
.pulse-action[aria-pressed="true"] { color: var(--blue-600); font-weight: var(--weight-semibold); }
.pulse-action:focus-visible { outline-offset: -3px; }

@media print {
  .pulse-chart-data > summary { display: none !important; }
  .pulse-chart { min-width: 0; }
}

/* ---------- M5 (package P3): glossary auto-links and corrections under the piece ---------- */
/* An auto-link is the site's own prose link with a dotted underline, so a glossary term reads
   apart from a story link without relying on colour (the link colour pair is the foundation's). */
.pulse-gl { text-decoration-style: dotted; text-underline-offset: 0.18em; }
/* Corrections: one quiet list under the piece, the kind in semibold, then the standards link. */
.pulse-art-corr-h { font-size: var(--pulse-fs-1); line-height: var(--pulse-leading-card); }
.pulse-art-corr-list { max-width: var(--pulse-measure); margin: var(--pulse-space-xs) 0 0; padding: 0; list-style: none; color: var(--ink); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
.pulse-art-corr-item + .pulse-art-corr-item { margin-top: var(--pulse-space-2xs); }
.pulse-art-corr-kind { font-weight: var(--weight-semibold); }
.pulse-art-corr-how { margin: var(--pulse-space-xs) 0 0; font-size: var(--pulse-text-sm); }
.pulse-art-corr-how a { display: inline-flex; align-items: center; min-height: var(--pulse-tap); }

/* ---------- M6 (package S5): Google's Preferred Sources plain link ----------
   One quiet line after each article's notes and on every standards page (inside part 70's
   .pulse-gloss-standards column): the site's own link colour pair, so no new contrast pair, and a
   full tap target. No image and no script from Google (src/seo/preferred_source.php). */
.pulse-prefsrc { margin: var(--pulse-space-s) 0 0; font-size: var(--pulse-text-sm); }
.pulse-prefsrc a { display: inline-flex; align-items: center; min-height: var(--pulse-tap); }

/* ---------- M6 (final gate): More on this topic ----------
   The SEO Steward's internal links after the body (a cluster piece's pillar first, then the page it
   follows up): one quiet list in the corrections' type, the site's own link colour pair (no new contrast
   pair) and a full tap target per link (src/publishing/pages_article.php, article_db_more_links()). */
.pulse-art-more-list { max-width: var(--pulse-measure); margin: var(--pulse-space-xs) 0 0; padding: 0; list-style: none; font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
.pulse-art-more-list a { display: inline-flex; align-items: center; min-height: var(--pulse-tap); }

/* ===== part 70-pages.css ===== */
/* =====================================================================
   EQSIS Pulse: pulse.css, part 70 (the other page types and the pattern
   library). Owner: package D (docs/design/BUILD-V2.md): Live, the hub
   index and hubs, the Data Desk series, glossary, search, standards, the
   analyst profile, the personal-page shells, 404, state.notice, and the
   shadow-only pattern library at /pulse/design/. Only the --pulse-* roles
   of part 00 and the site's tokens; no literal colour. Compact first: the
   unqueried rules are the 360 px phone; wider layouts sit in @container
   pulse-page (44rem, 58rem). Prefixes: .pulse-live*, .pulse-hub*,
   .pulse-desk*, .pulse-gloss*, .pulse-search*, .pulse-pl*, .pulse-notice*.
   ===================================================================== */

/* ---------- The breadcrumb's current crumb on a phone (every page type) ----------
   The unlinked current crumb repeats the h1 directly beneath it (an article's whole headline), so
   below 576 px it keeps to one line and ends in an ellipsis instead of wrapping to two or three. It
   takes the rest of the line when at least 6rem is left there, else a line of its own. The full
   text stays in the accessibility tree, and the h1 shows it in full. The BreadcrumbList is
   unchanged: unlinked crumbs never enter it. */
@media (max-width: 575.98px) {
  .breadcrumb-eq li[aria-current="page"] {
    flex: 1 1 6rem;
    min-width: 0;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}

/* ---------- Page heads (outside the section list, under the breadcrumb) ---------- */
.pulse-live-head, .pulse-hub-head, .pulse-desk-head, .pulse-gloss-head, .pulse-search-head, .pulse-pl-head {
  padding-top: var(--pulse-space-s);
}
.pulse-live-kicker, .pulse-hub-kind, .pulse-desk-kicker, .pulse-gloss-kicker, .pulse-search-kicker, .pulse-pl-kicker {
  margin: 0 0 var(--pulse-space-2xs);
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--pulse-text-label);
  line-height: var(--pulse-leading-dense);
  color: var(--pulse-label);
  font-variant-numeric: tabular-nums;
}
.pulse-live-status { color: var(--ink); }
.pulse-live-dek, .pulse-hub-about, .pulse-desk-about, .pulse-pl-dek {
  margin: var(--pulse-space-xs) 0 0;
  color: var(--pulse-meta);
}
.pulse-hub-meta, .pulse-gloss-meta, .pulse-pl-meta { margin-top: var(--pulse-space-xs); }
.pulse-hub-meta time, .pulse-gloss-meta time, .pulse-live-ed-state time { white-space: nowrap; }
.pulse-live-head .pulse-trust, .pulse-desk-head .pulse-trust { margin-top: var(--pulse-space-s); }
.pulse-live-head .pulse-notice { margin-bottom: 0; }
/* The follow chip arrives with the personal layer: its width is held on the meta row now, so
   nothing moves when it does (COMPONENTS.md 9). */
.pulse-hub-follow { display: inline-block; inline-size: 6rem; block-size: 1px; visibility: hidden; }

/* ---------- state.notice: one line on the current surface, never a box ---------- */
.pulse-notice {
  display: flex;
  align-items: flex-start;
  gap: var(--pulse-space-xs);
  max-width: var(--pulse-measure);
  margin-block: var(--pulse-space-s);
  color: var(--ink);
}
.pulse-notice[hidden] { display: none; }
.pulse-notice-icon { flex: none; inline-size: 1.25rem; block-size: 1.25rem; margin-top: 0.15em; color: var(--pulse-label); }
.pulse-notice-body { min-width: 0; }
.pulse-notice-text { margin: 0; font-size: var(--text-base); line-height: var(--pulse-leading-dense); }
.pulse-notice-link { font-weight: var(--weight-semibold); }
.pulse-notice-ways { display: flex; flex-wrap: wrap; gap: 0 var(--pulse-space-s); margin: var(--pulse-space-2xs) 0 0; padding: 0; list-style: none; }
.pulse-notice-ways a { display: inline-flex; align-items: center; min-height: var(--pulse-tap); min-width: var(--pulse-tap); font-weight: var(--weight-semibold); }

/* ---------- Lists shared by these pages: rows, cards, links ---------- */
.pulse-hub-rows, .pulse-search-list { margin: 0; padding: 0; list-style: none; }
.pulse-hub-rows > li + li, .pulse-search-list > li + li { margin-top: var(--pulse-space-m); padding-top: var(--pulse-space-m); border-top: 1px solid var(--pulse-rule); }
.pulse-hub-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--pulse-space-m); margin: 0; padding: 0; list-style: none; }
.pulse-hub-grid > li + li { padding-top: var(--pulse-space-m); border-top: 1px solid var(--pulse-rule); }
@container pulse-page (min-width: 44rem) {
  .pulse-hub-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--pulse-space-l); }
  .pulse-hub-grid > li, .pulse-hub-grid > li + li { padding-top: var(--pulse-space-m); border-top: 1px solid var(--pulse-rule); }
}
@container pulse-page (min-width: 58rem) {
  .pulse-hub-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.pulse-hub-sub, .pulse-gloss-sub, .pulse-search-sub, .pulse-search-sample-h {
  margin: var(--pulse-space-l) 0 var(--pulse-space-xs);
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--text-base);
  line-height: var(--pulse-leading-dense);
  color: var(--ink);
}
.pulse-hub-module > .pulse-hub-sub:first-child { margin-top: 0; }
/* Chips: one link each, 48 px tall, outlined; never a count badge. */
.pulse-hub-jump-list, .pulse-search-topics, .pulse-pl-toc-list {
  display: flex; flex-wrap: wrap; gap: var(--pulse-space-xs);
  margin: var(--pulse-space-s) 0 0; padding: 0; list-style: none;
}
.pulse-search-topics a {
  display: inline-flex; align-items: center; gap: var(--pulse-space-2xs);
  min-height: var(--pulse-tap);
  padding-inline: var(--pulse-space-s);
  border: 1px solid var(--field-border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink);
  font-weight: var(--weight-medium);
  text-decoration: none;
}
.pulse-search-topics a:hover {
  border-color: var(--pulse-label); text-decoration: underline; text-underline-offset: 3px;
}
/* The hub index jump list reads as text, not as a row of buttons: links with a middle dot between. */
.pulse-hub-jump-list, .pulse-pl-toc-list { gap: 0 var(--pulse-space-m); }
.pulse-hub-jump-link, .pulse-pl-toc-list a { display: inline-flex; align-items: center; gap: var(--pulse-space-2xs); min-height: var(--pulse-tap); min-width: var(--pulse-tap); font-weight: var(--weight-semibold); text-decoration: none; }
.pulse-hub-jump-link:hover, .pulse-pl-toc-list a:hover { text-decoration: underline; text-underline-offset: 3px; }
.pulse-hub-jump-n { color: var(--pulse-meta); font-weight: var(--weight-body); font-variant-numeric: tabular-nums; }
/* Ways on: a calm list of links, one per 48 px row, hairlines between (never a wall of buttons). */
.pulse-search-ways { max-width: 34rem; margin: 0; padding: 0; list-style: none; }
.pulse-search-ways > li { border-bottom: 1px solid var(--pulse-rule); }
.pulse-search-ways > li:first-child { border-top: 1px solid var(--pulse-rule); }
.pulse-search-ways a { display: flex; align-items: center; justify-content: space-between; gap: var(--pulse-space-s); min-height: var(--pulse-tap); font-weight: var(--weight-semibold); text-decoration: none; }
.pulse-search-ways a::after { content: "\203A" / ""; color: var(--pulse-meta); font-weight: var(--weight-body); }
.pulse-search-ways a:hover { text-decoration: underline; text-underline-offset: 3px; }

/* Notes at the end of a page: the standard disclaimer row, quiet. */
.pulse-hub-notes { padding-top: var(--pulse-space-m); border-top: 1px solid var(--pulse-rule); }
.pulse-hub-notes .pulse-copy p { margin: 0; max-width: var(--pulse-measure); color: var(--pulse-meta); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
.pulse-hub-notes .pulse-copy-state { margin: var(--pulse-space-2xs) 0 0; }

/* =====================================================================
   Live
   ===================================================================== */
.pulse-live-now-h { margin: 0 0 var(--pulse-space-s); }
.pulse-live-controls {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--pulse-space-xs) var(--pulse-space-s);
}
/* Key moments only: a real checkbox and its label, unboxed (no outer border or fill, so the row never
   reads as a settings form above the river); the whole 48 px line is the hit area. The filter is CSS
   (:has), so it works without JavaScript. Where :has() is not supported the control is not shown at
   all, rather than shown and dead. */
.pulse-live-filter { display: none; margin: 0; }
@supports selector(:has(a)) {
  .pulse-live-filter {
    position: relative;
    display: inline-flex; align-items: center; gap: var(--pulse-space-xs);
    min-height: var(--pulse-tap);
  }
  .pulse-live-filter:has(.pulse-live-km-input:checked) .pulse-live-km { font-weight: var(--weight-semibold); }
  .pulse-live-feed:has(.pulse-live-km-input:checked) .pulse-live-river > li:not([data-key-moment]):not([data-milestone]) { display: none; }
}
.pulse-live-km-input { flex: none; inline-size: 1.125rem; block-size: 1.125rem; margin: 0; accent-color: var(--pulse-label); }
.pulse-live-km { color: var(--ink); font-size: var(--pulse-text-sm); font-weight: var(--weight-medium); cursor: pointer; }
.pulse-live-km::after { content: ""; position: absolute; inset: 0; }
/* The new-updates slot: reserved at its final height, so a "Show 2 new updates" swap moves nothing. */
.pulse-live-slot { display: flex; align-items: center; min-height: var(--pulse-reserve-since); }
.pulse-live-slot-note { margin: 0; color: var(--pulse-meta); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
.pulse-live-device p { margin: 0; max-width: var(--pulse-measure); color: var(--pulse-meta); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
.pulse-live-device + .pulse-copy-state { margin: var(--pulse-space-2xs) 0 0; }

/* The river: one hairline between rows, the series' own rhythm; the since bookmark draws in a gap. */
.pulse-live-river { margin: var(--pulse-space-s) 0 0; padding: 0; list-style: none; }
.pulse-live-river > li { padding-block: var(--pulse-space-m); border-top: 1px solid var(--pulse-rule); }
.pulse-live-river--fold { margin: 0; }
.pulse-live-river--fold > li { padding-block: var(--pulse-space-s); }
.pulse-live-river--fold > li:last-child { border-bottom: 0; padding-bottom: 0; }

/* Folded smaller updates: a real <details>; the summary is one 48 px row. */
.pulse-live-group { padding-block: var(--pulse-space-xs); }
.pulse-live-fold-sum {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 0 var(--pulse-space-s);
  min-height: var(--pulse-tap);
  color: var(--ink);
  font-size: var(--text-base);
  line-height: var(--pulse-leading-dense);
  cursor: pointer;
  list-style: none;
  font-variant-numeric: tabular-nums;
}
.pulse-live-fold-sum::-webkit-details-marker { display: none; }
.pulse-live-fold-range { white-space: nowrap; }
.pulse-live-fold-act { display: inline-flex; align-items: center; gap: var(--pulse-space-2xs); color: var(--pulse-label); font-weight: var(--weight-semibold); }
.pulse-live-fold-act::after {
  content: ""; inline-size: 0.5rem; block-size: 0.5rem;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: translateY(-0.15rem) rotate(45deg);
}
.pulse-live-fold[open] .pulse-live-fold-act::after { transform: translateY(0.1rem) rotate(-135deg); }
.pulse-live-fold[open] .pulse-live-fold-show, .pulse-live-fold:not([open]) .pulse-live-fold-hide { display: none; }
.pulse-live-fold-sum:hover .pulse-live-fold-act { text-decoration: underline; text-underline-offset: 3px; }

/* Milestones: schedule facts in the river, quiet, with a rule running on. */
.pulse-live-river > .pulse-live-ms {
  display: flex; align-items: center; gap: var(--pulse-space-xs);
  padding-block: var(--pulse-space-s);
  color: var(--pulse-meta);
  font-size: var(--pulse-text-sm);
  line-height: var(--pulse-leading-dense);
}
.pulse-live-ms::after { content: ""; flex: 1 1 1rem; min-inline-size: 1rem; border-top: 1px solid var(--pulse-rule); }
.pulse-live-ms-time { flex: none; color: var(--ink); font-weight: var(--weight-semibold); font-variant-numeric: tabular-nums; }
.pulse-live-ms-text a { display: inline-flex; align-items: center; min-height: var(--pulse-tap-dense); }
.pulse-live-end { margin: var(--pulse-space-m) 0 0; color: var(--pulse-meta); font-size: var(--text-base); }

/* Today's schedule: market hours and editions, its own section with an h2 that reads as a kicker
   (beside the river from a 58rem page container). */
.pulse-live-rail { margin-top: var(--pulse-space-l); padding-top: var(--pulse-space-m); border-top: 1px solid var(--pulse-rule); }
.pulse-live-rail-title {
  margin: 0 0 var(--pulse-space-s);
  font-family: var(--font-display); font-weight: var(--weight-semibold);
  font-size: var(--pulse-text-label); line-height: var(--pulse-leading-dense); color: var(--pulse-label);
}
.pulse-live-rail-h {
  margin: 0 0 var(--pulse-space-xs);
  font-family: var(--font-display); font-weight: var(--weight-semibold);
  font-size: var(--text-base); line-height: var(--pulse-leading-dense); color: var(--ink);
}
.pulse-live-hours + .pulse-live-rail-h { margin-top: var(--pulse-space-m); }
.pulse-live-hours { margin: 0; }
.pulse-live-hours > div {
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: 0 var(--pulse-space-s);
  padding-block: var(--pulse-space-xs);
  border-bottom: 1px solid var(--pulse-rule);
  font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense);
}
.pulse-live-hours dt { font-weight: var(--weight-medium); color: var(--ink); }
.pulse-live-hours dd { margin: 0; color: var(--ink); font-variant-numeric: tabular-nums; }
.pulse-live-eds { margin: 0; padding: 0; list-style: none; }
.pulse-live-eds > li { padding-block: var(--pulse-space-2xs); border-bottom: 1px solid var(--pulse-rule); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
.pulse-live-eds a { display: inline-flex; align-items: center; min-height: var(--pulse-tap-dense); font-weight: var(--weight-semibold); font-size: var(--text-base); }
.pulse-live-ed-state { display: block; color: var(--pulse-meta); font-variant-numeric: tabular-nums; padding-bottom: var(--pulse-space-2xs); }
.pulse-live-days { margin: 0; padding: 0; list-style: none; }
.pulse-live-days > li { border-bottom: 1px solid var(--pulse-rule); }
.pulse-live-days > li:first-child { border-top: 1px solid var(--pulse-rule); }
.pulse-live-days a { display: flex; align-items: center; min-height: var(--pulse-tap); font-weight: var(--weight-semibold); }

@container pulse-page (min-width: 44rem) {
  /* The river's times hang in the 4rem rail (card.row does it for each row); the fold and the
     milestones keep the same edge. */
  .pulse-live-fold-sum { padding-inline-start: calc(var(--pulse-rail) + var(--pulse-space-m)); }
  .pulse-live-river > .pulse-live-ms { display: grid; grid-template-columns: var(--pulse-rail) auto minmax(1rem, 1fr); column-gap: var(--pulse-space-m); }
  .pulse-live-end { padding-inline-start: calc(var(--pulse-rail) + var(--pulse-space-m)); }
}
@container pulse-page (min-width: 58rem) {
  .pulse-live-grid > .pulse-col-rail { grid-row: 1; }
  .pulse-live-rail { margin-top: 0; }
}

/* =====================================================================
   Hubs and the hub index
   ===================================================================== */
.pulse-hub-exhibit, .pulse-desk-latest { max-width: 46rem; }
.pulse-hub-module > .pulse-trust { margin-top: var(--pulse-space-s); }
.pulse-hub-group-head { margin-bottom: var(--pulse-space-s); }
.pulse-hub-members { margin: 0; padding: 0; list-style: none; max-width: 46rem; }
.pulse-hub-members > li {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0 var(--pulse-space-xs);
  min-height: var(--pulse-tap);
  border-bottom: 1px solid var(--pulse-rule);
  font-size: var(--text-base);
}
.pulse-hub-members > li:first-child { border-top: 1px solid var(--pulse-rule); }
.pulse-hub-members a { display: inline-flex; align-items: center; min-height: var(--pulse-tap); font-weight: var(--weight-semibold); }
.pulse-hub-member-note { color: var(--pulse-meta); font-size: var(--pulse-text-sm); }
.pulse-hub-members-note { margin-top: var(--pulse-space-xs); }
.pulse-hub-personal { min-height: var(--pulse-tap); }
.pulse-hub-personal > .pulse-notice:first-child { margin-top: 0; }
.pulse-hub-sample { margin-top: var(--pulse-space-l); padding-top: var(--pulse-space-m); border-top: 1px dashed var(--field-border); }
.pulse-hub-sample > .pulse-notice:first-child { margin-top: 0; }
.pulse-hub-copy p, .pulse-hub-designation p { margin: 0; max-width: var(--pulse-measure); color: var(--pulse-meta); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
.pulse-hub-copy + .pulse-copy-state, .pulse-hub-designation + .pulse-copy-state { margin: var(--pulse-space-2xs) 0 0; }
.pulse-hub-copy ~ .pulse-hub-copy { margin-top: var(--pulse-space-s); }
.pulse-hub-designation { margin-top: var(--pulse-space-xs); }

/* =====================================================================
   Data Desk series
   ===================================================================== */
.pulse-desk-method p { margin: 0 0 var(--pulse-space-s); max-width: var(--pulse-measure); font-size: var(--text-base); line-height: var(--leading-body); }
.pulse-desk-method p:last-child { margin-bottom: 0; }
.pulse-desk-learn a { display: inline-flex; align-items: center; min-height: var(--pulse-tap); font-weight: var(--weight-semibold); }
/* M5 (database renders): the latest reading's own dated words under its one exhibit, the owner
   page of the standing data, and the earlier readings as dated links (never a table). */
.pulse-desk-reading { max-width: var(--pulse-measure); margin-top: var(--pulse-space-m); }
.pulse-desk-reading-date { margin: 0; color: var(--pulse-meta); font-size: var(--pulse-text-sm); }
.pulse-desk-reading-h { margin: var(--pulse-space-2xs) 0 0; font-family: var(--font-display); font-size: var(--text-lg); line-height: var(--pulse-leading-dense); }
.pulse-desk-reading-h a { display: inline-block; min-height: var(--pulse-tap); padding-block: var(--pulse-space-2xs); }
.pulse-desk-reading-plain { margin: var(--pulse-space-2xs) 0 0; font-size: var(--text-base); line-height: var(--leading-body); }
.pulse-desk-owner { margin: var(--pulse-space-s) 0 0; max-width: var(--pulse-measure); font-size: var(--text-base); line-height: var(--leading-body); }
.pulse-desk-readings { margin: 0; padding: 0; list-style: none; max-width: 46rem; }
.pulse-desk-readings > li + li { margin-top: var(--pulse-space-m); padding-top: var(--pulse-space-m); border-top: 1px solid var(--pulse-rule); }
/* Live's way on, under the honest close (on the band): the current edition and the day's hubs. */
.pulse-live-onward { margin-top: var(--pulse-space-m); max-width: var(--pulse-measure); }
.pulse-live-onward-h { margin: 0 0 var(--pulse-space-2xs); font-family: var(--font-display); font-size: var(--text-lg); line-height: var(--pulse-leading-dense); color: var(--ink); }
.pulse-live-onward-list { margin: 0; padding: 0; list-style: none; }
.pulse-live-onward-list > li { display: flex; flex-wrap: wrap; align-items: center; column-gap: var(--pulse-space-xs); border-bottom: 1px solid var(--pulse-rule); }
.pulse-live-onward-list > li:first-child { border-top: 1px solid var(--pulse-rule); }
.pulse-live-onward-list a { display: inline-flex; align-items: center; min-height: var(--pulse-tap); font-weight: var(--weight-semibold); }
.pulse-live-onward-note { color: var(--pulse-meta); font-size: var(--pulse-text-sm); }
/* An empty day on Live and an empty hub index say so in one plain line. */
.pulse-live-none, .pulse-hub-none { margin: 0 0 var(--pulse-space-s); max-width: var(--pulse-measure); color: var(--pulse-meta); font-size: var(--text-base); line-height: var(--leading-body); }
/* A semantic table; the wrapper scrolls only if a cell cannot wrap (keyboard reachable). */
.pulse-desk-tablewrap { max-width: 46rem; overflow-x: auto; }
.pulse-desk-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-base);
  line-height: var(--pulse-leading-dense);
  font-variant-numeric: tabular-nums;
}
.pulse-desk-table caption {
  caption-side: top;
  padding-bottom: var(--pulse-space-xs);
  text-align: start;
  color: var(--ink);
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
}
.pulse-desk-table th, .pulse-desk-table td {
  padding: var(--pulse-space-xs) var(--pulse-space-xs) var(--pulse-space-xs) 0;
  border-bottom: 1px solid var(--pulse-rule);
  text-align: start;
  vertical-align: baseline;
}
.pulse-desk-table thead th { color: var(--pulse-meta); font-size: var(--pulse-text-sm); font-weight: var(--weight-semibold); border-bottom-color: var(--field-border); }
.pulse-desk-table tbody th { font-weight: var(--weight-medium); color: var(--ink); }
.pulse-desk-table .pulse-desk-num { text-align: end; }

/* =====================================================================
   Glossary and standards
   ===================================================================== */
.pulse-gloss-def { margin: var(--pulse-space-s) 0 0; color: var(--ink); }
.pulse-gloss-entry { max-width: var(--pulse-measure); }
.pulse-gloss-unit + .pulse-gloss-unit { margin-top: var(--pulse-space-s); }
.pulse-gloss-label {
  margin: 0 0 var(--pulse-space-2xs);
  font-family: var(--font-display); font-weight: var(--weight-semibold);
  font-size: var(--pulse-text-label); line-height: var(--pulse-leading-dense);
  color: var(--pulse-label);
}
.pulse-gloss-unit p { margin: 0; font-size: var(--text-base); line-height: var(--leading-body); }
.pulse-gloss-story { margin-top: var(--pulse-space-xs) !important; }
.pulse-gloss-story a { font-weight: var(--weight-semibold); }
.pulse-gloss-story-kind, .pulse-gloss-related-kind { color: var(--pulse-meta); font-size: var(--pulse-text-sm); }
.pulse-gloss-learn > .pulse-gloss-sub:first-child { margin-top: 0; }
.pulse-gloss-related { margin: 0 0 var(--pulse-space-l); padding: 0; list-style: none; max-width: 46rem; }
.pulse-gloss-related > li { display: flex; flex-wrap: wrap; align-items: center; gap: 0 var(--pulse-space-xs); min-height: var(--pulse-tap); border-bottom: 1px solid var(--pulse-rule); }
.pulse-gloss-related > li:first-child { border-top: 1px solid var(--pulse-rule); }
.pulse-gloss-related a { display: inline-flex; align-items: center; min-height: var(--pulse-tap); font-weight: var(--weight-semibold); }
.pulse-gloss-standards { padding-bottom: var(--pulse-space-xl); }
.pulse-gloss-standards h1 {
  margin: 0;
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: var(--pulse-fs-4); line-height: var(--pulse-leading-lead);
  color: var(--blue-900); text-wrap: balance;
}
.pulse-gloss-copy { margin-top: var(--pulse-space-m); }
.pulse-gloss-copy .pulse-copy p { max-width: var(--pulse-measure); font-size: var(--text-base); line-height: var(--leading-body); }
.pulse-gloss-others { margin-top: var(--pulse-space-l); padding-top: var(--pulse-space-m); border-top: 1px solid var(--pulse-rule); }
.pulse-gloss-others .pulse-gloss-sub { margin-top: 0; }
.pulse-gloss-others .pulse-gloss-related { margin-bottom: 0; }
/* The published corrections under the corrections policy row (M4, package R5; ADR-033;
   templates/components/corrections_list.php). One column at the reading measure, a hairline between
   items, the kind and the IST time as a meta line, the headline as a 48 px link, then the sentence.
   Only --ink, --pulse-meta and --pulse-rule on the page surface, pairs the foundation already checks. */
.pulse-corrections { margin-top: var(--pulse-space-l); }
.pulse-corrections > .pulse-gloss-sub { margin-top: 0; }
.pulse-corrections-empty { margin: 0; color: var(--pulse-meta); font-size: var(--text-base); line-height: var(--leading-body); }
.pulse-corrections-list { margin: 0; padding: 0; list-style: none; max-width: var(--pulse-measure); }
.pulse-correction { padding: var(--pulse-space-s) 0; border-bottom: 1px solid var(--pulse-rule); }
.pulse-correction:first-child { border-top: 1px solid var(--pulse-rule); }
.pulse-correction p { margin: 0; }
.pulse-correction-meta { color: var(--pulse-meta); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); font-variant-numeric: tabular-nums; }
.pulse-correction-kind { font-weight: var(--weight-semibold); }
.pulse-correction-meta time { white-space: nowrap; }
.pulse-correction-piece { font-weight: var(--weight-semibold); overflow-wrap: anywhere; }
.pulse-correction-piece a { display: inline-flex; align-items: center; min-height: var(--pulse-tap); }
.pulse-correction-what { color: var(--ink); font-size: var(--text-base); line-height: var(--leading-body); }

/* =====================================================================
   Search and 404
   ===================================================================== */
.pulse-search-form { max-width: 40rem; margin-top: var(--pulse-space-s); }
.pulse-search-label {
  display: block; margin-bottom: var(--pulse-space-xs);
  font-family: var(--font-display); font-weight: var(--weight-semibold);
  font-size: var(--text-base); line-height: var(--pulse-leading-dense); color: var(--ink);
}
.pulse-search-row { display: flex; gap: var(--pulse-space-xs); }
.pulse-search-input {
  flex: 1 1 auto; min-width: 0;
  min-height: var(--pulse-tap);
  padding-inline: var(--pulse-space-s);
  border: 1px solid var(--field-border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--text-base);
}
.pulse-search-submit {
  flex: none;
  min-height: var(--pulse-tap);
  padding-inline: var(--pulse-space-m);
  border: 1px solid var(--pulse-label);
  border-radius: var(--radius-sm);
  background: var(--pulse-label);
  color: var(--surface);
  font-family: var(--font-body);
  font-weight: var(--weight-semibold);
  font-size: var(--text-base);
}
.pulse-search-submit:hover { background: var(--blue-700); border-color: var(--blue-700); }
.pulse-search-hint, .pulse-search-help { margin: var(--pulse-space-xs) 0 0; max-width: var(--pulse-measure); color: var(--pulse-meta); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
.pulse-search-more-wrap { margin: var(--pulse-space-s) 0 0; }
.pulse-search-more-wrap:has(> [hidden]) { display: none; }
.pulse-search-more {
  min-height: var(--pulse-tap); padding-inline: var(--pulse-space-m);
  border: 1px solid var(--field-border); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--ink); font-weight: var(--weight-semibold);
}
.pulse-search-sample { margin-top: var(--pulse-space-l); padding-top: var(--pulse-space-m); border-top: 1px dashed var(--field-border); }
.pulse-search-sample > .pulse-notice:first-child { margin-top: 0; }
.pulse-search-browse > .pulse-search-sub { margin-top: var(--pulse-space-l); }
.pulse-search-404 { padding-bottom: var(--pulse-space-xl); }
.pulse-search-404 .pulse-search-sub { margin-top: var(--pulse-space-l); }

/* =====================================================================
   The pattern library (/pulse/design/, shadow only)
   ===================================================================== */
/* Code in the library (token names, file paths) never drops under 13 px: Bootstrap sets code at 0.875em. */
.pulse-type-patterns code { font-size: max(0.8125rem, 0.875em); }
.pulse-pl-meta code, .pulse-pl-type-meta code, .pulse-pl-mini code { font-size: max(0.8125rem, 0.875em); color: var(--ink); }
.pulse-pl-stubs { margin: var(--pulse-space-xs) 0 0; max-width: var(--pulse-measure); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); color: var(--ink); }
.pulse-pl-sub {
  margin: var(--pulse-space-l) 0 var(--pulse-space-2xs);
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: var(--pulse-fs-1); line-height: var(--pulse-leading-card); color: var(--blue-900);
}
.pulse-pl-found > .pulse-pl-sub:first-child { margin-top: 0; }
.pulse-pl-note { margin: 0 0 var(--pulse-space-xs); max-width: var(--pulse-measure); color: var(--pulse-meta); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }

/* Type and space scales */
.pulse-pl-type, .pulse-pl-space, .pulse-pl-swatches, .pulse-pl-cats, .pulse-pl-marks, .pulse-pl-entries { margin: 0; padding: 0; list-style: none; }
.pulse-pl-type-row { display: flex; flex-direction: column; gap: var(--pulse-space-2xs); padding-block: var(--pulse-space-xs); border-bottom: 1px solid var(--pulse-rule); }
.pulse-pl-type-sample { color: var(--ink); overflow-wrap: anywhere; }
.pulse-pl-type-meta { color: var(--pulse-meta); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
.pulse-pl-fs-figure { font-family: var(--font-display); font-weight: var(--weight-display); font-size: var(--pulse-fs-figure); line-height: var(--pulse-leading-figure); color: var(--pulse-figure-ink); font-variant-numeric: tabular-nums; }
.pulse-pl-fs-4 { font-family: var(--font-display); font-weight: var(--weight-display); font-size: var(--pulse-fs-4); line-height: var(--pulse-leading-lead); color: var(--blue-900); }
.pulse-pl-fs-3 { font-family: var(--font-display); font-weight: var(--weight-display); font-size: var(--pulse-fs-3); line-height: var(--pulse-leading-lead); color: var(--blue-900); }
.pulse-pl-fs-2 { font-family: var(--font-display); font-weight: var(--weight-display); font-size: var(--pulse-fs-2); line-height: var(--leading-tight); color: var(--blue-900); }
.pulse-pl-fs-1 { font-family: var(--font-display); font-weight: var(--weight-display); font-size: var(--pulse-fs-1); line-height: var(--pulse-leading-card); color: var(--blue-900); }
.pulse-pl-fs-dek { font-size: var(--pulse-fs-dek); line-height: var(--pulse-leading-dense); }
.pulse-pl-fs-base { font-size: var(--text-base); line-height: var(--leading-body); }
.pulse-pl-fs-sm { font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
.pulse-pl-fs-xs { font-size: var(--pulse-text-xs); line-height: var(--pulse-leading-dense); }
.pulse-pl-space-row { display: flex; flex-direction: column; gap: var(--pulse-space-2xs); padding-block: var(--pulse-space-xs); border-bottom: 1px solid var(--pulse-rule); }
.pulse-pl-space-bar { display: block; block-size: 0.75rem; background: var(--pulse-label); }
.pulse-pl-space-bar--2xs { inline-size: var(--pulse-space-2xs); }
.pulse-pl-space-bar--xs { inline-size: var(--pulse-space-xs); }
.pulse-pl-space-bar--s { inline-size: var(--pulse-space-s); }
.pulse-pl-space-bar--m { inline-size: var(--pulse-space-m); }
.pulse-pl-space-bar--l { inline-size: var(--pulse-space-l); }
.pulse-pl-space-bar--xl { inline-size: var(--pulse-space-xl); }
.pulse-pl-measure { margin-top: var(--pulse-space-s); }
.pulse-pl-measure p { margin: 0; max-width: var(--pulse-measure); padding-inline-end: var(--pulse-space-xs); border-inline-end: 2px dashed var(--field-border); font-size: var(--text-base); line-height: var(--leading-body); }

/* Colour roles: swatches named by role */
.pulse-pl-swatches { display: grid; grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr)); gap: var(--pulse-space-xs) var(--pulse-space-s); }
.pulse-pl-swatch { display: flex; align-items: center; gap: var(--pulse-space-xs); min-height: var(--pulse-tap-dense); }
/* The library's state table: each row header links its entry, a dense-row 44 px target. */
.pulse-pl-table th a { display: inline-flex; align-items: center; min-height: var(--pulse-tap-dense); }
.pulse-pl-chip { flex: none; inline-size: 2rem; block-size: 2rem; border: 1px solid var(--line); border-radius: var(--radius-sm); }
.pulse-pl-chip--ink { background: var(--ink); }
.pulse-pl-chip--meta { background: var(--pulse-meta); }
.pulse-pl-chip--label { background: var(--pulse-label); }
.pulse-pl-chip--plain-label { background: var(--pulse-plain-label); }
.pulse-pl-chip--up { background: var(--pulse-up); }
.pulse-pl-chip--down { background: var(--pulse-down); }
.pulse-pl-chip--flat { background: var(--pulse-flat); }
.pulse-pl-chip--chart-main { background: var(--pulse-chart-main); }
.pulse-pl-chip--chart-compare { background: var(--pulse-chart-compare); }
.pulse-pl-chip--chart-ref { background: var(--pulse-chart-ref); }
.pulse-pl-chip--chart-quiet { background: var(--pulse-chart-quiet); }
.pulse-pl-chip--rule { background: var(--pulse-rule); }
.pulse-pl-chip--band { background: var(--surface-alt); }
.pulse-pl-chip--deep { background: var(--pulse-stamp-bg); }
.pulse-pl-chip--split-a { background: var(--pulse-split-a); }
.pulse-pl-chip--split-b { background: var(--pulse-split-b); }

/* Tags, category markers, direction marks, the split bar */
.pulse-pl-tags { display: flex; flex-wrap: wrap; gap: var(--pulse-space-xs); margin: 0 0 var(--pulse-space-s); }
.pulse-pl-cats { display: flex; flex-wrap: wrap; gap: var(--pulse-space-xs) var(--pulse-space-m); font-size: var(--pulse-text-sm); }
.pulse-pl-cats > li { display: inline-flex; align-items: center; gap: var(--pulse-space-xs); }
.pulse-pl-cat { inline-size: 0.5rem; block-size: 0.5rem; background: var(--pulse-meta); }
.pulse-pl-cat--markets-today { background: var(--pulse-cat-markets-today); }
.pulse-pl-cat--trading-desk { background: var(--pulse-cat-trading-desk); }
.pulse-pl-cat--investing { background: var(--pulse-cat-investing); }
.pulse-pl-cat--companies { background: var(--pulse-cat-companies); }
.pulse-pl-cat--sectors-and-themes { background: var(--pulse-cat-sectors-and-themes); }
.pulse-pl-cat--economy-and-policy { background: var(--pulse-cat-economy-and-policy); }
.pulse-pl-cat--global-markets { background: var(--pulse-cat-global-markets); }
.pulse-pl-cat--commodities-and-currency { background: var(--pulse-cat-commodities-and-currency); }
.pulse-pl-cat--data-desk { background: var(--pulse-cat-data-desk); }
.pulse-pl-cat--learn { background: var(--pulse-cat-learn); }
.pulse-pl-marks > li { padding-block: var(--pulse-space-2xs); font-size: var(--text-base); }
.pulse-pl-split {
  margin-top: var(--pulse-space-s);
  padding: calc(var(--pulse-split-h-frame) + var(--pulse-space-s)) var(--pulse-space-s) var(--pulse-space-s);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
}
.pulse-pl-split.pulse-split-left { padding: var(--pulse-space-s) var(--pulse-space-s) var(--pulse-space-s) calc(var(--pulse-split-h) + var(--pulse-space-s)); }
.pulse-pl-split p { margin: 0; }

/* Treatments: the live run of render_sections(), inside a frame the gutter outdent fits */
.pulse-pl-mini { padding-block: var(--pulse-space-xs); border-bottom: 1px solid var(--pulse-rule); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
.pulse-pl-mini:first-child { border-top: 1px solid var(--pulse-rule); }
.pulse-pl-demo {
  margin-top: var(--pulse-space-s);
  padding: var(--pulse-space-m) var(--pulse-gutter);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
}
.pulse-pl-demo-text { margin: 0; max-width: var(--pulse-measure); font-size: var(--text-base); line-height: var(--leading-body); }

/* Entries and specimens */
.pulse-pl-entry { padding-block: var(--pulse-space-l); border-top: 1px solid var(--pulse-rule); }
.pulse-pl-group > .pulse-sec-head + .pulse-pl-entry { border-top: 0; padding-top: 0; }
.pulse-pl-forms > .pulse-pl-entry:first-child { border-top: 0; padding-top: 0; }
.pulse-pl-name { margin: 0; font-family: var(--font-display); font-weight: var(--weight-display); font-size: var(--pulse-fs-1); line-height: var(--pulse-leading-card); color: var(--blue-900); }
.pulse-pl-meta { margin: var(--pulse-space-2xs) 0 0; color: var(--pulse-meta); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
.pulse-pl-purpose { margin: var(--pulse-space-xs) 0 0; max-width: var(--pulse-measure); font-size: var(--text-base); line-height: var(--pulse-leading-dense); }
.pulse-pl-specs { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--pulse-space-m); margin-top: var(--pulse-space-s); }
.pulse-pl-cap { margin: 0 0 var(--pulse-space-xs); font-family: var(--font-display); font-weight: var(--weight-semibold); font-size: var(--pulse-text-label); line-height: var(--pulse-leading-dense); color: var(--pulse-label); }
.pulse-pl-stage {
  padding: var(--pulse-space-s) var(--pulse-gutter);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--surface);
}
.pulse-pl-stage--stub { border-style: dashed; }
/* On a phone the stage drops its side padding and side borders, so a specimen gets the real page
   column (312 px at 360), never a narrower one: compact SVG twins then draw at their own scale, at
   or above their 272 px design floor and the 13 px text floor, exactly as on a real page. */
@media (max-width: 575.98px) {
  .pulse-pl-stage { padding-inline: 0; border-inline: 0; border-radius: 0; }
}
.pulse-pl-error { padding: var(--pulse-space-s); border: 2px solid var(--danger); border-radius: var(--radius-md); color: var(--ink); }
.pulse-pl-error p { margin: 0; }
.pulse-pl-error-msg { margin-top: var(--pulse-space-2xs) !important; font-size: var(--pulse-text-sm); overflow-wrap: anywhere; }
@container pulse-page (min-width: 58rem) {
  /* Infographic sizes: the mini beside the inline; a wide form takes the full row. */
  .pulse-pl-specs--sizes { grid-template-columns: minmax(0, 22rem) minmax(0, 1fr); align-items: start; }
  .pulse-pl-size--wide { grid-column: 1 / -1; }
  .pulse-pl-specs--sizes > .pulse-pl-size--inline:first-child { grid-column: 1 / -1; }
}
/* Chrome specimens are drawn in place: the bottom bar is fixed on a phone page, not here. */
@media (max-width: 767.98px) {
  .pulse-pl-stage .pulse-dock { height: auto; }
  .pulse-pl-stage .pulse-bottombar { position: static; box-shadow: none; }
}
/* Forms the live page shows at one width only, or after the script runs, are drawn in place at
   every width: the Stamp's progress row (phones) and contents panel (992 px and up), and a filled
   "New" tag. The specimens sit in an inert stage, so nothing here is sticky or operable. */
.pulse-pl-stage .pulse-progress {
  position: static;
  display: flex; align-items: center; gap: var(--pulse-space-xs);
  min-block-size: var(--pulse-reserve-progress);
  margin-inline: 0;
  padding-inline: 0;
  border-block-start: 1px solid var(--pulse-rule);
  font-size: var(--pulse-text-sm);
  line-height: var(--pulse-leading-dense);
}
.pulse-pl-stage .pulse-progress-panel {
  position: static;
  display: block;
  max-inline-size: 22rem;
  margin-block-start: 0;
  padding: var(--pulse-card-pad);
  border-radius: var(--radius-lg);
  background: var(--surface-alt);
}

@media print {
  .pulse-live-controls, .pulse-live-slot, .pulse-hub-follow, .pulse-search-form { display: none !important; }
}

/* ===== part 72-nudge.css ===== */
/* =====================================================================
   EQSIS Pulse: pulse.css, part 72 (the web nudge). Owner: package A3
   (M7; docs/build/M7-PLAN.md, ADR-046 section 6): the one
   plain line pulse.js adds at the end of <main> for a returning reader
   (.pulse-nudge, a polite status region), with a follow button or one
   link (.pulse-nudge-act). It is appended after the page's own content,
   so nothing above it moves. Only the site's tokens and the --pulse-*
   roles of part 00; no literal colour: the text is the body ink, the
   link the site's link, the button the site's .btn-outline.
   ===================================================================== */

.pulse-nudge {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3);
  margin-block: var(--pulse-space-m);
  font-size: var(--text-base);
  line-height: var(--pulse-leading-dense);
}
.pulse-nudge-act { min-block-size: var(--pulse-tap); display: inline-flex; align-items: center; }
a.pulse-nudge-act { text-decoration: underline; text-underline-offset: 0.2em; }

@media print {
  .pulse-nudge { display: none !important; }
}

/* ===== part 74-preferences.css ===== */
/* =====================================================================
   EQSIS Pulse: pulse.css, part 74 (privacy). Owner: package A5 (M7,
   docs/build/M7-PLAN.md). ADR-048: the DPDP profiling notice (.pulse-dpdp*, templates/components/
   dpdp_notice.php), an in-flow strip between </main> and the site footer
   that the events script shows (no fixed position, so it never covers the
   site's cookie notice or the dock); and the preference centre
   (.pulse-prefs*, templates/pages/preferences.php). Only the site's
   tokens and the --pulse-* roles of part 00; no literal colour, no
   literal font family; every size in rem from the scales; controls at
   least 48 px (var(--pulse-tap)); no motion.
   ===================================================================== */

/* ---------- The profiling notice ---------- */
.pulse-dpdp {
  padding-block: var(--pulse-space-m);
  border-top: 1px solid var(--pulse-rule);
  background: var(--surface-alt);
  color: var(--ink);
}
.pulse-dpdp[hidden] { display: none; }
.pulse-dpdp-copy p { margin: 0 0 var(--pulse-space-xs); max-width: var(--pulse-measure); font-size: var(--text-base); line-height: var(--pulse-leading-dense); }
.pulse-dpdp .pulse-copy-state { margin: 0 0 var(--pulse-space-xs); }
.pulse-dpdp-more { display: flex; flex-wrap: wrap; align-items: center; gap: var(--pulse-space-xs) var(--pulse-space-m); margin: 0; }
.pulse-dpdp-more a { display: inline-flex; align-items: center; min-height: var(--pulse-tap); font-weight: var(--weight-semibold); }
.pulse-dpdp-close { min-height: var(--pulse-tap); display: inline-flex; align-items: center; justify-content: center; }
.pulse-dpdp-close[hidden] { display: none; }

/* ---------- The preference centre ---------- */
.pulse-prefs { padding-bottom: var(--pulse-space-xl); }
.pulse-prefs-title {
  margin: 0;
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: var(--pulse-fs-4); line-height: var(--pulse-leading-lead);
  color: var(--blue-900); text-wrap: balance;
}
.pulse-prefs .pulse-copy p { max-width: var(--pulse-measure); font-size: var(--text-base); line-height: var(--leading-body); }
.pulse-prefs-nojs { margin: var(--pulse-space-s) 0 0; max-width: var(--pulse-measure); color: var(--pulse-meta); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
.pulse-prefs-nojs[hidden] { display: none; }
.pulse-prefs-section { margin-top: var(--pulse-space-l); padding-top: var(--pulse-space-m); border-top: 1px solid var(--pulse-rule); }
.pulse-prefs-h {
  margin: 0 0 var(--pulse-space-xs);
  font-family: var(--font-display); font-weight: var(--weight-semibold);
  font-size: var(--pulse-fs-1); line-height: var(--pulse-leading-dense); color: var(--ink);
}
.pulse-prefs-sub {
  margin: var(--pulse-space-m) 0 var(--pulse-space-2xs);
  font-family: var(--font-display); font-weight: var(--weight-semibold);
  font-size: var(--text-base); line-height: var(--pulse-leading-dense); color: var(--ink);
}
.pulse-prefs-acts { display: flex; flex-wrap: wrap; gap: var(--pulse-space-xs); margin-top: var(--pulse-space-s); }
.pulse-prefs-acts[hidden], .pulse-prefs-list[hidden], .pulse-prefs-form[hidden], .pulse-prefs-answer[hidden], .pulse-prefs-requests[hidden], .pulse-prefs-state[hidden] { display: none; }
.pulse-prefs-btn { min-height: var(--pulse-tap); display: inline-flex; align-items: center; justify-content: center; }
.pulse-prefs-btn[hidden] { display: none; }
.pulse-prefs-state { margin: var(--pulse-space-xs) 0 0; color: var(--pulse-meta); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
.pulse-prefs-list { margin: var(--pulse-space-s) 0 0; padding: 0; list-style: none; max-width: 46rem; }
.pulse-prefs-item {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--pulse-space-2xs) var(--pulse-space-s);
  min-height: var(--pulse-tap); padding-block: var(--pulse-space-2xs);
  border-bottom: 1px solid var(--pulse-rule);
}
.pulse-prefs-item:first-child { border-top: 1px solid var(--pulse-rule); }
.pulse-prefs-name { flex: 1 1 12rem; font-weight: var(--weight-semibold); }
.pulse-prefs-on { color: var(--pulse-meta); font-size: var(--pulse-text-sm); }
.pulse-prefs-answer { margin-top: var(--pulse-space-s); padding: var(--pulse-space-s); background: var(--surface-alt); border-radius: var(--radius-sm); }
.pulse-prefs-answer .pulse-copy p { margin: 0 0 var(--pulse-space-2xs); }
.pulse-prefs-ref { margin: 0; font-variant-numeric: tabular-nums; }
.pulse-prefs-refcode { font-weight: var(--weight-semibold); letter-spacing: 0.04em; }
.pulse-prefs-form { margin-top: var(--pulse-space-s); max-width: 40rem; }
.pulse-prefs-fieldset { margin: 0 0 var(--pulse-space-s); padding: 0; border: 0; }
.pulse-prefs-legend { margin-bottom: var(--pulse-space-2xs); font-weight: var(--weight-semibold); font-size: var(--text-base); }
.pulse-prefs-choice { display: flex; align-items: center; gap: var(--pulse-space-xs); min-height: var(--pulse-tap); }
.pulse-prefs-choice input { inline-size: 1.25rem; block-size: 1.25rem; flex: none; }
.pulse-prefs-label { display: block; margin: var(--pulse-space-s) 0 var(--pulse-space-2xs); font-weight: var(--weight-semibold); }
.pulse-prefs-input {
  display: block; inline-size: 100%; max-width: 28rem; min-height: var(--pulse-tap);
  padding-inline: var(--pulse-space-s);
  border: 1px solid var(--field-border); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--ink);
  font-family: var(--font-body); font-size: var(--text-base);
}
.pulse-prefs-correct .pulse-prefs-btn { margin-top: var(--pulse-space-s); }
.pulse-prefs-requests { margin: var(--pulse-space-s) 0 0; padding: 0; list-style: none; color: var(--pulse-meta); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
.pulse-prefs-requests > li { padding-block: var(--pulse-space-2xs); }

@media print {
  .pulse-dpdp, .pulse-prefs-acts, .pulse-prefs-form { display: none !important; }
}

/* ===== part 76-wire.css ===== */
/* =====================================================================
   EQSIS Pulse: pulse.css, part 76 (the live wire). Owner: package P3
   (M11; docs/build/M11-PLAN.md section 8, ADR-066): block.wire_list in
   its four variants (the /pulse/wire/ page, the front page's "What's
   moving now", Live's headlines, a hub's "In the news elsewhere"), the
   wire page's head and its quiet state. Only the site's tokens and the
   --pulse-* roles of part 00; no literal colour. Text pairs used are the
   ones data/check/contrast_pairs.json already checks in the four colour
   states: --ink and --pulse-meta on --surface and --surface-alt, --ink,
   --pulse-meta and --blue-700 on --pulse-new-bg (a new row), and
   --pulse-plain-label on --surface and --surface-alt (Trending, "EQSIS
   Pulse"). Trending is a word with an icon, never colour alone. Compact
   first: the unqueried rules are the 360 px phone; every row is one link
   at least 48 px tall; nothing animates unless motion is allowed, and
   then only opacity (no layout shift).
   ===================================================================== */

/* ---------- The wire page's head (outside the section list) ---------- */
.pulse-wire-head { padding-top: var(--pulse-space-s); }
.pulse-wire-kicker {
  margin: 0 0 var(--pulse-space-2xs);
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--pulse-text-label);
  line-height: var(--pulse-leading-dense);
  color: var(--pulse-plain-label);
}
.pulse-wire-dek { margin: var(--pulse-space-xs) 0 0; color: var(--pulse-meta); }

/* ---------- The module ---------- */
.pulse-wire { max-width: 48rem; }
.pulse-wire-intro, .pulse-wire-asof {
  margin: 0 0 var(--pulse-space-xs);
  max-width: var(--pulse-measure);
  color: var(--pulse-meta);
  font-size: var(--pulse-text-sm);
  line-height: var(--pulse-leading-dense);
  font-variant-numeric: tabular-nums;
}
.pulse-wire-sub {
  display: flex; align-items: center; gap: var(--pulse-space-2xs);
  margin: var(--pulse-space-s) 0 var(--pulse-space-2xs);
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--pulse-text-base);
  line-height: var(--pulse-leading-dense);
  color: var(--ink);
}

/* The reserved slot keeps its height whether it holds the note or the "Show n new" button, so the
   button appearing never moves a row (the Live page's slot rule). */
.pulse-wire-controls { display: flex; flex-wrap: wrap; align-items: center; gap: var(--pulse-space-xs); margin: 0 0 var(--pulse-space-2xs); }
.pulse-wire-slot { display: flex; flex: 1 1 14rem; align-items: center; min-height: var(--pulse-tap); }
.pulse-wire-slot-note { margin: 0; color: var(--pulse-meta); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
.pulse-wire-show {
  min-height: var(--pulse-tap); padding: 0 var(--sp-3);
  border: 1px solid var(--field-border); border-radius: var(--radius-sm);
  background: var(--pulse-new-bg); color: var(--ink);
  font-family: var(--font-body); font-size: var(--pulse-text-sm); font-weight: var(--weight-semibold);
}
.pulse-wire-show:hover { text-decoration: underline; text-underline-offset: 3px; }
.pulse-wire-pause { flex: 0 0 auto; }
[data-pulse-wire][data-paused="true"] .pulse-wire-pause { border-width: 2px; }

/* ---------- Lists, items and groups ---------- */
.pulse-wire-list, .pulse-wire-group-list { margin: 0; padding: 0; list-style: none; }
.pulse-wire-item {
  position: relative;
  min-height: var(--pulse-tap);
  padding-block: var(--pulse-space-xs);
  border-top: 1px solid var(--pulse-rule);
}
.pulse-wire-list > .pulse-wire-item:first-child { border-top: 0; }
.pulse-wire-meta {
  margin: 0;
  color: var(--pulse-meta);
  font-size: var(--pulse-text-sm);
  line-height: var(--pulse-leading-dense);
  font-variant-numeric: tabular-nums;
}
.pulse-wire-meta time { white-space: nowrap; }
.pulse-wire-src { font-weight: var(--weight-semibold); }
.pulse-wire-src--pulse { color: var(--pulse-plain-label); }
.pulse-wire-link {
  display: block;
  margin-top: var(--pulse-space-2xs);
  color: var(--ink);
  font-family: var(--font-body);
  font-weight: var(--weight-semibold);
  font-size: var(--text-base);
  line-height: var(--pulse-leading-card);
  text-decoration: none;
  overflow-wrap: anywhere;
}
/* The headline is the row's one link, stretched over the row (a 48 px target at any length). */
.pulse-wire-link::after { content: ""; position: absolute; inset: 0; }
.pulse-wire-link:hover { text-decoration: underline; text-underline-offset: 3px; }
.pulse-wire-out { display: inline-block; margin-inline-start: 0.3em; vertical-align: 0.05em; color: var(--pulse-meta); }
.pulse-wire-item--new { background: var(--pulse-new-bg); padding-inline: var(--pulse-space-xs); }
.pulse-wire-item--new .pulse-wire-link { color: var(--blue-700); }

.pulse-wire-trend {
  display: inline-flex; align-items: center; gap: 0.25em;
  color: var(--pulse-plain-label);
  font-weight: var(--weight-semibold);
}
.pulse-wire-icon { flex: 0 0 auto; }

.pulse-wire-group { padding-block: var(--pulse-space-s) var(--pulse-space-2xs); border-top: 1px solid var(--pulse-rule); }
.pulse-wire-river > .pulse-wire-group:first-child { border-top: 0; padding-top: 0; }
/* A group is headed by its leading item: its meta line, its headline as the heading (the head's one link,
   stretched over the head: a 48 px target), then "N sources" and Trending. */
.pulse-wire-group-head { position: relative; min-height: var(--pulse-tap); margin-bottom: var(--pulse-space-2xs); }
.pulse-wire-group-h {
  margin: var(--pulse-space-2xs) 0 0;
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-size: var(--pulse-text-card);
  line-height: var(--pulse-leading-card);
  color: var(--blue-900);
}
.pulse-wire-group-h .pulse-wire-link { margin-top: 0; font: inherit; color: inherit; }
.pulse-wire-group-meta { margin: var(--pulse-space-2xs) 0 0; color: var(--pulse-meta); font-size: var(--pulse-text-sm); line-height: var(--pulse-leading-dense); }
.pulse-wire-group-list { padding-inline-start: var(--pulse-space-s); border-inline-start: 3px solid var(--pulse-rule); }
.pulse-wire-group-list > .pulse-wire-item:first-child { border-top: 0; }

/* ---------- Trending stories as chips (front) ---------- */
.pulse-wire-trending { margin-bottom: var(--pulse-space-xs); }
.pulse-wire-chips { display: flex; flex-wrap: wrap; gap: var(--pulse-space-xs); margin: 0; padding: 0; list-style: none; }
.pulse-wire-chip {
  display: inline-flex; flex-direction: column; justify-content: center;
  min-height: var(--pulse-tap); max-width: 100%;
  padding: var(--sp-1) var(--pulse-space-s);
  border: 1px solid var(--field-border);
  border-radius: var(--radius-md);
  color: var(--ink);
  text-decoration: none;
}
.pulse-wire-chip:hover { background: var(--surface-alt); }
.pulse-wire-chip:hover .pulse-wire-chip-t { text-decoration: underline; text-underline-offset: 3px; }
.pulse-wire-chip-t { font-size: var(--pulse-text-sm); font-weight: var(--weight-semibold); line-height: var(--pulse-leading-dense); overflow-wrap: anywhere; }
.pulse-wire-chip-n { color: var(--pulse-meta); font-size: var(--pulse-text-xs); line-height: var(--pulse-leading-dense); font-variant-numeric: tabular-nums; }

/* ---------- The way on, and the quiet state ---------- */
.pulse-wire-more { margin: var(--pulse-space-xs) 0 0; }
.pulse-wire-more-link, .pulse-wire-quiet-link a {
  display: inline-flex; align-items: center;
  min-height: var(--pulse-tap);
  font-weight: var(--weight-semibold);
}
.pulse-wire-quiet { padding-block: var(--pulse-space-xs); }
.pulse-wire-quiet-line { margin: 0; max-width: var(--pulse-measure); color: var(--ink); line-height: var(--leading-body); }
.pulse-wire-quiet-link { margin: var(--pulse-space-2xs) 0 0; }

/* ---------- How the page works ---------- */
.pulse-wire-how { padding-block: var(--pulse-space-s); }
.pulse-wire-how-h {
  margin: 0 0 var(--pulse-space-xs);
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--pulse-text-card);
  line-height: var(--pulse-leading-card);
  color: var(--ink);
}
.pulse-wire-how p { margin: 0 0 var(--pulse-space-xs); color: var(--ink); }

/* ---------- Wider screens: the list keeps a readable measure; the page shows times in a rail ---------- */
@container pulse-page (min-width: 44rem) {
  .pulse-wire--page .pulse-wire-item { display: grid; grid-template-columns: 9rem minmax(0, 1fr); column-gap: var(--pulse-space-s); }
  .pulse-wire--page .pulse-wire-meta { padding-top: var(--pulse-space-2xs); }
  .pulse-wire--page .pulse-wire-link { margin-top: 0; font-size: var(--pulse-fs-1); }
}

/* ---------- Motion: an entering row fades in, opacity only, and only where motion is allowed ---------- */
@keyframes pulse-wire-in { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: no-preference) {
  :root:not([data-motion="reduce"]) .pulse-wire-item--enter { animation: pulse-wire-in var(--dur-base, 0.2s) var(--ease, ease-out) both; }
}

@media print {
  .pulse-wire-controls, .pulse-wire-out { display: none !important; }
  .pulse-wire-link::after { content: " (" attr(href) ")"; position: static; font-weight: var(--weight-body); color: var(--pulse-meta); }
}

/* ---------- A hub's "In the news elsewhere" (a flow section after Latest) ---------- */
.pulse-hub-wire { margin-top: var(--pulse-space-m); padding-top: var(--pulse-space-m); border-top: 1px solid var(--pulse-rule); }
.pulse-hub-wire-h { margin-bottom: var(--pulse-space-xs); }

/* ===== part 80-interactive.css ===== */
/* =====================================================================
   EQSIS Pulse: pulse.css, part 80 (interactive). Owner: package E
   (docs/design/BUILD-V2.md): the states pulse.js sets (.pulse-js-*), the
   since marker (line and bookmark), the progress row and the contents
   panel (.pulse-progress*), the word-notes switch state, the share sheet
   and Copy for WhatsApp (.pulse-sheet*), and the D3 share-frame previews
   (.pulse-frame*: the SVG twin of the frame spec and the reflowing card).
   M5 additions, package P6 (docs/build/M5-PLAN.md): the soft push opt-in
   (.pulse-optin*) and the offline page (.pulse-offline*). The share-card
   painter (src/publishing/cards.php) reads the .pulse-frame-m--* and
   .pulse-frame-t--* roles below through data/publishing/frame_palette.json,
   so the PNG and the SVG preview agree (FramePaletteTest).
   Every state is reachable without motion: colour and opacity only, and
   no slot changes height when a script fills it. Colours are aliases of
   site tokens; no literal colour, no literal font family.
   ===================================================================== */

/* ---------- Script states ---------- */
/* Hidden but holding its space (the contents panel while the Stamp shows, the progress row over the
   fixed-chrome cap): nothing below it moves. */
.pulse-js-off { visibility: hidden; opacity: 0; }
.pulse-progress, .pulse-progress-panel { transition: opacity var(--dur-base) var(--ease), visibility var(--dur-base) var(--ease); }
@media (prefers-reduced-motion: reduce) {
  .pulse-progress, .pulse-progress-panel { transition: none; }
}
:root[data-motion="reduce"] .pulse-progress,
:root[data-motion="reduce"] .pulse-progress-panel { transition: none; }
/* The copy fallback's textarea: off the page, never focusable by the reader, no layout. */
.pulse-js-offscreen {
  position: fixed; inset-block-start: 0; inset-inline-start: 0;
  inline-size: 1px; block-size: 1px; padding: 0; border: 0;
  opacity: 0; pointer-events: none;
}
/* A row's reserved "New" slot (card.row): invisible and unspoken until the since marker shows it. */
[data-pulse-new]:not(.pulse-js-on) { visibility: hidden; }
/* What covers the foot of the screen (pulse.js part 9 measures it into --pulse-cover-bottom and sets
   .pulse-js-cover): the site's consent banner, the bottom bar, the action bar and the progress row
   while it is stuck above them, counted once where they overlap. A control that takes focus is then
   scrolled clear of all of them, plus 1.5rem (WCAG 2.4.11), at every width: from 768 px that is the
   banner alone. Without a script the banner never shows and part 30's bar-height rules stand. Later
   in the cascade than part 30 and the site's eqsis.css, at equal or higher specificity, so it wins. */
html.pulse-js-cover { scroll-padding-bottom: calc(var(--pulse-cover-bottom, 0px) + var(--sp-5)); }

/* ---------- Since your last visit: the line (the Stamp's bottom band) ----------
   The slot is reserved at 3rem (two lines of 17 px text at 1.4 fit inside it), so the swap from the
   server's fallback to the returning reader's line never moves anything. */
.pulse-since--line {
  display: flex; align-items: center;
  min-block-size: var(--pulse-reserve-since);
  margin: 0;
  font-size: var(--text-base);
  line-height: 1.4;
}
.pulse-since-link {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  min-block-size: var(--pulse-tap);
  color: inherit;
  font-weight: var(--weight-medium);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}
.pulse-since-link:hover { text-decoration-thickness: 2px; }
.pulse-since-chev { flex: none; inline-size: 1em; block-size: 1em; }
.pulse-since-text { font-variant-numeric: tabular-nums; }

/* ---------- Since your last visit: the bookmark ----------
   Drawn by pulse.js inside the row it sits above (.pulse-since-at), on the row's top edge, so it
   lies in the existing gap and no row moves: a 2px rule across, the pill on the text's left edge. */
.pulse-since-at { position: relative; }
.pulse-since--bookmark {
  container: pulse-since / inline-size;
  position: absolute; inset-inline: 0; inset-block-start: 0;
  z-index: 1;
  display: flex; align-items: center; gap: var(--sp-2);
  transform: translateY(-50%);
  pointer-events: none;
}
.pulse-since--bookmark[hidden] { display: none; }
.pulse-since-rule {
  position: absolute; inset-inline: 0; inset-block-start: 50%;
  block-size: 2px; margin-block-start: -1px;
  background: var(--pulse-since-rule);
}
.pulse-since-pill, .pulse-since-all {
  position: relative;
  padding: 0 var(--sp-2);
  font-size: var(--pulse-text-sm);
  line-height: 1.6;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.pulse-since-pill {
  border: 2px solid var(--pulse-since-rule);
  border-radius: var(--radius-lg);
  background: var(--surface);
  color: var(--pulse-since-pill-fg);
  font-weight: var(--weight-semibold);
}
/* Live: "That is everything since your visit." beside the pill where the row is wide enough; on a
   narrow phone it is read by screen readers only, so the bookmark stays one line in its gap. */
.pulse-since-all {
  position: absolute; inline-size: 1px; block-size: 1px; overflow: hidden;
  clip-path: inset(50%);
  color: var(--ink); background: var(--surface);
}
@container pulse-since (min-width: 30rem) {
  .pulse-since-all { position: relative; inline-size: auto; block-size: auto; overflow: visible; clip-path: none; }
}

/* ---------- The progress row (phones) and the contents panel (desktop) ----------
   Markup by package B (edition_progress.php): <nav class="pulse-progress" aria-label="This edition"
   data-pulse-progress> and <nav class="pulse-progress-panel" data-pulse-contents>. */
.pulse-progress { display: none; }
@media (max-width: 767.98px) {
  .pulse-progress {
    position: sticky;
    inset-block-end: calc(var(--pulse-bottombar-h) + env(safe-area-inset-bottom));
    z-index: 1034;
    display: flex; align-items: center; gap: var(--sp-2);
    min-block-size: var(--pulse-reserve-progress);
    margin-inline: calc(-1 * var(--pulse-gutter));
    padding-inline: var(--pulse-gutter);
    background: var(--surface);
    border-block-start: 1px solid var(--pulse-rule);
    font-size: var(--pulse-text-sm);
    line-height: var(--pulse-leading-dense);
  }
}
@media (max-width: 767.98px) and (max-height: 26rem) {
  .pulse-progress { position: static; }
}
.pulse-progress-pos { flex: 1 1 auto; min-inline-size: 0; color: var(--ink); font-variant-numeric: tabular-nums; }
.pulse-progress-next, .pulse-progress-open {
  display: inline-flex; align-items: center; justify-content: center;
  min-block-size: var(--pulse-tap); min-inline-size: var(--pulse-tap);
  padding-inline: var(--sp-2);
  white-space: nowrap;
}
.pulse-progress-next { color: var(--blue-600); font-weight: var(--weight-semibold); }
.pulse-progress-open {
  border: 1px solid var(--field-border); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--ink);
  font-family: var(--font-body); font-size: var(--pulse-text-sm); font-weight: var(--weight-semibold);
}
.pulse-progress-dialog {
  inline-size: min(26rem, calc(100vw - 2 * var(--pulse-gutter)));
  padding: var(--pulse-card-pad);
  border: 1px solid var(--line); border-radius: var(--radius-md);
  background: var(--surface); color: var(--ink);
  box-shadow: var(--shadow-raised);
}
.pulse-progress-dialog::backdrop { background: var(--ink); opacity: 0.4; }
.pulse-progress-panel { display: none; }
@media (min-width: 992px) {
  .pulse-progress-panel {
    display: block;
    position: sticky; inset-block-start: calc(var(--header-h) + var(--sp-4));
    margin-block-start: var(--pulse-space-m);
    padding: var(--pulse-card-pad);
    border-radius: var(--radius-lg);
    background: var(--surface-alt);
  }
}
.pulse-progress-list { margin: 0; padding: 0; list-style: none; }
.pulse-progress-list a {
  display: flex; align-items: baseline; gap: var(--sp-2);
  min-block-size: var(--pulse-tap); padding-block: var(--sp-2);
  border-inline-start: 3px solid transparent; padding-inline-start: var(--sp-3);
  color: var(--ink); text-decoration: none;
}
.pulse-progress-list a:hover { text-decoration: underline; text-underline-offset: 3px; }
.pulse-progress-list a[aria-current] { border-inline-start-color: var(--pulse-progress-done); font-weight: var(--weight-semibold); }

/* ---------- Word notes: off (the switch) ----------
   The terms read as plain text: no underline, no icon, out of the tab order (pulse.js), not
   clickable. The plain-words lines stay. */
.pulse-js-notes-off [data-pulse-note] > summary,
.pulse-js-notes-off button[data-pulse-note] {
  pointer-events: none;
  cursor: text;
  text-decoration: none;
  border-color: transparent;
  background: transparent;
  color: inherit;
  font-weight: inherit;
}
.pulse-js-notes-off [data-pulse-note] > summary svg,
.pulse-js-notes-off button[data-pulse-note] svg { display: none; }
[data-pulse-note-switch][role="switch"] {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  min-block-size: var(--pulse-tap); padding-inline: var(--sp-3);
  border: 1px solid var(--field-border); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--ink);
  font-family: var(--font-body); font-size: var(--pulse-text-sm); font-weight: var(--weight-semibold);
}
[data-pulse-note-switch][aria-checked="true"] { border-color: var(--pulse-progress-done); }

/* ---------- Reader feedback: answered ---------- */
[data-pulse-feedback] button[aria-disabled="true"] { cursor: default; }
[data-pulse-feedback] button[aria-pressed="true"] { border-width: 2px; border-color: var(--pulse-progress-done); }

/* ---------- Share: the button, the sheet, Copy for WhatsApp ----------
   The button sits on the unit's last row. The sheet floats (the one thing here that does, so it alone
   takes the raised shadow), white, a 1px line, --radius-md, two columns (actions, preview), under
   the button. pulse.js keeps it inside the gutters of the screen when it opens; without a script
   the caller's data-align says which side of the button it opens on. (A fixed sheet is not used:
   the pulse-page container's layout containment would hold it inside the page column.) */
.pulse-sheet { position: relative; display: inline-block; vertical-align: middle; }
.pulse-sheet-d > summary { list-style: none; }
.pulse-sheet-d > summary::-webkit-details-marker { display: none; }
.pulse-sheet-btn, .pulse-sheet-act {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  min-block-size: var(--pulse-tap); min-inline-size: var(--pulse-tap);
  padding-inline: var(--sp-3);
  border: 1px solid var(--field-border); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--ink);
  font-family: var(--font-body); font-size: var(--pulse-text-sm); font-weight: var(--weight-semibold);
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
}
.pulse-sheet-btn:hover, .pulse-sheet-act:hover { background: var(--surface-alt); }
.pulse-sheet-d[open] > .pulse-sheet-btn { border-color: var(--pulse-progress-done); }
.pulse-sheet-icon { flex: none; inline-size: 1.25rem; block-size: 1.25rem; }
.pulse-sheet-panel {
  position: absolute; inset-block: calc(100% + var(--sp-2)) auto; inset-inline: auto 0;
  z-index: 20;
  display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-3);
  align-items: start;
  inline-size: min(24rem, calc(100vw - 2 * var(--pulse-gutter)));
  padding: var(--pulse-card-pad);
  border: 1px solid var(--line); border-radius: var(--radius-md);
  background: var(--surface); color: var(--ink);
  box-shadow: var(--shadow-raised);
}
.pulse-sheet[data-align="start"] .pulse-sheet-panel { inset-inline: 0 auto; }
.pulse-sheet-panel--story-4x5 { grid-template-columns: minmax(0, 1fr) 7.5rem; }
@media (min-width: 768px) {
  .pulse-sheet-panel--story-4x5 { grid-template-columns: minmax(0, 1fr) 9rem; }
}
.pulse-sheet-acts { display: grid; gap: var(--sp-2); margin: 0; padding: 0; list-style: none; }
.pulse-sheet-acts .pulse-sheet-act { inline-size: 100%; text-align: center; }
.pulse-sheet-status {
  min-block-size: 2.9em;
  margin: var(--sp-2) 0 0;
  color: var(--ink);
  font-size: var(--pulse-text-sm);
  line-height: 1.45;
}
.pulse-sheet-close {
  grid-column: 1 / -1;
  justify-self: start;
  min-block-size: var(--pulse-tap); padding-inline: var(--sp-3);
  border: 0; background: transparent;
  color: var(--blue-600);
  font-family: var(--font-body); font-size: var(--pulse-text-sm); font-weight: var(--weight-semibold);
  text-decoration: underline; text-underline-offset: 3px;
}
/* "Copy for WhatsApp" on its own: its status reads beside or under it once the reader has copied. */
.pulse-sheet--copy { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 0 var(--sp-3); }
.pulse-sheet--copy .pulse-sheet-status { min-block-size: 0; margin: 0; }

/* ---------- The share frame, SVG twin of the frame spec ----------
   The spec's own geometry, scaled to its box; fills are class roles (no colour in the markup). The
   text is real text at the spec's source sizes; the frame shows at about a third of them, as a
   WhatsApp preview does. */
.pulse-frame-svg {
  display: block;
  inline-size: 100%; block-size: auto;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--surface);
}
.pulse-frame-m--bg { fill: var(--surface); }
.pulse-frame-m--band { fill: var(--surface-alt); }
.pulse-frame-m--split-a { fill: var(--pulse-split-a); }
.pulse-frame-m--split-b { fill: var(--pulse-split-b); }
.pulse-frame-m--tag { fill: var(--pulse-status-bg); stroke: var(--pulse-status-border); stroke-width: 2; }
.pulse-frame-m--part-main, .pulse-frame-m--bar-main { fill: var(--pulse-chart-main); }
.pulse-frame-m--part-compare { fill: var(--pulse-chart-compare); }
.pulse-frame-m--part-quiet { fill: var(--pulse-chart-quiet); }
.pulse-frame-m--part-outline, .pulse-frame-m--bar-outline { fill: var(--surface); stroke: var(--pulse-chart-ref); stroke-width: 3; }
.pulse-frame-m--bar-up { fill: var(--pulse-up); }
.pulse-frame-m--bar-down { fill: var(--pulse-down); }
.pulse-frame-m--tick, .pulse-frame-m--zero { fill: var(--pulse-chart-ref); }
.pulse-frame-m--dir-up { fill: var(--pulse-up); }
.pulse-frame-m--dir-down { fill: var(--pulse-down); }
.pulse-frame-m--dir-ink { fill: var(--ink); }
.pulse-frame-t { fill: var(--ink); font-variant-numeric: tabular-nums; }
.pulse-frame-t--body { font-family: var(--font-body); font-weight: var(--weight-body); }
.pulse-frame-t--semi { font-family: var(--font-body); font-weight: var(--weight-semibold); }
.pulse-frame-t--display { font-family: var(--font-display); font-weight: var(--weight-display); }
.pulse-frame-t--headline, .pulse-frame-t--figure.pulse-frame-t--display { fill: var(--pulse-figure-ink); }
.pulse-frame-t--section { fill: var(--pulse-label); }
.pulse-frame-t--date, .pulse-frame-t--source, .pulse-frame-t--site { fill: var(--pulse-meta); }
.pulse-frame-t--up { fill: var(--pulse-up); }
.pulse-frame-t--down { fill: var(--pulse-down); }
.pulse-frame-logo--dark { display: none; }
:root[data-theme="dark"] .pulse-frame-logo--light { display: none; }
:root[data-theme="dark"] .pulse-frame-logo--dark { display: inline; }

/* ---------- The share frame as a reflowing card (the visual-story Cards view) ----------
   The frame's zones in the frame's order at the design system's sizes (never under the text floor):
   the 0.25rem split bar on the top edge, the top row, the headline, the figure, the meaning line,
   the foot zone, the tinted brand band. At least 4:5 tall; longer content makes it taller, never
   smaller text and never a cut row (no overflow clipping: it would drop the aspect ratio's
   automatic minimum height). The split bar is a background layer, so the corner radius clips it.
   An inset object in the flow: a border, no shadow. */
.pulse-frame {
  container: pulse-frame / inline-size;
  display: flex; flex-direction: column; gap: var(--pulse-space-xs);
  aspect-ratio: 4 / 5;
  padding: calc(var(--pulse-card-pad) + var(--pulse-split-h)) var(--pulse-card-pad) 0;
  border: 1px solid var(--line); border-block-start-color: transparent; border-radius: var(--radius-lg);
  background: var(--pulse-split-rule) 0 0 / 100% var(--pulse-split-h) no-repeat border-box, var(--surface);
  color: var(--ink);
}
.pulse-frame--card-1200x630 { aspect-ratio: 1200 / 630; }
.pulse-frame-top {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--sp-1) var(--sp-3);
  color: var(--pulse-meta);
  font-size: var(--pulse-text-sm);
  line-height: var(--pulse-leading-dense);
}
.pulse-frame-section { color: var(--pulse-label); font-weight: var(--weight-semibold); }
.pulse-frame-title {
  margin: 0;
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: var(--pulse-fs-1); line-height: var(--pulse-leading-card);
  color: var(--blue-900);
  text-wrap: balance;
}
@container pulse-frame (min-width: 26rem) {
  .pulse-frame-title { font-size: var(--pulse-fs-2); line-height: var(--leading-tight); }
}
.pulse-frame-fig { margin-block: var(--pulse-space-xs); }
.pulse-frame-key { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-1) var(--sp-3); margin: 0; }
.pulse-frame-num {
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: var(--pulse-fs-figure);
  font-size: min(var(--pulse-fs-figure), 20cqi);
  line-height: var(--pulse-leading-figure);
  color: var(--pulse-figure-ink);
}
.pulse-frame-of { font-size: var(--pulse-fs-1); line-height: var(--pulse-leading-card); max-inline-size: 16rem; }
.pulse-frame-parts {
  display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-4);
  margin: var(--sp-2) 0 0; padding: 0; list-style: none;
  font-size: var(--text-base);
}
.pulse-frame-table { inline-size: 100%; border-collapse: collapse; font-size: var(--text-base); }
.pulse-frame-table th, .pulse-frame-table td { padding: var(--sp-1) 0; border-block-end: 1px solid var(--pulse-rule); text-align: start; font-weight: var(--weight-body); }
.pulse-frame-table td { text-align: end; font-weight: var(--weight-semibold); white-space: nowrap; }
.pulse-frame-rows { display: grid; gap: var(--sp-2); margin: 0; padding: 0; list-style: none; font-size: var(--text-base); line-height: var(--pulse-leading-dense); }
.pulse-frame-lead { display: inline-block; min-inline-size: 1.5rem; color: var(--pulse-label); font-family: var(--font-display); font-weight: var(--weight-display); }
.pulse-frame-meaning { margin: 0; font-size: var(--pulse-fs-dek); line-height: var(--pulse-leading-dense); max-inline-size: var(--pulse-measure); }
.pulse-frame-meaning .pulse-unit-label { margin-inline-end: var(--sp-1); }
/* The equals mark of the plain-words line: two bars, EQ green over SIS blue (decoration). */
.pulse-frame-eq {
  display: inline-block;
  inline-size: 1.25rem; block-size: 0.75rem;
  margin-inline-end: var(--sp-2);
  vertical-align: 0.05em;
  background:
    linear-gradient(var(--pulse-split-a), var(--pulse-split-a)) top / 100% 0.25rem no-repeat,
    linear-gradient(var(--pulse-split-b), var(--pulse-split-b)) bottom / 100% 0.25rem no-repeat;
}
.pulse-frame-foot {
  display: grid; gap: var(--sp-1);
  margin-block-start: auto;
  padding-block-start: var(--pulse-space-xs);
  color: var(--pulse-meta);
  font-size: var(--pulse-text-sm);
  line-height: var(--pulse-leading-dense);
}
.pulse-frame-foot p { margin: 0; }
.pulse-frame-foot .pulse-unit-label { margin-inline-end: var(--sp-1); }
.pulse-frame-foot .pulse-copy-state, .pulse-frame-band .pulse-copy-state { margin: 0; }
.pulse-frame-band {
  display: grid; gap: var(--sp-1);
  margin-inline: calc(-1 * var(--pulse-card-pad));
  padding: var(--sp-3) var(--pulse-card-pad);
  border-end-start-radius: calc(var(--radius-lg) - 1px);
  border-end-end-radius: calc(var(--radius-lg) - 1px);
  background: var(--surface-alt);
  color: var(--ink);
  font-size: var(--pulse-text-sm);
  line-height: var(--pulse-leading-dense);
}
.pulse-frame-band p { margin: 0; }
.pulse-frame-brand { display: flex; flex-wrap: wrap; align-items: center; gap: 0 var(--sp-3); }
.pulse-frame-lockup {
  display: inline-flex; align-items: center; gap: var(--sp-1);
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: var(--text-base);
  color: var(--ink);
}
.pulse-frame-logo { display: block; inline-size: auto; block-size: 1.125rem; }
img.pulse-frame-logo--dark { display: none; }
:root[data-theme="dark"] img.pulse-frame-logo--light { display: none; }
:root[data-theme="dark"] img.pulse-frame-logo--dark { display: block; }
.pulse-frame-site { color: var(--pulse-meta); }
/* The AI badge keeps its tag look; its hit area grows to 48 px through an overlay, so the band never
   grows (the block.trust_strip rule). Its row's status marker sits beside the link, never inside it,
   and wraps with it as one piece. */
.pulse-frame-aiwrap { display: inline-flex; flex-wrap: wrap; align-items: center; gap: var(--sp-1) var(--sp-2); }
.pulse-frame-ai { position: relative; text-decoration: none; }
.pulse-frame-ai::after { content: ""; position: absolute; inset-inline: 0; inset-block: calc((100% - var(--pulse-tap)) / 2); }
.pulse-frame-ai:hover { text-decoration: underline; }

/* ---------- The soft push opt-in (M5, package P6; ADR-040) ----------
   pulse-pwa.js places it after a value moment, never on a first load. It is fixed, so placing it moves
   nothing on the page (no layout shift); it sits above the dock under 768 px, under the site's cookie
   notice (1050) and above the action bar (1036), and never takes focus by itself. Its words are the
   push_optin_prompt row; the buttons are the site's own and at least 48 px tall. */
.pulse-optin {
  position: fixed; inset-inline-end: var(--sp-3); bottom: calc(var(--sp-3) + env(safe-area-inset-bottom));
  z-index: 1037; inline-size: min(26rem, calc(100% - 2 * var(--sp-3)));
  display: grid; gap: var(--sp-3); padding: var(--sp-4);
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--pulse-status-border); border-radius: var(--radius-md); box-shadow: var(--shadow-raised);
  font-size: var(--text-base); line-height: var(--pulse-leading-dense);
}
.pulse-optin-text { margin: 0; }
.pulse-optin-acts { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.pulse-optin-btn { min-block-size: var(--pulse-tap); display: inline-flex; align-items: center; justify-content: center; }
@media (max-width: 767.98px) {
  .pulse-optin { bottom: calc(var(--pulse-dock-h, var(--pulse-bottombar-h)) + var(--sp-2) + env(safe-area-inset-bottom)); }
  body.pulse:has(.pulse-actionbar) .pulse-optin { bottom: calc(var(--pulse-dock-h, var(--pulse-bottombar-h)) + var(--pulse-actionbar-h) + var(--sp-2) + env(safe-area-inset-bottom)); }
}
@media (max-height: 26rem) {
  .pulse-optin { position: static; inline-size: auto; margin: var(--sp-3) var(--pulse-gutter); }
}

/* ---------- The offline page (M5, package P6; ADR-040) ---------- */
.pulse-offline { padding-block: var(--pulse-space-l); }
.pulse-offline-kicker { margin: 0 0 var(--sp-2); color: var(--pulse-label); font-weight: var(--weight-semibold); }
.pulse-offline-title { margin: 0 0 var(--sp-4); font-family: var(--font-display); font-weight: var(--weight-display); font-size: var(--pulse-fs-3); line-height: var(--leading-tight); }
.pulse-offline-ways { display: grid; gap: var(--sp-2); margin: var(--sp-5) 0 0; padding: 0; list-style: none; }
.pulse-offline-ways a { display: inline-flex; align-items: center; min-block-size: var(--pulse-tap); }

@media print {
  .pulse-sheet, .pulse-progress, .pulse-progress-panel, .pulse-since--bookmark, .pulse-optin { display: none !important; }
}
