/* ============================================================================
   CHAPTER HUB — shared editorial-chapter mechanics
   ----------------------------------------------------------------------------
   Shared across every 7-chapter hub (acoustic-panels, acoustic-foam, and any
   future tool). Deliberately tool-agnostic: color comes from --color-accent
   so each hub can override the token at :root or on <body>.

   Most of the visual vocabulary lives elsewhere:

   • treatment-hub.css  shell chrome (reader chips, state directive, sticky
                        chapter rail, chapter heading, copy-link button,
                        chapter-commercial-row, verify checklist, myth grid,
                        .treatment-shell + .treatment-content scaffolding,
                        .for-reader-state reveal).
   • category-hub.css   editorial content cards (stage-entry, decision-module,
                        decision-prompt, spec-grid, spec-card, quantity-stack,
                        quantity-read, quantity-calc-frame, acoustic-calc-*,
                        placement-stack, planner-cta, room-grid, room-card,
                        picks-stack, pick-row, install-grid, install-row,
                        library, shape-list, shape-card).

   This file adds the mechanics those two don't cover:

     -1. Directive PATH          — progressive 4-step reveal inside the hero,
         gated on an explicit in-session chip click. Pure-CSS visibility via
         data-revealed + nth-child(-n+N).
      0. Vertical rhythm         — tighter inter-chapter gap than the default
         shared by hub pages (overrides baseline from treatment-hub.css).
      1. Install-block wrapper   — group heading above the install-grid in
         Ch 7, since install is one of three sub-blocks sharing the chapter
         with verify + myths.
      2. Priority reorder        — when a reader-state chip is active, the
         matching stage-entry, room-card, and pick-row float to the top of
         their list and carry a "Start here for …" pill so the page visibly
         adapts.
      3. Priority badge pill     — shared pill styling for the three
         surfaces above; uses the site accent token.
      4. Next-topics breathing   — space-6 padding-block on cards so content
         doesn't touch the horizontal dividers.
      5. Local polish            — how the legacy cards breathe inside the
         .chapter container (was .page-section before).

   Per-hub color identity is provided by an adjacent foam-hub.css / whatever,
   which overrides --color-accent at the :root-level scope of that page.
   ============================================================================ */


/* ═══════════════════════════════════════════════════════════════════════════
   -1. DIRECTIVE PATH — progressive 4-step reveal in the hero
   ---------------------------------------------------------------------------
   When a reader-state chip is active, the directive banner shows a 4-step
   "path" of concrete actions, ordered by first-principles priority. Step 1
   is visible on reveal; clicking "Show step N of 4" progressively reveals
   the rest via the data-revealed attribute on .directive-path__steps.

   Reveal is pure CSS (no height transitions in JS). The JS inside the
   <script> block only mutates the data-revealed attribute and the button
   label — which steps are visible is driven by :nth-child(-n+N) rules
   matching the current revealed count.

   The outer .reader-chips__directive (from treatment-hub.css) is a padded,
   border-left'd wrapper designed for a one-line directive. Inside it, we
   render a block-level .directive-path that takes over the full width
   with its own vertical rhythm.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Session-gated visibility ────────────────────────────────────────────────
   By default the directive banner stays hidden — even when a reader-state
   is active from a previous localStorage session. It only appears after the
   reader explicitly clicks a chip on THIS page load (the click handler in
   module 1 sets body[data-directive-revealed="true"]). This keeps the hero
   clean and makes the reveal feel intentional rather than pre-filled.

   Specificity note: the treatment-hub rule
       body:not([data-reader-state]) .reader-chips__directive { display:none }
   still hides the banner when no state is set at all. This rule adds a
   second gate — hide ALSO when the directive hasn't been explicitly
   revealed this session (i.e. state came only from localStorage restore).
   The union of the two means the directive needs BOTH state AND reveal
   to appear. */
body:not([data-directive-revealed]) .reader-chips__directive {
  display: none;
}

/* Hero state-variants that wrap a directive-path need block layout (the
   default .for-reader-state { display: inline } from treatment-hub.css was
   designed for inline lede fragments, not multi-step blocks). Each hub has
   its own reader-state vocabulary — panels uses studio/theatre/office/
   rehearsal; foam uses apartment/podcast/recording/bedroom — so the rule
   enumerates all known states. If a new hub introduces more states, add
   them here rather than duplicating the CSS per-hub. */
[data-reader-state="studio"]    .reader-chips__directive .for-reader-state[data-state="studio"],
[data-reader-state="theatre"]   .reader-chips__directive .for-reader-state[data-state="theatre"],
[data-reader-state="office"]    .reader-chips__directive .for-reader-state[data-state="office"],
[data-reader-state="rehearsal"] .reader-chips__directive .for-reader-state[data-state="rehearsal"],
[data-reader-state="apartment"] .reader-chips__directive .for-reader-state[data-state="apartment"],
[data-reader-state="podcast"]   .reader-chips__directive .for-reader-state[data-state="podcast"],
[data-reader-state="recording"] .reader-chips__directive .for-reader-state[data-state="recording"],
[data-reader-state="bedroom"]   .reader-chips__directive .for-reader-state[data-state="bedroom"],
/* Bass-traps hub reader-states (bass-hub.css). mix-room and drums are
   exclusive to the bass-traps hub; the others overlap with treatment
   siblings so a chip picked on one hub carries across. */
[data-reader-state="mix-room"]  .reader-chips__directive .for-reader-state[data-state="mix-room"],
[data-reader-state="drums"]     .reader-chips__directive .for-reader-state[data-state="drums"],
/* Sound-diffuser hub reader-states (diffuser-hub.css). listening and
   live-room are exclusive to the diffuser hub (audiophile / rehearsal
   flutter-kill contexts); mix-room and recording overlap with bass and
   foam respectively so a chip picked on one hub carries across. */
[data-reader-state="listening"] .reader-chips__directive .for-reader-state[data-state="listening"],
[data-reader-state="live-room"] .reader-chips__directive .for-reader-state[data-state="live-room"],
/* Soundbar hub reader-states (soundbar-hub.css). Three lifecycle states:
   prepurchase ("I don't own one yet"), comparing ("I'm comparing tiers"),
   owner ("I own one and it's not right"). Distinct from the treatment
   hubs' room-context states — soundbars route by buyer lifecycle, not
   by room type. No shared keys with other hubs. */
[data-reader-state="prepurchase"] .reader-chips__directive .for-reader-state[data-state="prepurchase"],
[data-reader-state="comparing"]   .reader-chips__directive .for-reader-state[data-state="comparing"],
[data-reader-state="owner"]       .reader-chips__directive .for-reader-state[data-state="owner"],
/* Make Music pillar reader-states (make-music-hub.css). Three craft-stage
   states: curious ("I want to start making music, don't know how"), stuck
   ("I own gear but I'm not improving"), exploring ("I do one craft and
   want to learn the other"). The pillar routes across both sub-hubs so
   these keys are pillar-local; the DJ sub-hub uses its own state names
   (learning/gigging/upgrading) below. */
[data-reader-state="curious"]   .reader-chips__directive .for-reader-state[data-state="curious"],
[data-reader-state="stuck"]     .reader-chips__directive .for-reader-state[data-state="stuck"],
[data-reader-state="exploring"] .reader-chips__directive .for-reader-state[data-state="exploring"],
/* DJ sub-hub reader-states (dj-hub.css). Three lifecycle states inside the
   DJ craft: learning ("first controller, pre-purchase or just-bought"),
   gigging ("ready to play for other people, need reliable + club-ready"),
   upgrading ("I have an entry rig, where's the honest capability jump").
   These shadow the soundbar lifecycle triplet in spirit but use craft-
   specific language so the chip copy reads native to a DJ context. */
[data-reader-state="learning"]  .reader-chips__directive .for-reader-state[data-state="learning"],
[data-reader-state="gigging"]   .reader-chips__directive .for-reader-state[data-state="gigging"],
[data-reader-state="upgrading"] .reader-chips__directive .for-reader-state[data-state="upgrading"],
/* MIDI sub-hub reader-states (midi-hub.css). Four craft-entry states:
   beginner ("never produced"), pianist ("I play piano, going digital"),
   beatmaker ("I make beats, pad-first"), upgrader ("I own a starter,
   what's the honest next step"). */
[data-reader-state="beginner"]  .reader-chips__directive .for-reader-state[data-state="beginner"],
[data-reader-state="pianist"]   .reader-chips__directive .for-reader-state[data-state="pianist"],
[data-reader-state="beatmaker"] .reader-chips__directive .for-reader-state[data-state="beatmaker"],
[data-reader-state="upgrader"]  .reader-chips__directive .for-reader-state[data-state="upgrader"] {
  display: block;
}

/* Loosen the directive banner so the multi-step path has room to breathe.
   Slightly deeper padding + a faint surface tint give it a "card in the
   dark hero" feel without competing with the chips above. */
.reader-chips__directive {
  padding: var(--space-5) var(--space-6);
  background: rgba(255, 255, 255, 0.03);
  border-radius: 0 10px 10px 0;
}

/* ── Container ── */
.directive-path {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  max-width: 640px;
}

/* ── Intro label ("For your studio, here's the path:") ── */
.directive-path__intro {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.55);
  line-height: 1.5;
}

.directive-path__intro strong {
  color: var(--color-accent);
  font-weight: 700;
}

/* ── Ordered list of steps ── */
.directive-path__steps {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

/* Each step is a row: number + body (action / why / link) */
.directive-path__step {
  display: none; /* hidden by default; revealed via nth-child rules below */
  grid-template-columns: auto 1fr;
  gap: var(--space-4);
  padding-block: var(--space-1);
  animation: directive-step-reveal 320ms var(--ease-out, cubic-bezier(0.2, 0.8, 0.2, 1));
}

@keyframes directive-step-reveal {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Progressive reveal driven by data-revealed. Each rule matches
   the first N children for the declared value. */
.directive-path__steps[data-revealed="1"] .directive-path__step:nth-child(-n+1),
.directive-path__steps[data-revealed="2"] .directive-path__step:nth-child(-n+2),
.directive-path__steps[data-revealed="3"] .directive-path__step:nth-child(-n+3),
.directive-path__steps[data-revealed="4"] .directive-path__step:nth-child(-n+4) {
  display: grid;
}

/* ── Step number — mono accent ── */
.directive-path__num {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: 700;
  color: var(--color-accent);
  letter-spacing: 0.04em;
  min-width: 2ch;
  padding-top: 3px; /* optical-align with .directive-path__action */
}

/* ── Step body (action, why, link stacked) ── */
.directive-path__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0; /* let flex children shrink below their content width */
}

.directive-path__action {
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  font-weight: 500;
  line-height: 1.4;
  color: rgba(255, 255, 255, 0.92);
}

.directive-path__action strong {
  color: #fff;
  font-weight: 700;
}

.directive-path__why {
  font-family: var(--font-serif);
  font-size: var(--fs-sm);
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.60);
  font-style: italic;
}

.directive-path__link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-top: 2px;
  align-self: flex-start;

  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-accent);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  padding-bottom: 1px;
  transition: border-color 180ms ease;
}

.directive-path__link:hover,
.directive-path__link:focus-visible {
  border-bottom-color: var(--color-accent);
}

/* ── Reveal-next button ── */
.directive-path__more {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  margin-top: var(--space-1);

  border: 1px solid rgba(255, 255, 255, 0.25);
  border-radius: 999px;
  background: transparent;
  color: rgba(255, 255, 255, 0.82);

  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;

  cursor: pointer;
  transition: border-color 180ms ease, color 180ms ease, background 180ms ease;
}

.directive-path__more:hover,
.directive-path__more:focus-visible {
  border-color: var(--color-accent);
  color: var(--color-accent);
  background: color-mix(in srgb, var(--color-accent) 10%, transparent);
  outline: 0;
}

.directive-path__more[hidden] {
  display: none;
}

.directive-path__more-arrow {
  font-size: 14px;
  transition: transform 180ms ease;
}

.directive-path__more:hover .directive-path__more-arrow,
.directive-path__more:focus-visible .directive-path__more-arrow {
  transform: translateY(2px);
}


/* ═══════════════════════════════════════════════════════════════════════════
   0. VERTICAL RHYTHM OVERRIDES — chapter-hub baseline
   ---------------------------------------------------------------------------
   The shared .mission--hub hero lays down padding-block-end: space-24 at
   desktop (96px). Stacking the default .treatment-shell-wrap padding-top
   of space-10 (40px) on top of it creates a 136px void between the dark
   hero's last element (directive banner) and the first chapter heading.
   Pull the shell up so Ch 1's heading feels connected to the hero copy
   above, without eliminating the visual break entirely.

   Also slightly reduce the inter-chapter gap inside .treatment-content so
   7 chapters don't stretch the scroll length unnecessarily. We stay one
   space-token above the treatment hub to preserve a family-resemblance
   rhythm; panels just runs a touch tighter because its chapters are
   denser editorial content (numbered reads, cards) rather than tall
   scorecards and full-width tables.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Tighter handoff from the dark hero to the cream shell. */
.treatment-shell-wrap {
  padding-block-start: var(--space-6, 24px);
}

@media (min-width: 900px) {
  .treatment-shell-wrap {
    padding-block-start: var(--space-8, 32px);
  }
}

/* Tighter inter-chapter rhythm for panels (base kept in treatment-hub.css
   is space-16 / space-20 — we drop one token per breakpoint). */
.treatment-content {
  gap: var(--space-12, 48px);
}

@media (min-width: 1100px) {
  .treatment-content {
    gap: var(--space-16, 64px);
  }
}

/* ── Next-topics section — card breathing room ───────────────────────────────
   Base .next-topic styling in category-hub.css sets padding: 0 var(--space-6)
   at desktop (horizontal-only). That pushes the role eyebrow flush against
   the top border and the "Explore →" CTA flush against the bottom — cramped.
   Add symmetrical vertical padding so each card reads as a composed unit
   with clear top/bottom margins. Keep horizontal padding & dividers intact.

   Also tighten the page-section header → grid gap from 40px to 32px so the
   narrow text column (58ch max) doesn't feel disconnected from the wide
   card row below. */
.page-section .page-section__header {
  margin-bottom: var(--space-8, 32px);
}

@media (min-width: 1100px) {
  .next-topic {
    padding-block: var(--space-6, 24px);
  }
}


/* ═══════════════════════════════════════════════════════════════════════════
   1. INSTALL-BLOCK WRAPPER (Ch 7, Block 7A)
   ═══════════════════════════════════════════════════════════════════════════ */

.install-block {
  margin-block-end: var(--space-10, 40px);
}

.install-block__title {
  font-family: var(--font-serif, 'Source Serif 4', serif);
  font-size: var(--fs-xl, 24px);
  font-weight: 600;
  line-height: var(--lh-snug, 1.25);
  color: var(--color-ink);
  margin: 0 0 var(--space-5, 20px);
  letter-spacing: var(--tracking-snug, -0.01em);
}

/* ─── Numbered step list inside .install-block ────────────────────────────
   Used by hub chapters that need a flowing "anatomy / process checklist"
   (make-music Ch 3 MIDI protocol, dj-controllers Ch 3 channel count, Ch 5
   scratch tiers, Ch 6 connection checklist). Two-column grid: monospace
   number pill on the left, serif body column on the right. Hairline
   separators keep the list legible without boxing each step into a card
   (the `.stage-entry` component is the card version of this pattern).
   Tints through --color-accent so every hub's palette reaches the numbers. */
.install-block__steps {
  list-style: none;
  margin: 0;
  padding: 0;
}

.install-block__step {
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: var(--space-5, 20px);
  padding-block: var(--space-4, 16px);
  border-top: 1px solid var(--color-line, #E7E2DC);
}

.install-block__step:first-child {
  border-top: 0;
  padding-block-start: 0;
}

.install-block__step:last-child {
  padding-block-end: 0;
}

.install-block__step-num {
  font-family: var(--font-mono, 'JetBrains Mono', monospace);
  font-size: var(--fs-xs, 13px);
  font-weight: 600;
  letter-spacing: var(--tracking-wide, 0.04em);
  color: var(--color-accent, #0E7490);
  padding-top: 4px;           /* optical align to first line of serif body */
  white-space: nowrap;
  min-width: 1.75rem;
}

.install-block__step-body {
  font-family: var(--font-serif, 'Source Serif 4', serif);
  color: var(--color-ink, #1F1A16);
  min-width: 0;               /* let long words wrap instead of overflowing */
}

.install-block__step-what {
  font-size: var(--fs-base, 16px);
  line-height: var(--lh-relaxed, 1.65);
  margin: 0;
}

.install-block__step-what + .install-block__step-what {
  margin-top: var(--space-3, 12px);
}

.install-block__step-what strong { color: var(--color-ink, #1F1A16); }
.install-block__step-what em     { font-style: italic; }

@media (max-width: 520px) {
  .install-block__step { column-gap: var(--space-3, 12px); }
  .install-block__step-num { min-width: 1.5rem; font-size: 12px; }
}


/* ═══════════════════════════════════════════════════════════════════════════
   2. PRIORITY REORDER — when a reader-state chip is active
   ---------------------------------------------------------------------------
   Each list uses flex-order to hoist the matching card to the top without
   disturbing the DOM order for readers with no chip selection or for bots
   crawling the page. The outline + pill make the adaptation legible.
   ═══════════════════════════════════════════════════════════════════════════ */

/* 2a. Ch 4 placement reads (.stage-entry inside .placement-stack__reads) ─── */

[data-reader-state="studio"]    .placement-stack__reads .stage-entry[data-priority-for~="studio"],
[data-reader-state="theatre"]   .placement-stack__reads .stage-entry[data-priority-for~="theatre"],
[data-reader-state="office"]    .placement-stack__reads .stage-entry[data-priority-for~="office"],
[data-reader-state="rehearsal"] .placement-stack__reads .stage-entry[data-priority-for~="rehearsal"] {
  order: -1;
  background: var(--color-surface-2, #F6F4F1);
  border-left: 3px solid var(--color-accent, #0E7490);
  border-top: 0;
  padding-left: var(--space-4, 16px);
  position: relative;
}

/* When the ordered-first hoisted item has been moved, the DOM-first item
   keeps its original :first-child border-top:0 rule which is correct for
   a natural top-of-list — but we restore the hairline so the second visual
   row reads as a new row, not a continuation of the hoisted card. */
[data-reader-state="studio"]    .placement-stack__reads .stage-entry:not([data-priority-for~="studio"]):first-child,
[data-reader-state="theatre"]   .placement-stack__reads .stage-entry:not([data-priority-for~="theatre"]):first-child,
[data-reader-state="office"]    .placement-stack__reads .stage-entry:not([data-priority-for~="office"]):first-child,
[data-reader-state="rehearsal"] .placement-stack__reads .stage-entry:not([data-priority-for~="rehearsal"]):first-child {
  border-top: 1px solid var(--color-line, #E7E2DC);
}


/* 2b. Ch 5 room cards (.room-card inside .room-grid) ─────────────────────── */

[data-reader-state="studio"]    .room-grid .room-card[data-priority-for~="studio"],
[data-reader-state="theatre"]   .room-grid .room-card[data-priority-for~="theatre"],
[data-reader-state="office"]    .room-grid .room-card[data-priority-for~="office"],
[data-reader-state="rehearsal"] .room-grid .room-card[data-priority-for~="rehearsal"] {
  order: -1;
  position: relative;
}

[data-reader-state="studio"]    .room-grid .room-card[data-priority-for~="studio"]    .room-card__frame,
[data-reader-state="theatre"]   .room-grid .room-card[data-priority-for~="theatre"]   .room-card__frame,
[data-reader-state="office"]    .room-grid .room-card[data-priority-for~="office"]    .room-card__frame,
[data-reader-state="rehearsal"] .room-grid .room-card[data-priority-for~="rehearsal"] .room-card__frame {
  outline: 2px solid var(--color-accent, #0E7490);
  outline-offset: 0;
}


/* 2c. Ch 6 pick rows (.pick-row inside .picks-stack) ─────────────────────── */

[data-reader-state="studio"]    .picks-stack .pick-row[data-priority-for~="studio"],
[data-reader-state="theatre"]   .picks-stack .pick-row[data-priority-for~="theatre"],
[data-reader-state="office"]    .picks-stack .pick-row[data-priority-for~="office"],
[data-reader-state="rehearsal"] .picks-stack .pick-row[data-priority-for~="rehearsal"] {
  order: -1;
  background: var(--color-surface-2, #F6F4F1);
  border-top: 0;
  position: relative;
}


/* ═══════════════════════════════════════════════════════════════════════════
   3. "START HERE" PILL — shown next to the priority-matched card
   ---------------------------------------------------------------------------
   Rendered via ::before on the priority item; pure CSS, zero markup. The
   wording is generic ("Start here") rather than state-specific so the
   selector stays simple; the surrounding card and chapter lede already
   name the use-case.
   ═══════════════════════════════════════════════════════════════════════════ */

[data-reader-state] .placement-stack__reads .stage-entry[data-priority-for]::before,
[data-reader-state] .room-grid .room-card[data-priority-for]::before,
[data-reader-state] .picks-stack .pick-row[data-priority-for]::before {
  content: none; /* hidden by default */
}

[data-reader-state="studio"]    .placement-stack__reads .stage-entry[data-priority-for~="studio"]::before,
[data-reader-state="theatre"]   .placement-stack__reads .stage-entry[data-priority-for~="theatre"]::before,
[data-reader-state="office"]    .placement-stack__reads .stage-entry[data-priority-for~="office"]::before,
[data-reader-state="rehearsal"] .placement-stack__reads .stage-entry[data-priority-for~="rehearsal"]::before,

[data-reader-state="studio"]    .room-grid .room-card[data-priority-for~="studio"]::before,
[data-reader-state="theatre"]   .room-grid .room-card[data-priority-for~="theatre"]::before,
[data-reader-state="office"]    .room-grid .room-card[data-priority-for~="office"]::before,
[data-reader-state="rehearsal"] .room-grid .room-card[data-priority-for~="rehearsal"]::before,

[data-reader-state="studio"]    .picks-stack .pick-row[data-priority-for~="studio"]::before,
[data-reader-state="theatre"]   .picks-stack .pick-row[data-priority-for~="theatre"]::before,
[data-reader-state="office"]    .picks-stack .pick-row[data-priority-for~="office"]::before,
[data-reader-state="rehearsal"] .picks-stack .pick-row[data-priority-for~="rehearsal"]::before {
  content: "Start here";
  position: absolute;
  top: var(--space-2, 8px);
  right: var(--space-3, 12px);
  z-index: 2;

  display: inline-block;
  padding: 2px 8px;
  background: var(--color-accent, #0E7490);
  color: var(--color-surface, #FFFFFF);
  font-family: var(--font-mono, 'JetBrains Mono', monospace);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  border-radius: 2px;
  pointer-events: none;
}


/* ═══════════════════════════════════════════════════════════════════════════
   4. LOCAL POLISH — how legacy cards breathe inside the new .chapter
   ---------------------------------------------------------------------------
   The legacy category-hub.css cards carried their own rhythm from .page-section
   parents. Inside .chapter that rhythm mostly still works; we intentionally
   do NOT add margin-block-end here because .chapter-commercial-row already
   has `margin-top: var(--space-4)` (from treatment-hub.css), and adding a
   margin-bottom to the grids above stacks with it for 40px of unwanted gap.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Keyboard-focus affordance for stage-entry (the rail can put keyboard focus
   on a chapter entry; the hover style should also trigger on focus). */
.chapter .stage-entry:focus-visible {
  outline: 0;
  border-left: 3px solid var(--color-accent, #0E7490);
  padding-left: calc(var(--space-4, 16px) - 3px);
}

/* Chapter-lede sometimes carries inline <span class="for-reader-state"> state
   variants (Ch 4, for instance). The default .for-reader-state rule hides
   them; when revealed they should sit inline, not start a new block, since
   the full lede is a single paragraph. */
.chapter-lede .for-reader-state {
  display: inline;
}

/* At 1200px+ the legacy .room-grid jumps to 4 columns. Inside the chapter
   content column (rail 220 + gap 32 = 252px occupied), the remaining
   ~840px makes 4 cards feel cramped (~210px each with a 4:3 thumb). Cap
   the grid to 3 columns when it lives inside a chapter at desktop so the
   cards breathe (~280px each). Treatment-hub.css doesn't need this since
   its Ch 5 doesn't use .room-grid. */
@media (min-width: 1100px) {
  .chapter .room-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}


/* ═══════════════════════════════════════════════════════════════════════════
   5. CH 3 CALCULATOR — light padding normalisation inside the chapter
   ---------------------------------------------------------------------------
   The legacy .acoustic-calc-simple was designed for a full-width .page-section.
   Inside the .chapter content column (narrower at mid-widths) the body can
   feel cramped without a little internal padding. Purely additive — no layout
   overrides that could break the calc's own responsive rules.
   ═══════════════════════════════════════════════════════════════════════════ */

.chapter .acoustic-calc-simple .calc-simple-body {
  padding: var(--space-5, 20px);
}
