/* GENERATED from tokens.ts brandable defaults (branding plan D4) — do not edit. */
@scope (.theme-canvas) {
  :scope {
    --flow-surface: #faf6f0;
    --flow-surface-raised: #f5efe5;
    --flow-surface-sunken: #f0f4f5;
    --flow-surface-inverse: #003087;
    --flow-accent: #005eb8;
    --flow-ink-emphasis: #005eb8;
    --flow-ink-emphasis-on-dark: #ffffff;
    --flow-ink-subtle: #4c6272;
    --flow-ink-subtle-on-dark: #d8dde0;
    --flow-ink-accent: #7c2855;
    --flow-ink-accent-on-dark: #fae100;
    --flow-fg-on-light: #212b32;
    --flow-fg-on-dark: #ffffff;
    --flow-link-on-light: #005eb8;
    --flow-link-on-dark: #ffffff;
    --flow-field-bg: #ffffff;
    --flow-field-bg-on-dark: rgba(255, 255, 255, 0.08);
    --flow-field-text: #212b32;
    --flow-field-text-on-dark: #ffffff;
    --flow-field-border: #4c6272;
    --flow-field-border-on-dark: #aeb7bd;
    --flow-field-label-color: #212b32;
    --flow-field-label-color-on-dark: #ffffff;
    --flow-field-placeholder-color: #768692;
    --flow-field-placeholder-color-on-dark: #aeb7bd;
    --flow-field-help-color: #4c6272;
    --flow-field-help-color-on-dark: #d8dde0;
    --flow-field-required-color: #da291c;
    --flow-field-required-color-on-dark: #ffd7d3;
    --flow-field-group-border: #aeb7bd;
    --flow-field-group-border-on-dark: #aeb7bd;
    --flow-header-ground: #ffffff;
    --flow-header-ink: #172b43;
    --flow-header-navigation: #f2f7fc;
    --flow-footer-ground: #070b16;
    --flow-footer-band: #005eb8;
    --flow-footer-ink: #ffffff;
    --flow-footer-band-ink: #ffffff;
    --flow-footer-accent: #83c5ff;
    --flow-index-gap: 4rem;
    --flow-card-surface: #ffffff;
    --flow-card-ink: #172432;
    --flow-card-border: #d5dbe1;
    --flow-card-padding: 1.75rem;
    --flow-card-radius: 12px;
    --flow-editorial-ground: #070b16;
    --flow-editorial-accent: #a5c8ff;
    --flow-editorial-secondary: #c8ed8d;
    --flow-editorial-tertiary: #c4b5fd;
    --flow-editorial-font: Georgia, "Times New Roman", serif;
    --color-accent: #f5dcc9;
    --color-accent-soft: #fbeddf;
    --color-highlight: #c7d5c5;
    --color-highlight-soft: #dee7dc;
    --color-surface-accent: #e2eef9;
    --color-nhs-red: #da291c;
    --color-nhs-yellow: #fae100;
    --font-sans: "Plus Jakarta Sans", "Frutiger W01", Arial, sans-serif;
  }
}

@scope (.theme-canvas) {
/*! flow-structural-contract v1 (@treeviewdesigns/flow-shared) */
/*
 * Theme-independent BEHAVIOUR rules for the Pages layout contract — what the
 * editor's block controls (width / alignment / space-below) actually DO.
 * Versioned with `blockClasses()` (src/layout/contract.ts), the emitter of
 * this class vocabulary, so the two can never drift apart.
 *
 * Themes do NOT copy these rules. Each theme's build concatenates this file
 * (wrapped in `@scope (.theme-canvas)`) AHEAD of the theme's authored
 * tokens.css inside `dist/tokens.css` — contract first, theme after, so a
 * theme can deliberately override a structural default by plain source order
 * (e.g. the NHS narrow-surface `--mb-*` remap). The sentinel banner above is
 * asserted by the theme build guard and (per the tenant-branding plan, B1.c)
 * by Flow's scan-time validator.
 *
 * SKIN stays out of this file entirely: values come from theme tokens
 * (`--space-*`), and per-widget rules target CANONICAL classes only
 * (`.flow-button`, `.flow-heading`, `.flow-richtext`) — theme widget
 * overrides keep the canonical root + modifier classes alongside their own
 * (the D-C convention), so no theme class name ever appears here.
 */

/* ── Segment surfaces — UNIVERSAL render recipes (segment-surface-styles) ──
   Theme-independent MECHANISM for the four segment background modes. The
   contract's `sectionStyle()` emits per-section custom properties
   (`--flow-section-bg-image`, `--flow-section-gradient`, …) and
   `sectionClasses()` emits the gating `flow-section--surface-{mode}` class; the
   recipes below turn those into a rendered surface. Every CONFORMING theme gets
   the mechanism for free (the theme only gates which modes the drawer offers);
   theme `tokens.css` supplies FLAVOUR (default tints, preset colour mixes) only.

   Positioning contract: `.flow-section` had NO `position` before this feature.
   `position: relative` anchors the surface layers to the section; `isolation:
   isolate` gives them a clean stacking context so the `::before` overlay and the
   `z-index:1` inner cannot escape into sibling sections. The surface covers the
   FULL `<section>` (including gutters / full-bleed), NOT the max-width
   `.flow-section__inner`. */
.flow-section { position: relative; isolation: isolate; }

/* Content lift — all content sits ABOVE the image / overlay / gradient layers
   and stays interactive (links + buttons clickable). */
.flow-section__inner { position: relative; z-index: 1; }

/* image — a positioned background layer painted on the section itself. The
   `image-set()` lives in `--flow-section-bg-image` (responsive WebP set); the
   `@supports` block below feeds a plain `url(...)` fallback for engines without
   `image-set()`. Position + attachment default to a sensible centre/scroll. */
.flow-section--surface-image {
  background-image: var(--flow-section-bg-image);
  background-position: var(--flow-section-bg-position, center);
  background-size: cover;
  background-repeat: no-repeat;
  background-attachment: var(--flow-section-bg-attachment, scroll);
}

/* overlay — a tint laid OVER the image, BELOW the content (`z-index:0` keeps it
   under the `z-index:1` inner). `pointer-events: none` so it never intercepts
   clicks meant for the content above it. Only paints when an overlay colour is
   set (a transparent default leaves the image untouched). */
.flow-section--surface-image::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-color: var(--flow-section-overlay-colour, transparent);
  opacity: var(--flow-section-overlay-opacity, 1);
}

/* gradient FILL — the section background is the resolved gradient value. A
   `gradient-*` Colour fill (Workstream B) emits this class; it is SUPPRESSED by
   `sectionClasses()` while an image overlay is active (both paint
   `background-image`), so the two never collide. A `solid-*` Colour base paints
   `background-color` and so coexists with an image. */
.flow-section--fill-gradient {
  background-image: var(--flow-section-gradient);
}

/* ════════════════════════════════════════════════════════════════════════
   SECTION-RENDER FLOOR + block-spacing rhythm (theme-agnostic LAYOUT floor).

   `sectionClasses()` (contract.ts) ALWAYS emits `flow-section--pad-{token}`,
   `flow-section--width-{token}` and `flow-section--bg-{token}` on every section,
   and the render stacks blocks as direct children of `.flow-section__inner` /
   `.flow-column`. Turning those emitted classes into real `padding-block` /
   `max-width` / `background-color`, and giving stacked blocks a default vertical
   rhythm, is LAYOUT the contract already presupposes — so it lives HERE, not per
   theme. A theme that authors none of it still renders plain-but-correct instead
   of a collapsed, unpadded, transparent mess.

   BOUNDARY: layout + token PLUMBING only. Every value is a theme token
   (`--space-*`, `--section-bg-*`, `--container-*`); NO literal skin (colours,
   borders, shadows, card chrome) lives here — that stays theme-authored in
   `tokens.css`, which is concatenated AFTER this contract and so overrides any
   floor rule on source order (a theme styles its look on top of the floor). */

/* Section box — vertical padding on the section; the horizontal GUTTER belongs to
   the CONTAINED inner (Workstream B §B5), NOT the section, so `pad-none` /
   `width-full_bleed` content bleeds edge-to-edge while a contained section keeps
   its breathing room. The surface (background + `::before` overlay, inset:0 on
   `.flow-section`) still covers the FULL section width regardless. */
.flow-section { padding-block: var(--space-md); }
.flow-section__inner { width: 100%; }
.flow-section--width-contained .flow-section__inner {
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--container-gutter, 1.5rem);
}
.flow-section--width-full_bleed .flow-section__inner { max-width: none; }

/* Padding token scale (the emitted `flow-section--pad-{token}` classes). */
.flow-section--pad-none { padding-block: var(--space-none); }
.flow-section--pad-sm { padding-block: var(--space-sm); }
.flow-section--pad-md { padding-block: var(--space-md); }
.flow-section--pad-lg { padding-block: var(--space-lg); }
.flow-section--pad-xl { padding-block: var(--space-xl); }
.flow-section--pad-2xl { padding-block: var(--space-2xl); }

/* Solid Colour backgrounds — wire the emitted `flow-section--bg-{token}` class
   (the `solid-{token}` fill, prefix-stripped) to the theme's surface token.
   WITHOUT this a section is transparent, so a prior section's fixed-image surface
   bleeds through (the reported bug). Colour ONLY; the dark-surface text flip is
   content-tone's job (tone classes below + the `data-surface-tone` predicate). A
   solid base coexists with an image overlay (it shows behind it); only a
   `gradient-*` fill is suppressed under an image (Workstream B). */
.flow-section--bg-default { background-color: var(--section-bg-default); }
.flow-section--bg-muted { background-color: var(--section-bg-muted); }
.flow-section--bg-accent { background-color: var(--section-bg-accent); }
.flow-section--bg-brand { background-color: var(--section-bg-brand); }
.flow-section--bg-hero { background-color: var(--section-bg-hero); }
/* Transparent fill (`solid-transparent`) — an EXPLICIT no-surface base so the
   section shows the page/body background. NOT a `--section-bg-*` colour token
   (it has no variable + no contrast model — transparent-background plan D1); it
   is the one fill that intentionally paints nothing. Explicit (not the mere
   absence of a rule) so a prior section's fixed-image surface cannot bleed
   through. Foreground stays light-surface ink by default (never a dark surface,
   D3); an author layering over a dark page sets contentTone. */
.flow-section--bg-transparent { background-color: transparent; }

/* Hero transparent baseline (`transparentBackground` prop, D5/D6) — the shared
   floor for a hero that claims no surface of its own. Themes paint `.flow-hero`
   with their own band + on-band light ink, so each theme MUST also handle
   `.flow-hero--transparent` to drop that band, reset foreground to on-light ink,
   and suppress image-less decorations. This baseline guarantees a sensible
   default for any future theme that ships no explicit override. */
.flow-hero--transparent { background: transparent; }

/* Hero image overlay scrim (component-surface-parity-and-motion A) — a tint laid
   OVER the background image, UNDER the content; the SFC renders it + sets the
   colour/opacity inline. Content is lifted above it generically so the scrim
   never covers the copy regardless of each theme's hero-layer z-index. */
.flow-hero__overlay { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.flow-hero__eyebrow, .flow-hero__headline, .flow-hero__subhead, .flow-hero__actions { position: relative; z-index: 1; }

/* Hero call-to-action group (repeater-properties-hero-buttons plan) — the Hero
   renders 0..N buttons inside this wrapper. Baseline layout (flex + wrap + gap)
   so multiple buttons sit in a row and wrap on narrow widths regardless of
   theme; a theme tunes the gap/alignment. Content-lift via the rule above. */
.flow-hero__actions { display: flex; flex-wrap: wrap; gap: var(--space-sm, 0.75rem); }

/* Authorable surface MOTION (B) — the shared contract. Ken Burns "zoom" is this
   CSS keyframe on the image; `parallax` is the JS composable; `cinematic` = both
   (they compose: scale on the <img>, translate on the <picture>). The a11y +
   editor guards are promoted from lumen to the shared contract so EVERY
   theme/component inherits them — themes only retune timing/easing. */
@keyframes flow-kenburns {
  from { transform: scale(1.12); }
  to { transform: scale(1); }
}
img[data-surface-motion="zoom"],
img[data-surface-motion="cinematic"] {
  animation: flow-kenburns 18s ease-out forwards;
  will-change: transform;
}
@keyframes flow-pan-left {
  from { transform: scale(1.1) translateX(3%); }
  to { transform: scale(1.1) translateX(-3%); }
}
@keyframes flow-pan-right {
  from { transform: scale(1.1) translateX(-3%); }
  to { transform: scale(1.1) translateX(3%); }
}
img[data-surface-motion="pan-left"] { animation: flow-pan-left 12s ease-in-out forwards; }
img[data-surface-motion="pan-right"] { animation: flow-pan-right 12s ease-in-out forwards; }
@media (prefers-reduced-motion: reduce) {
  img[data-surface-motion] { animation: none; }
}
/* Editor-canvas freeze: this file is concatenated INSIDE `@scope (.theme-canvas)`
   (see banner above), so `:scope` IS the `.theme-canvas` root. Target the root
   carrying `data-editor-mode` (the live editor canvas) — a nested
   `.theme-canvas[data-editor-mode]` would never match, since the scope root is
   the only `.theme-canvas`. The tenant FRONT root has no `data-editor-mode`, so
   its hero animates; only the editor freezes. */
:scope[data-editor-mode] img[data-surface-motion] { animation: none; }

/* Block-spacing rhythm (Layer 1) — uniform `--space-md` between stacked blocks.
   `margin-block-start: 0` kills UA top-margins generically (no per-widget reset
   needed); `margin-block-end` carries the rhythm so the authorable per-block
   `.flow-block--mb-*` `!important` override (below) replaces it cleanly. Row
   children lay out horizontally → no vertical rhythm on them. */
.flow-section__inner > * { margin-block-start: 0; margin-block-end: var(--space-md); }
.flow-section__inner > :last-child { margin-block-end: 0; }
.flow-row > * { margin-block-end: 0; }
.flow-column > * { margin-block-start: 0; margin-block-end: var(--space-md); }
.flow-column > :last-child { margin-block-end: 0; }

/* RichText list-item paragraph reset (richtext-list-item-paragraph-spacing
   plan) — theme-agnostic DOM-parity normalisation. Tiptap's list schema wraps
   every `<li>`'s content in a `<p>`, and the sanitiser keeps it, so the saved +
   live-editor markup is `<li><p>…</p></li>`. Without this reset the theme's
   `.flow-richtext p` block margin stacks on top of `.flow-richtext li`,
   spreading list items apart the moment a list is edited — on the editor canvas
   AND the published front render. Zeroing the paragraph margin hands list
   spacing back to the theme's `.flow-richtext li` rule alone, keeping both
   surfaces identical. Specificity (0,1,2) beats the theme's `.flow-richtext p`
   (0,1,1) regardless of source order, so no theme override is needed; the
   drawer RichTextEditor.vue carries the same reset locally. */
.flow-richtext li > p { margin: 0; }

/* Content tone (segment-content-tone plan) — colour-agnostic PLUMBING. A
   non-token surface can flip its foreground so text stays readable on a dark
   surface; the THEME supplies the actual colours via the four brandable tokens
   (`--flow-fg-on-dark`, `--flow-link-on-dark`, `--flow-fg-on-light`,
   `--flow-link-on-light`). The white/`inherit` fallbacks make "Light text" work
   in EVERY theme (even un-migrated ones) before any theme declares the tokens.
   `.flow-heading` / `.flow-richtext` are `color: inherit`, so they follow the
   section automatically. The link selector is `a:where(:any-link)` —
   specificity (0,1,1): ONE class + ONE element — deliberately above every
   (0,1,0) theme link rule (`:where(a)`, `:where(a):visited`,
   `.flow-section--bg-hero :where(a)`), which sit in the later authored block and
   would otherwise win on source order (a visited link would render the theme's
   visited colour — e.g. NHS purple — on a dark surface). */
.flow-section--tone-light {
  color: var(--flow-fg-on-dark, #ffffff);
}

.flow-section--tone-light a:where(:any-link) {
  color: var(--flow-link-on-dark, #ffffff);
  text-decoration: underline;
}

/* Linked content tokens keep readable ink on automatically detected dark
   surfaces too, including visited links. The theme owns the colour value. */
[data-surface-tone="dark"] .flow-token-block a:where(:any-link) {
  color: var(--flow-link-on-dark, #ffffff);
  text-decoration: underline;
  text-underline-offset: .2em;
}

.flow-section--tone-dark {
  color: var(--flow-fg-on-light, inherit);
}

.flow-section--tone-dark a:where(:any-link) {
  color: var(--flow-link-on-light, currentColor);
}

/* Inline ink roles (palette-provenance plan, D9.2) — colour-agnostic PLUMBING
   for the per-span `inkColor` RichText mark and the block-level Heading ink
   prop. Each `flow-ink-{role}` class resolves to the THEME's own
   `--flow-ink-{role}` colour; the literal `currentColor` final fallback makes a
   role inert-but-safe in any theme that hasn't declared the token yet (it reads
   as the surrounding text colour, never an illegible default). Ink is FLOOR-ONLY
   in v1 — exactly `emphasis / subtle / accent`, no theme extras (D9.5).

   Dark-surface override — keyed on BOTH dark-band signals (the ink-level
   application of Lesson 114). A role prefers its `-on-dark` realisation on:
     · `[data-surface-tone="dark"]` — the AUTO marker the render predicate emits
       for a dark token/gradient surface or an image overlay; AND
     · `.flow-section--tone-light` — the author's EXPLICIT "Light text" content
       tone. This case does NOT emit the `data-surface-tone` marker
       (`buildIsDarkSurface()` opts an explicit light tone OUT), so without this
       second selector an `emphasis`/`accent` heading on an author-declared dark
       band would wrongly use its on-LIGHT token and turn illegible. "Light text"
       means "this ground is dark", so the on-dark ink realisation is correct.
   On either signal the role cascades on-dark → base token → `currentColor`. The
   shared package owns these class names + the signal-scoped selectors; each theme
   owns the `--flow-ink-{role}[-on-dark]` values + the dark-surface metadata.

   SPECIFICITY (doubled class, deliberate — palette-provenance follow-up): the
   block-level Heading ink prop applies `flow-ink-{role}` to the SAME element that
   carries `.flow-heading` (likewise `.flow-richtext`), whose theme rule is
   `color: inherit` at (0,1,0). A single `.flow-ink-{role}` is also (0,1,0), so it
   would lose on source order to the theme's later-authored `.flow-heading` block.
   Doubling the class — `.flow-ink-{role}.flow-ink-{role}` — lifts the base rule to
   (0,2,0) so ink wins over the element's inherit, and the dark override to (0,3,0)
   so it still beats the base. Harmless on inline `<span class="flow-ink-{role}">`
   (a single class matches the doubled selector). */
.flow-ink-emphasis.flow-ink-emphasis { color: var(--flow-ink-emphasis, currentColor); }
.flow-ink-subtle.flow-ink-subtle { color: var(--flow-ink-subtle, currentColor); }
.flow-ink-accent.flow-ink-accent { color: var(--flow-ink-accent, currentColor); }

[data-surface-tone="dark"] .flow-ink-emphasis.flow-ink-emphasis,
.flow-section--tone-light .flow-ink-emphasis.flow-ink-emphasis { color: var(--flow-ink-emphasis-on-dark, var(--flow-ink-emphasis, currentColor)); }
[data-surface-tone="dark"] .flow-ink-subtle.flow-ink-subtle,
.flow-section--tone-light .flow-ink-subtle.flow-ink-subtle { color: var(--flow-ink-subtle-on-dark, var(--flow-ink-subtle, currentColor)); }
[data-surface-tone="dark"] .flow-ink-accent.flow-ink-accent,
.flow-section--tone-light .flow-ink-accent.flow-ink-accent { color: var(--flow-ink-accent-on-dark, var(--flow-ink-accent, currentColor)); }

/* image fallback — engines without `image-set()` cannot parse
   `--flow-section-bg-image` (an `image-set(...)`), so the whole `background`
   shorthand drops. The resolver also emits a `url(src)` form there is no clean
   way to express as a second custom property; instead, where `image-set()` is
   unsupported we let the declared property fail gracefully (the section shows
   its token/transparent base). Modern engines (the support floor for the
   editor + front) all support `image-set()`, so this is a rare-old-browser
   degradation, not a primary path. */


/* Per-block "space below" overrides — `.flow-block--mb-{token}` (element spacing).
   `auto` emits no class (the theme's own rhythm applies); `!important` beats
   the theme rhythm pairs (`.flow-section__inner > *` / `.flow-column > *`)
   and their `:last-child` resets. Values are the THEME's spacing tokens. */
.flow-block--mb-none { margin-block-end: var(--space-none) !important; }
.flow-block--mb-sm { margin-block-end: var(--space-sm) !important; }
.flow-block--mb-md { margin-block-end: var(--space-md) !important; }
.flow-block--mb-lg { margin-block-end: var(--space-lg) !important; }
.flow-block--mb-xl { margin-block-end: var(--space-xl) !important; }
.flow-block--mb-2xl { margin-block-end: var(--space-2xl) !important; }

/* ── Block width + alignment ─────────────────────────────────────────────
   The `flow-block--w-*` / `flow-block--a-*` classes land on the column /
   row-track ITEM on both surfaces: the front widget root (WidgetRenderer)
   and the editor's BlockShell wrapper. `auto` width emits no class — the
   widget's own CSS decides. Margins, not `justify-self`, so one mechanism
   aligns in the front flex column, the front nested-row grid track, AND the
   editor wrapper's normal flow.

   `display: flex` BLOCKIFIES the item — `margin-inline: auto` cannot
   position an inline-level box (the button widget root is inline-flex) in
   normal block flow. Flex (not block) so a widget root keeps its flex
   interior (gap / align-items) when the class lands on it.

   TEXT WIDGETS (.flow-heading, .flow-richtext) are EXCLUDED from the box
   transform in the self-targeted form: `blockClasses()` emits `--w-hug`
   whenever align != left, and on the front these classes sit directly on
   the widget root — without the exclusion an aligned heading would be
   flexified and shrunk to fit-content. Text widgets align via text-align
   (below); their box stays a full-width block, and an explicit `hug` width
   on them is visually inert by design. */
.flow-block--w-hug:not(:is(.flow-heading, .flow-richtext)) { display: flex; inline-size: fit-content; max-inline-size: 100%; }
.flow-block--w-fill:not(:is(.flow-heading, .flow-richtext)) { display: flex; inline-size: 100%; }
.flow-block--a-center { margin-inline: auto; }
.flow-block--a-right { margin-inline-start: auto; margin-inline-end: 0; }

/* Button pair rules — the editor's wrapper indirection: the BlockShell
   wrapper carries the class (and deliberately stays full slot width — it is
   the DnD hitbox), so the width-constrained widget INSIDE must follow.
   Descendant rules never match on the front (the classes sit ON the widget
   root), so the descendant forms are editor-only by construction. */
.flow-block--w-fill .flow-button { inline-size: 100%; }
.flow-block--w-hug .flow-button { display: flex; inline-size: fit-content; }

/* Editor inner alignment. `:not(--w-fill)` keeps these off FILL blocks: on
   fill, align moves the LABEL (the justify-content rules below) —
   `fit-content` here would out-cascade the fill pair rule's
   `inline-size: 100%` (same specificity, later in source) and shrink the
   widget. */
.flow-block--a-center:not(.flow-block--w-fill) .flow-button {
  display: flex;
  inline-size: fit-content;
  margin-inline: auto;
}
.flow-block--a-right:not(.flow-block--w-fill) .flow-button {
  display: flex;
  inline-size: fit-content;
  margin-inline-start: auto;
  margin-inline-end: 0;
}

/* Fill + align — the DUAL semantic: on a fill block the align tokens move
   the CONTENT (the button label), not the block. Default (no align class) =
   left; the self form covers the front, the descendant form covers the
   editor's wrapper indirection. */
.flow-block--w-fill.flow-button,
.flow-block--w-fill .flow-button { justify-content: flex-start; }
.flow-block--w-fill.flow-block--a-center.flow-button,
.flow-block--w-fill.flow-block--a-center .flow-button { justify-content: center; }
.flow-block--w-fill.flow-block--a-right.flow-button,
.flow-block--w-fill.flow-block--a-right .flow-button { justify-content: flex-end; }

/* Bare-grid button width — editor↔live parity (editor-theme-invariant-interactions
   W3). The front render is WRAPPER-LESS: a button (inline-flex, hugs by default)
   is a DIRECT grid child of its row/column track, so the grid's default
   `justify-items: stretch` STRETCHES the auto-width button to fill the track —
   diverging from the EDITOR, where the `.flow-block` SLOT is the grid child (it
   fills the track) and the button hugs INSIDE it. `justify-self: start` makes the
   bare front button keep its intrinsic (hug) width at the track start; the
   existing `--a-*` (margin-inline auto) + `--w-fill` (inline-size: 100%) rules
   above then center / right / fill it exactly as they do the editor's inner
   button. This matches ONLY on the front: in the editor the button is
   `.flow-row > .flow-block > .flow-button` (not a direct grid child), so the
   editor's slots — which SHOULD fill the track — are untouched. A content-sized
   (button-group) track already hugs, so `start` is a no-op there. */
.flow-row > .flow-button,
.flow-column > .flow-button { justify-self: start; }

/* ── Text-widget alignment ───────────────────────────────────────────────
   Alignment on text widgets is TEXT alignment — identical in hug and fill
   (no "alignment only works when hugging" trap), no flexification of
   semantic text elements. Descendant form = editor (classes on the
   BlockShell wrapper); self form = front no-wrapper render (classes on the
   widget root). Richtext has no Tiptap text-align extension, so this is the
   only alignment mechanism for it. */
.flow-block--a-center :is(.flow-heading, .flow-richtext),
.flow-block--a-center:is(.flow-heading, .flow-richtext) { text-align: center; }
.flow-block--a-right :is(.flow-heading, .flow-richtext),
.flow-block--a-right:is(.flow-heading, .flow-richtext) { text-align: right; }

/* ── Row responsive layout — STRUCTURE only (per-breakpoint row toolbar) ───
   Theme-independent PER-BREAKPOINT row geometry for `.flow-row`. The contract's
   `rowStyle()` emits four families of inline custom properties, each with a
   `-d` (desktop >= 1024px), `-t` (tablet 640-1023px), `-m` (mobile < 640px)
   variant: `--row-cols-*` (a `grid-template-columns` track string),
   `--row-justify-*` (`justify-content`), `--row-gap-*` (`gap`), and
   `--row-valign-*` (`align-items`). Inline styles cannot hold container
   queries, so the queries that SELECT the active band live here. EVERY row
   (proportional AND content) emits all four families — the per-band toolbar
   (`docs/plans/segment-responsive-toolbar.md`) lets Size / Gap / Align / Justify
   vary by device, so the structural rules must own all four.

   `display: grid` is the contract's too (editor-theme-invariant-interactions):
   it WAS left to each theme's authored base rule (§2.1, with gap/align stripped
   in lockstep), but that proved fragile — a theme conversion can silently omit
   it, and without `display: grid` every `grid-template-columns` here is inert,
   so the row renders as a block and its columns STACK. `flow-theme-lumen@0.3.0`
   shipped exactly that omission while `flow-theme-nhs` carried the rule, so the
   same payload laid out side-by-side on NHS and stacked on Lumen. The base
   geometry is theme-INVARIANT, so it belongs here where every conforming theme
   embeds it and none can drop it. A theme that wants a non-grid row can still
   override on source order (its authored `tokens.css` follows this contract).

   The query container is the NAMED `theme-canvas` container (the canvas / front
   page region establishes `container: theme-canvas / inline-size`), the SAME
   container the theme's legacy auto-stack queried — NOT a row-level container
   (a contained row can be narrower than the canvas, which would pick the wrong
   band). The bands match the List Grid widget's (mobile-first base, >= 640
   tablet, >= 1024 desktop) so rows and grids break at the same widths.

   STACKING is class-driven (`rowClasses()` emits `flow-row--stack-{mobile|
   tablet}`): a band-scoped `grid-template-columns: 1fr !important` collapses the
   row to one column. The `!important` + class scope is deliberate — it beats the
   per-band `--row-cols-*` rules below. This SUPERSEDES the theme's old blanket
   force-stack (dropped in lockstep). A CONTENT row gets the default
   `flow-row--stack-mobile`, so it keeps stacking < 640px exactly as before;
   `sizing*` is moot on a collapsed band. */
.flow-row {
  display: grid;
  grid-template-columns: var(--row-cols-m, 1fr);
  gap: var(--row-gap-m, var(--space-md));
  align-items: var(--row-valign-m, start);
  justify-content: var(--row-justify-m, normal);
}
@container theme-canvas (min-width: 640px) {
  .flow-row {
    grid-template-columns: var(--row-cols-t, 1fr);
    gap: var(--row-gap-t, var(--space-md));
    align-items: var(--row-valign-t, start);
    justify-content: var(--row-justify-t, normal);
  }
}
@container theme-canvas (min-width: 1024px) {
  .flow-row {
    grid-template-columns: var(--row-cols-d, 1fr);
    gap: var(--row-gap-d, var(--space-md));
    align-items: var(--row-valign-d, start);
    justify-content: var(--row-justify-d, normal);
  }
}
/* Stack intent — collapse to one column at-and-below the authored breakpoint.
   `639.98px` / `1023.98px` keep the columns ON at exactly 640 / 1024 (aligning
   the row break edge with the List Grid `min-width` bands). */
@container theme-canvas (max-width: 639.98px) {
  .flow-row--stack-mobile { grid-template-columns: 1fr !important; }
}
@container theme-canvas (max-width: 1023.98px) {
  .flow-row--stack-tablet { grid-template-columns: 1fr !important; }
}

/* ── List Grid widget — STRUCTURE only (Lists module plan §7.4) ───────────
   Theme-independent LAYOUT for the `listgrid` render widget: the responsive
   column grid + per-card span. Card SKIN (border, padding, shadow,
   typography) is the theme's — only grid geometry lives here.

   The SFC emits inline `--listgrid-cols-d/t/m` (clamped column counts) and a
   `--listgrid-gap` token; inline styles cannot hold container queries, so the
   queries that SELECT which column count + which per-card span is active live
   here. Responsiveness uses CONTAINER queries (not viewport media queries) so
   the grid reflows correctly inside the edit-in-place canvas device frames as
   well as on the front. The widget root is the query container.

   VARIANT SKIN HOOK (theme-declared-widget-variants plan, Workstream A): the SFC
   emits `flow-listgrid--{variant}` / `flow-listaccordion--{variant}` (the resolved,
   post-fallback variant key) as a BEM modifier on the block. The variant GEOMETRY
   (columns/gap/imageRatio/contentAlign) arrives via the inline custom-props above —
   so the canonical variants already render distinctly with NO skin here. By
   contract decision the canonical skin is EMPTY: structural.css ships no
   `--{variant}` rules; the SKIN (eyebrow colour, hover, sliding arrow, layout)
   is wholly THEME-owned (each theme's tokens.css targets these hooks). */
.flow-listgrid-widget { container-type: inline-size; }

/* Gap scale → theme spacing tokens. Structure maps the named steps; the
   `--space-*` values are the THEME's. */
.flow-listgrid { --listgrid-gap-none: 0; }
.flow-listgrid {
  --listgrid-gap-sm: var(--space-sm);
  --listgrid-gap-md: var(--space-md);
  --listgrid-gap-lg: var(--space-lg);
  --listgrid-gap-xl: var(--space-xl);
}

.flow-listgrid {
  display: grid;
  gap: var(--listgrid-gap, var(--space-md));
  /* Mobile-first: the mobile column count is the base. */
  grid-template-columns: repeat(var(--listgrid-cols-m, 1), minmax(0, 1fr));
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Per-card span — mobile-first base picks the mobile-clamped value. */
.flow-listgrid__card { grid-column: span var(--card-span-m, 1); }

@container (min-width: 640px) {
  .flow-listgrid {
    grid-template-columns: repeat(var(--listgrid-cols-t, 2), minmax(0, 1fr));
  }
  .flow-listgrid__card { grid-column: span var(--card-span-t, 1); }
}

@container (min-width: 1024px) {
  .flow-listgrid {
    grid-template-columns: repeat(var(--listgrid-cols-d, 3), minmax(0, 1fr));
  }
  .flow-listgrid__card { grid-column: span var(--card-span-d, 1); }
}

/* Each card's inner wrapper (an <a> when the card is a link — so the whole
   card is one discernible-name click target — otherwise a <div>) is the flex
   column that stacks the media frame above the content. It fills the
   equal-height card (stretched by the grid) so the theme can pin a cta to the
   bottom. SKIN (the card's own border / padding / shadow) is the theme's. */
.flow-listgrid__card { display: flex; min-inline-size: 0; }
.flow-listgrid__inner {
  display: flex;
  flex-direction: column;
  inline-size: 100%;
}
/* Content column under the media frame; grows to fill the card height so a
   bottom-pinned cta lines up across a row of mixed-length cards. */
.flow-listgrid__content {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-inline-size: 0;
}
/* Every card image is cropped to the author-chosen ratio (the SFC emits
   `--flow-list-image-aspect` from the `imageRatio` prop; `cover` crops without
   distortion) so a row of mixed-size source images stays uniform. The image
   fills its media frame, which the theme may round / clip. */
.flow-listgrid__image {
  display: block;
  inline-size: 100%;
  aspect-ratio: var(--flow-list-image-aspect, 3 / 2);
  object-fit: cover;
}

/* ── Stats widget — STRUCTURE only (stats-as-list-collection-widget plan) ──
   Theme-independent LAYOUT for the `liststats` render widget: the responsive
   column grid + per-card span — the SAME mechanism as `.flow-listgrid`, with
   `liststats`-namespaced custom properties. Card SKIN (border, glass, figure
   typography, icon size) is the theme's; only grid geometry lives here.

   The SFC emits inline `--liststats-cols-d/t/m` (clamped column counts) + a
   `--liststats-gap` token; the container queries that SELECT the active column
   count + per-card span live here (inline styles cannot hold container queries).
   Responsiveness uses CONTAINER queries so the grid reflows in the edit-in-place
   canvas device frames as well as on the front. The widget root is the query
   container.

   VARIANT SKIN HOOK: the SFC emits `flow-liststats--{variant}` (the resolved,
   post-fallback variant key) as a BEM modifier. The variant GEOMETRY arrives via
   the inline custom-props; the canonical skin is EMPTY here — every theme owns the
   `--{variant}` appearance (each theme's tokens.css targets these hooks). */
.flow-liststats-widget { container-type: inline-size; }

/* Gap scale → theme spacing tokens (structure maps the named steps; the
   `--space-*` values are the THEME's). */
.flow-liststats { --liststats-gap-none: 0; }
.flow-liststats {
  --liststats-gap-sm: var(--space-sm);
  --liststats-gap-md: var(--space-md);
  --liststats-gap-lg: var(--space-lg);
  --liststats-gap-xl: var(--space-xl);
}

.flow-liststats {
  display: grid;
  gap: var(--liststats-gap, var(--space-md));
  /* Mobile-first: the mobile column count is the base. */
  grid-template-columns: repeat(var(--liststats-cols-m, 1), minmax(0, 1fr));
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Per-card span — mobile-first base picks the mobile-clamped value. */
.flow-liststats__card { grid-column: span var(--card-span-m, 1); }

@container (min-width: 640px) {
  .flow-liststats {
    grid-template-columns: repeat(var(--liststats-cols-t, 2), minmax(0, 1fr));
  }
  .flow-liststats__card { grid-column: span var(--card-span-t, 1); }
}

@container (min-width: 1024px) {
  .flow-liststats {
    grid-template-columns: repeat(var(--liststats-cols-d, 4), minmax(0, 1fr));
  }
  .flow-liststats__card { grid-column: span var(--card-span-d, 1); }
}

/* Each card's inner wrapper (an <a> when the card links — so the whole card is
   one discernible-name click target — otherwise a <div>) fills the equal-height
   card (stretched by the grid). SKIN (the card's own border / padding / glass) is
   the theme's. */
.flow-liststats__card { display: flex; min-inline-size: 0; }
.flow-liststats__inner {
  display: flex;
  inline-size: 100%;
}
/* The figure is the stacked figure column (icon / eyebrow / value / caption). It
   fills the card so the theme can centre or distribute the figure. Margin reset
   because <figure> carries a default UA margin. */
.flow-liststats__figure {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-inline-size: 0;
  margin: 0;
}

/* ── List Timeline widget — STRUCTURE only (listtimeline-widget plan) ──────
   Layout for the `listtimeline` widget: an ordered list of entries, each a
   marker column (dot / number / thumbnail) + a content column (date/title/
   blurb). The marker TREATMENT (dot vs CSS `counter` number vs thumbnail), the
   vertical connecting LINE, the gutter width, and all colour are the THEME's
   (keyed on `.flow-listtimeline--{variant}`); structure provides only the row
   layout + entry rhythm. `position: relative` on the entry/marker lets a theme
   draw the connecting line as an absolutely-positioned pseudo-element.

   VARIANT SKIN HOOK: the SFC emits `flow-listtimeline--{variant}` (the resolved,
   post-fallback key). Geometry (`gap`) arrives via the inline custom prop; the
   canonical skin is EMPTY here. */
.flow-listtimeline-widget { container-type: inline-size; }

/* Gap scale → theme spacing tokens (structure maps the named steps; the
   `--space-*` values are the THEME's). */
.flow-listtimeline { --listtimeline-gap-none: 0; }
.flow-listtimeline {
  --listtimeline-gap-sm: var(--space-sm);
  --listtimeline-gap-md: var(--space-md);
  --listtimeline-gap-lg: var(--space-lg);
  --listtimeline-gap-xl: var(--space-xl);
}

.flow-listtimeline {
  display: flex;
  flex-direction: column;
  gap: var(--listtimeline-gap, var(--space-lg));
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Each entry: marker column beside the content column. `position: relative` so a
   theme can draw the connecting line; `min-inline-size: 0` lets the content wrap. */
.flow-listtimeline__entry {
  position: relative;
  display: flex;
  gap: var(--listtimeline-marker-gap, var(--space-md));
  min-inline-size: 0;
}

/* The marker holds the dot AND (optionally) the thumbnail; the variant CSS shows
   one. `flex: none` keeps the gutter fixed; `position: relative` anchors the line. */
.flow-listtimeline__marker {
  position: relative;
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* The content column (date / title / blurb). */
.flow-listtimeline__content { min-inline-size: 0; flex: 1 1 auto; }
.flow-listtimeline__date { margin: 0; }
.flow-listtimeline__title { margin: 0; }
.flow-listtimeline__blurb > :first-child { margin-block-start: 0; }
.flow-listtimeline__blurb > :last-child { margin-block-end: 0; }

/* A linked entry: the whole content block is one discernible-name target. */
.flow-listtimeline__link { color: inherit; text-decoration: none; display: block; }

/* ── List Accordion widget — STRUCTURE only (Lists module plan §7.4) ──────
   Progressive-enhancement layout for the scripted `listaccordion` widget.
   Pre-hydration (no `.is-enhanced`) every panel is open + present (the SSR /
   no-JS contract — nothing is collapsed by CSS the client cannot undo). Once
   the component hydrates it adds `.is-enhanced`, and the `[hidden]` panels
   collapse; the open panel animates. SKIN (header chevron, borders, panel
   padding, type) is the theme's. */
.flow-listaccordion { display: block; }
.flow-listaccordion__heading { margin: 0; }
.flow-listaccordion__header {
  display: flex;
  inline-size: 100%;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm, 0.5rem);
  text-align: start;
  cursor: pointer;
}
/* The title fills the row so the author's `contentAlign` (emitted as an inline
   text-align on this span) has space to act; the chevron stays pinned to the
   trailing edge as the expand affordance. `left` (default) reads as a left-hug
   title — identical to the prior space-between layout, so no visual regression. */
.flow-listaccordion__header-text {
  flex: 1 1 auto;
  min-inline-size: 0;
}
/* The browser honours `hidden` (collapsed = removed from layout + AT). The
   open panel animates its reveal once enhanced; pre-enhancement no transition
   runs (content is simply present). */
.flow-listaccordion.is-enhanced .flow-listaccordion__panel {
  overflow: hidden;
}
/* Panel body: a row so an image renders as a small thumbnail BESIDE the answer
   text (never full-width). Image-less panels are just the text column. The
   thumbnail is cropped to the author-chosen ratio (`--flow-list-image-aspect`,
   default square) and sized by `clamp` so it stays a thumbnail at any width.
   SKIN (thumbnail radius, gaps, type) is the theme's. */
.flow-listaccordion__panel-inner {
  display: flex;
  gap: var(--space-md, 1rem);
  align-items: flex-start;
  min-inline-size: 0;
}
.flow-listaccordion__image {
  flex: 0 0 auto;
  inline-size: clamp(88px, 28%, 132px);
  aspect-ratio: var(--flow-list-image-aspect, 1 / 1);
  object-fit: cover;
  display: block;
}
/* The text column (body + cta) beside the thumbnail; `min-inline-size:0` lets
   long words wrap instead of pushing the thumbnail. */
.flow-listaccordion__content {
  flex: 1 1 auto;
  min-inline-size: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-sm, 0.5rem);
}

/* ── Article List widget — STRUCTURE only (article-list-render-layer plan) ──
   Theme-independent LAYOUT for the `articlelist` render widget: a fixed
   responsive card grid (3 / 2 / 1 via container queries — no authorable
   column count in v1) + the card's inner flex anatomy, mirroring
   `.flow-listgrid` so themes skin both from the same patterns. Card SKIN
   (border, padding, shadow, typography, hover) is the theme's. The pager's
   controls are canonical `flow-button` anchors — the theme's tone-adaptive
   button skin applies with no pager-specific colour rules needed here. */
.flow-articlelist { container-type: inline-size; }

.flow-articlelist__grid {
  display: grid;
  gap: var(--flow-articlelist-gap, var(--space-md, 1rem));
  grid-template-columns: repeat(1, minmax(0, 1fr));
  margin: 0;
  padding: 0;
  list-style: none;
}

@container (min-width: 640px) {
  .flow-articlelist__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@container (min-width: 1024px) {
  .flow-articlelist__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* Card anatomy mirrors `.flow-listgrid`: the inner wrapper (an <a> when the
   article resolves a URL — the whole card is one discernible-name click
   target — otherwise a <div>) is the flex column stacking media over a
   growing content column, so bottom edges line up across a row. */
.flow-articlelist__card { display: flex; min-inline-size: 0; }
.flow-articlelist__inner {
  display: flex;
  flex-direction: column;
  inline-size: 100%;
}
.flow-articlelist__content {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-inline-size: 0;
}
.flow-articlelist__image {
  display: block;
  inline-size: 100%;
  aspect-ratio: var(--flow-list-image-aspect, 3 / 2);
  object-fit: cover;
}

/* Pager row: centred controls with the page status between them. The
   disabled boundary control is a same-classed <span> (aria-disabled) so the
   pager keeps its shape on the first / last page. */
.flow-articlelist__pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-md, 1rem);
  margin-block-start: var(--space-lg, 1.5rem);
}
.flow-articlelist__pager [aria-disabled='true'] {
  opacity: 0.5;
  pointer-events: none;
}

/* ── Form widget (forms-theme-styling plan) ────────────────────────────────
   The shared FormRenderer / FormFieldRenderer emit ONLY these canonical
   `flow-form*` / `flow-form-field*` hooks — all bespoke skin was removed from the
   components, so this floor is the single source of form appearance. The values
   are STANDARD DEFAULTS: neutral, accessible fallbacks behind `--flow-field-*` /
   `--flow-form-*` custom properties so a form reads cleanly on a theme that
   declares nothing. A theme RE-SKINS either cheaply (set the variables in its
   tokens.css) or deeply (write full rules against these same hooks); authored
   tokens.css follows this contract in source order, so a theme wins at equal
   specificity.

   The submit button is a canonical `.flow-button` skinned by the theme's own
   button rules (forms-theme-styling P1) — so NO button skin lives here, only the
   actions-row layout. */
.flow-form {
  display: flex;
  flex-direction: column;
  gap: var(--flow-form-gap, 1.25rem);
}
.flow-form__page {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--flow-form-field-gap, 1rem);
}
.flow-form__field { min-inline-size: 0; }
.flow-form__actions { display: flex; }

/* A missing / unpublished / withdrawn form (null payload) — a discreet note. */
.flow-form--unavailable {
  padding: 1rem 1.25rem;
  border: 1px dashed var(--flow-field-border, #94a3b8);
  border-radius: var(--flow-field-group-radius, 8px);
  color: var(--flow-field-help-color, #475569);
  font-size: 0.95rem;
}

/* Field wrapper + label / help / required marker. */
.flow-form-field {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  margin: 0;
  min-inline-size: 0;
  border: 0;
  padding: 0;
}
.flow-form-field--group {
  border: 1px solid var(--flow-field-group-border, #cbd5e1);
  border-radius: var(--flow-field-group-radius, 8px);
  padding: 0.75rem 1rem;
}
.flow-form-field__label,
.flow-form-field__legend {
  font-weight: var(--flow-field-label-weight, 600);
  font-size: 0.9rem;
  color: var(--flow-field-label-color, inherit);
}
.flow-form-field__required { color: var(--flow-field-required-color, #dc2626); }
.flow-form-field__help,
.flow-form-field__hint {
  margin: 0;
  font-size: 0.8rem;
  color: var(--flow-field-help-color, #64748b);
}

/* The text-entry controls (input / select / textarea / file upload). */
.flow-form-field__control {
  inline-size: 100%;
  padding: var(--flow-field-padding, 0.5rem 0.6rem);
  border: 1px solid var(--flow-field-border, #cbd5e1);
  border-radius: var(--flow-field-radius, 6px);
  background: var(--flow-field-bg, #ffffff);
  color: var(--flow-field-text, var(--flow-field-fg, inherit));
  font: inherit;
}
/* Native date/time inputs have no ::placeholder — the `dd/mm/yyyy` hint renders
   via the WebKit/Blink edit pseudo. It serves BOTH the empty hint AND the entered
   value with no reliable CSS state selector, so emptiness is signalled by the
   `data-filled` attribute the form renderer toggles from the input's value:
   default (empty) = PLACEHOLDER colour; `[data-filled]` = input TEXT colour. So
   it behaves like a normal input. (Firefox ignores this pseudo and uses the
   control colour — acceptable.) */
.flow-form-field__control::-webkit-datetime-edit {
  color: var(--flow-field-placeholder-color, #94a3b8);
}
.flow-form-field__control[data-filled]::-webkit-datetime-edit {
  color: var(--flow-field-text, var(--flow-field-fg, inherit));
}
.flow-form-field__control:focus-visible {
  outline: var(--flow-field-focus-width, 2px) solid var(--flow-field-focus-color, #2563eb);
  outline-offset: var(--flow-field-focus-offset, 1px);
}
/* Placeholder text — brandable per tone (theme-brandability-semantic-vocabulary).
   Defaults to a muted grey; on a dark band it flips to the on-dark value. */
.flow-form-field__control::placeholder {
  color: var(--flow-field-placeholder-color, #94a3b8);
  opacity: 1; /* Firefox lowers placeholder opacity by default — pin it. */
}
[data-surface-tone="dark"] .flow-form-field__control::placeholder,
.flow-section--tone-light .flow-form-field__control::placeholder {
  color: var(--flow-field-placeholder-color-on-dark, var(--flow-field-placeholder-color, rgba(255, 255, 255, 0.6)));
}

/* Native <select> — the OS dropdown arrow's position is inconsistent and often
   sits flush/too far against the right edge. Replace it with a chevron pinned a
   controlled inset from the inline-end, and reserve inline-end padding so a long
   value never runs under it.

   The chevron is DRAWN, not an image: two diagonal stripes (the arms) and three
   round dots (both ends and the point, for round caps), every layer in
   `currentColor`. So it is always the select's own text colour — the floor's
   `--flow-field-text` / `-on-dark`, a theme rule that pins the field colour, a
   focus state, or a tenant's `field-text` branding — with nothing per theme or
   per surface. An image could not read any of those.

   Geometry: each layer sits in its own square tile of the arm size. Keep the arm
   size an EVEN pixel count — tiles of different parity snap half a pixel apart
   and the caps drift off the arms. `--flow-field-chevron-inset` places the 1em
   box the arrow used to occupy; the arrow's right end sits a quarter of it in.

   Every rule that colours the control (incl. on a dark surface) must set
   `background-color`, never the `background` shorthand or a `background-image` —
   either outranks this rule there and replaces the chevron. */
select.flow-form-field__control {
  --_chevron-arm: var(--flow-field-chevron-arm, 4px);
  --_chevron-stroke: var(--flow-field-chevron-stroke, 1.4px);
  --_chevron-end: calc(var(--flow-field-chevron-inset, 0.75rem) + 0.25em);
  --_chevron-arm-stops:
    transparent calc(50% - var(--_chevron-stroke) / 2 - 0.35px),
    currentColor calc(50% - var(--_chevron-stroke) / 2 + 0.35px),
    currentColor calc(50% + var(--_chevron-stroke) / 2 - 0.35px),
    transparent calc(50% + var(--_chevron-stroke) / 2 + 0.35px);
  --_chevron-cap: radial-gradient(
    circle,
    currentColor calc(var(--_chevron-stroke) / 2 - 0.35px),
    transparent calc(var(--_chevron-stroke) / 2 + 0.35px)
  );
  appearance: none;
  -webkit-appearance: none;
  background-image:
    linear-gradient(45deg, var(--_chevron-arm-stops)),
    linear-gradient(-45deg, var(--_chevron-arm-stops)),
    var(--_chevron-cap),
    var(--_chevron-cap),
    var(--_chevron-cap);
  background-repeat: no-repeat;
  background-size: var(--_chevron-arm) var(--_chevron-arm);
  background-position:
    right calc(var(--_chevron-end) + var(--_chevron-arm)) center,
    right var(--_chevron-end) center,
    right calc(var(--_chevron-end) + 1.5 * var(--_chevron-arm)) top calc(50% - var(--_chevron-arm) / 2),
    right calc(var(--_chevron-end) + 0.5 * var(--_chevron-arm)) top calc(50% + var(--_chevron-arm) / 2),
    right calc(var(--_chevron-end) - 0.5 * var(--_chevron-arm)) top calc(50% - var(--_chevron-arm) / 2);
  padding-inline-end: var(--flow-field-chevron-gap, 2rem);
}
/* Forced colours (Windows High Contrast) drop gradient backgrounds, so the drawn
   chevron would vanish; hand the arrow back to the browser, which paints it in
   the system colours. (The fixed-colour SVG it replaced stayed, near-invisible.) */
@media (forced-colors: active) {
  select.flow-form-field__control {
    appearance: auto;
    -webkit-appearance: auto;
    background-image: none;
  }
}

.flow-form-field__option {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.9rem;
}
.flow-form-field__children {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
.flow-form-field__repeat {
  align-self: flex-start;
  margin-top: 0.5rem;
  padding: 0.35rem 0.75rem;
  border: 1px dashed var(--flow-field-border, #94a3b8);
  border-radius: var(--flow-field-radius, 6px);
  background: transparent;
  color: var(--flow-field-help-color, #475569);
  font-size: 0.85rem;
}
.flow-form-field__signature {
  display: flex;
  align-items: center;
  justify-content: center;
  block-size: 90px;
  border: 1px dashed var(--flow-field-border, #94a3b8);
  border-radius: var(--flow-field-radius, 6px);
  color: var(--flow-field-help-color, #94a3b8);
  font-size: 0.85rem;
}
.flow-form-field__value { color: var(--flow-field-help-color, #475569); }

/* On-dark — mirror the ink-role dual signal (Lesson 116): the AUTO dark marker
   `[data-surface-tone="dark"]` AND the author's EXPLICIT "Light text" tone
   `.flow-section--tone-light` (which never emits the auto marker). Only the text
   sitting DIRECTLY on the dark band lifts to light + the group outline; the
   white control keeps its dark text and stays readable as-is (a theme may
   override the control on dark via the `-on-dark` variables). */
[data-surface-tone="dark"] .flow-form-field__label,
[data-surface-tone="dark"] .flow-form-field__legend,
[data-surface-tone="dark"] .flow-form-field__option,
.flow-section--tone-light .flow-form-field__label,
.flow-section--tone-light .flow-form-field__legend,
.flow-section--tone-light .flow-form-field__option {
  color: var(--flow-field-label-color-on-dark, var(--flow-fg-on-dark, #ffffff));
}
[data-surface-tone="dark"] .flow-form-field__help,
[data-surface-tone="dark"] .flow-form-field__hint,
[data-surface-tone="dark"] .flow-form-field__value,
[data-surface-tone="dark"] .flow-form-field__repeat,
[data-surface-tone="dark"] .flow-form-field__signature,
.flow-section--tone-light .flow-form-field__help,
.flow-section--tone-light .flow-form-field__hint,
.flow-section--tone-light .flow-form-field__value,
.flow-section--tone-light .flow-form-field__repeat,
.flow-section--tone-light .flow-form-field__signature {
  color: var(--flow-field-help-color-on-dark, rgba(255, 255, 255, 0.75));
}
/* The dashed repeat/signature affordance borders flip with the input border
   (same opt-in-with-light-fallback shape as the control border rule below). */
[data-surface-tone="dark"] .flow-form-field__repeat,
[data-surface-tone="dark"] .flow-form-field__signature,
.flow-section--tone-light .flow-form-field__repeat,
.flow-section--tone-light .flow-form-field__signature {
  border-color: var(--flow-field-border-on-dark, var(--flow-field-border, #94a3b8));
}
/* The required `*` marker — consumes the (previously dormant) on-dark role. */
[data-surface-tone="dark"] .flow-form-field__required,
.flow-section--tone-light .flow-form-field__required {
  color: var(--flow-field-required-color-on-dark, #fca5a5);
}
/* Authored html_body content is body text sitting directly on the band. */
[data-surface-tone="dark"] .flow-form-field__html,
.flow-section--tone-light .flow-form-field__html {
  color: var(--flow-fg-on-dark, #ffffff);
}
[data-surface-tone="dark"] .flow-form-field--group,
.flow-section--tone-light .flow-form-field--group {
  border-color: var(--flow-field-group-border-on-dark, rgba(255, 255, 255, 0.4));
}
/* Control border on dark — the white input stays readable on a dark band, but a
   theme/tenant may want a distinct input border there (branding-component-colours
   -per-scheme). Defaults to the light `--flow-field-border` so nothing changes
   unless `--flow-field-border-on-dark` is set. */
[data-surface-tone="dark"] .flow-form-field__control,
.flow-section--tone-light .flow-form-field__control {
  border-color: var(--flow-field-border-on-dark, var(--flow-field-border, #cbd5e1));
}
/* Control BACKGROUND on dark — a solid light input reads poorly on a dark band,
   so a theme/tenant may set a translucent `--flow-field-bg-on-dark` (the
   `color-alpha` brandable role). Defaults to the light `--flow-field-bg` so
   nothing changes unless the on-dark value is set
   (theme-brandability-semantic-vocabulary plan). */
[data-surface-tone="dark"] .flow-form-field__control,
.flow-section--tone-light .flow-form-field__control {
  background-color: var(--flow-field-bg-on-dark, var(--flow-field-bg, #ffffff));
}
/* Control TEXT on dark — the typed value AND native date/time format text
   (which inherits the control colour) must flip legible on a dark band. Defaults
   to the light field text so nothing changes unless the on-dark value is set. */
[data-surface-tone="dark"] .flow-form-field__control,
.flow-section--tone-light .flow-form-field__control {
  color: var(--flow-field-text-on-dark, var(--flow-field-text, var(--flow-field-fg, inherit)));
}
/* Native date/time edit on dark — empty hint = placeholder-on-dark, filled
   (`data-filled`) = input text-on-dark (mirrors the base rules above per tone). */
[data-surface-tone="dark"] .flow-form-field__control::-webkit-datetime-edit,
.flow-section--tone-light .flow-form-field__control::-webkit-datetime-edit {
  color: var(--flow-field-placeholder-color-on-dark, var(--flow-field-placeholder-color, rgba(255, 255, 255, 0.6)));
}
[data-surface-tone="dark"] .flow-form-field__control[data-filled]::-webkit-datetime-edit,
.flow-section--tone-light .flow-form-field__control[data-filled]::-webkit-datetime-edit {
  color: var(--flow-field-text-on-dark, var(--flow-field-text, var(--flow-field-fg, inherit)));
}

/* ── Scroll-reveal (lumen-theme-conversion plan §3.3b) ──────────────────────
   Opt-in via the `data-reveal` attribute, set ONLY by the shared `v-reveal`
   directive when a live IntersectionObserver will flip it. The DEFAULT (no
   attribute) is fully visible + no animation, so SSR, the editor canvas, and
   reduced-motion all render settled content — the directive simply never adds
   the attribute there. Animation values read from `--flow-reveal-*` custom
   properties a theme may tune. */
[data-reveal] {
  transition:
    opacity var(--flow-reveal-duration, 1s) var(--flow-reveal-ease, cubic-bezier(0.2, 0.7, 0.2, 1)),
    transform var(--flow-reveal-duration, 1s) var(--flow-reveal-ease, cubic-bezier(0.2, 0.7, 0.2, 1));
  transition-delay: var(--flow-reveal-delay, 0ms);
  will-change: opacity, transform;
}
[data-reveal="hidden"] {
  opacity: 0;
  transform: translateY(var(--flow-reveal-distance, 28px));
}
[data-reveal="visible"] {
  opacity: 1;
  transform: none;
}
@media (prefers-reduced-motion: reduce) {
  [data-reveal] {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}

/* ── "On this page" section index — MECHANISM (section-anchors plan) ─────────
   Two things every conforming theme gets free, and one variable that governs
   both. `--flow-anchor-offset` is how far below the viewport top an anchored
   section should come to rest — set it once for a taller sticky header and the
   native `#hash` landing, the sticky index and the JS-driven jump all follow,
   because `SectionNav` MEASURES `scroll-margin-top` back off the target rather
   than keeping its own copy of the number.

   Everything here is wrapped in `:where()` for zero specificity: these are
   defaults a theme overrides with a single plain class selector, never a wall
   the theme has to fight. SKIN (colour, the active marker, type, spacing)
   belongs entirely to the theme, exactly as it does for `flow-nav*`. */

/* A section the index can link to must not land under fixed chrome — this is
   also what the browser uses for a `#hash` arriving on first load. */
:where(.flow-section[id]) {
  scroll-margin-top: var(--flow-anchor-offset, 6rem);
}

:where(.flow-section-nav__list) {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* The variants name a LAYOUT AXIS, so honouring the axis is mechanism: the
   stacked forms (`sidebar`, `left`, `right`) stack — the list default — and the
   top strip lays out inline and wraps rather than overflowing. */
:where(.flow-section-nav--top .flow-section-nav__list) {
  display: flex;
  flex-wrap: wrap;
}

/* `left` / `right` additionally ask to sit BESIDE the content. Reserving that
   room is the host's or theme's job, not this file's — only they know the
   content column's width, and a theme with no room to give is entitled to
   render them exactly like `sidebar`. What is mechanism is the ORDER: a
   right-hand index must come after the content for a reader moving through the
   page in sequence, so it is placed with `order` rather than moved in the DOM.
   Keeping the markup order fixed means the tab order and the screen-reader
   order stay the reading order whichever side is chosen. */
:where(.flow-section-nav--right) {
  order: 1;
}

/* PLACEMENT — including whether the index follows the reader — belongs to
   whoever places it, not to this file. A `position: sticky` on the nav itself
   would be inert anyway: sticky travels within its CONTAINING BLOCK, and the
   nav's parent is only ever as tall as the nav. The element that can usefully
   stick is the host's slot, whose parent spans the page — so the host or the
   theme sets it, using the same `--flow-anchor-offset` this file uses for
   `scroll-margin-top` so the resting line stays a single number. */

/* Optional, schema-authored image geometry. No marker means the old theme
   appearance. The backing stays INSIDE the image's layout box: no overflow. */
.flow-image[data-image-frame] { display: block; box-sizing: border-box; }
.flow-image[data-image-frame="plain"] img { border-radius: 0; }
.flow-image[data-image-frame="rounded"] img { border-radius: var(--flow-image-radius, 1.5rem); }
.flow-image[data-image-frame="offset"] {
  padding: 0 1rem 1rem 0;
  border-radius: var(--flow-image-radius, 1.5rem);
  background: linear-gradient(135deg, transparent 25%, var(--flow-image-backing, color-mix(in srgb, currentColor 12%, transparent)) 25%);
}
.flow-image[data-image-frame="offset"] img { border-radius: var(--flow-image-radius, 1.5rem); }
.flow-image[data-image-crop] img { width: 100%; height: auto; object-fit: cover; }
.flow-image[data-image-crop="landscape"] img { aspect-ratio: 3 / 2; }
.flow-image[data-image-crop="square"] img { aspect-ratio: 1; }
.flow-image[data-image-crop="portrait"] img { aspect-ratio: 2 / 3; }
[data-reveal-effect="fade"][data-reveal="hidden"] { transform: none; }
[data-reveal-effect="rise"][data-reveal="hidden"] { transform: translateY(16px); }
@media (prefers-reduced-motion: reduce) {
  [data-reveal-effect][data-reveal] { opacity: 1; transform: none; transition: none; }
}

/* Practice details: shared geometry, theme-owned colour and type. */

.flow-practiceinfo { font-family:var(--flow-font-body,inherit); font-size:1rem; line-height:1.6; }
.flow-practiceinfo p { margin:0 0 .75rem; }
.flow-practiceinfo a { color:inherit; text-decoration:underline; text-underline-offset:.2em; display:inline-block; padding-block:.4rem; }
.flow-practiceinfo__nhs { display:block; width:288px; max-width:none; height:auto; background:#fff; margin-inline:max(calc((100% - 288px)/2), -8px); }

.flow-navigationmenu-widget[data-presentation="columns"] > .flow-nav { width:100%; max-width:none; display:grid; grid-template-columns:repeat(auto-fit,minmax(min(100%,11rem),1fr)); gap:1.5rem 2rem; }
.flow-navigationmenu-widget[data-presentation="columns"] > .flow-nav > .flow-nav__item { border:0; min-width:0; }
.flow-navigationmenu-widget[data-presentation="columns"] .flow-nav__nested { border:0; padding-left:0; }

/* Contact panel owns its white ground and dark ink; the official black NHS
   descriptor stays intact. Other practice blocks inherit their section. */
.flow-navigationmenu-widget[data-density="compact"] > .flow-nav { border:0; }
.flow-navigationmenu-widget[data-density="compact"] .flow-nav .flow-nav__item { border:0; }
.flow-navigationmenu-widget[data-density="compact"] .flow-nav .flow-nav__link { min-height:44px; padding:.5rem 0; line-height:1.5; }
.flow-navigationmenu-widget[data-density="compact"] .flow-nav .flow-nav__label { padding:0 0 .65rem; font-size:.8rem; line-height:1.5; letter-spacing:.075em; text-transform:uppercase; }
.flow-navigationmenu-widget[data-density="compact"] .flow-nav__nested { padding:0; border:0; }

/* Navigation presentation belongs to the bound block, including in the editor. */
.flow-navigationmenu-widget[data-density="dense"] > .flow-nav,
.flow-navigationmenu-widget[data-density="dense"] .flow-nav__nested,
.flow-navigationmenu-widget[data-density="dense"] .flow-nav .flow-nav__item { border: 0; }
.flow-navigationmenu-widget[data-density="dense"] .flow-nav__nested { padding: 0; }
.flow-navigationmenu-widget[data-density="dense"] .flow-nav .flow-nav__link {
  min-height: 32px; padding: 3px 0; line-height: 1.5;
}
.flow-navigationmenu-widget[data-density="dense"] .flow-nav .flow-nav__label {
  padding: 0 0 .65rem; font-size: .8rem; line-height: 1.5; letter-spacing: .075em; text-transform: uppercase;
}
@container theme-canvas (max-width: 639.98px) {
  .flow-navigationmenu-widget[data-density="dense"] .flow-nav .flow-nav__link { min-height: 44px; padding-block: .5rem; }
}
@media (any-pointer: coarse) {
  .flow-navigationmenu-widget[data-density="dense"] .flow-nav .flow-nav__link { min-height: 44px; padding-block: .5rem; }
}
.flow-navigationmenu-widget {
  --flow-menu-emphasis: var(--flow-ink-emphasis, currentColor);
  --flow-menu-subtle: var(--flow-ink-subtle, currentColor);
  --flow-menu-accent: var(--flow-ink-accent, currentColor);
}
[data-surface-tone="dark"] .flow-navigationmenu-widget,
.flow-section--tone-light .flow-navigationmenu-widget {
  --flow-menu-emphasis: var(--flow-ink-emphasis-on-dark, currentColor);
  --flow-menu-subtle: var(--flow-ink-subtle-on-dark, currentColor);
  --flow-menu-accent: var(--flow-ink-accent-on-dark, currentColor);
}
.flow-navigationmenu-widget[data-heading-tone="emphasis"] .flow-nav .flow-nav__label { color: var(--flow-menu-emphasis); }
.flow-navigationmenu-widget[data-heading-tone="subtle"] .flow-nav .flow-nav__label { color: var(--flow-menu-subtle); }
.flow-navigationmenu-widget[data-heading-tone="accent"] .flow-nav .flow-nav__label { color: var(--flow-menu-accent); }
.flow-navigationmenu-widget[data-link-tone="emphasis"] .flow-nav .flow-nav__link:not(:focus) { color: var(--flow-menu-emphasis); }
.flow-navigationmenu-widget[data-link-tone="subtle"] .flow-nav .flow-nav__link:not(:focus) { color: var(--flow-menu-subtle); }
.flow-navigationmenu-widget[data-link-tone="accent"] .flow-nav .flow-nav__link:not(:focus) { color: var(--flow-menu-accent); }
.flow-navigationmenu-widget[data-link-tone]:not([data-link-tone="theme"]) .flow-nav .flow-nav__link:hover:not(:focus) {
  background: transparent; color: var(--flow-menu-emphasis); text-decoration: underline; text-underline-offset: .25em;
}

/* Token-bound links: the token remains the only source of their destination.
   Palettes have separate light/dark ink; filled buttons own both ground and ink. */
.flow-token-block {
  --flow-token-link-ink: var(--flow-fg, #172432);
  --flow-token-link-blue: #0759ad;
  --flow-token-link-violet: #6d28d9;
  --flow-token-link-green: #146b45;
  --flow-token-link-solid-text: #ffffff;
}
[data-surface-tone="dark"] .flow-token-block,
.flow-section--tone-light .flow-token-block {
  --flow-token-link-ink: var(--flow-fg-on-dark, #ffffff);
  --flow-token-link-blue: #86c5ff;
  --flow-token-link-violet: #c4b5fd;
  --flow-token-link-green: #88d9b0;
  --flow-token-link-solid-text: #0b1320;
}
.flow-token-block .flow-token-link.flow-token-link[data-link-colour="blue"] { --flow-token-link-ink: var(--flow-token-link-blue); }
.flow-token-block .flow-token-link.flow-token-link[data-link-colour="violet"] { --flow-token-link-ink: var(--flow-token-link-violet); }
.flow-token-block .flow-token-link.flow-token-link[data-link-colour="green"] { --flow-token-link-ink: var(--flow-token-link-green); }
.flow-token-block .flow-token-link.flow-token-link[data-link-appearance] {
  display: inline-flex; align-items: center; justify-content: center; gap: .65rem; max-width: 100%;
  color: var(--flow-token-link-ink); vertical-align: middle; overflow-wrap: anywhere;
}
.flow-token-block .flow-token-link.flow-token-link svg { flex: 0 0 20px; }
.flow-token-block .flow-token-link.flow-token-link[data-link-appearance]:not([data-link-appearance="text"]) {
  box-sizing: border-box; min-height: 44px; min-width: 44px; padding: .65rem 1.1rem;
  border: 1px solid color-mix(in srgb, var(--flow-token-link-ink) 65%, transparent);
  border-radius: 999px; line-height: 1.5; font-weight: 600; text-decoration: none;
}
.flow-token-block .flow-token-link.flow-token-link[data-link-appearance="outline"] { background: transparent; }
.flow-token-block .flow-token-link.flow-token-link[data-link-appearance="soft"] { background: color-mix(in srgb, var(--flow-token-link-ink) 9%, transparent); }
.flow-token-block .flow-token-link.flow-token-link[data-link-appearance="solid"] { background: var(--flow-token-link-ink); color: var(--flow-token-link-solid-text); }
.flow-token-block .flow-token-link.flow-token-link[data-link-shape="rounded"] { border-radius: .75rem; }
.flow-token-block .flow-token-link.flow-token-link[data-icon-only] { width: 48px; height: 48px; min-height: 48px; padding: 0; flex-shrink: 0; }
.flow-token-block .flow-token-link.flow-token-link[data-link-appearance]:not([data-link-appearance="text"]):hover:not(:focus) {
  border-color: var(--flow-token-link-ink); box-shadow: 0 4px 14px color-mix(in srgb, var(--flow-token-link-ink) 12%, transparent);
}
.flow-token-block .flow-token-link.flow-token-link[data-link-appearance]:focus-visible {
  color: #172432 !important; background: #ffeb3b !important;
  outline: 3px solid #ffeb3b; outline-offset: 3px; box-shadow: 0 0 0 6px #172432;
}
@media (prefers-reduced-motion: no-preference) {
  .flow-token-block .flow-token-link.flow-token-link[data-link-appearance]:not([data-link-appearance="text"]) { transition: transform 160ms ease, box-shadow 160ms ease; }
  .flow-token-block .flow-token-link.flow-token-link[data-link-appearance]:not([data-link-appearance="text"]):hover:not(:focus) { transform: translateY(-2px); }
}

/* Saturated brand fills need paler coloured ink than near-black sections. */
.flow-section--bg-brand[data-surface-tone="dark"] .flow-token-block,
.flow-section--bg-accent[data-surface-tone="dark"] .flow-token-block {
  --flow-token-link-blue: #e5f2ff;
  --flow-token-link-violet: #f1ebff;
  --flow-token-link-green: #e1faed;
}

/* Visitor control remains legible independently of the selected photograph. */
.flow-surface-motion-toggle {
  position: absolute; inset-inline-end: 1rem; bottom: 1rem; z-index: 20;
  display: inline-flex; align-items: center; gap: .5rem; min-height: 44px;
  padding: .5rem .875rem; border: 1px solid #aab2be; border-radius: 999px;
  background: #101827; color: #fff; font: 600 .8125rem/1.2 system-ui, sans-serif;
  cursor: pointer;
}
.flow-surface-motion-toggle:hover { background: #253449; }
.flow-surface-motion-toggle:focus-visible { outline: 3px solid #ffeb3b; outline-offset: 3px; }
.flow-hero[data-surface-paused="true"] * { animation-play-state: paused; }
/* Custom shading replaces, rather than stacks with, theme gradients. */
.flow-hero[data-shading="custom"]::before,
.flow-hero[data-shading="custom"]::after { content: none; }
.flow-hero[data-shading="custom"] .flow-hero__overlay { z-index: 1; }
.flow-hero[data-shading="custom"] .flow-hero__headline,
.flow-hero[data-shading="custom"] .flow-hero__eyebrow,
.flow-hero[data-shading="custom"] .flow-hero__subhead,
.flow-hero[data-shading="custom"] .flow-hero__actions { position: relative; z-index: 2; }

@media (max-width: 700px) {
  .flow-hero:has(.flow-surface-motion-toggle) { padding-bottom: 3rem; }
}

/* Animated hero: shared, theme-portable scene composition. */

.flow-animatedhero { --scene-ground: var(--flow-editorial-ground, #080f1c); --scene-ink: #f8fafc; --scene-accent: var(--flow-editorial-accent, #a5c8ff); position: relative; isolation: isolate; overflow: clip; background: var(--scene-ground); color: var(--scene-ink); min-height: 44rem; display: grid; align-items: center; }
.flow-animatedhero[data-height="compact"] { min-height: 34rem; }
.flow-animatedhero[data-height="immersive"] { min-height: min(58rem, 95svh); }
.flow-animatedhero__background { position: absolute; inset: -70px -3%; z-index: -3; }
.flow-animatedhero__background picture, .flow-animatedhero__background img { display: block; width: 100%; height: 100%; object-fit: cover; }
.flow-animatedhero__shade { opacity: var(--scene-shading, 1); position: absolute; inset: 0; z-index: -2; background: linear-gradient(90deg, color-mix(in srgb, var(--scene-ground) 94%, transparent), color-mix(in srgb, var(--scene-ground) 65%, transparent) 40%, color-mix(in srgb, var(--scene-ground) 10%, transparent)); }
.flow-animatedhero__layer { position: absolute; inset: -100px -4%; z-index: -1; display: flex; align-items: end; justify-content: end; pointer-events: none; }
.flow-animatedhero__layer picture { display: block; width: 90%; height: 100%; }
.flow-animatedhero__layer img { display: block; width: 100%; height: 100%; object-fit: contain; object-position: bottom right; }
.flow-animatedhero__layer[data-position="left"] { justify-content: start; }
.flow-animatedhero__layer[data-position="left"] img { object-position: bottom left; }
.flow-animatedhero__layer[data-position="centre"] { justify-content: center; }
.flow-animatedhero__layer[data-position="centre"] img { object-position: bottom center; }
.flow-animatedhero__layer[data-size="medium"] picture { width: 65%; }
.flow-animatedhero__layer[data-size="small"] picture { width: 40%; }
.flow-animatedhero__content { width: min(100% - 3rem, var(--flow-content-max-width, 72rem)); margin-inline: auto; padding-block: clamp(4rem, 8vw, 7rem); z-index: 1; }
.flow-animatedhero .flow-hero.flow-hero--transparent { min-height: 0; padding: 0; margin: 0; max-width: 43rem; background: none; color: var(--scene-ink); border: 0; box-shadow: none; display: block; }
.flow-animatedhero .flow-hero::before, .flow-animatedhero .flow-hero::after { display: none; }
.flow-animatedhero .flow-hero__headline { font-size: clamp(2.75rem, 5vw, 5rem); line-height: 1.04; letter-spacing: -.04em; max-width: 100%; margin: 0; color: inherit; }
.flow-animatedhero .flow-hero__eyebrow { margin: 0 0 1.5rem; color: var(--scene-accent); }
.flow-animatedhero .flow-hero__headline-accent { color: var(--scene-accent); }
.flow-animatedhero .flow-hero__subhead { font-size: 1.125rem; line-height: 1.7; max-width: 32rem; margin: 1.75rem 0 0; color: color-mix(in srgb, var(--scene-ink) 85%, var(--scene-ground)); }
.flow-animatedhero .flow-hero__actions { margin: 2rem 0 0; }
.flow-animatedhero .flow-hero__cta.flow-button { color: var(--scene-ink); border-color: color-mix(in srgb, var(--scene-ink) 45%, transparent); background: var(--scene-ground); }
.flow-animatedhero .flow-hero__cta.flow-button:hover { background: color-mix(in srgb, var(--scene-accent) 18%, var(--scene-ground)); }
.flow-animatedhero .flow-hero__cta.flow-button--primary { background: var(--scene-ink); color: var(--scene-ground); border-color: var(--scene-ink); }
.flow-animatedhero .flow-hero__cta.flow-button--primary:hover { background: color-mix(in srgb, var(--scene-ink) 90%, var(--scene-ground)); }
.flow-animatedhero .flow-hero__cta.flow-button--tertiary { background: transparent; border-color: transparent; text-decoration: underline; text-underline-offset: .2em; }
.flow-animatedhero .flow-hero__cta.flow-button:focus-visible { background: #ffeb3b; color: #212b32; outline: 3px solid #ffeb3b; outline-offset: 3px; box-shadow: 0 0 0 6px #212b32; }
.flow-animatedhero__edge { opacity: var(--scene-shading, 1); position: absolute; bottom: 0; left: 0; right: 0; height: 8rem; background: linear-gradient(transparent, var(--scene-ground)); pointer-events: none; }
.flow-animatedhero[data-composition="centre"] .flow-hero { margin-inline: auto; text-align: center; }
.flow-animatedhero[data-composition="centre"] .flow-hero__subhead { margin-inline: auto; }
.flow-animatedhero[data-composition="centre"] .flow-hero__actions { justify-content: center; }
.flow-animatedhero[data-composition="centre"] .flow-animatedhero__shade { background: color-mix(in srgb, var(--scene-ground) 78%, transparent); }
@media (max-width: 767px) {
  .flow-animatedhero, .flow-animatedhero[data-height] { min-height: 0; }
  .flow-animatedhero__content { width: calc(100% - 2rem); padding-block: 4.5rem 5rem; }
  .flow-animatedhero__shade { background: color-mix(in srgb, var(--scene-ground) 85%, transparent); }
  .flow-animatedhero__layer:not([data-mobile]) { display: none; }
  .flow-animatedhero .flow-hero__headline { font-size: clamp(2.4rem, 9vw, 3.5rem); }
  .flow-animatedhero__background, .flow-animatedhero__layer { transform: none !important; }
}
@media (prefers-reduced-motion: reduce) { .flow-animatedhero__background, .flow-animatedhero__layer { transform: none !important; } }
/* Match the editor's device preview to the same small-screen composition. */
@container theme-canvas (max-width: 767px) {
  .flow-animatedhero, .flow-animatedhero[data-height] { min-height: 0; }
  .flow-animatedhero__content { width: calc(100% - 2rem); padding-block: 4.5rem 5rem; }
  .flow-animatedhero__shade { background: color-mix(in srgb, var(--scene-ground) 85%, transparent); }
  .flow-animatedhero__layer:not([data-mobile]) { display: none; }
  .flow-animatedhero .flow-hero__headline { font-size: clamp(2.4rem, 9cqi, 3.5rem); }
  .flow-animatedhero__background, .flow-animatedhero__layer { transform: none !important; }
}
[data-editor-mode] .flow-animatedhero__background, [data-editor-mode] .flow-animatedhero__layer { transform: none; }

/* Care journey: native sticky scene. Without JS, on short/narrow screens, and
   with reduced motion this is an ordinary, fully visible two-column hero. */
.flow-care-journey { --scene-ground: var(--flow-editorial-ground, #080f1c); --scene-ink: #f8fafc; --scene-accent: var(--flow-editorial-accent, #a5c8ff); --journey-travel: calc(var(--journey-viewport-height, 100svh) * .9); position: relative; background: var(--scene-ground); color: var(--scene-ink); isolation: isolate; }
.flow-care-journey[data-height="compact"] { --journey-travel: calc(var(--journey-viewport-height, 100svh) * .65); }
.flow-care-journey[data-height="immersive"] { --journey-travel: calc(var(--journey-viewport-height, 100svh) * 1.2); }
.flow-care-journey__stage { position: relative; isolation: isolate; overflow: clip; min-height: 42rem; display: grid; align-items: start; }
/* Reserve the stage before hydration. Narrow editor containers override this below. */
@media (min-width: 1000px) and (min-height: 700px) and (prefers-reduced-motion: no-preference) {
  .flow-care-journey__stage { min-height: var(--journey-viewport-height, 100svh); }
}
.flow-care-journey__sky { position: absolute; inset: 0; z-index: -5; background: radial-gradient(ellipse at 75% 20%, color-mix(in srgb, var(--scene-accent) 24%, var(--scene-ground)), transparent 65%), var(--scene-ground); }
.flow-care-journey__photo { position: absolute; inset: -8%; }
.flow-care-journey__sky picture, .flow-care-journey__sky img { width: 100%; height: 100%; display: block; object-fit: cover; }
.flow-care-journey__shade { position: absolute; inset: 0; opacity: var(--scene-shading, 1); background: linear-gradient(90deg, var(--scene-ground), color-mix(in srgb, var(--scene-ground) 50%, transparent)); }
.flow-care-journey__orb { position: absolute; width: clamp(2.5rem, 4vw, 4.5rem); aspect-ratio: 1; top: 7%; right: 12%; border-radius: 50%; background: radial-gradient(circle at 35% 30%, var(--scene-sky-colour, #e4ecff), color-mix(in srgb, var(--scene-sky-colour, #e4ecff) 65%, transparent)); box-shadow: 0 0 3rem color-mix(in srgb, var(--scene-sky-colour, #e4ecff) 18%, transparent); }
.flow-care-journey__orb[data-sky-object="sun"] { background: var(--scene-sky-colour, #ffdc9e); box-shadow: 0 0 4rem 1rem color-mix(in srgb, var(--scene-sky-colour, #ffdc9e) 24%, transparent); }
.flow-care-journey[data-spacing="balanced"] .flow-care-journey__content { padding-top: clamp(5rem, 12svh, 9rem); }
.flow-care-journey__information { display: grid; gap: 2rem; min-width: 0; }
.flow-care-journey__stats { min-width: 0; color: var(--scene-ink); }
/* Composition sizing stays inside the reusable scene, including its editor preview. */
.flow-care-journey .flow-care-journey__stats .flow-liststats-widget[data-presentation] { padding: 0; background: transparent; color: inherit; }
.flow-care-journey .flow-care-journey__stats .flow-liststats-widget .flow-liststats { padding: 0; border: 0; gap: 1.75rem; }
.flow-care-journey[data-has-stats] .flow-care-journey__stats .flow-liststats-widget[data-presentation] .flow-liststats__card { padding: 1rem 0; border-inline: 0; }
.flow-care-journey[data-has-stats] .flow-care-journey__stats .flow-liststats-widget[data-presentation] .flow-liststats__value { font-size: clamp(2.5rem, 4cqi, 3.5rem); }
@container (min-width: 440px) {
  .flow-care-journey .flow-care-journey__stats .flow-liststats-widget .flow-liststats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.flow-care-journey[data-journey-phase] .flow-care-journey__information { align-items: center; }
.flow-care-journey[data-journey-phase] .flow-care-journey__information > * { grid-area: 1 / 1; }
.flow-care-journey[data-journey-phase] .flow-care-journey__stats { opacity: 0; }
.flow-care-journey[data-journey-phase]:has(.flow-care-journey__stats :focus-visible) .flow-care-journey__stats { opacity: 1 !important; transform: none !important; }
.flow-care-journey[data-journey-phase]:has(.flow-care-journey__stats :focus-visible) .flow-care-journey__message { opacity: 0 !important; }
.flow-care-journey__stars { position: absolute; inset: 0; width: 100%; height: 100%; color: var(--scene-accent); opacity: .65; }
.flow-care-journey__land { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.flow-care-journey__land--far { z-index: -4; fill: color-mix(in srgb, var(--scene-accent) 12%, var(--scene-ground)); }
.flow-care-journey__ridge { fill: color-mix(in srgb, var(--scene-accent) 8%, var(--scene-ground)); }
.flow-care-journey__land--middle { z-index: -3; fill: color-mix(in srgb, var(--scene-accent) 17%, var(--scene-ground)); }
.flow-care-journey__village { fill: color-mix(in srgb, var(--scene-accent) 22%, var(--scene-ground)); }
.flow-care-journey__windows { fill: color-mix(in srgb, var(--scene-accent) 75%, var(--scene-ink)); opacity: .5; }
.flow-care-journey__tree { stroke: color-mix(in srgb, var(--scene-accent) 22%, var(--scene-ground)); stroke-width: 7; }
.flow-care-journey__land--near-left, .flow-care-journey__land--near-right { z-index: 2; fill: var(--scene-ground); }
.flow-care-journey__leaves { color: color-mix(in srgb, var(--scene-accent) 20%, var(--scene-ground)); fill: currentColor; }
.flow-care-journey__content { position: relative; z-index: 1; display: grid; grid-template-columns: 1fr 1.06fr; gap: clamp(2.5rem, 5vw, 6rem); align-items: center; width: min(100% - 4rem, var(--flow-content-max-width, 72rem)); margin-inline: auto; padding-block: clamp(3rem, 6svh, 5rem) 6rem; }
.flow-care-journey .flow-care-journey__content .flow-hero.flow-hero--transparent { display: block; min-height: 0; max-width: none; padding: 0; margin: 0; border: 0; border-radius: 0; background: none; color: var(--scene-ink); box-shadow: none; }
.flow-care-journey .flow-hero::before, .flow-care-journey .flow-hero::after { display: none; }
.flow-care-journey .flow-hero.flow-hero--transparent .flow-hero__headline { margin: 0; max-width: none; font-size: clamp(2.8rem, 4.7vw, 4.6rem); line-height: 1.07; letter-spacing: -.045em; color: inherit; }
.flow-care-journey .flow-hero.flow-hero--transparent .flow-hero__headline-accent { color: var(--scene-accent); }
.flow-care-journey .flow-hero.flow-hero--transparent .flow-hero__eyebrow { color: var(--scene-accent); margin: 0 0 1.6rem; font-size: .75rem; letter-spacing: .16em; line-height: 1.6; }
.flow-care-journey .flow-hero.flow-hero--transparent .flow-hero__subhead { color: color-mix(in srgb, var(--scene-ink) 83%, var(--scene-ground)); font-size: 1.0625rem; line-height: 1.75; max-width: 29rem; margin: 1.8rem 0 0; }
.flow-care-journey__panel { position: relative; background: color-mix(in srgb, var(--scene-ground) 96%, var(--scene-accent)); border: 1px solid color-mix(in srgb, var(--scene-accent) 30%, var(--scene-ground)); border-radius: 1.5rem; padding: 1.75rem; box-shadow: 0 2rem 5rem #0005, 0 0 0 7px color-mix(in srgb, var(--scene-accent) 4%, transparent); transform-origin: center; }
.flow-care-journey__panel::after { content: ''; position: absolute; inset: -.75rem; border: 1px solid color-mix(in srgb, var(--scene-accent) 10%, transparent); border-radius: 2rem; pointer-events: none; }
.flow-care-journey__panel-rule { display: flex; gap: .3rem; padding-bottom: 1.4rem; }
.flow-care-journey__panel-rule span { width: .3rem; height: .3rem; border-radius: 50%; background: var(--scene-accent); opacity: .6; }
.flow-care-journey__panel .flow-hero.flow-hero--transparent .flow-hero__headline { font-family: inherit; font-size: 1.5rem; font-weight: 600; letter-spacing: -.025em; line-height: 1.3; }
.flow-care-journey__panel .flow-hero.flow-hero--transparent .flow-hero__actions { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .65rem; margin: 1.5rem 0 0; }
.flow-care-journey__panel .flow-hero.flow-hero--transparent .flow-hero__cta.flow-button { display: flex; justify-content: space-between; align-items: center; text-align: left; gap: .7rem; width: auto; min-width: 0; min-height: 5.25rem; height: auto; white-space: normal; margin: 0; padding: 1rem; border-radius: .7rem; border: 1px solid color-mix(in srgb, var(--scene-ink) 16%, transparent); box-shadow: none; background: color-mix(in srgb, var(--scene-accent) 6%, var(--scene-ground)); color: var(--scene-ink); font-size: .94rem; font-weight: 500; line-height: 1.4; text-decoration: none; transition: background .18s, border-color .18s; }
.flow-care-journey__panel .flow-hero.flow-hero--transparent .flow-hero__cta.flow-button:hover { background: color-mix(in srgb, var(--scene-accent) 17%, var(--scene-ground)); border-color: var(--scene-accent); text-decoration: underline; text-underline-offset: .25em; }
.flow-care-journey__panel .flow-hero.flow-hero--transparent .flow-hero__cta svg { flex-shrink: 0; color: var(--scene-accent); }
.flow-care-journey__panel .flow-hero.flow-hero--transparent .flow-hero__cta.flow-button:focus-visible { color: #212b32; background: #ffeb3b; outline: 3px solid #ffeb3b; outline-offset: 3px; box-shadow: 0 0 0 6px #212b32; }
.flow-care-journey__panel .flow-hero.flow-hero--transparent .flow-hero__cta:focus-visible svg { color: inherit; }
.flow-care-journey__media-layer { position: absolute; bottom: 0; right: 0; width: 45%; height: 35%; z-index: 2; pointer-events: none; }
.flow-care-journey__media-layer[data-position="left"] { right: auto; left: 0; }
.flow-care-journey__media-layer[data-position="centre"] { right: 25%; }
.flow-care-journey__media-layer[data-size="small"] { width: 20%; }
.flow-care-journey__media-layer[data-size="medium"] { width: 30%; }
.flow-care-journey__media-layer picture, .flow-care-journey__media-layer img { display: block; width: 100%; height: 100%; object-fit: contain; object-position: bottom; }
.flow-care-journey__media-layer[data-position="left"] img { object-position: left bottom; }
.flow-care-journey__media-layer[data-position="right"] img { object-position: right bottom; }
.flow-care-journey__edge { opacity: var(--scene-shading, .45); position: absolute; z-index: 3; bottom: 0; left: 0; right: 0; height: 5rem; background: linear-gradient(transparent, var(--scene-ground)); pointer-events: none; }
.flow-care-journey:has(:focus-visible) .flow-care-journey__panel { transform: none !important; }
.flow-care-journey:has(:focus-visible) .flow-care-journey__content { z-index: 4; }
@media (min-width: 1000px) and (min-height: 700px) and (prefers-reduced-motion: no-preference) {
  .flow-care-journey[data-journey-active] { height: calc(var(--journey-viewport-height, 100svh) + var(--journey-travel)); }
  .flow-care-journey[data-journey-active] .flow-care-journey__stage { position: sticky; top: 0; height: var(--journey-viewport-height, 100svh); min-height: 0; }
}
@media (max-width: 999px), (max-height: 699px) {
  .flow-care-journey:not([data-journey-phase]) .flow-care-journey__information { display: contents; }
  .flow-care-journey:not([data-journey-phase]) .flow-care-journey__message { grid-row: 1; }
  .flow-care-journey:not([data-journey-phase]) .flow-care-journey__panel { grid-row: 2; }
  .flow-care-journey:not([data-journey-phase]) .flow-care-journey__stats { grid-row: 3; }
  .flow-care-journey__content { grid-template-columns: 1fr; gap: 2.5rem; max-width: 40rem; width: calc(100% - 3rem); padding-block: 4rem 7rem; }
  .flow-care-journey__stage { min-height: 0; }
  .flow-care-journey__panel { padding: 1.4rem; }
  .flow-care-journey .flow-hero.flow-hero--transparent .flow-hero__headline { font-size: clamp(2.4rem, 8vw, 3.5rem); }
  .flow-care-journey__panel .flow-hero.flow-hero--transparent .flow-hero__headline { font-size: 1.4rem; }
  .flow-care-journey__land--near-left, .flow-care-journey__land--near-right, .flow-care-journey__media-layer { display: none; }
}
@media (max-width: 420px) {
  .flow-care-journey__panel .flow-hero.flow-hero--transparent .flow-hero__actions { grid-template-columns: 1fr; }
  .flow-care-journey__panel .flow-hero.flow-hero--transparent .flow-hero__cta.flow-button { min-height: 3.5rem; }
}
@media (prefers-reduced-motion: reduce) {
  .flow-care-journey { height: auto !important; }
  .flow-care-journey__stage { position: relative !important; height: auto !important; }
  .flow-care-journey [data-journey-part] { transform: none !important; }
  .flow-care-journey__stats, .flow-care-journey__message { opacity: 1 !important; }
  .flow-care-journey__panel .flow-hero.flow-hero--transparent .flow-hero__cta.flow-button { transition: none; }
}
@container theme-canvas (max-width: 999px) {
  .flow-care-journey:not([data-journey-phase]) .flow-care-journey__information { display: contents; }
  .flow-care-journey:not([data-journey-phase]) .flow-care-journey__message { grid-row: 1; }
  .flow-care-journey:not([data-journey-phase]) .flow-care-journey__panel { grid-row: 2; }
  .flow-care-journey:not([data-journey-phase]) .flow-care-journey__stats { grid-row: 3; }
  .flow-care-journey__content { grid-template-columns: 1fr; gap: 2.5rem; max-width: 40rem; width: calc(100% - 3rem); padding-block: 4rem 6rem; }
  .flow-care-journey__stage { min-height: 0; }
  .flow-care-journey__land--near-left, .flow-care-journey__land--near-right, .flow-care-journey__media-layer { display: none; }
  .flow-care-journey .flow-hero.flow-hero--transparent .flow-hero__headline { font-size: clamp(2.4rem, 8cqi, 3.5rem); }
  .flow-care-journey__panel .flow-hero.flow-hero--transparent .flow-hero__headline { font-size: 1.4rem; }
}
@container theme-canvas (max-width: 420px) {
  .flow-care-journey__panel .flow-hero.flow-hero--transparent .flow-hero__actions { grid-template-columns: 1fr; }
  .flow-care-journey__panel .flow-hero.flow-hero--transparent .flow-hero__cta.flow-button { min-height: 3.5rem; }
}
.flow-care-journey__panel .flow-hero.flow-hero--transparent .flow-hero__cta.flow-button--primary { background: var(--scene-accent); color: var(--scene-ground); border-color: var(--scene-accent); }
.flow-care-journey__panel .flow-hero.flow-hero--transparent .flow-hero__cta.flow-button--primary svg { color: inherit; }
.flow-care-journey__panel .flow-hero.flow-hero--transparent .flow-hero__cta.flow-button--primary:hover { background: color-mix(in srgb, var(--scene-accent) 85%, var(--scene-ink)); }
.flow-care-journey__panel .flow-hero.flow-hero--transparent .flow-hero__cta.flow-button--tertiary { background: transparent; border-color: transparent; text-decoration: underline; }
.flow-care-journey[data-composition="centre"] .flow-care-journey__content { grid-template-columns: 1fr; max-width: 48rem; gap: 2.5rem; }
.flow-care-journey[data-composition="centre"] .flow-care-journey__message { text-align: center; }
.flow-care-journey[data-composition="centre"] .flow-hero__subhead { margin-inline: auto; }
.flow-care-journey__panel .flow-hero.flow-hero--transparent .flow-hero__cta.flow-button:focus-visible { color: #212b32; background: #ffeb3b; }
@media (max-width: 999px) { .flow-care-journey__media-layer[data-mobile] { display: block; height: 8rem; } }
@container theme-canvas (max-width: 999px) { .flow-care-journey__media-layer[data-mobile] { display: block; height: 8rem; } }

/* Care journey: centred story. The scene floor is rooted; the care panel settles behind it. */
.flow-care-journey__meteors { position: absolute; inset: 0; overflow: hidden; pointer-events: none; mask-image: radial-gradient(ellipse 38% 32% at 50% 48%, transparent 50%, #000 100%); }
.flow-care-journey__meteors i { position: absolute; height: 1px; opacity: 0; transform-origin: 0 50%; background: linear-gradient(90deg, transparent, #edf6ff66 60%, #fff); }
.flow-care-journey__meteors i::after { content: ''; position: absolute; right: -1px; top: -1px; width: 3px; height: 3px; border-radius: 50%; background: #fff; box-shadow: 0 0 8px #e5f1ffb3; }
.flow-care-journey__media-layer, .flow-care-journey__land--near-left, .flow-care-journey__land--near-right { transform-origin: center bottom; }
.flow-care-journey__media-layer { mask-image: linear-gradient(#000 88%, transparent); }
.flow-care-journey__ground { opacity: var(--scene-shading, .45); position: absolute; inset: auto 0 0; height: 30%; z-index: 2; pointer-events: none; background: linear-gradient(transparent, var(--scene-ground) 96%); }
.flow-care-journey[data-composition="centre"] .flow-care-journey__content { max-width: var(--flow-content-max-width, 72rem); gap: 2rem; padding-block: 2.75rem 3rem; align-items: start; }
.flow-care-journey[data-composition="centre"] .flow-care-journey__information { width: 100%; }
.flow-care-journey[data-composition="centre"] .flow-care-journey__message { max-width: 64rem; margin-inline: auto; }
.flow-care-journey[data-composition="centre"] .flow-care-journey__message .flow-hero__headline { font-size: clamp(2.5rem, 4.7vw, 4.6rem); }
.flow-care-journey[data-composition="centre"] .flow-care-journey__message .flow-hero__subhead { max-width: 64rem; margin-inline: auto; text-wrap: balance; }
.flow-care-journey[data-composition="centre"] .flow-care-journey__panel { width: min(100%, 58rem); box-sizing: border-box; justify-self: center; padding: 1.5rem 1.75rem; }
.flow-care-journey[data-composition="centre"] .flow-care-journey__panel-rule { display: none; }
.flow-care-journey[data-composition="centre"] .flow-care-journey__panel .flow-hero__headline { text-align: center; }
.flow-care-journey[data-composition="centre"] .flow-care-journey__panel .flow-hero__actions { grid-template-columns: repeat(3, minmax(0, 1fr)); margin-top: 1rem; }
.flow-care-journey[data-composition="centre"] .flow-care-journey__panel .flow-hero__cta.flow-button { min-height: 4.75rem; font-size: 1rem; }
.flow-care-journey[data-composition="centre"] .flow-care-journey__stats { align-self: center; }
.flow-care-journey[data-composition="centre"] .flow-care-journey__stats .flow-liststats { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0; }
.flow-care-journey[data-composition="centre"][data-has-stats] .flow-care-journey__stats .flow-liststats-widget[data-presentation] .flow-liststats__card { padding: 1rem 1.5rem; border: 0; border-inline-start: 1px solid color-mix(in srgb, currentColor 18%, transparent); }
.flow-care-journey[data-composition="centre"][data-has-stats] .flow-care-journey__stats .flow-liststats-widget[data-presentation] .flow-liststats__card:first-child { border-inline-start: 0; }
.flow-care-journey[data-composition="centre"][data-journey-phase] .flow-care-journey__information { min-height: 13rem; }
.flow-care-journey:has(.flow-care-journey__panel :focus-visible) .flow-care-journey__panel { opacity: 1 !important; transform: none !important; z-index: 5; }
@media (min-width: 1000px) and (min-height: 700px) {
  .flow-care-journey[data-composition="centre"] .flow-care-journey__stage { min-height: var(--journey-viewport-height, 100svh); }
  .flow-care-journey[data-composition="centre"][data-journey-active] .flow-care-journey__stage { height: var(--journey-viewport-height, 100svh); }
}
@media (max-width: 999px) {
  .flow-care-journey[data-composition="centre"] .flow-care-journey__panel .flow-hero__actions { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .flow-care-journey[data-composition="centre"] .flow-care-journey__stats .flow-liststats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .flow-care-journey__meteors { display: none; }
}
@container theme-canvas (max-width: 999px) {
  .flow-care-journey[data-composition="centre"] .flow-care-journey__panel .flow-hero__actions { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .flow-care-journey[data-composition="centre"] .flow-care-journey__stats .flow-liststats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 420px) {
  .flow-care-journey[data-composition="centre"] .flow-care-journey__panel .flow-hero__actions, .flow-care-journey[data-composition="centre"] .flow-care-journey__stats .flow-liststats { grid-template-columns: 1fr; }
}
@container theme-canvas (max-width: 420px) {
  .flow-care-journey[data-composition="centre"] .flow-care-journey__panel .flow-hero__actions, .flow-care-journey[data-composition="centre"] .flow-care-journey__stats .flow-liststats { grid-template-columns: 1fr; }
}
@media (prefers-reduced-motion: reduce) { .flow-care-journey__meteors { display: none; } }
.flow-care-journey[data-composition="centre"][data-spacing="balanced"] .flow-care-journey__content { padding-top: clamp(4rem, 8svh, 6rem); }
/* The still/editor view keeps the same reading order as narrow screens. */
.flow-care-journey[data-composition="centre"]:not([data-journey-phase]) .flow-care-journey__information { display: contents; }
.flow-care-journey[data-composition="centre"]:not([data-journey-phase]) .flow-care-journey__message { grid-row: 1; }
.flow-care-journey[data-composition="centre"]:not([data-journey-phase]) .flow-care-journey__panel { grid-row: 2; }
.flow-care-journey[data-composition="centre"]:not([data-journey-phase]) .flow-care-journey__stats { grid-row: 3; }

/* Centre the opening in the visible viewport; retain natural flow for still/tall layouts. */
.flow-care-journey[data-composition="centre"][data-journey-phase] .flow-care-journey__content { align-self: center; translate: 0 calc(var(--journey-entry-offset, 0px) / -2); }
.flow-care-journey[data-composition="centre"][data-journey-phase] .flow-care-journey__information { min-height: 13rem; }

/* Optional practice panels reuse Content Tokens; unselected panels take no space. */
.flow-care-journey__practice-panels { position: relative; z-index: 4; display: flex; flex-wrap: wrap; justify-content: space-between; gap: 1rem; width: min(calc(100% - 3rem), var(--flow-content-max-width, 72rem)); margin: 2.5rem auto 0; }
.flow-care-journey__practice-panel { display: flex; align-items: flex-start; gap: .8rem; max-width: 24rem; padding: 1.1rem 1.4rem; border: 1px solid color-mix(in srgb, var(--scene-ink) 25%, transparent); border-radius: 1rem; background: color-mix(in srgb, var(--scene-ground) 90%, transparent); color: var(--scene-ink); box-shadow: 0 .75rem 2.5rem #051a3026; }
.flow-care-journey__practice-panel svg { width: 1.35rem; height: 1.35rem; flex: none; margin-top: .15rem; color: var(--scene-accent); }
.flow-care-journey__practice-panel p { margin: 0; font-size: .95rem; line-height: 1.6; }
.flow-care-journey__practice-panel .flow-care-journey__panel-label { font-weight: 700; margin-bottom: .2rem; }
.flow-care-journey__practice-panel address { font-size: .875rem; line-height: 1.5; font-style: normal; }
.flow-care-journey__practice-panel small { display: block; font-size: .75rem; margin-top: .2rem; }
.flow-care-journey__status-dot { width: .6rem; height: .6rem; border-radius: 50%; background: var(--scene-accent); flex: none; margin-top: .5rem; }
.flow-care-journey__practice-panel[data-status="open"] .flow-care-journey__status-dot { background: #9de9c0; }
.flow-care-journey__practice-panel[data-status="soon"] .flow-care-journey__status-dot { background: #ffdc91; }
.flow-care-journey__practice-panel--hours { margin-left: auto; }

@supports (backdrop-filter: blur(1px)) { .flow-care-journey__practice-panel { backdrop-filter: blur(18px); } }
@media (max-width: 599px) {
 .flow-care-journey__practice-panels { display: grid; grid-template-columns: 1fr; }
 .flow-care-journey__practice-panel { width: 100%; max-width: none; box-sizing: border-box; }
}

/* Optional compact opening status: part of the task panel, never another rail. */
.flow-care-journey .flow-care-journey__panel[data-status-badge] { position: relative; }
.flow-care-journey .flow-care-journey__practice-panels[data-compact] { position: absolute; top: 1.5rem; right: 1.75rem; left: auto; transform: none; width: auto; margin: 0; padding: 0; border: 0; background: none; box-shadow: none; }
.flow-care-journey .flow-care-journey__practice-panels[data-compact] .flow-care-journey__practice-panel { min-width: 0; padding: .4rem .75rem; border-radius: 100px; background: color-mix(in srgb, var(--scene-ink) 6%, var(--scene-ground)); border: 1px solid color-mix(in srgb, var(--scene-ink) 18%, transparent); box-shadow: none; }
.flow-care-journey .flow-care-journey__practice-panels[data-compact] .flow-care-journey__panel-label { font-size: .875rem; margin: 0; }
.flow-care-journey .flow-care-journey__panel[data-status-badge] .flow-hero__headline { text-align: left; padding-right: 10rem; min-height: 2.2rem; }
@keyframes flow-opening-welcome { 0%, 100% { box-shadow: 0 0 0 3px rgb(52 211 153 / .12); } 50% { box-shadow: 0 0 0 7px rgb(52 211 153 / .04), 0 0 12px rgb(52 211 153 / .6); } }
@media (prefers-reduced-motion: no-preference) {
  .flow-care-journey__practice-panels[data-compact][data-pulse] [data-status="open"] .flow-care-journey__status-dot { animation: flow-opening-welcome 2s ease-in-out 2; }
}
@media (max-width: 600px) {
 .flow-care-journey .flow-care-journey__practice-panels[data-compact] { position: static; display: flex; justify-content: flex-start; margin: 0 0 .8rem; }
 .flow-care-journey .flow-care-journey__panel[data-status-badge] .flow-hero__headline { padding-right: 0; }
}

@media (max-width: 999px), (prefers-reduced-motion: reduce) {
  .flow-care-journey__effects-toggle { display: none; }
}
}

/* =====================================================================
 * NHS theme — design tokens + scoped widget/layout styles (v2).
 *
 * ISOLATION MODEL (Pages v2 Phase 4, chunk 4d — decision 1.1 + Option A):
 * The whole file is wrapped in `@scope (.theme-canvas) { … }`. The
 * embedding layer applies `.theme-canvas` to the themed region:
 *   - Front render (Phase 9): the whole page body, so chrome (header/
 *     footer) + the document all inherit the theme.
 *   - Editor canvas (Phase 6): only the canvas pane, so theme styles
 *     never leak into the surrounding admin chrome.
 *
 * This file is PLAIN CSS — no `@import "tailwindcss"` / `@theme`. That is
 * deliberate: a Tailwind import would carry a global preflight that leaks
 * across the `@scope` boundary in both directions (admin ↔ canvas). The
 * canonical widgets emit plain `flow-*` BEM classes, so no utilities are
 * needed. Design tokens live on `:scope` (NOT `:root` — `<html>` is never
 * a descendant of the scope root, so `:root` inside `@scope` matches
 * nothing; see lessons.md #61).
 *
 * `@scope` is one-directional: admin's own preflight still cascades INTO
 * the canvas. That leak is benign (box-sizing / margin resets); if a
 * future surface needs to block it, add `.theme-canvas { all: revert; }`
 * at the boundary and re-assert below.
 *
 * Token values are sourced from NHS Frontend v9 (service-manual.nhs.uk).
 * Soft-tactile additions are modern-theme-specific and declared brandable
 * in tokens.ts so tenants can tune them.
 *
 * LAYOUT DOM CONTRACT (emitted by flow-shared WidgetRenderer, Phase 4
 * chunk 4c; themes style against it):
 *   <section class="flow-section flow-section--bg-{token}
 *                   flow-section--pad-{token} flow-section--width-{token}">
 *     <div class="flow-section__inner">
 *       <!-- blocks, and rows: -->
 *       <div class="flow-row [flow-row--stack-{mobile|tablet}]"
 *            style="--row-cols/gap/valign/justify-{d,t,m}: …">
 *         <!-- each grid track is one ROW SLOT: a bare block, OR a column
 *              that stacks blocks vertically (Pages v2 column stacking). A
 *              column child is a block OR a NESTED row of bare blocks — a
 *              horizontal cluster like a button group (Pages v2 column polish,
 *              model A1; one level only — no column inside a nested row): -->
 *         …block… | <div class="flow-column">…blocks &amp; nested rows…</div>
 *       </div>
 *     </div>
 *   </section>
 * ===================================================================== */

@scope (.theme-canvas) {
  :scope {
    /* NHS Frontend palette */
    --color-nhs-blue: #005EB8;
    --color-nhs-dark-blue: #003087;
    --color-nhs-bright-blue: #0072CE;
    --color-nhs-light-blue: #41B6E6;
    --color-nhs-aqua-blue: #00A9CE;

    --color-nhs-black: #212B32;
    --color-nhs-text: #212B32;
    --color-nhs-secondary-text: #4C6272;
    --color-nhs-grey-1: #4C6272;
    --color-nhs-grey-2: #768692;
    --color-nhs-grey-3: #AEB7BD;
    --color-nhs-grey-4: #D8DDE0;
    --color-nhs-grey-5: #F0F4F5;
    --color-nhs-white: #FFFFFF;

    /* --color-nhs-red / -yellow → now brandable EXTRAS in tokens.ts (editable) */
    --color-nhs-dark-pink: #7C2855;
    --color-nhs-pink: #AE2573;
    --color-nhs-warm-yellow: #FFB81C;
    --color-nhs-green: #009639;
    --color-nhs-button-green: #007f3b;
    --color-nhs-light-green: #78BE20;
    --color-nhs-aqua-green: #00A499;
    --color-nhs-purple: #330072;

    /* Soft tactile palette + display font — BRANDABLE, declared in
       tokens.ts with their defaultValue (the single source of truth).
       The build's emitTokensCss() plugin GENERATES their declarations into
       dist/tokens.css ahead of this file — re-declaring one here fails the
       build (duplicate guard). */

    /* Semantic-core ALIASES (theme-brandability-semantic-vocabulary): NHS's
       surface / surface-warm are now the shared `--flow-surface` /
       `--flow-surface-raised` core roles (brandable, generated). These authored
       aliases keep NHS's own vocabulary resolving to them, so the skin CSS +
       color-mix() below are untouched and a rebrand cascades. */
    --color-surface: var(--flow-surface);
    --color-surface-warm: var(--flow-surface-raised);

    /* Status semantics — derived so tenant rebranding flows through */
    --color-green-soft: color-mix(in oklab, var(--color-nhs-aqua-green) 22%, var(--color-surface));
    --color-orange: color-mix(in oklab, var(--color-nhs-warm-yellow) 55%, var(--color-nhs-red));
    --color-orange-soft: color-mix(in oklab, var(--color-orange) 28%, var(--color-surface));

    --radius-nhs: 4px;
    --shadow-focus: 0 -2px var(--color-nhs-yellow), 0 4px var(--color-nhs-text);

    /* Section background slots — themed values for the canonical
       BackgroundToken vocabulary (default/muted/brand/accent/hero). */
    /* Point at the shared semantic core so rebranding a role cascades to the
       rendered section surfaces (theme-brandability-semantic-vocabulary). */
    --section-bg-default: var(--flow-surface);
    --section-bg-muted: var(--flow-surface-sunken);
    --section-bg-brand: var(--flow-accent);
    --section-bg-accent: var(--color-surface-accent);
    --section-bg-hero: var(--flow-surface-inverse);

    /* Inline ink ROLE values (palette-provenance D9, B-ink). The author picks
       a semantic emphasis ROLE on a span/heading (emphasis/subtle/accent —
       FLOOR-ONLY in v1, no theme extras, no `default`); flow-shared's
       structural.css resolves `.flow-ink-{role}` to THESE theme-owned colours,
       so a global page that stores a role renders as NHS under NHS and as each
       other theme elsewhere. LITERAL lowercase hex (the content-tone build
       guard rejects uppercase / var()), so the values are independent of — not
       aliases of — the palette tokens. On-brand picks:
         - emphasis → NHS blue (the strong brand foreground);
         - subtle   → NHS secondary-text grey (a muted, receding tone);
         - accent   → NHS dark-pink (a supporting brand colour, distinct from
                      the blues so it reads as a deliberate accent on light).
       Every pair clears WCAG AA against every LIGHT floor surface it can sit on
       (default/muted/accent). */
    /* emphasis / subtle / accent are now brandable CORE tokens in tokens.ts
       (theme-brandability-semantic-vocabulary) — generated ahead of this file.
       Removed here to satisfy the duplicate-declaration guard. */

    /* On-dark ink variants — used when the span/heading sits on a DARK surface
       (a dark token surface like brand/hero, a dark gradient role, or an
       overlaid image; flow's render predicate emits the shared
       `[data-surface-tone="dark"]` marker, B-ink dark-surface metadata below).
       All three light realisations fail contrast on the NHS blue bands, so each
       role declares a legible on-dark counterpart that clears WCAG AA against
       BOTH dark floor surfaces (--section-bg-brand = NHS blue,
       --section-bg-hero = NHS dark-blue):
         - emphasis → white (the strongest emphasis on a blue band);
         - subtle   → NHS grey-4 (a muted LIGHT grey, still legible on blue);
         - accent   → NHS yellow (a supporting brand accent that pops on dark
                      blue and clears AA where warm-yellow alone would not). */
    /* on-dark ink roles → brandable CORE in tokens.ts (removed here; guard). */

    /* Padding scale — themed values for the canonical PaddingToken
       vocabulary (none/sm/md/lg/xl/2xl). Used for section block-padding
       and row gaps. */
    --space-none: 0;
    --space-sm: 1rem;
    --space-md: 2rem;
    --space-lg: 3rem;
    --space-xl: 4rem;
    --space-2xl: 6rem;

    /* Contained-width gutter + max width */
    --container-max: 1200px;
    --container-gutter: 1.5rem;

    /* Container query context so the editor's device-preview pane (Phase
       6) and the front render both reflow rows truthfully. */
    container: theme-canvas / inline-size;

    background-color: var(--color-surface);
    font-family: var(--font-sans);
    line-height: 1.5;
    color: var(--color-nhs-text);
  }

  /* Default NHS link styles — :where() keeps specificity at 0 so widget
     rules win. */
  :where(a) {
    color: var(--color-nhs-blue);
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 1.5px;
  }
  :where(a):hover { text-decoration-thickness: 2px; }
  :where(a):visited { color: var(--color-nhs-purple); }

  /* Chrome owns its ground; generic content-link and visited colours must not leak in. */
  .nhs-site-brand, .nhs-site-brand:visited { color: var(--color-nhs-white); text-decoration: none; }
  .nhs-site-footer a, .nhs-site-footer a:visited { color: var(--color-nhs-white); }

  /* Accessibility focus state — NHS Frontend convention, must beat any
     author class. */
  a:focus-visible,
  button:focus-visible,
  summary:focus-visible,
  [role="button"]:focus-visible,
  [tabindex]:focus-visible {
    outline: 4px solid transparent !important;
    outline-offset: 0 !important;
    background-color: var(--color-nhs-yellow) !important;
    color: var(--color-nhs-text) !important;
    box-shadow: 0 -2px var(--color-nhs-yellow), 0 4px var(--color-nhs-text) !important;
    text-decoration: none !important;
  }

  input:focus-visible,
  select:focus-visible,
  textarea:focus-visible {
    outline: 4px solid var(--color-nhs-yellow) !important;
    outline-offset: 0 !important;
    background-color: var(--color-nhs-white) !important;
    color: var(--color-nhs-text) !important;
    box-shadow: inset 0 0 0 2px var(--color-nhs-text) !important;
  }

  /* ── Section ──────────────────────────────────────────────────────── */
  .flow-section {
    padding-block: var(--space-md);
  }
  .flow-section__inner { width: 100%; }

  /* The inline gutter lives on the CONTAINED inner only (mirrors the shared
     structural contract + Lumen) — so a `width-full_bleed` section reaches the
     viewport edges with no x-axis inset. Putting `padding-inline` on the outer
     `.flow-section` trapped full-bleed heroes behind a gutter. */
  .flow-section--width-contained .flow-section__inner {
    max-width: var(--container-max);
    margin-inline: auto;
    padding-inline: var(--container-gutter);
  }
  .flow-section--width-full_bleed .flow-section__inner { max-width: none; }

  .flow-section--pad-none { padding-block: var(--space-none); }
  .flow-section--pad-sm { padding-block: var(--space-sm); }
  .flow-section--pad-md { padding-block: var(--space-md); }
  .flow-section--pad-lg { padding-block: var(--space-lg); }
  .flow-section--pad-xl { padding-block: var(--space-xl); }
  .flow-section--pad-2xl { padding-block: var(--space-2xl); }

  .flow-section--bg-default { background-color: var(--section-bg-default); }
  .flow-section--bg-muted { background-color: var(--section-bg-muted); }
  .flow-section--bg-accent { background-color: var(--section-bg-accent); }
  .flow-section--bg-brand {
    background-color: var(--section-bg-brand);
    color: var(--color-nhs-white);
  }
  .flow-section--bg-hero {
    background-color: var(--section-bg-hero);
    color: var(--color-nhs-white);
  }
  .flow-section--bg-brand :where(a),
  .flow-section--bg-hero :where(a) { color: var(--color-nhs-white); }

  /* ── Segment surfaces — THEME FLAVOUR (segment-surface-styles plan §5c) ──
     The render MECHANISM for the four surface modes (image layer, overlay
     ::before, gradient background, backdrop-filter glass) ships in the
     flow-shared structural contract embedded ABOVE this authored block — this
     theme does NOT re-declare any of it. It supplies only FLAVOUR: sensible
     default values for the surface custom properties so a freshly-applied
     surface reads well before the author tunes it, plus the legibility chrome
     an NHS image surface needs.

     `sectionStyle()` emits the per-instance custom properties (the chosen
     image, gradient, overlay colour/opacity, glass tint/opacity) inline on the
     `<section>`, OVERRIDING these defaults when the author sets them. Where the
     author leaves a property unset, these house defaults apply:
       - a deep NHS-blue overlay tint at a legible default opacity, so an
         image surface with the overlay capability on but no colour chosen
         still darkens for white-text contrast (the NHS image-band convention). */
  .flow-section--surface-image {
    --flow-section-overlay-colour: var(--color-nhs-dark-blue);
    --flow-section-overlay-opacity: 0.45;
  }

  /* Image + gradient FILL surfaces frequently carry white text on a dark
     band, mirroring the brand/hero token sections — keep links legible there
     without forcing colour (the author may pick a light surface, so this is a
     CONVENTION default, scoped only when paired with a white-ink content set
     the author opts into via the brand/hero token base). The overlay default
     above provides the contrast; the token-mode `--bg-brand`/`--bg-hero` rules
     above already flip link colour, so no extra link rule is needed here. */

  /* ── Row ──────────────────────────────────────────────────────────────
     The theme owns ONLY `display: grid`. Gap, vertical alignment, the column
     tracks, AND horizontal justify are ALL per-breakpoint now, owned by the
     flow-shared structural contract (embedded ABOVE this authored block):
     `rowStyle()` emits `--row-cols/gap/valign/justify-{d,t,m}` custom
     properties and the contract's `@container theme-canvas` rules apply
     `grid-template-columns` + `gap` + `align-items` + `justify-content` per
     band. `gap` + `align-items` were STRIPPED from this authored base rule in
     lockstep with the per-breakpoint toolbar (segment-responsive-toolbar plan
     §2.1): because the theme build concatenates structural CSS BEFORE this
     authored file, an authored `gap`/`align-items` here would WIN by source
     order and pin every band to the desktop value. The per-token
     `.flow-row--gap-*` / `.flow-row--valign-*` classes were removed for the
     same reason — a single-token class can only carry one band's value, so it
     is both wrong and now unstyled.

     `rowClasses()` still emits `flow-row--stack-{mobile|tablet}`, which the
     contract's `@container` rules collapse to one column. The old blanket
     force-stack was removed earlier (responsive-rows). */
  .flow-row {
    display: grid;
  }

  /* ── Column ───────────────────────────────────────────────────────────
     A row slot that stacks >= 2 blocks vertically (Pages v2 column stacking).
     A `.flow-row` grid child is now a bare `.flow-block` OR a `.flow-column`
     (see LAYOUT DOM CONTRACT above). `min-width: 0` + `max-width: 100%` floor
     the grid item so a wide/unbreakable stacked child (image, long word,
     max-width button) can't blow its track out — the same overflow guard the
     bare-block slot carries. The vertical rhythm between stacked blocks lives
     with Layer 1 in the Block-spacing section below. Mobile (< 640px) already
     collapses the row to 1fr; a column is vertical regardless, so no new
     responsive rule is needed. */
  .flow-column {
    display: flex;
    flex-direction: column;
    min-width: 0;
    max-width: 100%;
  }

  /* A column child may be a NESTED row (Pages v2 column polish, model A1) — a
     horizontal cluster of bare blocks, e.g. a button group, stacked among the
     column's blocks. Its vertical rhythm is already covered by the
     `.flow-column > *` margin rule (Layer 1, below). As a flex item it stretches
     to the column width; floor it at `min-width: 0` so a wide cluster shrinks
     instead of blowing the column's grid track out (the same overflow guard the
     bare-block slot + the column itself carry). The nested row's own `.flow-row`
     grid + inline content-sized `grid-template-columns` lay the cluster out, and
     the structural contract's `flow-row--stack-mobile` rule (a nested row gets
     the same stack-intent class from `rowClasses()`) collapses it to one column
     on narrow surfaces — so a button group stacks on phones as before. */
  .flow-column > .flow-row {
    min-width: 0;
    max-width: 100%;
  }

  /* ── Heading widget ───────────────────────────────────────────────── */
  .flow-heading {
    font-weight: 700;
    line-height: 1.2;
    margin: 0;
    color: inherit;
  }
  .flow-heading--h1 { font-size: clamp(2.5rem, 4cqi, 3.5rem); line-height: 1.08; letter-spacing: -0.025em; text-wrap: balance; }
  .flow-heading--h2 { font-size: 2rem; letter-spacing: -0.015em; text-wrap: balance; }
  .flow-heading--h3 { font-size: 1.5rem; }
  .flow-heading--h4 { font-size: 1.25rem; }
  .flow-heading--h5 { font-size: 1.125rem; }
  .flow-heading--h6 { font-size: 1rem; }

  /* ── Rich Text widget ─────────────────────────────────────────────── */
  .flow-richtext { color: inherit; }
  .flow-richtext > :first-child { margin-top: 0; }
  .flow-richtext > :last-child { margin-bottom: 0; }
  .flow-richtext h2 { font-size: 2rem; font-weight: 700; line-height: 1.2; margin: 2rem 0 1rem; }
  .flow-richtext h3 { font-size: 1.5rem; font-weight: 700; line-height: 1.2; margin: 1.75rem 0 0.75rem; }
  .flow-richtext h4 { font-size: 1.25rem; font-weight: 700; line-height: 1.3; margin: 1.5rem 0 0.5rem; }
  .flow-richtext p { margin: 0 0 1rem; }
  .flow-richtext ul,
  .flow-richtext ol { margin: 0 0 1rem; padding-inline-start: 1.5rem; }
  .flow-richtext li { margin-bottom: 0.5rem; }
  .flow-richtext blockquote {
    margin: 0 0 1rem;
    padding-inline-start: 1rem;
    border-inline-start: 4px solid var(--color-nhs-grey-3);
    color: var(--color-nhs-secondary-text);
  }
  .flow-richtext table { border-collapse: collapse; width: 100%; margin: 0 0 1rem; }
  .flow-richtext th,
  .flow-richtext td { border: 1px solid var(--color-nhs-grey-4); padding: 0.5rem 0.75rem; text-align: left; }
  .flow-richtext th { background-color: var(--color-nhs-grey-5); font-weight: 700; }

  /* ── Image widget ─────────────────────────────────────────────────── */
  .flow-image { display: block; }
  .flow-image img { display: block; width: 100%; height: auto; border-radius: 1rem; }

  /* ── Button widget skin — styles the canonical button AND the NHS
     override (PageButtonOverride.vue keeps the canonical classes per the
     structural-contract D-C convention).
     `inline-size: fit-content` is the DEFAULT-width parity fix: as a direct
     flex item of `.flow-column` on the front the button would otherwise
     blockify and stretch, while the editor (where the BlockShell wrapper is
     the flex item) shows it hugging. fit-content beats the item stretch, so
     both surfaces hug by default — `flow-block--w-fill` (structural
     contract) opts into full width. */
  .flow-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: fit-content;
    gap: 0.5rem;
    padding: 0.75rem 1rem;
    border-radius: var(--radius-nhs);
    font-weight: 700;
    text-decoration: none;
    transition: background-color 0.15s ease;
  }
  .flow-button:active { box-shadow: none; transform: translateY(1px); }
  .flow-button--primary {
    background-color: var(--color-nhs-button-green);
    color: var(--color-nhs-white);
    box-shadow: inset 0 -4px 0 color-mix(in oklab, var(--color-nhs-button-green) 50%, black);
  }
  .flow-button--primary:hover { background-color: color-mix(in oklab, var(--color-nhs-button-green) 85%, black); }
  .flow-button--secondary {
    background-color: var(--color-nhs-white);
    color: var(--color-nhs-text);
    border: 2px solid var(--color-nhs-grey-2);
  }
  .flow-button--secondary:hover { background-color: var(--color-nhs-grey-5); }
  .flow-button--tertiary {
    background-color: transparent;
    color: var(--color-nhs-blue);
    text-decoration: underline;
  }
  /* Theme-declared EXTRA variant (manifest `buttonVariants.reverse` —
     theme button variants plan): the NHS Design System reverse button,
     for use on solid-colour backgrounds (brand-blue segments). White
     surface, ink text, the signature pressed shadow in grey. */
  .flow-button--reverse {
    background-color: var(--color-nhs-white);
    color: var(--color-nhs-text);
    box-shadow: inset 0 -4px 0 var(--color-nhs-grey-2);
  }
  .flow-button--reverse:hover { background-color: var(--color-nhs-grey-5); }

  /* ── Dark-surface overrides (tone-adaptive-button-variants plan) ─────
     Keyed on the established dark-context signals: the AUTO marker, the
     author's explicit "Light text" tone (which never emits the auto
     marker), and the filled/image hero (its own dark surface, no section
     marker). primary/secondary/reverse carry their own opaque fills, so
     only `color` is restated — structural's tone-light text rules (0,1,1)
     outrank the bare variant classes (0,1,0) and would bleed white text
     onto the white cards. tertiary (transparent, link-style) genuinely
     flips: blue underline → white underline.

     The hero selector is keyed on [data-background-asset]: an IMAGE hero is a
     dark ground (the scrim guarantees it), but since the NhsHeroOverride the
     imageless hero is the modern WARM surface — a light ground where these
     white remaps would be invisible ink. */
  [data-surface-tone="dark"] .flow-button--primary,
  .flow-section--tone-light .flow-button--primary,
  .flow-hero[data-background-asset]:not(.flow-hero--transparent) .flow-button--primary {
    color: var(--color-nhs-white);
  }
  [data-surface-tone="dark"] .flow-button--secondary,
  .flow-section--tone-light .flow-button--secondary,
  .flow-hero[data-background-asset]:not(.flow-hero--transparent) .flow-button--secondary {
    color: var(--color-nhs-text);
  }
  [data-surface-tone="dark"] .flow-button--tertiary,
  .flow-section--tone-light .flow-button--tertiary,
  .flow-hero[data-background-asset]:not(.flow-hero--transparent) .flow-button--tertiary {
    color: var(--color-nhs-white);
  }
  [data-surface-tone="dark"] .flow-button--reverse,
  .flow-section--tone-light .flow-button--reverse,
  .flow-hero[data-background-asset]:not(.flow-hero--transparent) .flow-button--reverse {
    color: var(--color-nhs-text);
  }

  /* ── Button widget override (components/PageButtonOverride.vue) ─────
     The override keeps the CANONICAL `flow-button` / `flow-button--{variant}`
     classes alongside its own (the structural-contract D-C convention), so
     the `.flow-button*` skin above styles it directly — the former
     `.nhs-button*` skin block was a word-for-word duplicate and was
     consolidated away (2026-06-11). Only the genuine NHS-only diff stays:
     the trailing directional arrow, hidden on the tertiary variant. */
  .nhs-button--tertiary .nhs-button__arrow { display: none; }

  /* Focus is INSTANT. The hover transitions above include background-color,
     which made the yellow focus fill ease in over 200ms — technically fine
     (the box-shadow indicator is untransitioned and lands immediately), but a
     focus state that drifts in reads as lag, not polish. Measured during the
     WCAG 2.2 audit; also a caution for auditors — reading a computed style
     straight after .focus() races this very transition. */
  a:focus-visible,
  button:focus-visible,
  [role="button"]:focus-visible,
  [tabindex]:focus-visible {
    transition: none !important;
  }

  /* ── Divider widget ───────────────────────────────────────────────── */
  .flow-divider--line {
    border: 0;
    border-top: 1px solid var(--color-nhs-grey-4);
    margin: 0;
  }
  .flow-divider--space { display: block; height: var(--space-lg); }

  /* ── Hero widget ──────────────────────────────────────────────────── */
  /* `isolation: isolate` makes the hero its own stacking context so the
     negative-z background layer + scrim sit BEHIND the normal-flow content
     without needing a z-index on every child. */
  .flow-hero {
    position: relative;
    overflow: hidden;
    isolation: isolate;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 1rem;
    /* Full-bleed background, container-aligned content (mirrors Lumen's hero:
       image bleeds edge-to-edge, copy lines up with the page container). The
       `max()` keeps the side padding at the container gutter until the section
       is wider than the container, then grows it so the content edge meets the
       centred container — the image layer (inset:0) ignores padding and bleeds.
       Needs the section at width:full_bleed for the image to reach the edges. */
    padding-block: var(--space-xl);
    padding-inline: max(var(--container-gutter), calc((100% - var(--container-max)) / 2));
    background-color: var(--color-nhs-dark-blue);
    color: var(--color-nhs-white);
  }
  /* Background image — flow-shared's Hero renders the image as a
     `<picture class="flow-hero__bg">` (ResponsiveImage); the theme positions it
     as a cover layer behind the content. Without this the picture renders inline
     as a block image above the headline (the "image doesn't work" symptom). */
  .flow-hero__bg {
    position: absolute;
    inset: 0;
    z-index: -2;
    display: block;
  }
  .flow-hero__bg img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
  }
  /* Dark-blue scrim over a photo so the white hero text stays legible on any
     image (only when a background image is set). */
  .flow-hero[data-background-asset]:not([data-shading="custom"])::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: linear-gradient(
      180deg,
      color-mix(in oklab, var(--color-nhs-dark-blue) 35%, transparent),
      color-mix(in oklab, var(--color-nhs-dark-blue) 72%, transparent)
    );
  }
  .flow-hero__headline { font-size: 2.5rem; font-weight: 700; line-height: 1.2; margin: 0; max-width: 30rem; }
  .flow-hero__subhead { font-size: 1.25rem; margin: 0; max-width: 36rem; }
  /* The hero CTA group (repeater-properties-hero-buttons): the wrapper carries the
     top spacing (the column hero stacks headline → subhead → actions), and the
     structural `.flow-hero__actions` baseline lays the buttons in a wrapping row. */
  .flow-hero__actions { margin-top: 0.5rem; }
  /* Transparent hero (transparentBackground prop, plan D6) — with NO background
     image the hero claims no surface of its own: drop the dark-blue band and
     reset the headline/subhead foreground (inherited from `.flow-hero`) to
     on-light ink so it stays legible on the page background. An IMAGE hero is
     unaffected — the image + its scrim keep providing the dark ground the white
     text needs, so the override is scoped to the image-less case. */
  .flow-hero--transparent:not([data-background-asset]) {
    background-color: transparent;
    color: var(--color-nhs-text);
  }
  /* Transparent hero DEFAULT text follows the section content tone (component-
     surface-parity-and-motion, hero ink). Without this the on-light nhs-text above
     wins even when the author declared "Light text" on a dark page, leaving the
     headline/subhead illegible. Both dark-band signals flip it to on-dark; an ink
     role on the headline/subhead overrides this per element. */
  .flow-section--tone-light .flow-hero--transparent:not([data-background-asset]),
  [data-surface-tone="dark"] .flow-hero--transparent:not([data-background-asset]) { color: var(--flow-fg-on-dark, #ffffff); }
  /* Hero ink roles on the DARK band — the default dark-blue band AND the image
     ground (its dark scrim) are dark, so an author ink role on the headline/subhead
     uses its on-dark realisation. Doubled class (0,3,0) beats the structural base
     (0,2,0). The transparent hero is excluded — it follows the section tone
     (structural F1 `.flow-section--tone-light .flow-ink-*`) or the on-light base. */
  .flow-hero:not(.flow-hero--transparent) .flow-ink-emphasis.flow-ink-emphasis { color: var(--flow-ink-emphasis-on-dark); }
  .flow-hero:not(.flow-hero--transparent) .flow-ink-subtle.flow-ink-subtle { color: var(--flow-ink-subtle-on-dark); }
  .flow-hero:not(.flow-hero--transparent) .flow-ink-accent.flow-ink-accent { color: var(--flow-ink-accent-on-dark); }

  /* ── The modern inner-page hero (NhsHeroOverride) ─────────────────────────
     Warm surface, radial accent top-right, blue title, content settled at the
     bottom of a fixed-minimum band so every page's hero is the same height
     whether or not its title wraps — the PageHero design, carried over.

     ORDER MATTERS HERE: this block must sit AFTER the `.flow-hero` base rules
     above. Both are single-class selectors, so source order is the only thing
     letting `.nhs-hero` win — the first draft of this block was inserted
     earlier in the file and silently lost every tie, shipping the old dark
     band with a blue title on it. Caught by measuring the rendered ground.

     INK IS PINNED, deliberately: the hero paints its OWN warm ground, so it
     owns its ink (the care-card rule). The two grounds it does NOT own opt
     back out below: an image hero lifts to white over the scrim, and a
     transparent hero inherits the section's foreground untouched. */
  .nhs-hero {
    background-color: var(--color-surface-warm);
    color: var(--color-nhs-text);
    padding: 0;
    display: block;
  }
  /* The accent spans the hero and paints its glow with the radial's CENTRE at
     the top-right corner — not an oversized circle pushed past the edge. The
     rendered pixels are identical (everything outside was clipped by the
     hero's overflow anyway), but no element extends beyond its container:
     PageOverflowTest counts geometry, and clipping does not excuse it — the
     first draft protruded 77px at tablet width and failed the gate. */
  .nhs-hero__accent {
    pointer-events: none;
    position: absolute;
    inset: 0;
    background: radial-gradient(40rem circle at calc(100% + 4rem) -20%, var(--color-accent-soft) 0%, transparent 60%);
  }
  .nhs-hero__inner {
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    align-items: flex-start;
    min-height: 14rem;
    max-width: var(--container-max);
    margin-inline: auto;
    padding: 2.5rem var(--container-gutter);
  }
  @media (min-width: 40rem) {
    .nhs-hero__inner { min-height: 15rem; padding-block: 3rem; }
  }
  @media (min-width: 64rem) {
    .nhs-hero__inner { min-height: 16rem; padding-block: 3.5rem; }
  }
  .nhs-hero .flow-hero__headline {
    font-size: clamp(2rem, 4cqi, 3rem);
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -0.02em;
    color: var(--color-nhs-blue);
    max-width: 24ch;
  }
  .nhs-hero .flow-hero__subhead {
    margin-top: 0.75rem;
    font-size: 1.0625rem;
    line-height: 1.55;
    color: var(--color-nhs-secondary-text);
    max-width: 55ch;
  }
  .nhs-hero .flow-hero__actions {
    margin-top: 1.5rem;
  }

  /* Ground 2 — an image hero. The image + scrim are the ground; text lifts to
     white, and the warm surface underneath is irrelevant. */
  .nhs-hero[data-background-asset] .flow-hero__headline { color: var(--color-nhs-white); }
  .nhs-hero[data-background-asset] .flow-hero__subhead { color: var(--color-nhs-white); }

  /* Ground 3 — transparent. The hero paints nothing, so it owns nothing:
     inherit the section's foreground, whatever structural.css made it. */
  .nhs-hero.flow-hero--transparent { background-color: transparent; }
  .nhs-hero.flow-hero--transparent .flow-hero__headline { color: inherit; }
  .nhs-hero.flow-hero--transparent .flow-hero__subhead { color: inherit; }

  /* ── Form widget — skin the shared flow-form* / flow-form-field* floor
     (forms-theme-styling P3 + branding-component-colours-per-scheme). NHS keeps
     the identity-carrying SHAPE — chunky 2px SQUARE inputs, NHS radius on groups
     — while the COLOURS now flow through the brandable `--flow-field-*` tokens
     (declared in tokens.ts, tenant-editable per background scheme). So a tenant
     can retint the input/fieldset border + help + required marker; the border
     WIDTH + radius stay theme-owned. The label + on-dark realisations resolve
     straight from the floor + the `-on-dark` brandable tokens (no authored rule
     needed). Focus is the signature 4px yellow `!important` ring above (locked
     accessibility token) — deliberately NOT brandable. `.flow-button` submit is
     skinned by the NHS button rules above. */
  .flow-form-field__control {
    border: 2px solid var(--flow-field-border);
    border-radius: 0;
    color: var(--color-nhs-text);
  }
  .flow-form-field--group {
    border-color: var(--flow-field-group-border);
    border-radius: var(--radius-nhs);
  }
  .flow-form-field__required { color: var(--flow-field-required-color); }
  .flow-form-field__help,
  .flow-form-field__hint,
  .flow-form-field__value { color: var(--flow-field-help-color); }

  /* ── Article List widget — card APPEARANCE (article-list-render-layer) ──
     LAYOUT (the fixed 3/2/1 card grid, the inner flex anatomy, the pager row)
     lives in the flow-shared structural contract (`.flow-articlelist*`). This
     block owns only card CHROME + typography — the same conventions as the
     List Grid cards below, keyed to the NHS tokens so tenant rebranding flows
     through. The pager's Previous/Next are canonical `.flow-button` anchors —
     the NHS button skin (incl. tone-adaptive on-dark) applies untouched. */
  .flow-articlelist__card {
    overflow: hidden;
    background-color: var(--color-nhs-white);
    border: 1px solid var(--color-nhs-grey-4);
    border-radius: var(--radius-nhs);
    box-shadow: 0 1px 2px color-mix(in oklab, var(--color-nhs-black) 8%, transparent);
    transition: box-shadow 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
  }
  .flow-articlelist__inner {
    color: var(--color-nhs-text);
    text-decoration: none;
  }
  .flow-articlelist__card--link {
    cursor: pointer;
    border-top: 4px solid var(--color-nhs-blue);
  }
  .flow-articlelist__card--link:hover {
    border-color: var(--color-nhs-grey-3);
    box-shadow: 0 6px 16px color-mix(in oklab, var(--color-nhs-black) 14%, transparent);
    transform: translateY(-2px);
  }
  .flow-articlelist__card--link:has(.flow-articlelist__link:focus-visible) {
    outline: 4px solid transparent !important;
    outline-offset: 0 !important;
    box-shadow: 0 0 0 4px var(--color-nhs-yellow), 0 0 0 8px var(--color-nhs-text) !important;
  }
  .flow-articlelist__media {
    overflow: hidden;
    background-color: var(--color-nhs-grey-5);
  }
  .flow-articlelist__image { transition: transform 0.3s ease; }
  .flow-articlelist__card--link:hover .flow-articlelist__image { transform: scale(1.04); }
  .flow-articlelist__content {
    gap: 0.5rem;
    padding: var(--space-md);
  }
  .flow-articlelist__eyebrow {
    font-size: 0.8125rem;
    font-weight: 700;
    line-height: 1.3;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--color-nhs-secondary-text);
  }
  .flow-articlelist__title {
    font-size: 1.25rem;
    font-weight: 700;
    line-height: 1.3;
    color: var(--color-nhs-text);
  }
  .flow-articlelist__card--link .flow-articlelist__title { color: var(--color-nhs-blue); }
  .flow-articlelist__card--link:hover .flow-articlelist__title { text-decoration: underline; }
  .flow-articlelist__body {
    font-size: 1rem;
    line-height: 1.5;
    color: var(--color-nhs-text);
  }
  .flow-articlelist__body > :first-child { margin-top: 0; }
  .flow-articlelist__body > :last-child { margin-bottom: 0; }
  .flow-articlelist__placeholder { color: var(--color-nhs-secondary-text); }
  .flow-articlelist__pager-status { color: var(--color-nhs-secondary-text); }
  /* On-dark legibility (Lesson 116 keying — BOTH dark-band signals): the text
     that sits DIRECTLY on the section surface (pager status, empty-state
     placeholder) lifts on a dark band; the cards keep their own white surface
     and stay legible as-is, and the pager buttons are tone-adaptive already. */
  .flow-section--tone-light .flow-articlelist__pager-status,
  [data-surface-tone="dark"] .flow-articlelist__pager-status,
  .flow-section--tone-light .flow-articlelist__placeholder,
  [data-surface-tone="dark"] .flow-articlelist__placeholder {
    color: var(--flow-fg-on-dark, #ffffff);
  }

  /* ── List Grid widget — card APPEARANCE (Lists module) ────────────────
     LAYOUT (the grid itself, column counts, gap, card column-span, the inner
     flex column, the fixed-ratio media frame, the growing content column)
     lives in the flow-shared structural contract (`.flow-listgrid*` + the
     `--listgrid-*` / `--flow-list-image-aspect` custom properties the SFC
     emits). This block owns only the card CHROME + typography — borders,
     radius, padding, shadow, hover, focus, and link affordances — keyed to
     the NHS tokens so tenant rebranding flows through. The SFC emits, per
     resolved item:

       <li class="flow-listgrid__card [flow-listgrid__card--link]">
         <a|div class="flow-listgrid__inner [flow-listgrid__link]">
           <div class="flow-listgrid__media"><img class="flow-listgrid__image"></div>
           <div class="flow-listgrid__content">
             <span class="flow-listgrid__eyebrow">…</span>
             <span class="flow-listgrid__title">…</span>
             <div  class="flow-listgrid__body">…bodyHtml…</div>
             <span class="flow-listgrid__cta">…linkLabel…</span>
           </div>
         </a|div>
       </li>

     A card with a resolved link wraps its content in an `<a>` (the whole card
     is the click target); a plain card uses a `<div>` with identical chrome. */
  .flow-listgrid__card {
    overflow: hidden;
    background-color: var(--color-nhs-white);
    border: 1px solid var(--color-nhs-grey-4);
    border-radius: var(--radius-nhs);
    box-shadow: 0 1px 2px color-mix(in oklab, var(--color-nhs-black) 8%, transparent);
    transition: box-shadow 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
  }

  /* The inner wrapper inherits ink colour and never underlines as a whole —
     only the title/cta advertise the link. Fills the card (structural flex
     column) so the cta can pin to the bottom of equal-height cards. */
  .flow-listgrid__inner {
    color: var(--color-nhs-text);
    text-decoration: none;
  }

  /* Linked cards advertise interactivity: a top accent rule (the NHS
     "clickable card" convention), a lifted shadow + subtle raise on hover. */
  .flow-listgrid__card--link {
    cursor: pointer;
    border-top: 4px solid var(--color-nhs-blue);
  }
  .flow-listgrid__card--link:hover {
    border-color: var(--color-nhs-grey-3);
    box-shadow: 0 6px 16px color-mix(in oklab, var(--color-nhs-black) 14%, transparent);
    transform: translateY(-2px);
  }
  /* The whole card is the link — the NHS yellow focus ring belongs to the
     card. The accessible focus lands on the inner `<a>`, so `:focus-within`
     lifts it to the card box. Beats the global `a:focus-visible` skin. */
  .flow-listgrid__card--link:has(.flow-listgrid__link:focus-visible) {
    outline: 4px solid transparent !important;
    outline-offset: 0 !important;
    box-shadow: 0 0 0 4px var(--color-nhs-yellow), 0 0 0 8px var(--color-nhs-text) !important;
  }
  /* …and the global focus rule must NOT also flood the whole-card anchor
     solid yellow — an <a> that fills a 200px card turns the entire card into
     a yellow slab on Tab. Measured before fixing: rgb(250,225,0) across the
     full card. The ring above is the indicator; the fill is for text-scale
     links only. Specificity (0,2,1) beats the global (0,1,1) at equal
     !important. */
  .flow-listgrid__link:focus-visible {
    background-color: var(--color-nhs-white) !important;
    color: var(--color-nhs-text) !important;
    box-shadow: none !important;
  }

  /* Media frame — a tinted placeholder while the image loads; corners clip to
     the card via the card's `overflow: hidden`. The image is cropped to the
     author's ratio by the structural rule; the theme adds the hover zoom. */
  .flow-listgrid__media {
    overflow: hidden;
    background-color: var(--color-nhs-grey-5);
  }
  .flow-listgrid__image { transition: transform 0.3s ease; }
  .flow-listgrid__card--link:hover .flow-listgrid__image { transform: scale(1.04); }

  /* Content column — generous padding + rhythm; grows to fill the card. */
  .flow-listgrid__content {
    gap: 0.5rem;
    padding: var(--space-md);
  }

  .flow-listgrid__eyebrow {
    font-size: 0.8125rem;
    font-weight: 700;
    line-height: 1.3;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--color-nhs-secondary-text);
  }

  .flow-listgrid__title {
    font-size: 1.25rem;
    font-weight: 700;
    line-height: 1.3;
    color: var(--color-nhs-text);
  }
  /* On a linked card the title reads as the link affordance (NHS blue),
     underlined on card hover — without the card itself being underlined. */
  .flow-listgrid__card--link .flow-listgrid__title { color: var(--color-nhs-blue); }
  .flow-listgrid__card--link:hover .flow-listgrid__title { text-decoration: underline; }

  .flow-listgrid__body {
    font-size: 1rem;
    line-height: 1.5;
    color: var(--color-nhs-text);
  }
  .flow-listgrid__body > :first-child { margin-top: 0; }
  .flow-listgrid__body > :last-child { margin-bottom: 0; }

  /* Call-to-action — pinned to the bottom of the content column so a row of
     mixed-length cards aligns its links. Reads as a forward affordance. */
  .flow-listgrid__cta {
    margin-top: auto;
    padding-top: 0.5rem;
    font-weight: 700;
    color: var(--color-nhs-blue);
  }
  .flow-listgrid__cta::after {
    content: "→";
    margin-inline-start: 0.375rem;
    transition: margin-inline-start 0.15s ease;
  }
  .flow-listgrid__card--link:hover .flow-listgrid__cta { text-decoration: underline; }
  .flow-listgrid__card--link:hover .flow-listgrid__cta::after { margin-inline-start: 0.625rem; }

  /* ── The three grid variants, made DISTINCT ──────────────────────────────
     They shared one look and differed only in geometry, which wastes the
     choice the picker offers. Mapped to the NhsCard family:

       cards      NhsCard default/clickable — plain hairline box, the border
                  turning NHS blue on hover (no permanent top bar);
       editorial  NhsCard feature — the 4px blue top bar as standing chrome;
       list       NhsServiceLink — flush hairline rows, no card box, the title
                  leading and the row tinting on hover. */
  .flow-listgrid--cards .flow-listgrid__card--link {
    border-top-width: 1px;
    border-top-color: var(--color-nhs-grey-4);
  }
  .flow-listgrid--cards .flow-listgrid__card--link:hover {
    border-color: var(--color-nhs-blue);
  }

  .flow-listgrid--editorial .flow-listgrid__card {
    border-top: 4px solid var(--color-nhs-blue);
  }

  .flow-listgrid--list .flow-listgrid__card {
    background-color: transparent;
    border: 0;
    border-bottom: 1px solid var(--color-nhs-grey-4);
    border-radius: 0;
    box-shadow: none;
  }
  .flow-listgrid--list .flow-listgrid__card--link:hover {
    background-color: var(--color-nhs-grey-5);
    box-shadow: none;
    transform: none;
  }
  .flow-listgrid--list .flow-listgrid__content {
    padding: var(--space-sm) 0.25rem;
  }
  .flow-listgrid--list .flow-listgrid__title {
    color: var(--color-nhs-blue);
  }

  /* The CTA arrow answers hover with a 3px nudge — the same gesture the
     in-page nav uses, so the affordances feel related. Inline-block because a
     transform on an inline box is inert. */
  .flow-listgrid__cta::after {
    display: inline-block;
    transition: transform 0.2s ease;
  }
  .flow-listgrid__card--link:hover .flow-listgrid__cta::after {
    transform: translateX(3px);
  }
  @media (prefers-reduced-motion: reduce) {
    .flow-listgrid__cta::after,
    .flow-listgrid__card--link:hover .flow-listgrid__image {
      transition: none;
      transform: none;
    }
  }

  /* ── Stats widget — stat-card APPEARANCE (stats-as-list-collection-widget) ──
     LAYOUT (the responsive column grid + per-card span) lives in the flow-shared
     structural contract (`.flow-liststats*` + the `--liststats-*` custom props the
     SFC emits). This block owns only the figure CHROME + typography, keyed off
     `.flow-liststats--{variant}`. SFC markup, per resolved item:

       <li class="flow-liststats__card [flow-liststats__card--link]">
         <a|div class="flow-liststats__inner [flow-liststats__link]">
           <figure class="flow-liststats__figure">
             <img   class="flow-liststats__icon">           (optional)
             <span  class="flow-liststats__eyebrow">…</span>  (optional kicker)
             <p     class="flow-liststats__value">…title…</p> (the big figure)
             <figcaption class="flow-liststats__label">…bodyHtml…</figcaption>
           </figure>
         </a|div>
       </li>

     NHS ships TWO extra variants beyond the canonical `figures`: `bordered`
     (hairline card + soft shadow) and `plain` (chrome-free with vertical
     dividers). Centred figures with the NHS-blue value. */
  .flow-liststats__inner {
    display: flex;
    inline-size: 100%;
    color: var(--color-nhs-text);
    text-decoration: none;
  }
  .flow-liststats__figure {
    gap: 0.35rem;
    align-items: center;
    padding: var(--space-md);
  }
  .flow-liststats__icon {
    block-size: 2.5rem;
    inline-size: 2.5rem;
    object-fit: contain;
    margin-block-end: 0.25rem;
  }
  .flow-liststats__eyebrow {
    font-size: 0.75rem;
    font-weight: 700;
    line-height: 1.3;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--color-nhs-secondary-text);
  }
  .flow-liststats__value {
    margin: 0;
    font-size: 2.5rem;
    font-weight: 700;
    line-height: 1.05;
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
    color: var(--color-nhs-blue);
  }
  .flow-liststats__label {
    font-size: 0.9375rem;
    line-height: 1.4;
    color: var(--color-nhs-text);
  }
  .flow-liststats__label > :first-child { margin-top: 0; }
  .flow-liststats__label > :last-child { margin-bottom: 0; }

  /* Dark-surface flip — chrome-free figures (`figures`/`plain`) sit DIRECTLY on
     the section surface, so on a dark band their NHS-blue value + grey label fail
     contrast and disappear. TWO independent signals mark a dark band, and a
     chrome-free figure must honour BOTH:
       · `.flow-section--tone-light` — the author's explicit "Light text" content
         tone (the class headings ride). The `data-surface-tone` marker is NOT
         emitted for this case, so keying only on the marker missed it.
       · `[data-surface-tone="dark"]` — an AUTO-detected dark fill (Brand/Hero
         token, dark gradient role, or image overlay) with no explicit tone.
     Switch to the WCAG-AA-checked on-dark ink. `bordered` is the exception: it
     paints each figure on its own WHITE card, so it must KEEP the light-surface
     ink — re-asserted below at higher specificity (0,3,0). */
  .flow-section--tone-light .flow-liststats__value,
  [data-surface-tone="dark"] .flow-liststats__value { color: var(--flow-ink-emphasis-on-dark, #ffffff); }
  .flow-section--tone-light .flow-liststats__label,
  [data-surface-tone="dark"] .flow-liststats__label { color: var(--flow-fg-on-dark, #ffffff); }
  .flow-section--tone-light .flow-liststats__eyebrow,
  [data-surface-tone="dark"] .flow-liststats__eyebrow { color: var(--flow-ink-subtle-on-dark, #d8dde0); }
  .flow-section--tone-light .flow-liststats--carded .flow-liststats__value,
  [data-surface-tone="dark"] .flow-liststats--carded .flow-liststats__value { color: var(--color-nhs-blue); }
  .flow-section--tone-light .flow-liststats--carded .flow-liststats__label,
  [data-surface-tone="dark"] .flow-liststats--carded .flow-liststats__label { color: var(--color-nhs-text); }
  .flow-section--tone-light .flow-liststats--carded .flow-liststats__eyebrow,
  [data-surface-tone="dark"] .flow-liststats--carded .flow-liststats__eyebrow { color: var(--color-nhs-secondary-text); }

  /* A linked stat card warms on hover + shows the NHS focus ring. */
  .flow-liststats__card--link { cursor: pointer; border-radius: var(--radius-nhs); }
  .flow-liststats__card--link:hover { background-color: var(--color-nhs-grey-5); }
  .flow-liststats__card--link:has(.flow-liststats__link:focus-visible) {
    outline: 4px solid transparent !important;
    box-shadow: 0 0 0 4px var(--color-nhs-yellow), 0 0 0 8px var(--color-nhs-text) !important;
  }

  /* `bordered` — each figure sits in a hairline card with a soft shadow. */
  .flow-liststats--carded .flow-liststats__inner {
    background-color: var(--color-nhs-white);
    border: 1px solid var(--color-nhs-grey-4);
    border-radius: var(--radius-nhs);
    box-shadow: 0 1px 2px color-mix(in oklab, var(--color-nhs-black) 8%, transparent);
  }

  /* `plain` — chrome-free figures separated by vertical hairline dividers. */
  .flow-liststats--plain .flow-liststats__card + .flow-liststats__card .flow-liststats__inner {
    border-inline-start: 1px solid var(--color-nhs-grey-4);
  }

  /* ── Timeline widget — NHS skin (listtimeline-widget plan) ────────────────
     LAYOUT (the entry stack + marker/content columns + `gap`) ships in flow-shared
     structural.css (`.flow-listtimeline*`). The SKIN — marker rail, the marker
     TREATMENT (dot / CSS-`counter` number / avatar thumbnail), the vertical
     connecting LINE, and the per-entry accent — lives here, keyed off
     `.flow-listtimeline--{variant}`. Four variants (D-D): `dotted` (a coloured
     dot), `numbered` (a CSS-`counter` sequential number in place of the dot),
     `compact` (tighter rhythm + smaller dot), `avatar` (a round thumbnail from the
     item's image instead of the dot). The per-entry accent ink rides on the marker
     (→ dot via `currentColor`) AND the title (plan E).

     SFC markup, per entry: <li class="flow-listtimeline__entry">
       <div class="flow-listtimeline__marker [flow-ink-{accent}]">
         <span class="flow-listtimeline__dot"> <img class="flow-listtimeline__thumb">
       <a|div class="flow-listtimeline__content [flow-listtimeline__link]">
         <p class="flow-listtimeline__date"> <p class="flow-listtimeline__title [flow-ink-{accent}]">
         <div class="flow-listtimeline__blurb"> */
  .flow-listtimeline { --listtimeline-marker-gap: 1.1rem; }

  /* Marker rail — a fixed-width vertical column: the dot sits at the top and the
     connecting line is drawn beneath it. `color` is the DEFAULT marker ink, which
     a per-entry `flow-ink-{accent}` (specificity 0,2,0) overrides; the dot reads
     it via `currentColor`. */
  .flow-listtimeline__marker {
    flex-direction: column;
    justify-content: flex-start;
    inline-size: 1.75rem;
    padding-block-start: 0.2rem;
    color: var(--color-nhs-blue);
  }
  /* The connecting line — drawn on the marker from just below the dot down through
     the inter-entry gap to the next entry's dot. Hidden on the last entry. */
  .flow-listtimeline__marker::before {
    content: "";
    position: absolute;
    inset-block-start: 1.5rem;
    inset-block-end: calc(-1 * var(--listtimeline-gap, var(--space-lg)));
    inset-inline-start: 50%;
    inline-size: 2px;
    transform: translateX(-50%);
    background: var(--color-nhs-grey-4);
  }
  .flow-listtimeline__entry:last-child .flow-listtimeline__marker::before { display: none; }

  /* The dot — a filled disc that inherits the marker ink (so an accent tints it). */
  .flow-listtimeline__dot {
    inline-size: 0.85rem;
    block-size: 0.85rem;
    border-radius: 50%;
    background: currentColor;
    box-shadow: 0 0 0 4px color-mix(in srgb, currentColor 14%, transparent);
  }

  /* The thumbnail is hidden on every variant except `avatar`. */
  .flow-listtimeline__thumb { display: none; }

  /* Content typography — NHS blue date kicker, dark title, secondary blurb. */
  .flow-listtimeline__date {
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--color-nhs-secondary-text);
  }
  .flow-listtimeline__title {
    margin-block-start: 0.15rem;
    font-size: 1.1875rem;
    font-weight: 700;
    line-height: 1.3;
    color: var(--color-nhs-text);
  }
  .flow-listtimeline__blurb {
    margin-block-start: 0.35rem;
    font-size: 1rem;
    line-height: 1.5;
    color: var(--color-nhs-secondary-text);
  }
  .flow-listtimeline__link:hover .flow-listtimeline__title { text-decoration: underline; }
  .flow-listtimeline__link:focus-visible {
    outline: 4px solid transparent;
    box-shadow: 0 0 0 4px var(--color-nhs-yellow), 0 0 0 8px var(--color-nhs-text);
    border-radius: var(--radius-nhs);
  }

  /* Dark-surface flip — the timeline is chrome-free and sits DIRECTLY on the
     section surface, so its DEFAULT ink must follow the section foreground on a
     dark band; both dark signals are honoured (Lesson 114). A per-entry accent
     overrides this via the structural `[data-surface-tone="dark"] .flow-ink-{role}`
     rule (0,3,0), which beats these (0,2,0). */
  .flow-section--tone-light .flow-listtimeline__marker,
  [data-surface-tone="dark"] .flow-listtimeline__marker { color: var(--flow-ink-emphasis-on-dark, #ffffff); }
  .flow-section--tone-light .flow-listtimeline__marker::before,
  [data-surface-tone="dark"] .flow-listtimeline__marker::before { background: rgba(255, 255, 255, 0.3); }
  .flow-section--tone-light .flow-listtimeline__date,
  [data-surface-tone="dark"] .flow-listtimeline__date { color: var(--flow-ink-subtle-on-dark, #d8dde0); }
  .flow-section--tone-light .flow-listtimeline__title,
  [data-surface-tone="dark"] .flow-listtimeline__title { color: var(--flow-fg-on-dark, #ffffff); }
  .flow-section--tone-light .flow-listtimeline__blurb,
  [data-surface-tone="dark"] .flow-listtimeline__blurb { color: var(--flow-ink-subtle-on-dark, #d8dde0); }

  /* `numbered` — the dot becomes a CSS-`counter` sequential number: the <ol>
     resets the counter, each entry increments it, the dot renders it. */
  .flow-listtimeline--numbered { counter-reset: flow-timeline; }
  .flow-listtimeline--numbered .flow-listtimeline__entry { counter-increment: flow-timeline; }
  .flow-listtimeline--numbered .flow-listtimeline__marker { inline-size: 2.25rem; }
  .flow-listtimeline--numbered .flow-listtimeline__dot {
    inline-size: 1.85rem;
    block-size: 1.85rem;
    background: currentColor;
    box-shadow: none;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.8125rem;
    font-weight: 700;
    line-height: 1;
  }
  /* The number text is reverse-knockout white over the marker-ink disc; setting
     it on the ::before (not the dot) keeps the dot's `background: currentColor`
     reading the marker ink (so a per-entry accent still tints the disc). */
  .flow-listtimeline--numbered .flow-listtimeline__dot::before {
    content: counter(flow-timeline);
    color: var(--color-nhs-white);
  }
  .flow-listtimeline--numbered .flow-listtimeline__marker::before { inset-block-start: 2.45rem; }

  /* `numbered`, WIDE: the modern ProcessSteps treatment. On a desktop the
     steps of a process read better marching ACROSS the page than down it —
     the register / self-help designs lay them out as columns under large
     numbered badges, joined by a thin accent line that says "in this order".

     All of it is CSS over the canonical markup: the entries become equal grid
     columns, each entry stacks its own marker over its content, the badge
     grows to the design's 3rem disc with a paper ring to lift it off any
     band, and the connector is the entry's ::after — drawn from the badge's
     right edge into the neighbouring column, and not drawn at all on the
     last. The vertical rail (`__marker::before`) is suppressed; the
     horizontal line replaces it. Below 48rem none of this applies and the
     vertical timeline above remains exactly as it was. */
  @media (min-width: 48rem) {
    /* The variant class rides ON the list element itself (`<ul
       class="flow-listtimeline flow-listtimeline--numbered">`) — a descendant
       selector here matches nothing and the grid silently never happens,
       which is exactly how the first draft failed. (The `--compact` gap rule
       further down has the same descendant shape and is equally inert —
       noted for its own fix rather than smuggled into this one.) */
    .flow-listtimeline--numbered {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
      gap: var(--space-md);
    }
    .flow-listtimeline--numbered .flow-listtimeline__entry {
      flex-direction: column;
      gap: 1rem;
    }
    .flow-listtimeline--numbered .flow-listtimeline__marker {
      inline-size: 3rem;
    }
    .flow-listtimeline--numbered .flow-listtimeline__dot {
      inline-size: 3rem;
      block-size: 3rem;
      font-size: 1.25rem;
      box-shadow: 0 0 0 4px var(--color-surface);
    }
    .flow-listtimeline--numbered .flow-listtimeline__dot::before {
      font-size: 1.25rem;
    }
    /* No vertical rail in the horizontal layout… */
    .flow-listtimeline--numbered .flow-listtimeline__marker::before {
      display: none;
    }
    /* …the connector runs along the badge row instead. `--color-accent` is the
       brandable warm accent the modern design used for exactly this line. */
    .flow-listtimeline--numbered .flow-listtimeline__entry::after {
      content: "";
      position: absolute;
      inset-inline-start: 3.5rem;
      inset-inline-end: calc(-1 * var(--space-md));
      inset-block-start: 1.5rem;
      block-size: 2px;
      background: var(--color-accent, var(--color-nhs-grey-4));
      pointer-events: none;
    }
    .flow-listtimeline--numbered .flow-listtimeline__entry:last-child::after {
      display: none;
    }
  }

  /* `compact` — tighter rhythm + a smaller dot, for dense logs. */
  .flow-listtimeline--compact .flow-listtimeline { --listtimeline-marker-gap: 0.8rem; }
  .flow-listtimeline--compact .flow-listtimeline__marker { inline-size: 1.35rem; }
  .flow-listtimeline--compact .flow-listtimeline__dot { inline-size: 0.6rem; block-size: 0.6rem; box-shadow: none; }
  .flow-listtimeline--compact .flow-listtimeline__marker::before { inset-block-start: 1.05rem; }
  .flow-listtimeline--compact .flow-listtimeline__title { font-size: 1.0625rem; }
  .flow-listtimeline--compact .flow-listtimeline__blurb { font-size: 0.9375rem; margin-block-start: 0.25rem; }

  /* `avatar` — a round thumbnail replaces the dot (people / quotes). The dot is
     hidden only when the entry HAS a thumbnail, so an image-less entry keeps its
     dot. */
  .flow-listtimeline--avatar .flow-listtimeline__marker { inline-size: 3rem; }
  .flow-listtimeline--avatar .flow-listtimeline__entry:has(.flow-listtimeline__thumb) .flow-listtimeline__dot { display: none; }
  .flow-listtimeline--avatar .flow-listtimeline__thumb {
    display: block;
    inline-size: 2.5rem;
    block-size: 2.5rem;
    border-radius: 50%;
    object-fit: cover;
    box-shadow: 0 0 0 2px color-mix(in srgb, currentColor 30%, transparent);
  }
  .flow-listtimeline--avatar .flow-listtimeline__marker::before { inset-block-start: 3rem; }

  /* Placeholder (unbound list in the editor canvas). */
  .flow-listtimeline__placeholder {
    margin: 0;
    padding: 1.5rem;
    text-align: center;
    color: var(--color-nhs-secondary-text);
    font-style: italic;
  }

  /* ── List Accordion widget — panel APPEARANCE (Lists module Phase 5) ───
     LAYOUT + behaviour (the scripted open/close, height/opacity animation,
     ARIA wiring) live in the flow-shared SFC + structural contract. This
     block owns only the panel CHROME — group border + dividers, the header
     button skin, the chevron indicator (incl. expanded rotation), panel
     padding, and the focus ring — keyed to the NHS tokens. SFC markup:

       <div class="flow-listaccordion">
         <div class="flow-listaccordion__item">
           <h3 class="flow-listaccordion__heading">
             <button class="flow-listaccordion__header" aria-expanded="…"
                     aria-controls="…">
               <span class="flow-listaccordion__header-text">title</span>
               <span class="flow-listaccordion__chevron" aria-hidden="true"></span>
             </button>
           </h3>
           <div class="flow-listaccordion__panel" role="region">
             <div class="flow-listaccordion__panel-inner">…bodyHtml…</div>
           </div>
         </div>
       </div>

     The button carries `aria-expanded`; the open state is styled off that
     attribute so the chrome stays correct regardless of how the SFC tracks
     open/closed internally. */
  .flow-listaccordion {
    border: 1px solid var(--color-nhs-grey-4);
    border-radius: var(--radius-nhs);
    overflow: hidden;
    background-color: var(--color-nhs-white);
  }
  /* Divider between items (not above the first). */
  .flow-listaccordion__item + .flow-listaccordion__item {
    border-top: 1px solid var(--color-nhs-grey-4);
  }

  /* Variants (shared-list-variant-vocabulary). `panel` = each item a standalone
     bordered card, separated by a gap; `flush` = borderless, edge-to-edge, items
     parted only by the base hairline divider. The base box above is the neutral
     default; each variant re-skins it so the two read distinctly. */
  .flow-listaccordion--panel {
    border: 0;
    border-radius: 0;
    background-color: transparent;
    overflow: visible;
  }
  .flow-listaccordion--panel .flow-listaccordion__item {
    border: 1px solid var(--color-nhs-grey-4);
    border-radius: var(--radius-nhs);
    background-color: var(--color-nhs-white);
    overflow: hidden;
  }
  .flow-listaccordion--panel .flow-listaccordion__item + .flow-listaccordion__item {
    margin-top: var(--space-sm);
  }
  .flow-listaccordion--flush {
    border: 0;
    border-radius: 0;
    background-color: transparent;
  }

  .flow-listaccordion__heading { margin: 0; }

  .flow-listaccordion__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    width: 100%;
    padding: var(--space-sm) var(--space-sm);
    background-color: transparent;
    border: 0;
    font-family: inherit;
    font-size: 1.125rem;
    font-weight: 700;
    line-height: 1.3;
    text-align: start;
    color: var(--color-nhs-blue);
    cursor: pointer;
    transition: background-color 0.15s ease, color 0.15s ease;
  }
  /* The NHS.UK expander's signature open state: a 4px blue rule down the
     item's leading edge (NhsDetails carried exactly this). Keyed off the
     button's aria-expanded via :has(), so the accessible state and the visual
     state cannot disagree. */
  .flow-listaccordion__item:has(> .flow-listaccordion__heading > .flow-listaccordion__header[aria-expanded="true"]) {
    border-inline-start: 4px solid var(--color-nhs-blue);
  }

  .flow-listaccordion__header:hover {
    background-color: var(--color-nhs-grey-5);
    text-decoration: underline;
  }
  /* Expanded header reads as the active panel: ink-coloured, grey rail. */
  .flow-listaccordion__header[aria-expanded="true"] {
    color: var(--color-nhs-text);
    background-color: var(--color-nhs-grey-5);
  }
  /* NHS yellow focus state — beats the global button:focus-visible skin. */
  .flow-listaccordion__header:focus-visible {
    outline: 4px solid transparent !important;
    outline-offset: 0 !important;
    background-color: var(--color-nhs-yellow) !important;
    color: var(--color-nhs-text) !important;
    box-shadow: 0 -2px var(--color-nhs-yellow), 0 4px var(--color-nhs-text) !important;
    text-decoration: none !important;
  }

  .flow-listaccordion__header-text { flex: 1 1 auto; min-width: 0; }

  /* Chevron indicator — a CSS-drawn caret that rotates on expand. Decorative
     (the SFC marks it aria-hidden); state comes from the button's
     aria-expanded so it stays in sync with the accessible state. */
  .flow-listaccordion__chevron {
    flex: 0 0 auto;
    width: 0.8rem;
    height: 0.8rem;
    margin-inline-start: 0.5rem;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: rotate(45deg);
    transition: transform 0.2s ease;
  }
  .flow-listaccordion__header[aria-expanded="true"] .flow-listaccordion__chevron {
    transform: rotate(225deg);
  }

  /* Panel body — a flex row (structural) so an image sits as a small thumbnail
     beside the answer. The theme owns padding + the thumbnail's rounded frame
     and the text-column typography. */
  .flow-listaccordion__panel-inner {
    padding: var(--space-sm) var(--space-md) var(--space-md);
    color: var(--color-nhs-text);
    font-size: 1rem;
    line-height: 1.5;
  }
  /* Thumbnail — rounded frame on a tinted placeholder; sized + cropped by the
     structural rule (clamp width + `--flow-list-image-aspect` + cover). */
  .flow-listaccordion__image {
    border-radius: var(--radius-nhs);
    background-color: var(--color-nhs-grey-5);
  }
  .flow-listaccordion__body > :first-child { margin-top: 0; }
  .flow-listaccordion__body > :last-child { margin-bottom: 0; }
  /* In-answer link reads as the standard NHS text link. */
  .flow-listaccordion__link {
    font-weight: 700;
    color: var(--color-nhs-blue);
    text-decoration: underline;
  }
  .flow-listaccordion__link:hover { color: var(--color-nhs-blue-dark, var(--color-nhs-blue)); }

  /* ── Content token block widget — structured display (content-tokens plan
     DD5 / §7.3) ─────────────────────────────────────────────────────────
     flow-shared owns the STRUCTURE (an <address> of stacked lines, a weekday
     <table>, a scalar <p>, or the `[label]` fallback <p>); this block owns
     only APPEARANCE, keyed to the NHS tokens. The INLINE `flow-token` span is
     semantics-only and is deliberately NOT skinned — it inherits the
     surrounding text. Emitted markup (flow-shared Token.vue):

       <div class="flow-token-block">
         <address class="flow-token-block__address">
           <span class="flow-token-block__line">…</span>
         </address>
         — or —
         <table class="flow-token-block__hours"><tbody>
           <tr class="flow-token-block__hours-row">
             <th class="flow-token-block__day">Monday</th>
             <td class="flow-token-block__times">09:00–17:30</td>
           </tr>
         </tbody></table>
         — or —
         <p class="flow-token-block__text">…</p>
         — or —
         <p class="flow-token-block__fallback">[Label]</p>
       </div> */
  .flow-token-block {
    color: var(--color-nhs-text);
    font-size: 1rem;
    line-height: 1.5;
  }

  /* Postal address — stacked lines; reset the browser's italic <address>. */
  .flow-token-block__address {
    font-style: normal;
    display: flex;
    flex-direction: column;
  }
  .flow-token-block__line { display: block; }

  /* Opening hours — a compact two-column weekday table. */
  .flow-token-block__hours {
    border-collapse: collapse;
    inline-size: auto;
    text-align: start;
  }
  .flow-token-block__hours-row + .flow-token-block__hours-row .flow-token-block__day,
  .flow-token-block__hours-row + .flow-token-block__hours-row .flow-token-block__times {
    border-top: 1px solid var(--color-nhs-grey-4);
  }
  .flow-token-block__day {
    padding: 0.35rem 1.25rem 0.35rem 0;
    font-weight: 700;
    text-align: start;
    color: var(--color-nhs-text);
  }
  .flow-token-block__times {
    padding: 0.35rem 0;
    color: var(--color-nhs-secondary-text);
    font-variant-numeric: tabular-nums;
  }
  .flow-token-block__times--closed {
    font-style: italic;
    color: var(--color-nhs-secondary-text);
  }

  /* Scalar token — plain paragraph, no margin drift inside a block slot. */
  .flow-token-block__text { margin: 0; }

  /* Unresolved reference — muted so an unfilled token reads as a placeholder. */
  .flow-token-block__fallback {
    margin: 0;
    font-style: italic;
    color: var(--color-nhs-secondary-text);
  }

  /* Dark-surface flip — the block sits DIRECTLY on the section surface, so its
     ink follows the section foreground on a dark band (both dark signals
     honoured, Lesson 114). */
  .flow-section--tone-light .flow-token-block,
  [data-surface-tone="dark"] .flow-token-block { color: var(--flow-fg-on-dark, #ffffff); }
  .flow-section--tone-light .flow-token-block__day,
  [data-surface-tone="dark"] .flow-token-block__day { color: var(--flow-fg-on-dark, #ffffff); }
  .flow-section--tone-light .flow-token-block__times,
  .flow-section--tone-light .flow-token-block__times--closed,
  .flow-section--tone-light .flow-token-block__fallback,
  [data-surface-tone="dark"] .flow-token-block__times,
  [data-surface-tone="dark"] .flow-token-block__times--closed,
  [data-surface-tone="dark"] .flow-token-block__fallback { color: var(--flow-ink-subtle-on-dark, #d8dde0); }
  .flow-section--tone-light .flow-token-block__hours-row + .flow-token-block__hours-row .flow-token-block__day,
  .flow-section--tone-light .flow-token-block__hours-row + .flow-token-block__hours-row .flow-token-block__times,
  [data-surface-tone="dark"] .flow-token-block__hours-row + .flow-token-block__hours-row .flow-token-block__day,
  [data-surface-tone="dark"] .flow-token-block__hours-row + .flow-token-block__hours-row .flow-token-block__times {
    border-top-color: rgba(255, 255, 255, 0.3);
  }

  /* ── Navigation widget + chrome nav (Navigation module plan §5) ────────
     Skins the SHARED flow-shared NavRenderer.vue class hooks — the same
     component renders BOTH the page-editor `navigationmenu` widget AND the
     theme chrome nav slots, so these rules cover both placements inside
     `.theme-canvas`. NavRenderer owns target dispatch + link security; the
     theme owns ONLY appearance. Emitted markup (RESOLVED tree, recursive):

       <ul class="flow-nav flow-nav--horizontal|--vertical">
         <li class="flow-nav__item">
           <!-- leaf / flat-nested -->
           <a|Link class="flow-nav__link">label</a>   (page / external)
           <span class="flow-nav__label">label</span>  (none / rejected)
           <ul class="flow-nav__nested …">…children…</ul>   (flat degrade)
           <!-- panel-opening (supported display) -->
           <button class="flow-nav__trigger" aria-expanded …>
             <span class="flow-nav__trigger-text">label</span>
             <span class="flow-nav__chevron" aria-hidden></span>
           </button>
           <div class="flow-nav__panel flow-nav__panel--dropdown" role="region"
                [hidden]>…nested NavRenderer…</div>
         </li>
       </ul>

     The supports handshake (manifest `navigationSlots`) decides whether a
     child node opens a `flow-nav__panel` or degrades to a flat
     `flow-nav__nested` list — so BOTH presentations must read acceptably here.
     MEGA IS DEFERRED: `flow-nav__panel--mega` / `flow-nav__column*` /
     `flow-nav__cards` are intentionally NOT styled this phase (no slot
     advertises 'mega', so the renderer never emits them). The unsupported
     path degrades to `flow-nav__nested`, which is styled below. */

  /* Reset list chrome on every nav level (the renderer recurses through
     `<ul>`s — nested lists must not inherit browser bullets/indent). */
  .flow-nav,
  .flow-nav__nested {
    list-style: none;
    margin: 0;
    padding: 0;
  }
  .flow-nav__item { margin: 0; }

  /* Links + labels — generous hit targets (>= 44px tall via padding + the
     1.5 line-height), NHS-blue ink, underline reserved for hover so the bar
     reads as chrome rather than body copy. */
  .flow-nav__link,
  .flow-nav__label,
  .flow-nav__trigger {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.625rem 0.75rem;
    font-weight: 700;
    line-height: 1.5;
    color: var(--color-nhs-blue);
    text-decoration: none;
    border-radius: var(--radius-nhs);
  }
  /* A `none`-target label is a non-interactive heading — ink-coloured, not a
     link affordance. */
  .flow-nav__label {
    color: var(--color-nhs-text);
    cursor: default;
  }
  .flow-nav__link:hover {
    text-decoration: underline;
    text-decoration-thickness: 2px;
    text-underline-offset: 2px;
    background-color: var(--color-nhs-grey-5);
  }

  /* Disclosure trigger — a button styled to match the links beside it, with a
     CSS chevron that rotates when its panel is open. The whole control is a
     comfortable tap target. */
  .flow-nav__trigger {
    width: 100%;
    justify-content: space-between;
    background-color: transparent;
    border: 0;
    font-family: inherit;
    font-size: inherit;
    cursor: pointer;
    transition: background-color 0.15s ease, color 0.15s ease;
  }
  .flow-nav__trigger:hover {
    background-color: var(--color-nhs-grey-5);
    text-decoration: underline;
    text-decoration-thickness: 2px;
    text-underline-offset: 2px;
  }
  .flow-nav__trigger[aria-expanded="true"] {
    color: var(--color-nhs-text);
    background-color: var(--color-nhs-grey-5);
  }
  .flow-nav__trigger-text { min-width: 0; }

  /* Chevron — a CSS-drawn caret pointing down, flipping to up when expanded.
     Decorative (the renderer marks it aria-hidden). */
  .flow-nav__chevron {
    flex: 0 0 auto;
    width: 0.5rem;
    height: 0.5rem;
    margin-inline-start: 0.5rem;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: rotate(45deg);
    transition: transform 0.2s ease;
  }
  .flow-nav__trigger[aria-expanded="true"] .flow-nav__chevron {
    transform: rotate(225deg);
  }

  /* NHS yellow focus state — beats the global a/button:focus-visible skin. */
  .flow-nav__link:focus-visible,
  .flow-nav__trigger:focus-visible {
    outline: 4px solid transparent !important;
    outline-offset: 0 !important;
    background-color: var(--color-nhs-yellow) !important;
    color: var(--color-nhs-text) !important;
    box-shadow: 0 -2px var(--color-nhs-yellow), 0 4px var(--color-nhs-text) !important;
    text-decoration: none !important;
  }

  /* ── Horizontal placement — the header-style site-nav bar ──────────────
     A single row of top-level items; only the FIRST level is horizontal —
     nested lists + open dropdown panels stack vertically. */
  .flow-nav--horizontal {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.25rem;
  }
  /* A top-level item anchors its dropdown panel (absolute overlay on the bar). */
  .flow-nav--horizontal > .flow-nav__item { position: relative; }

  /* The disclosure panel overlays the bar from the left edge of its item. */
  .flow-nav--horizontal > .flow-nav__item > .flow-nav__panel {
    position: absolute;
    inset-inline-start: 0;
    inset-block-start: 100%;
    z-index: 50;
    min-width: 14rem;
  }

  /* ── Vertical placement — stacked sidebar / footer columns ─────────────
     The default orientation. Items stack; nested lists indent under their
     parent. The footer slot (supports: []) lands here — every node degrades
     to a `flow-nav__nested` list, giving the footer its native column tree. */
  .flow-nav--vertical {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
  }

  /* ── Dropdown panel chrome ─────────────────────────────────────────────
     A bordered, raised card. `[hidden]` (the renderer's closed state) keeps it
     out of the flow; open, it shows the nested NavRenderer list. On the
     vertical placement it reads as an inline expanding sub-list rather than an
     overlay. */
  .flow-nav__panel {
    background-color: var(--color-nhs-white);
    border: 1px solid var(--color-nhs-grey-4);
    border-top: 4px solid var(--color-nhs-blue);
    border-radius: var(--radius-nhs);
    box-shadow: 0 6px 16px color-mix(in oklab, var(--color-nhs-black) 14%, transparent);
    padding: 0.5rem;
  }
  .flow-nav__panel[hidden] { display: none; }
  /* On the vertical bar the panel is an inline sub-list — no overlay, no raise. */
  .flow-nav--vertical .flow-nav__panel {
    margin-inline-start: 1rem;
    box-shadow: none;
    border-top-width: 1px;
  }

  /* ── Flat-nested degradation ───────────────────────────────────────────
     A node with children whose display the slot does NOT support (or
     `display:'link'` with children) renders its children as a plain nested
     list under the parent's own link. Indent + a subtle rail keep the
     hierarchy legible even without a panel — this is the footer's normal
     layout AND the graceful fallback for an unsupported mega/dropdown. */
  .flow-nav__nested {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    margin-inline-start: 1rem;
    padding-inline-start: 0.5rem;
    border-inline-start: 2px solid var(--color-nhs-grey-4);
  }

  /* ══ Chrome navigation — header dropdown + footer columns ════════════════
     The header and footer bars are solid NHS blue, so the bound chrome nav
     uses WHITE ink (the base blue ink above suits the page `navigationmenu`
     widget on light pages). Scoped to `.flow-header-nav` / `.flow-footer-nav`
     wrappers (chrome/SiteHeader.vue + SiteFooter.vue) so the page-widget nav is
     untouched. Design language: SOLID surfaces, a warm-yellow brand accent, a
     confident NHS-blue-tinted elevation, and purposeful micro-motion — no
     translucency / backdrop blur. */

  /* ── Header: white ink on the blue bar (pill hover + active states) ──── */
  .flow-header-nav .flow-nav__link,
  .flow-header-nav .flow-nav__label,
  .flow-header-nav .flow-nav__trigger {
    color: var(--color-nhs-white);
    font-weight: 600;
    border-radius: 9999px;
    transition: background-color 0.15s ease, color 0.15s ease;
  }
  .flow-header-nav .flow-nav__link:hover,
  .flow-header-nav .flow-nav__trigger:hover {
    color: var(--color-nhs-white);
    background-color: color-mix(in oklab, var(--color-nhs-white) 15%, transparent);
    text-decoration: none;
  }
  .flow-header-nav .flow-nav__trigger[aria-expanded="true"] {
    color: var(--color-nhs-white);
    background-color: color-mix(in oklab, var(--color-nhs-white) 22%, transparent);
  }

  /* ── Header: dropdown panel — a crisp white card with a warm-yellow accent
     edge and a soft, NHS-blue-tinted elevation (overlays the page content). */
  .flow-header-nav .flow-nav--horizontal > .flow-nav__item > .flow-nav__panel {
    margin-block-start: 0.625rem;
    min-width: 15rem;
    padding: 0.5rem;
    border: 1px solid color-mix(in oklab, var(--color-nhs-blue) 12%, var(--color-nhs-white));
    border-top: 3px solid var(--color-nhs-warm-yellow, var(--color-nhs-blue));
    border-radius: calc(var(--radius-nhs) * 1.75);
    background: var(--color-nhs-white);
    box-shadow:
      0 4px 8px -4px color-mix(in oklab, var(--color-nhs-blue) 22%, transparent),
      0 22px 48px -16px color-mix(in oklab, var(--color-nhs-blue) 42%, transparent);
  }
  /* Reveal on open (progressive — instant where discrete transitions are
     unsupported; suppressed under reduced-motion below). */
  @supports (transition-behavior: allow-discrete) {
    .flow-header-nav .flow-nav--horizontal > .flow-nav__item > .flow-nav__panel {
      transition:
        opacity 0.18s ease,
        transform 0.18s ease,
        display 0.18s allow-discrete,
        overlay 0.18s allow-discrete;
    }
    .flow-header-nav .flow-nav--horizontal > .flow-nav__item > .flow-nav__panel:not([hidden]) {
      opacity: 1;
      transform: translateY(0);
    }
    @starting-style {
      .flow-header-nav .flow-nav--horizontal > .flow-nav__item > .flow-nav__panel:not([hidden]) {
        opacity: 0;
        transform: translateY(-0.5rem);
      }
    }
  }
  /* Dropdown links — dark ink rows; on hover a warm-yellow accent slides in
     from the left and the label nudges across. */
  .flow-header-nav .flow-nav__panel .flow-nav__link,
  .flow-header-nav .flow-nav__panel .flow-nav__label {
    display: block;
    padding: 0.5rem 0.875rem;
    border-radius: var(--radius-nhs);
    font-weight: 600;
    color: var(--color-nhs-blue);
    box-shadow: inset 0 0 0 0 var(--color-nhs-warm-yellow, var(--color-nhs-blue));
    transition: background-color 0.15s ease, box-shadow 0.15s ease, padding-inline-start 0.15s ease;
  }
  .flow-header-nav .flow-nav__panel .flow-nav__label {
    color: var(--color-nhs-text);
    font-weight: 700;
  }
  .flow-header-nav .flow-nav__panel .flow-nav__link:hover {
    color: var(--color-nhs-blue);
    background-color: color-mix(in oklab, var(--color-nhs-blue) 7%, var(--color-nhs-white));
    box-shadow: inset 3px 0 0 0 var(--color-nhs-warm-yellow, var(--color-nhs-blue));
    padding-inline-start: 1.125rem;
    text-decoration: none;
  }

  /* ── Footer: clean columns — accent-underlined heading + link list ───────
     No panel, no translucency. The footer slot's `supports: []` degrades each
     group to a nested list (NavRenderer recurses with a `flow-nav__nested` list
     that ALSO carries `flow-nav--vertical`), so the grid + heading rules are
     scoped to the ROOT list's DIRECT children
     (`.flow-footer-nav > .flow-nav--vertical > .flow-nav__item`) — the nested
     recursion is never restyled. */
  .flow-footer-nav > .flow-nav--vertical {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
    gap: 2rem 2.5rem;
    align-items: start;
  }
  .flow-footer-nav > .flow-nav--vertical > .flow-nav__item {
    min-width: 0;
  }
  /* Column heading — the top-level item's own link / label, underlined with a
     thin brand rule (ROOT level only). */
  .flow-footer-nav > .flow-nav--vertical > .flow-nav__item > .flow-nav__link,
  .flow-footer-nav > .flow-nav--vertical > .flow-nav__item > .flow-nav__label,
  .flow-footer-nav > .flow-nav--vertical > .flow-nav__item > .flow-nav__trigger {
    display: block;
    margin: 0 0 0.875rem;
    padding: 0 0 0.625rem;
    border-bottom: 1px solid color-mix(in oklab, var(--color-nhs-white) 16%, transparent);
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--color-nhs-warm-yellow, var(--color-nhs-white));
  }
  .flow-footer-nav > .flow-nav--vertical > .flow-nav__item > .flow-nav__link:hover {
    color: var(--color-nhs-white);
    background: transparent;
    text-decoration: none;
  }
  /* Column items — clean white links that nudge across on hover. */
  .flow-footer-nav .flow-nav__nested {
    margin-inline-start: 0;
    padding-inline-start: 0;
    border-inline-start: 0;
    gap: 0;
  }
  .flow-footer-nav .flow-nav__nested .flow-nav__link,
  .flow-footer-nav .flow-nav__nested .flow-nav__label {
    padding: 0.375rem 0;
    font-weight: 400;
    color: color-mix(in oklab, var(--color-nhs-white) 82%, transparent);
    transition: color 0.15s ease, transform 0.15s ease;
  }
  .flow-footer-nav .flow-nav__nested .flow-nav__link:hover {
    color: var(--color-nhs-white);
    background: transparent;
    text-decoration: none;
    transform: translateX(3px);
  }

  /* Honour reduced-motion — drop the dropdown reveal transition. */
  @media (prefers-reduced-motion: reduce) {
    .flow-header-nav .flow-nav--horizontal > .flow-nav__item > .flow-nav__panel {
      transition: none;
    }
  }

  /* Skip link — paired with chrome/SkipLink.vue. */
  .nhs-skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    padding: 12px 16px;
    background: var(--color-nhs-yellow);
    color: var(--color-nhs-text);
    font-weight: 700;
    z-index: 1000;
    text-decoration: underline;
  }
  .nhs-skip-link:focus { left: 0; outline: 4px solid var(--color-nhs-yellow); }

  /* ── Block spacing (Pages v2 element spacing — Layer 1 + Layer 2) ──────
     Two-layer vertical rhythm for stacked blocks. NO new markup: the rules
     target the existing block-boundary element (the widget root on the front,
     the `.flow-block` chrome wrapper in the editor — both are the direct
     child of `.flow-section__inner`).

     SOURCE ORDER IS LOAD-BEARING: the widget-root resets above zero margins
     via shorthand (`.flow-heading { margin: 0 }`, `.flow-divider--line
     { margin: 0 }`) at the same specificity (0,1,0) as `.flow-section__inner
     > *`. These rules MUST stay after those resets so the rhythm wins on
     source order — and before the trailing responsive @container so the
     <640px step-downs below can override the two largest tokens. */

  /* Layer 1 — default rhythm (uniform --space-md between top-level blocks). */
  .flow-section__inner > * { margin-block-end: var(--space-md); }
  .flow-section__inner > :last-child { margin-block-end: 0; }
  .flow-row > * { margin-block-end: 0; }

  /* Layer 1 (columns) — a `.flow-column` slot stacks its blocks with the same
     default rhythm. Blocks in a column are direct children of `.flow-column`
     (not `.flow-section__inner`), so they need their own rhythm pair, at the
     same (0,1,0) specificity as the widget-root `margin: 0` resets above — kept
     after them so source order wins. Layer 2 `.flow-block--mb-*` `!important`
     below still overrides per block; the last child clears the trailing gap. */
  .flow-column > * { margin-block-end: var(--space-md); }
  .flow-column > :last-child { margin-block-end: 0; }

  /* Layer 2 — the authorable per-block "Space below" override
     (`.flow-block--mb-*`) lives in the STRUCTURAL CONTRACT
     (@treeviewdesigns/flow-shared structural.css, concatenated ahead of this
     file by the build's emitTokensCss plugin). The values stay theme-owned
     via the `--space-*` tokens above; the narrow-surface remap below stays
     authored here and wins on source order. */

  /* ── Block width + alignment ──────────────────────────────────────────
     MOVED to the structural contract (flow-shared structural.css) — the
     `flow-block--w-*` / `flow-block--a-*` behaviour rules, the button pair
     rules (canonical `.flow-button` hooks; the override keeps the canonical
     classes per the D-C convention), the fill dual semantic, and the
     text-widget text-align rules all ship there so every theme behaves
     identically. Do NOT re-add behaviour rules here — authored CSS after
     the contract is for deliberate per-theme overrides only. */

  /* ── The index as a COLUMN beside the content (`left` / `right`) ──────────
     What the original designs did: `<aside class="lg:col-span-3 lg:sticky">`
     beside a nine-column content well.

     Flow cannot express that by wrapping the document in a grid — a page is a
     stack of full-width sections and some are deliberately full-bleed, which is
     exactly the wall `chrome.pageGroupLayout` hit before it was retired. So the
     column is made the other way round: the index band goes STICKY and
     ZERO-HEIGHT, which takes it out of the flow entirely, and the contained
     sections that follow give up the width it needs. Full-bleed sections are
     untouched, because the reservation is padding on `.flow-section__inner`
     rather than a grid around everything.

     Reaching those sections from the band is possible because `WidgetRenderer`
     wraps them in `.flow-document`, a sibling of the band — hence `~`.

     Below the breakpoint there is no room to give and the request is declined:
     the band reverts to its in-flow contents-list behaviour, which is the
     honest answer on a phone rather than a 16rem column squeezing the content
     to nothing. */
  /* Declared at the THEME ROOT, not on the band. Custom properties inherit
     DOWN the tree, and the content sections are the band's SIBLINGS — so a
     value set on the band never reaches them, the `calc()` below becomes
     invalid at computed-value time, and padding silently resolves to 0 rather
     than to the fallback. The symptom is the index sitting on top of the text.
     Measured, not eyeballed: a screenshot of that failure looks plausible. */
  :scope {
    --nhs-index-column: 15rem;
    --nhs-index-gap: 3rem;
  }

  @media (min-width: 64rem) {
    /* `:has(~ .flow-document)` keys these rules to the FRONT's structure, where
       the band is a SIBLING placed before the document. In the editor canvas
       the band is a CHILD of `.flow-document`, so without this guard the
       sticky/zero-height pair would collapse the index over the canvas's first
       section — the reservation could never leak there (its `~` combinator
       cannot match a parent), but the band's own rules could and did. */
    .flow-section-nav-slot:has(.flow-section-nav--left):has(~ .flow-document),
    .flow-section-nav-slot:has(.flow-section-nav--right):has(~ .flow-document) {
      position: sticky;
      top: var(--flow-anchor-offset, 6rem);
      /* Zero height is what keeps the index out of the flow: the band occupies
         no vertical space, so the content starts at the top of the page as it
         would with no index at all. */
      height: 0;
      z-index: 4;
      padding-block: 0;
      overflow: visible;
    }

    .flow-section-nav-slot:has(.flow-section-nav--left):has(~ .flow-document) .flow-section-nav,
    .flow-section-nav-slot:has(.flow-section-nav--right):has(~ .flow-document) .flow-section-nav {
      width: var(--nhs-index-column);
      max-width: var(--nhs-index-column);
      /* The band is a contained section, so its inner already sits at the
         content column's edges — the index lands exactly where the content
         used to start, which is the point. */
      padding-block-start: 0.35rem;
    }

    .flow-section-nav-slot:has(.flow-section-nav--right):has(~ .flow-document) .flow-section-nav {
      margin-inline-start: auto;
    }

    /* The reservation. Includes the gutter because `.flow-section__inner`
       already carries `padding-inline` and this replaces one side of it. */
    .flow-section-nav-slot:has(.flow-section-nav--left) ~ .flow-document
      .flow-section--width-contained .flow-section__inner {
      padding-inline-start: calc(var(--container-gutter, 1.5rem) + var(--nhs-index-column) + var(--nhs-index-gap));
    }

    .flow-section-nav-slot:has(.flow-section-nav--right) ~ .flow-document
      .flow-section--width-contained .flow-section__inner {
      padding-inline-end: calc(var(--container-gutter, 1.5rem) + var(--nhs-index-column) + var(--nhs-index-gap));
    }
  }

  /* ── In-page navigation widgets (navigationmenu + pagegroupnav) ───────────
     Both shipped UNSKINNED: zero rules, so a navigation an author dropped into
     a page rendered as the bare `flow-nav` silhouette with no NHS character at
     all. The header and footer chrome carry their own nav styling, but that is
     scoped to the chrome — a nav placed IN the page inherited none of it.

     NHS reads a list of links plainly and at size: underlines on hover (the NHS
     Design System underlines its links), hairline-separated rows, and hit areas
     that clear the 44px target guidance rather than the tight rows a desktop
     menu can get away with.

     TONE SAFETY: no colour is pinned. Hairlines mix from `currentColor`, which
     structural.css has already lifted on a dark band, and the accent is the
     brandable emphasis ink with its on-dark twin — NHS blue on white, white on
     NHS blue. */
  .flow-navigationmenu-widget,
  .flow-pagegroupnav-widget {
    --nhs-nav-ink: var(--flow-ink-emphasis, currentColor);
    font-family: var(--font-sans);
  }
  [data-surface-tone="dark"] .flow-navigationmenu-widget,
  [data-surface-tone="dark"] .flow-pagegroupnav-widget,
  .flow-section--tone-light .flow-navigationmenu-widget,
  .flow-section--tone-light .flow-pagegroupnav-widget {
    --nhs-nav-ink: var(--flow-ink-emphasis-on-dark, var(--flow-ink-emphasis, currentColor));
  }

  .flow-navigationmenu-widget .flow-nav__link,
  .flow-pagegroupnav-widget .flow-nav__link {
    color: var(--nhs-nav-ink);
    text-decoration: none;
  }
  .flow-navigationmenu-widget .flow-nav__link:hover,
  .flow-pagegroupnav-widget .flow-nav__link:hover {
    /* Keep the surface visible: the generic pale navigation hover ground
       cannot be paired with the on-dark ink used by these widgets. */
    background-color: transparent;
    text-decoration: underline;
    text-underline-offset: 3px;
    text-decoration-thickness: 2px;
  }

  /* Vertical — a hairline index. Rows are generously tall: this is a page-level
     list a patient reads and taps, not a dense desktop menu. */
  .flow-navigationmenu-widget > .flow-nav--vertical,
  .flow-pagegroupnav-widget > .flow-nav--vertical {
    max-width: 28rem;
    border-top: 1px solid color-mix(in srgb, currentColor 20%, transparent);
  }
  .flow-navigationmenu-widget > .flow-nav--vertical > .flow-nav__item,
  .flow-pagegroupnav-widget > .flow-nav--vertical > .flow-nav__item {
    border-bottom: 1px solid color-mix(in srgb, currentColor 20%, transparent);
  }
  .flow-navigationmenu-widget .flow-nav--vertical .flow-nav__link,
  .flow-navigationmenu-widget .flow-nav--vertical .flow-nav__label,
  .flow-navigationmenu-widget .flow-nav--vertical .flow-nav__trigger,
  .flow-pagegroupnav-widget .flow-nav--vertical .flow-nav__link,
  .flow-pagegroupnav-widget .flow-nav--vertical .flow-nav__label,
  .flow-pagegroupnav-widget .flow-nav--vertical .flow-nav__trigger {
    display: block;
    padding: 0.85rem 0.25rem;
    border-radius: 0;
    font-size: 1rem;
    font-weight: 600;
    line-height: 1.4;
  }

  /* A label is a non-navigable heading row — quieter, and it must not suggest
     it can be tapped. */
  .flow-navigationmenu-widget .flow-nav--vertical .flow-nav__label,
  .flow-pagegroupnav-widget .flow-nav--vertical .flow-nav__label {
    color: color-mix(in srgb, var(--nhs-nav-ink, currentColor) 78%, transparent);
    font-weight: 700;
    text-transform: none;
  }

  /* Children indent under their parent behind a rule, so the hierarchy is
     readable without relying on indentation alone. */
  .flow-navigationmenu-widget .flow-nav__nested,
  .flow-pagegroupnav-widget .flow-nav__nested {
    padding: 0.1rem 0 0.5rem 1rem;
    margin-inline-start: 0.25rem;
    border-inline-start: 1px solid color-mix(in srgb, currentColor 20%, transparent);
  }
  .flow-navigationmenu-widget .flow-nav__nested .flow-nav__link,
  .flow-pagegroupnav-widget .flow-nav__nested .flow-nav__link {
    padding: 0.55rem 0.25rem;
    font-size: 0.9375rem;
    font-weight: 400;
  }

  /* Horizontal — a grounded strip. No hover nudge: shifting one item shoves
     its neighbours along the row. */
  .flow-navigationmenu-widget > .flow-nav--horizontal,
  .flow-pagegroupnav-widget > .flow-nav--horizontal {
    gap: 0.25rem 1.5rem;
    padding-bottom: 0.7rem;
    border-bottom: 1px solid color-mix(in srgb, currentColor 20%, transparent);
  }
  .flow-navigationmenu-widget .flow-nav--horizontal .flow-nav__link,
  .flow-pagegroupnav-widget .flow-nav--horizontal .flow-nav__link {
    padding: 0.5rem 0.15rem;
    font-size: 1rem;
    font-weight: 600;
  }

  /* The editor's "nothing bound yet" state — visible enough to explain itself,
     quiet enough not to look like content. */
  .flow-navigationmenu__placeholder,
  .flow-pagegroupnav__placeholder {
    padding: 0.75rem 1rem;
    border: 1px dashed color-mix(in srgb, currentColor 35%, transparent);
    border-radius: var(--radius-nhs);
    font-size: 0.9375rem;
    font-style: italic;
    color: color-mix(in srgb, currentColor 70%, transparent);
  }

  /* ── Callout — the NHS care-card family (13/16 → skinned) ─────────────────
     The canonical callout shipped UNSKINNED in this theme: `.flow-callout` had
     no rules at all, so an author's callout rendered as bare paragraphs,
     indistinguishable from body copy. On a GP site that is the widget carrying
     "call 111", "bring photo ID", "do not attend if infectious" — the content
     that most needs to stand out.

     The four canonical variants take the four NHS shapes, WITHOUT inventing
     copy: NHS care cards carry an eyebrow ("Non-urgent advice") tied to a
     severity vocabulary the canonical widget does not have, and generating that
     text over an author's callout would put words in their mouth. So the visual
     language carries the meaning and the author's own words stay theirs.

       note  → inset text: a blue rule down the side, quietest of the four
       info  → care card: full blue border with the title as a filled header bar
       do    → green rule + tick
       dont  → red rule + cross

     INK IS PINNED HERE ON PURPOSE, against the usual rule. A callout paints its
     OWN white ground, so it no longer inherits the band's foreground — on a
     dark section, inherited (lifted) light text would land white-on-white. The
     Lumen pearl-panel bug was the opposite case: ink pinned on a panel that did
     NOT own its ground. Owning the ground is what earns the right to own the
     ink. */
  .flow-callout {
    background-color: var(--color-nhs-white);
    color: var(--color-nhs-text);
    border-left: 4px solid var(--color-nhs-blue);
    padding: 1rem 1.25rem;
  }
  .flow-callout__title {
    margin: 0 0 0.35rem;
    font-weight: 700;
    font-size: 1.125rem;
    line-height: 1.3;
    color: inherit;
  }
  .flow-callout__body {
    margin: 0;
    line-height: 1.6;
    color: inherit;
  }
  .flow-callout__body > :last-child {
    margin-bottom: 0;
  }

  /* note — NHS inset text: the quietest form, a rule and nothing else. */
  .flow-callout--note {
    padding-block: 0.5rem;
  }

  /* info — the NHS care card. The title becomes the filled header bar, so the
     padding moves off the root and onto the parts; the bar has to reach the
     card's edges to read as NHS rather than as a heading with a background. */
  .flow-callout--info {
    border: 2px solid var(--color-nhs-blue);
    border-left-width: 2px;
    padding: 0;
  }
  .flow-callout--info .flow-callout__title {
    margin: 0;
    padding: 0.75rem 1.25rem;
    background-color: var(--color-nhs-blue);
    color: var(--color-nhs-white);
    font-size: 1.25rem;
  }
  .flow-callout--info .flow-callout__body {
    padding: 1rem 1.25rem;
  }

  /* A callout owning its ground is what makes its EDGE vanish when the band
     behind it shares the accent: an NHS-blue header bar on an NHS-blue section
     reads as a title floating in space with no card under it. The white body
     below still separates itself, so only the bar is lost — which is worse than
     losing the whole card, because it looks broken rather than plain.

     On a dark band the card's frame turns white. It keeps the NHS shape (blue
     bar, white body) and gets its edge back. Caught by rendering the care card
     on `solid-brand`, which in this theme IS NHS blue. */
  [data-surface-tone="dark"] .flow-callout--info {
    border-color: var(--color-nhs-white);
  }

  /* do / dont — the NHS tick and cross. Drawn as a MASK over a background
     colour rather than an inline SVG, so the mark takes the variant's accent
     and never needs a second copy of the icon per colour. Decorative by
     construction: generated content with no text, so nothing is announced
     twice over the title that already says it. */
  .flow-callout--do,
  .flow-callout--dont {
    background-color: var(--color-nhs-grey-5);
  }
  .flow-callout--do {
    border-left-color: var(--color-nhs-green);
  }
  .flow-callout--dont {
    border-left-color: var(--color-nhs-red);
  }
  .flow-callout--do .flow-callout__title,
  .flow-callout--dont .flow-callout__title {
    display: flex;
    align-items: center;
    gap: 0.6rem;
  }
  .flow-callout--do .flow-callout__title::before,
  .flow-callout--dont .flow-callout__title::before {
    content: "";
    flex: none;
    width: 1.375rem;
    height: 1.375rem;
    mask-repeat: no-repeat;
    mask-position: center;
    mask-size: contain;
    -webkit-mask-repeat: no-repeat;
    -webkit-mask-position: center;
    -webkit-mask-size: contain;
  }
  .flow-callout--do .flow-callout__title::before {
    background-color: var(--color-nhs-green);
    mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>');
    -webkit-mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>');
  }
  .flow-callout--dont .flow-callout__title::before {
    background-color: var(--color-nhs-red);
    mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>');
    -webkit-mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>');
  }

  /* ── "On this page" section index ─────────────────────────────────────────
     Four presentations, and each is the right answer to a different page:

       left / right  a column beside the content. The best default for a long
                     page: vertical, so ten entries cost no more room than
                     three, and it stays in view the whole way down.
       sidebar       a contents list at the head of the content. The NHS
                     Design System's own shape, and the safe answer anywhere.
       top           a strip that follows the reader. Reads well up to about
                     six entries; beyond that it becomes a wall of buttons, so
                     it scrolls on one line rather than wrapping into a block.

     The column and the contents list share one treatment, taken from the
     original `TableOfContents`: a faint hairline running the list's full
     height, and the current section lighting a SEGMENT of that line in NHS
     blue rather than drawing a second line beside it. That is what makes it
     read as a position along a path instead of a highlighted row.

     TONE SAFETY: no text colour is pinned. Quiet tones and hairlines mix from
     `currentColor`, which structural.css has already lifted on a dark band;
     the one real colour is the brandable EMPHASIS ink, swapped for its on-dark
     twin exactly as structural.css swaps the `.flow-ink-*` roles. */
  .flow-section-nav {
    --nhs-index-ink: var(--flow-ink-emphasis, currentColor);
    --nhs-index-rail: color-mix(in srgb, currentColor 20%, transparent);
    --nhs-index-rail-hover: color-mix(in srgb, currentColor 45%, transparent);
    font-family: var(--font-sans);
  }
  [data-surface-tone="dark"] .flow-section-nav,
  .flow-section--tone-light .flow-section-nav {
    --nhs-index-ink: var(--flow-ink-emphasis-on-dark, var(--flow-ink-emphasis, currentColor));
  }

  .flow-section-nav__label {
    margin: 0 0 1.15rem;
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: color-mix(in srgb, currentColor 62%, transparent);
  }

  .flow-section-nav__link {
    display: block;
    text-decoration: none;
    color: color-mix(in srgb, currentColor 70%, transparent);
    transition:
      color 0.2s ease,
      border-color 0.2s ease,
      background-color 0.2s ease;
  }

  /* ── The rail: `left`, `right`, and the plain contents list ─────────────── */
  .flow-section-nav--left .flow-section-nav__list,
  .flow-section-nav--right .flow-section-nav__list,
  .flow-section-nav--sidebar .flow-section-nav__list {
    border-inline-start: 1px solid var(--nhs-index-rail);
  }
  .flow-section-nav--left .flow-section-nav__link,
  .flow-section-nav--right .flow-section-nav__link,
  .flow-section-nav--sidebar .flow-section-nav__link {
    /* -1px pulls the row's own border ON TOP of the rail, so an active row
       lights that segment instead of sitting beside a second line. */
    margin-inline-start: -1px;
    border-inline-start: 2px solid transparent;
    padding: 0.5rem 0 0.5rem 1rem;
    font-size: 0.875rem;
    line-height: 1.45;
    /* A long heading wraps to two lines and then stops, so one verbose
       section cannot push the rest of the index off the screen. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .flow-section-nav--left .flow-section-nav__link:hover,
  .flow-section-nav--right .flow-section-nav__link:hover,
  .flow-section-nav--sidebar .flow-section-nav__link:hover {
    border-inline-start-color: var(--nhs-index-rail-hover);
    color: currentColor;
  }
  .flow-section-nav--left .flow-section-nav__link--active,
  .flow-section-nav--right .flow-section-nav__link--active,
  .flow-section-nav--sidebar .flow-section-nav__link--active,
  .flow-section-nav--left .flow-section-nav__link--active:hover,
  .flow-section-nav--right .flow-section-nav__link--active:hover,
  .flow-section-nav--sidebar .flow-section-nav__link--active:hover {
    border-inline-start-color: var(--nhs-index-ink);
    color: var(--nhs-index-ink);
    font-weight: 600;
  }

  .flow-section-nav--sidebar {
    max-width: 24rem;
  }

  /* A column is sticky, so a very long index would otherwise run past the
     bottom of the screen with no way to reach the end. It scrolls inside
     itself instead, with the scrollbar hidden — the rail already signals
     that the list continues. */
  .flow-section-nav--left,
  .flow-section-nav--right {
    max-height: calc(100vh - var(--flow-anchor-offset, 6rem) - 3rem);
    overflow-y: auto;
    scrollbar-width: none;
    overscroll-behavior: contain;
  }
  .flow-section-nav--left::-webkit-scrollbar,
  .flow-section-nav--right::-webkit-scrollbar {
    display: none;
  }

  /* ── The bar ──────────────────────────────────────────────────────────────
     One line, always. Wrapping is what turns a long page's index into a wall
     of buttons two or three rows deep, pushing the content down the screen —
     so it scrolls sideways instead, and a fade at each edge shows there is
     more without spending room on arrows. */
  .flow-section-nav-slot:has(.flow-section-nav--top) {
    position: sticky;
    top: 0;
    z-index: 5;
    padding-block: 0.7rem;
    background: color-mix(in srgb, var(--color-surface) 86%, transparent);
    backdrop-filter: blur(12px) saturate(1.3);
    -webkit-backdrop-filter: blur(12px) saturate(1.3);
    box-shadow: 0 1px 0 0 color-mix(in srgb, var(--color-nhs-text) 12%, transparent);
  }
  .flow-section-nav--top {
    display: flex;
    align-items: center;
    gap: 1rem;
    min-width: 0;
  }
  .flow-section-nav--top .flow-section-nav__label {
    margin: 0;
    flex: none;
    display: none;
  }
  .flow-section-nav--top .flow-section-nav__list {
    flex-wrap: nowrap;
    gap: 0.4rem;
    overflow-x: auto;
    scrollbar-width: none;
    scroll-padding-inline: 1.5rem;
    min-width: 0;
    /* The fade. A mask rather than a gradient overlay, so it works over the
       glass backdrop without painting a second surface on top of it. */
    mask-image: linear-gradient(to right, transparent 0, #000 1.25rem, #000 calc(100% - 1.25rem), transparent 100%);
    -webkit-mask-image: linear-gradient(to right, transparent 0, #000 1.25rem, #000 calc(100% - 1.25rem), transparent 100%);
  }
  .flow-section-nav--top .flow-section-nav__list::-webkit-scrollbar {
    display: none;
  }
  .flow-section-nav--top .flow-section-nav__link {
    padding: 0.4rem 0.85rem;
    border: 1px solid var(--nhs-index-rail);
    border-radius: var(--radius-nhs);
    font-size: 0.875rem;
    white-space: nowrap;
  }
  .flow-section-nav--top .flow-section-nav__link:hover {
    border-color: var(--nhs-index-rail-hover);
    background: color-mix(in srgb, currentColor 6%, transparent);
  }
  .flow-section-nav--top .flow-section-nav__link--active,
  .flow-section-nav--top .flow-section-nav__link--active:hover {
    border-color: var(--nhs-index-ink);
    background: color-mix(in srgb, var(--nhs-index-ink) 10%, transparent);
    color: var(--nhs-index-ink);
    font-weight: 600;
  }
  @media (min-width: 48rem) {
    .flow-section-nav--top .flow-section-nav__label {
      display: block;
    }
  }

  @media (prefers-reduced-motion: reduce) {
    .flow-section-nav__link {
      transition: none;
    }
  }


  /* ── Narrow-surface responsive pass (chunk 6.6) ───────────────────────
     Container queries (NOT @media — the canvas is the `theme-canvas`
     container; the editor's device preview narrows its width to fire these).
     Placed LAST in @scope so the display-type / hero / section-padding
     step-downs win over the base widget rules above on source order, at equal
     specificity (no `!important` needed). Mobile (< 640px) reads as a phone
     render rather than just a reflowed grid; tablet (768px) keeps desktop sizing. */
  @container theme-canvas (max-width: 640px) {
    .flow-heading--h1 { font-size: 1.875rem; }
    .flow-heading--h2 { font-size: 1.5rem; }
    .flow-heading--h3 { font-size: 1.25rem; }
    .flow-heading--h4 { font-size: 1.125rem; }
    .flow-heading--h5 { font-size: 1.0625rem; }
    .flow-heading--h6 { font-size: 1rem; }

    .flow-richtext h2 { font-size: 1.5rem; }
    .flow-richtext h3 { font-size: 1.25rem; }
    .flow-richtext h4 { font-size: 1.125rem; }

    .flow-hero { padding-block: var(--space-lg); }
    .flow-hero__headline { font-size: 1.875rem; }
    .flow-hero__subhead { font-size: 1.0625rem; }

    /* Tame the largest vertical section padding (smaller tokens are fine). */
    .flow-section--pad-xl { padding-block: var(--space-lg); }
    .flow-section--pad-2xl { padding-block: var(--space-xl); }

    /* Step down the two largest "Space below" overrides on narrow surfaces.
       Source order keeps these after the Layer-2 base rules above, so they
       win at equal specificity (both carry `!important`). */
    .flow-block--mb-xl { margin-block-end: var(--space-lg) !important; }
    .flow-block--mb-2xl { margin-block-end: var(--space-xl) !important; }
  }

  /* Theme-owned section navigation. The explicit column-* variants leave the
     legacy page settings unchanged until the tenant saves its theme settings. */
  :scope { --flow-index-width: 14rem; }
  .flow-section-nav--managed {
    color: var(--flow-fg-on-light, #212b32);
    background: var(--section-bg-default, #fff);
    border: 1px solid color-mix(in srgb, currentColor 20%, transparent);
    border-radius: 0.375rem;
    padding: 1.25rem;
    margin-block: 1.5rem;
    overflow-wrap: anywhere;
    transform: translateY(var(--flow-index-shift, 0px));
  }
  .flow-section-nav--managed[data-obscured] { visibility: hidden; }
  .flow-section-nav--managed .flow-section-nav__label { color: inherit; font-size: 0.75rem; }
  .flow-section-nav--managed .flow-section-nav__list { list-style: none; padding: 0; margin: 0; }
  .flow-section-nav--managed .flow-section-nav__link {
    display: flex;
    align-items: center;
    min-height: 44px;
    padding: 0.625rem 0.75rem;
    border-inline-start: 3px solid color-mix(in srgb, currentColor 22%, transparent);
    color: inherit;
    font-size: 0.875rem;
    line-height: 1.5;
    text-decoration: none;
    text-wrap: pretty;
  }
  .flow-section-nav--managed .flow-section-nav__link:hover {
    text-decoration: underline;
    text-underline-offset: 0.2em;
    background: color-mix(in srgb, currentColor 5%, transparent);
  }
  .flow-section-nav--managed .flow-section-nav__link--active {
    border-inline-start-color: var(--flow-ink-emphasis, currentColor);
    color: var(--flow-ink-emphasis, currentColor);
    background: color-mix(in srgb, currentColor 7%, transparent);
    font-weight: 700;
  }
  .flow-section-nav--managed .flow-section-nav__link:focus-visible,
  .flow-section-nav--managed .flow-section-nav__toggle:focus-visible {
    outline: 3px solid #212b32;
    outline-offset: 2px;
    background: #ffeb3b;
    color: #212b32;
    text-decoration: underline;
  }
  .flow-section-nav__toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    width: 100%;
    min-height: 44px;
    font: inherit;
    font-weight: 700;
    text-align: start;
    color: inherit;
    background: transparent;
    border: 0;
    padding: 0.5rem 0;
    cursor: pointer;
  }
  .flow-section-nav--managed > .flow-section-nav__label,
  .flow-section-nav--managed > .flow-section-nav__progress,
  .flow-section-nav--managed:not([data-expanded]) > .flow-section-nav__list { display: none; }
  .flow-section-nav--managed[data-expanded] > .flow-section-nav__list { margin-block-start: 0.75rem; }
  .flow-section-nav__progress-text { display: flex; align-items: baseline; gap: 0.35rem; font-size: 1.75rem; font-weight: 700; }
  .flow-section-nav__progress-text > span { font-size: 0.75rem; font-weight: 400; }
  .flow-section-nav__progress-track { display: block; height: 3px; margin-block: 0.75rem 1rem; background: color-mix(in srgb, currentColor 15%, transparent); }
  .flow-section-nav__progress-track > span { display: block; height: 100%; background: var(--flow-ink-emphasis, currentColor); }

  @media (min-width: 64rem) {
    .flow-section-nav-slot:has(.flow-section-nav--managed):has(~ .flow-document) {
      /* The zero-height navigation slot must not shield the content beside it. */
      pointer-events: none;
      position: sticky;
      top: var(--flow-anchor-offset, 6rem);
      height: 0;
      z-index: 4;
      padding-block: 0;
      overflow: visible;
    }
    .flow-section-nav-slot:has(~ .flow-document) .flow-section-nav--managed {
      pointer-events: auto;
      width: var(--flow-index-width);
      margin-block: 0;
      max-height: calc(100dvh - var(--flow-anchor-offset, 6rem) - 2rem);
      overflow-y: auto;
      scrollbar-width: thin;
      overscroll-behavior: contain;
    }
    .flow-section-nav-slot:has(~ .flow-document) .flow-section-nav--floating {
      box-shadow: 0 12px 32px -12px #0004;
      border-block-start: 3px solid var(--flow-ink-emphasis, currentColor);
    }
    .flow-section-nav-slot:has(~ .flow-document) :is(.flow-section-nav--column-right, .flow-section-nav--floating-right) { margin-inline-start: auto; }
    .flow-section-nav-slot:has(~ .flow-document) .flow-section-nav--managed > .flow-section-nav__toggle { display: none; }
    .flow-section-nav-slot:has(~ .flow-document) .flow-section-nav--managed > :is(.flow-section-nav__label, .flow-section-nav__list, .flow-section-nav__progress) { display: block; }
    .flow-section-nav-slot:has(:is(.flow-section-nav--column-left, .flow-section-nav--floating-left)) ~ .flow-document .flow-section--width-contained .flow-section__inner {
      padding-inline-start: calc(var(--container-gutter) + var(--flow-index-width) + var(--flow-index-gap));
    }
    .flow-section-nav-slot:has(:is(.flow-section-nav--column-right, .flow-section-nav--floating-right)) ~ .flow-document .flow-section--width-contained .flow-section__inner {
      padding-inline-end: calc(var(--container-gutter) + var(--flow-index-width) + var(--flow-index-gap));
    }
  }
  /* Outer-margin floating needs space for the complete content width AND two
     accessible panels. Below this it takes a reserved column, never overlays. */
  @media (min-width: 120rem) {
    .flow-section-nav-slot:has(~ .flow-document) .flow-section-nav--floating-left {
      translate: calc(-100% - var(--flow-index-gap)) 0;
    }
    .flow-section-nav-slot:has(~ .flow-document) .flow-section-nav--floating-right {
      translate: calc(100% + var(--flow-index-gap)) 0;
    }
    .flow-section-nav-slot:has(.flow-section-nav--floating) ~ .flow-document .flow-section--width-contained .flow-section__inner { padding-inline: var(--container-gutter); }
  }
  :scope[data-editor-mode] .flow-section-nav--managed > .flow-section-nav__toggle { display: none; }
  :scope[data-editor-mode] .flow-section-nav--managed > :is(.flow-section-nav__label, .flow-section-nav__list, .flow-section-nav__progress) { display: block; }
  @media (prefers-reduced-motion: reduce) {
    .flow-section-nav--managed * { transition: none; scroll-behavior: auto; }
  }
  @media print {
    .flow-section-nav-slot:has(.flow-section-nav--managed) { display: none; }
    .flow-section-nav-slot:has(.flow-section-nav--managed) ~ .flow-document .flow-section--width-contained .flow-section__inner { padding-inline: var(--container-gutter); }
  }
}

/* Author-selected card surfaces: layout and content stay canonical. */
@scope (.theme-canvas) {
  :scope { --flow-image-backing: color-mix(in srgb, var(--color-nhs-blue) 20%, transparent); }
  .flow-listgrid-widget[data-card-treatment] .flow-listgrid__card {
    border: 1px solid color-mix(in srgb, var(--color-nhs-blue) 20%, var(--color-nhs-white));
    border-radius: 1.25rem;
    background: var(--color-nhs-white);
    box-shadow: none;
  }
  .flow-listgrid-widget[data-card-treatment] .flow-listgrid__inner {
    background: transparent;
    border: 0;
    border-radius: inherit;
    box-shadow: none;
    color: var(--color-nhs-text);
  }
  .flow-listgrid-widget[data-card-treatment] .flow-listgrid__content { position: relative; padding: 1.5rem; }
  .flow-listgrid-widget[data-card-treatment] .flow-listgrid__indicator {
    display: grid;
    place-items: center;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: 50%;
    color: var(--color-nhs-blue);
    background: color-mix(in srgb, var(--color-nhs-blue) 9%, var(--color-nhs-white));
    font-size: 1.5rem;
    margin-bottom: 0.75rem;
  }
  .flow-listgrid-widget[data-card-treatment="soft"] .flow-listgrid__card {
    background: linear-gradient(150deg, var(--color-nhs-white) 55%, color-mix(in srgb, var(--color-nhs-blue) 6%, var(--color-nhs-white)));
    box-shadow: 0 0.5rem 1.5rem color-mix(in srgb, var(--color-nhs-text) 5%, transparent);
  }
  .flow-listgrid-widget[data-card-treatment="outline"] .flow-listgrid__card { border: 2px solid var(--color-nhs-blue); }
  .flow-listgrid-widget[data-card-treatment] .flow-listgrid__title { color: var(--color-nhs-blue); }
  .flow-listgrid-widget[data-card-treatment] .flow-listgrid__body { color: var(--color-nhs-text); }
  .flow-listgrid-widget[data-card-treatment] .flow-listgrid__card--link:hover { border-color: var(--color-nhs-blue); }
  @media (prefers-reduced-motion: reduce) {
    .flow-listgrid-widget .flow-listgrid__card,
    .flow-listgrid-widget .flow-listgrid__inner,
    .flow-listgrid-widget .flow-listgrid__image,
    .flow-listgrid-widget .flow-listgrid__cta::after { transition: none !important; transform: none !important; }
  }
}

/* Opt-in editorial treatments. Each is selected in the component inspector;
   theme colours and typography remain variables, without changing old pages. */
@scope (.theme-canvas) {
  .flow-heading[data-typography="editorial"] {
    font-family: var(--flow-editorial-font, Georgia, 'Times New Roman', serif);
    font-size: clamp(2.25rem, 4.5cqi, 4.25rem); font-weight: 500;
    line-height: 1.08; letter-spacing: -.035em; text-wrap: balance;
  }
  .flow-hero[data-presentation="editorial"] {
    position: relative; isolation: isolate; overflow: hidden; display: block;
    min-height: 38rem; background: var(--flow-editorial-ground, #061b28);
    color: #fff; padding: 0; border-radius: 0;
  }
  .flow-hero[data-presentation="editorial"] .nhs-hero__inner,
  .flow-hero[data-presentation="editorial"] > .relative {
    position: relative; z-index: 2; width: 100%; max-width: 76rem; box-sizing: border-box;
    min-height: 38rem; padding: clamp(4rem, 8cqi, 7rem) 2rem 5rem;
    margin-inline: auto; display: flex; flex-direction: column; justify-content: center; align-items: flex-start;
  }
  .flow-hero[data-presentation="editorial"] .flow-hero__headline {
    font-family: var(--flow-editorial-font, Georgia, 'Times New Roman', serif);
    font-size: clamp(2.75rem, 4.8cqi, 4.8rem); line-height: 1.04; font-weight: 500;
    letter-spacing: -.04em; max-width: 17ch; margin: 1.5rem 0 0;
  }
  .flow-hero[data-presentation="editorial"] .flow-hero__headline:not([class*="flow-ink-"]) { color: #fff; }
  .flow-hero[data-presentation="editorial"] .flow-hero__subhead:not([class*="flow-ink-"]) { color: #eef4f5; }
  .flow-hero__headline-accent { display: block; color: var(--flow-editorial-accent, #8be0df); }
  .flow-hero__eyebrow { position: relative; font-size: .75rem; font-weight: 700; letter-spacing: .18em; text-transform: uppercase; color: var(--flow-editorial-accent, #8be0df); margin: 0; }
  .flow-hero[data-presentation="editorial"] .flow-hero__subhead { max-width: 46ch; font-size: 1.125rem; line-height: 1.8; margin: 1.75rem 0 0; }
  .flow-hero[data-presentation="editorial"] .flow-hero__actions { margin-top: 2rem; position: relative; }
  .flow-hero[data-presentation="editorial"] .flow-hero__cta.flow-button { border-radius: 999px; padding: .9rem 1.5rem; border: 1px solid #abc2ca; background: color-mix(in srgb,var(--flow-editorial-ground) 80%,transparent); color: white; box-shadow: none; min-height: 48px; }
  .flow-hero[data-presentation="editorial"] .flow-hero__cta::after { content: '↓'; margin-left: 1.75rem; }
  .flow-hero[data-presentation="editorial"] .flow-hero__cta.flow-button:hover:not(:focus-visible) { background: color-mix(in srgb,var(--flow-editorial-accent) 15%,var(--flow-editorial-ground)); color: #fff; }
  .flow-hero[data-presentation="editorial"] .flow-hero__cta.flow-button:focus-visible { background: #ffeb3b; color: #151b20; outline: 3px solid #ffeb3b; outline-offset: 4px; }
  .flow-hero[data-overlay-treatment="directional"] .nhs-hero__inner { position: relative; z-index: 2; }
  .flow-hero:not([data-presentation="editorial"]):not([data-background-asset]) :is(.flow-hero__headline-accent, .flow-hero__eyebrow) { color: var(--flow-ink-accent-on-dark, #f7a7ce); }
  .nhs-hero:not([data-presentation="editorial"]):not([data-background-asset]) :is(.flow-hero__headline-accent, .flow-hero__eyebrow) { color: var(--flow-ink-accent, #005eb8); }
  .flow-hero[data-background-asset][data-overlay-treatment="directional"]:not([data-shading="custom"])::after { content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none; background: linear-gradient(90deg, var(--flow-editorial-ground) 0%, color-mix(in srgb,var(--flow-editorial-ground) 90%,transparent) 30%, color-mix(in srgb,var(--flow-editorial-ground) 45%,transparent) 62%, transparent 100%), linear-gradient(0deg, var(--flow-editorial-ground) 0%, transparent 40%); }
  .flow-liststats-widget[data-presentation="editorial"] { padding: 0 2rem 3rem; background: var(--flow-editorial-ground, #061b28); color: #fff; }
  .flow-liststats-widget[data-presentation="editorial"] .flow-liststats { max-width: 72rem; margin: 0 auto; padding-block: 2rem; border-block: 1px solid #ffffff30; gap: 0; }
  .flow-liststats-widget[data-presentation="editorial"] .flow-liststats__card { padding: 0 2rem; background: transparent; border: 0; box-shadow: none; border-radius: 0; }
  .flow-liststats-widget[data-presentation="editorial"] .flow-liststats__card + .flow-liststats__card { border-left: 1px solid #ffffff30; }
  .flow-liststats-widget[data-presentation="editorial"] .flow-liststats__inner { padding: 0; background: transparent; color: #fff; }
  .flow-liststats-widget[data-presentation="editorial"] .flow-liststats__value { font-size: clamp(2.75rem, 4cqi, 4rem); line-height: 1.15; font-weight: 600; letter-spacing: -.05em; color: var(--flow-editorial-accent, #8be0df); }
  .flow-liststats-widget[data-presentation="editorial"] .flow-liststats__card:nth-child(2n) .flow-liststats__value:not([data-stat-accent]) { color: var(--flow-editorial-secondary); }
  .flow-liststats-widget[data-presentation="editorial"] .flow-liststats__card:nth-child(3n) .flow-liststats__value:not([data-stat-accent]) { color: var(--flow-editorial-tertiary); }
  .flow-liststats-widget[data-presentation="editorial"] .flow-liststats__label { color: #edf5f7; font-size: .9375rem; margin-top: .6rem; }
  .flow-listtimeline-widget[data-presentation="process"] .flow-listtimeline { display: grid; grid-template-columns: repeat(3,minmax(0,1fr)); gap: 2.5rem; counter-reset: none; padding: 2rem 0; }
  .flow-listtimeline-widget[data-presentation="process"] .flow-listtimeline__entry { display: block; padding: 0; border: 0; position: relative; }
  .flow-listtimeline-widget[data-presentation="process"] .flow-listtimeline__entry::before,
  .flow-listtimeline-widget[data-presentation="process"] .flow-listtimeline__marker::before,
  .flow-listtimeline-widget[data-presentation="process"] .flow-listtimeline__dot { display: none; }
  .flow-listtimeline-widget[data-presentation="process"] .flow-listtimeline__marker { position: relative; width: 5rem; height: 5rem; display: flex; align-items: center; justify-content: center; margin: 0 0 2rem; border-radius: 1.4rem; border: 1px solid color-mix(in srgb,currentColor 40%,transparent); background: color-mix(in srgb,currentColor 7%,transparent); box-shadow: 0 0 3rem color-mix(in srgb,currentColor 12%,transparent); }
  .flow-process__number { font-size: 1.5rem; font-weight: 500; letter-spacing: -.04em; }
  .flow-listtimeline-widget[data-presentation="process"] .flow-listtimeline__thumb { display: block; width: 3rem; height: 3rem; object-fit: contain; border-radius: .5rem; }
  .flow-listtimeline-widget[data-presentation="process"] .flow-listtimeline__marker:has(.flow-listtimeline__thumb) .flow-process__number { display: none; }
  .flow-listtimeline-widget[data-presentation="process"] .flow-listtimeline__entry:not(:last-child)::after { content: ''; position: absolute; left: 6rem; right: 0; top: 2.5rem; height: 1px; background: linear-gradient(90deg,currentColor,transparent); opacity: .5; transform-origin: left; }
  .flow-listtimeline-widget[data-presentation="process"] .flow-listtimeline__title { font-size: 1.4rem; line-height: 1.3; margin: .75rem 0; color: inherit; }
  .flow-listtimeline-widget[data-presentation="process"] .flow-listtimeline__blurb { color: inherit; opacity: .9; font-size: 1rem; line-height: 1.8; }
  .flow-listtimeline-widget[data-presentation="process"] .flow-listtimeline__date { color: inherit; font-size: .7rem; letter-spacing: .15em; opacity: .8; }
  .flow-listtimeline-widget[data-presentation="process"] .flow-listtimeline__entry[data-reveal="visible"]::after { animation: flow-process-connect 1000ms ease-out both; }
  @keyframes flow-process-connect { from { transform: scaleX(0); opacity: 0; } to { transform: scaleX(1); opacity: .5; } }
  @container theme-canvas (max-width: 700px) {
    .flow-hero[data-presentation="editorial"] .nhs-hero__inner, .flow-hero[data-presentation="editorial"] > .relative { padding: 4rem 1.5rem; min-height: 36rem; }
    .flow-hero[data-background-asset][data-overlay-treatment="directional"]:not([data-shading="custom"])::after { background: linear-gradient(90deg,color-mix(in srgb,var(--flow-editorial-ground) 94%,transparent),color-mix(in srgb,var(--flow-editorial-ground) 80%,transparent)),linear-gradient(0deg,var(--flow-editorial-ground),transparent 70%); }
    .flow-liststats-widget[data-presentation="editorial"] { padding: 0 1.5rem 2rem; }
    .flow-liststats-widget[data-presentation="editorial"] .flow-liststats__card { padding: 1rem 0; }
    .flow-liststats-widget[data-presentation="editorial"] .flow-liststats__card + .flow-liststats__card { border-left: 0; border-top: 1px solid #ffffff30; }
    .flow-listtimeline-widget[data-presentation="process"] .flow-listtimeline { grid-template-columns: 1fr; }
    .flow-listtimeline-widget[data-presentation="process"] .flow-listtimeline__entry { padding-left: 6.5rem; min-height: 8rem; }
    .flow-listtimeline-widget[data-presentation="process"] .flow-listtimeline__marker { position: absolute; left: 0; top: 0; }
    .flow-listtimeline-widget[data-presentation="process"] .flow-listtimeline__entry:not(:last-child)::after { left: 2.5rem; top: 6rem; bottom: 0; height: auto; width: 1px; right: auto; }
  }
  @media (prefers-reduced-motion: reduce) { .flow-listtimeline-widget[data-presentation="process"] .flow-listtimeline__entry::after { animation: none !important; } }
}

@scope (.theme-canvas) {
  .flow-hero[data-presentation="editorial"] [data-surface-motion="zoom"] img,
  .flow-hero[data-presentation="editorial"] img[data-surface-motion="zoom"],
  .flow-hero[data-presentation="editorial"] img[data-surface-motion="cinematic"] { animation-duration: 4s; }
  .flow-listtimeline-widget[data-presentation="process"] .flow-listtimeline__marker::after { display: none; }
}

@scope (.theme-canvas) {
  .flow-hero[data-presentation="editorial"] .flow-hero__cta.flow-button--primary { background: var(--flow-editorial-accent); color: var(--flow-editorial-ground); border-color: transparent; }
  .flow-hero[data-presentation="editorial"] .flow-hero__cta.flow-button--tertiary { background: transparent; color: #fff; border-color: transparent; text-decoration: underline; }
  .flow-hero[data-presentation="editorial"] .flow-hero__cta.flow-button--reverse { background: #fff; color: var(--flow-editorial-ground); }
  .flow-hero[data-presentation="editorial"] .flow-hero__cta.flow-button:focus-visible { background: #ffeb3b; color: #151b20; }
  .flow-listtimeline-widget[data-presentation="process"] .flow-listtimeline__entry[data-reveal="visible"] .flow-listtimeline__marker { animation: flow-process-arrive 900ms ease-out both; }
  @keyframes flow-process-arrive { from { box-shadow: 0 0 0 transparent; } 60% { box-shadow: 0 0 3rem color-mix(in srgb,currentColor 25%,transparent); } to { box-shadow: 0 0 3rem color-mix(in srgb,currentColor 12%,transparent); } }
  @media (prefers-reduced-motion: reduce) { .flow-listtimeline-widget[data-presentation="process"] .flow-listtimeline__entry .flow-listtimeline__marker { animation: none !important; } }
}

@scope (.theme-canvas) {
  .flow-hero[data-presentation="editorial"] .flow-hero__cta::after { content: none; }
  .flow-hero__action-icon { flex: 0 0 18px; margin-left: 1.25rem; transition: transform 180ms ease; }
  .flow-hero__action-icon[data-direction="right"] { transform: rotate(-90deg); }
  .flow-hero[data-button-treatment="refined"] .flow-hero__cta.flow-button {
    display: inline-flex; align-items: center; justify-content: space-between; gap: 1.25rem;
    min-height: 44px; padding: .65rem 1.2rem; border-radius: 999px;
    font-size: .875rem; line-height: 1.4; font-weight: 650; max-width: 100%;
    border-color: color-mix(in srgb,currentColor 38%,transparent);
    transition: background-color 180ms ease, border-color 180ms ease;
  }
  .flow-hero[data-button-treatment="refined"] .flow-hero__action-icon { margin-left: 0; }
  .flow-hero[data-button-treatment="refined"] .flow-hero__cta:hover { border-color: currentColor; }
  .flow-hero[data-button-treatment="refined"] .flow-hero__cta:hover .flow-hero__action-icon[data-direction="down"] { transform: translateY(2px); }
  .flow-hero[data-button-treatment="refined"] .flow-hero__cta:hover .flow-hero__action-icon[data-direction="right"] { transform: translateX(2px) rotate(-90deg); }
  .flow-liststats-widget[data-presentation="editorial"][data-density="compact"] { padding-bottom: 1.5rem; }
  .flow-liststats-widget[data-presentation="editorial"][data-density="compact"] .flow-liststats { padding-block: 1.5rem; }
  .flow-liststats-widget[data-presentation="editorial"][data-density="compact"] .flow-liststats__card { padding: 0 1.75rem; }
  .flow-liststats-widget[data-presentation="editorial"][data-density="compact"] .flow-liststats__figure { min-height: 0; padding: 0; gap: 0; align-items: stretch; }
  .flow-liststats-widget[data-presentation="editorial"][data-density="compact"] .flow-liststats__value { font-size: clamp(2.25rem, 3.5cqi, 3rem); line-height: 1.1; }
  .flow-liststats-widget[data-presentation="editorial"][data-density="compact"] .flow-liststats__label { margin-top: .5rem; font-size: .875rem; line-height: 1.5; }
  @container theme-canvas (max-width: 700px) {
    .flow-liststats-widget[data-presentation="editorial"][data-density="compact"] .flow-liststats__card { padding: 1rem 0; }
  }
  @media (prefers-reduced-motion: reduce) {
    .flow-hero .flow-hero__action-icon { transition: none; }
    .flow-hero[data-button-treatment="refined"] .flow-hero__cta:hover .flow-hero__action-icon[data-direction="down"] { transform: none; }
    .flow-hero[data-button-treatment="refined"] .flow-hero__cta:hover .flow-hero__action-icon[data-direction="right"] { transform: rotate(-90deg); }
  }
}

@scope (.theme-canvas) {
  .flow-liststats-widget[data-presentation="editorial"][data-density="compact"] .flow-liststats__card:first-child { padding-left: 0; }
  .flow-liststats-widget[data-presentation="editorial"][data-density="compact"] .flow-liststats__card:last-child { padding-right: 0; }
}

@scope (.theme-canvas) {
  .flow-liststats-widget[data-presentation="editorial"] .flow-stat-affix { font-size: .52em; letter-spacing: -.025em; }
  .flow-liststats-widget[data-presentation="editorial"] .flow-liststats__label p + p { margin-top: .4rem; font-size: .8125rem; color: #b9c2d0; }
  .flow-liststats-widget[data-presentation="editorial"] .flow-liststats__label strong { font-weight: 650; }
  .flow-liststats-widget[data-presentation="editorial"] .flow-liststats__card:nth-child(4n) .flow-liststats__value:not([data-stat-accent]) { color: var(--flow-editorial-accent); }
}

@scope (.theme-canvas) {
  .flow-listgrid-widget[data-card-treatment="editorial"] .flow-listgrid__card {
    background: var(--flow-card-surface); color: var(--flow-card-ink); border: 1px solid var(--flow-card-border);
    border-radius: var(--flow-card-radius); box-shadow: 0 3px 12px #17243206; overflow: visible;
    transition: transform 180ms ease, box-shadow 180ms ease, border-color 180ms ease;
  }
  .flow-listgrid-widget[data-card-treatment="editorial"] .flow-listgrid__inner {
    background: transparent; color: inherit; padding: 0; border-radius: inherit; text-decoration: none; height: 100%;
  }
  .flow-listgrid-widget[data-card-treatment="editorial"] .flow-listgrid__content { position: relative; padding: var(--flow-card-padding); display: flex; flex-direction: column; align-items: stretch; gap: 0; flex: 1; }
  .flow-listgrid-widget[data-card-treatment="editorial"] .flow-listgrid__eyebrow { color: color-mix(in srgb,var(--flow-card-ink) 75%,var(--flow-card-surface)); font-size: .6875rem; letter-spacing: .12em; line-height: 1.5; font-weight: 650; margin: 0 2rem .75rem 0; }
  .flow-listgrid-widget[data-card-treatment="editorial"] .flow-listgrid__title { color: var(--flow-card-ink); font-size: 1.375rem; line-height: 1.3; letter-spacing: -.025em; font-weight: 650; margin: 0 1.5rem .75rem 0; }
  .flow-listgrid-widget[data-card-treatment="editorial"] .flow-listgrid__body { color: color-mix(in srgb,var(--flow-card-ink) 85%,var(--flow-card-surface)); font-size: 1rem; line-height: 1.65; margin: 0; }
  .flow-listgrid-widget[data-card-treatment="editorial"] .flow-listgrid__body p { margin: 0; }
  .flow-listgrid-widget[data-card-treatment="editorial"] .flow-listgrid__indicator { position: absolute; top: var(--flow-card-padding); right: var(--flow-card-padding); display: flex; width: 20px; height: 20px; margin: 0; border: 0; border-radius: 0; background: transparent; color: var(--flow-card-ink); transition: transform 180ms ease; }
  .flow-listgrid-widget[data-card-treatment="editorial"] .flow-listgrid__content:has(.flow-listgrid__cta) .flow-listgrid__indicator { top: auto; bottom: var(--flow-card-padding); }
  .flow-listgrid-widget[data-card-treatment="editorial"] .flow-listgrid__content:has(.flow-listgrid__cta) .flow-listgrid__body { margin-bottom: 1.5rem; }
  .flow-listgrid-widget[data-card-treatment="editorial"] .flow-listgrid__cta { display: block; margin-top: auto; padding: 1rem 2rem 0 0; border-top: 1px solid var(--flow-card-border); color: var(--flow-card-ink); font-size: .8125rem; font-weight: 650; line-height: 1.5; }
  .flow-listgrid-widget[data-card-treatment="editorial"] .flow-listgrid__cta::after { content: none; }
  .flow-listgrid-widget[data-card-treatment="editorial"] .flow-listgrid__card--link:hover { border-color: var(--flow-card-ink); box-shadow: 0 12px 24px #17243212; transform: translateY(-2px); }
  .flow-listgrid-widget[data-card-treatment="editorial"] .flow-listgrid__card--link:hover .flow-listgrid__indicator { transform: translateX(3px); }
  .flow-listgrid-widget[data-card-treatment="editorial"] .flow-listgrid__link:focus-visible { outline: 3px solid #ffeb3b; outline-offset: 3px; box-shadow: 0 0 0 2px #172432; }
  .flow-listgrid-widget[data-card-treatment="editorial"] .flow-listgrid__media { border-radius: var(--flow-card-radius) var(--flow-card-radius) 0 0; overflow: hidden; }
  @media (prefers-reduced-motion: reduce) {
    .flow-listgrid-widget[data-card-treatment="editorial"] .flow-listgrid__card,
    .flow-listgrid-widget[data-card-treatment="editorial"] .flow-listgrid__indicator { transition: none; }
    .flow-listgrid-widget[data-card-treatment="editorial"] .flow-listgrid__card--link:hover,
    .flow-listgrid-widget[data-card-treatment="editorial"] .flow-listgrid__card--link:hover .flow-listgrid__indicator { transform: none; }
  }
}

@scope (.theme-canvas) {
  .flow-practice-footer { background: var(--flow-footer-ground); color: var(--flow-footer-ink); }
  .flow-practice-footer__container { max-width: 72rem; padding-inline: 2rem; margin-inline: auto; }
  .flow-practice-footer__signature { background: var(--flow-footer-band); padding-block: 3.5rem; }
  .flow-practice-footer__signature > div { display: flex; justify-content: space-between; align-items: center; gap: 2rem; }
  .flow-practice-footer__signature h2 { margin: 0; font-family: var(--flow-editorial-font); font-size: clamp(2.25rem,4cqi,4rem); line-height: 1.15; letter-spacing: -.035em; color: var(--flow-footer-ink); }
  .flow-practice-footer__contact { font-size: 1rem; line-height: 1.6; }
  .flow-practice-footer__body { padding-block: 4rem 2rem; }
  .flow-practice-footer .flow-footer-nav > .flow-nav { gap: 3rem; }
  .flow-practice-footer .flow-footer-nav > .flow-nav > .flow-nav__item > :is(.flow-nav__label,.flow-nav__link) { color: var(--flow-footer-accent); padding-bottom: 1rem; border-color: color-mix(in srgb,var(--flow-footer-ink) 20%,transparent); font-size: .75rem; }
  .flow-practice-footer a, .flow-practice-footer a:visited { color: var(--flow-footer-ink); }
  .flow-practice-footer .flow-footer-nav .flow-nav__nested .flow-nav__link { color: var(--flow-footer-ink); min-height: 44px; display: flex; align-items: center; font-size: .9375rem; line-height: 1.5; }
  .flow-practice-footer .flow-footer-nav .flow-nav__nested .flow-nav__link:hover { color: var(--flow-footer-accent); text-decoration: underline; text-underline-offset: .3em; transform: none; }
  .flow-practice-footer__columns { display: grid; grid-template-columns: repeat(auto-fit,minmax(12rem,1fr)); gap: 2rem; }
  .flow-practice-footer__urgent { margin-top: 3rem; border-block: 1px solid color-mix(in srgb,var(--flow-footer-ink) 20%,transparent); padding-block: 1.5rem; display: flex; align-items: center; justify-content: space-between; gap: 2rem; }
  .flow-practice-footer__urgent p { margin: 0; max-width: 45rem; font-size: .9375rem; line-height: 1.7; }
  .flow-practice-footer__action { display: inline-flex; align-items: center; justify-content: space-between; gap: 1.5rem; flex-shrink: 0; min-height: 44px; padding: .65rem 1rem; border: 1px solid color-mix(in srgb,var(--flow-footer-ink) 50%,transparent); border-radius: 999px; font-size: .875rem; font-weight: 600; text-decoration: none; }
  .flow-practice-footer__action:hover { background: color-mix(in srgb,var(--flow-footer-ink) 10%,transparent); }
  .flow-practice-footer__legal { margin-top: 2rem; }
  .flow-practice-footer__legal ul { display: flex; flex-wrap: wrap; gap: .75rem 2rem; list-style: none; padding: 0; }
  .flow-practice-footer__legal a { display: inline-block; padding-block: .5rem; font-size: .875rem; }
  .flow-practice-footer__copyright { margin: 2rem 0 0; font-size: .8125rem; line-height: 1.7; color: color-mix(in srgb,var(--flow-footer-ink) 80%,var(--flow-footer-ground)); }
  .flow-practice-footer a:focus-visible { outline: 3px solid #ffeb3b; outline-offset: 3px; background: #ffeb3b; color: #172432; }
  @media (max-width: 48rem) {
    .flow-practice-footer__container { padding-inline: 1.25rem; }
    .flow-practice-footer__signature > div, .flow-practice-footer__urgent { flex-direction: column; align-items: flex-start; }
    .flow-practice-footer .flow-footer-nav > .flow-nav { grid-template-columns: 1fr; gap: 2rem; }
  }
}

@scope (.theme-canvas) {
  /* Flush accordions share the section ground, so their ink must follow its tone. */
  :is([data-surface-tone="dark"], .flow-section--tone-light) .flow-listaccordion--flush :is(.flow-listaccordion__header, .flow-listaccordion__panel-inner) { color: var(--flow-fg-on-dark, #fff); }
  :is([data-surface-tone="dark"], .flow-section--tone-light) .flow-listaccordion--flush .flow-listaccordion__item { border-color: color-mix(in srgb,var(--flow-fg-on-dark, #fff) 30%,transparent); }
  :is([data-surface-tone="dark"], .flow-section--tone-light) .flow-listaccordion--flush .flow-listaccordion__header:is(:hover,[aria-expanded="true"]) { background: color-mix(in srgb,var(--flow-fg-on-dark, #fff) 8%,transparent); }
  :is([data-surface-tone="dark"], .flow-section--tone-light) .flow-listaccordion--flush .flow-listaccordion__link { color: var(--flow-link-on-dark, #fff); }
}

@scope (.theme-canvas) {
  .flow-practice-footer { --footer-space: 4rem; text-align: left; overflow-wrap: anywhere; }
  .flow-practice-footer[data-footer-density="compact"] { --footer-space: 2rem; }
  .flow-practice-footer__body { padding-block: var(--footer-space) 2rem; }
  .flow-practice-footer__signature { padding-block: var(--footer-space); }
  .flow-practice-footer__introduction { max-width: 36rem; margin: 1.25rem 0 0; font-size: 1.0625rem; line-height: 1.7; color: inherit; }
  .flow-practice-footer[data-footer-alignment="center"] { text-align: center; }
  .flow-practice-footer[data-footer-alignment="center"] .flow-practice-footer__signature > div { justify-content: center; }
  .flow-practice-footer[data-footer-alignment="center"] .flow-practice-footer__introduction { margin-inline: auto; }
  .flow-practice-footer[data-footer-alignment="center"] .flow-footer-nav .flow-nav__link { justify-content: center; }
  .flow-practice-footer[data-footer-alignment="center"] :is(.flow-practice-footer__urgent,.flow-practice-footer__legal ul) { justify-content: center; }
  .flow-practice-footer[data-footer-style="minimal"] .flow-practice-footer__signature { background: transparent; padding-bottom: 0; }
  .flow-practice-footer[data-footer-style="minimal"] .flow-practice-footer__signature h2 { font-family: inherit; font-size: 1.75rem; font-weight: 600; }
  .flow-practice-footer[data-footer-style="minimal"] .flow-practice-footer__body { padding-top: 2rem; }
  .flow-practice-footer[data-footer-style="minimal"] .flow-practice-footer__urgent { margin-top: 2rem; }
  .flow-practice-footer[data-footer-style="columns"] .flow-practice-footer__signature { background: transparent; }
  .flow-practice-footer[data-footer-style="columns"] .flow-practice-footer__signature h2 { font-size: 2.5rem; }
  @media (min-width: 64rem) {
    .flow-practice-footer[data-footer-style="columns"] { display: grid; grid-template-columns: minmax(2rem,1fr) minmax(0,20rem) minmax(0,52rem) minmax(2rem,1fr); }
    .flow-practice-footer[data-footer-style="columns"] .flow-practice-footer__signature { grid-column: 2; padding-inline: 0; }
    .flow-practice-footer[data-footer-style="columns"] .flow-practice-footer__signature > div { display: block; padding-inline: 2rem; }
    .flow-practice-footer[data-footer-style="columns"] .flow-practice-footer__body { grid-column: 3; min-width: 0; width: 100%; }
    .flow-practice-footer[data-footer-style="columns"] .flow-footer-nav > .flow-nav { grid-template-columns: repeat(auto-fit,minmax(9rem,1fr)); gap: 1.5rem; }
    .flow-practice-footer[data-footer-style="columns"] .flow-practice-footer__urgent { flex-wrap: wrap; }
    .flow-practice-footer[data-footer-style="columns"]:not(:has(.flow-practice-footer__signature)) .flow-practice-footer__body { grid-column: 2 / 4; }
  }
  @media (max-width: 48rem) {
    .flow-practice-footer[data-footer-alignment="center"] :is(.flow-practice-footer__signature > div,.flow-practice-footer__urgent) { align-items: center; }
  }
}

@scope (.theme-canvas) {
  .flow-practice-footer__signature h2 { color: inherit; }
  .flow-practice-footer[data-footer-style="statement"] .flow-practice-footer__signature { color: var(--flow-footer-band-ink,var(--flow-footer-ink)); }
  .flow-practice-footer[data-footer-style="statement"] .flow-practice-footer__signature a { color: inherit; }
  .flow-practice-footer__identity { min-width: 0; max-width: 100%; }
  .flow-practice-footer__utility { grid-column: 1 / -1; min-width: 0; width: 100%; }
  .flow-practice-footer__logo { display: flex; align-items: center; max-width: 100%; min-height: 44px; margin-bottom: 1.5rem; }
  .flow-practice-footer__logo img { display: block; width: 100%; height: auto; max-height: 160px; object-fit: contain; object-position: left; }
  .flow-practice-footer[data-footer-alignment="center"] .flow-practice-footer__logo { margin-inline: auto; }
  .flow-practice-footer[data-footer-alignment="center"] .flow-practice-footer__logo img { object-position: center; }
}

@scope (.theme-canvas) {
  .flow-practice-footer a:focus-visible { color: #172432 !important; background: #ffeb3b; outline: 3px solid #ffeb3b; outline-offset: 3px; box-shadow: 0 0 0 6px #172432; }
}

@scope (.theme-canvas) {
  .flow-practice-footer__accreditation { flex: 0 1 auto; max-width: 100%; margin: 0; }
  .flow-practice-footer__accreditation img { display: block; width: 100%; height: auto; }
  .flow-practice-footer[data-footer-logo-placement="accreditation"] .flow-practice-footer__signature > div { flex-wrap: wrap; gap: 2rem 3rem; }
  .flow-practice-footer[data-footer-logo-placement="accreditation"] .flow-practice-footer__identity { flex: 1 1 22rem; }
  .flow-practice-footer[data-footer-logo-placement="accreditation"] .flow-practice-footer__contact { flex-basis: 100%; }
  .flow-practice-footer[data-footer-style="columns"] .flow-practice-footer__accreditation { margin-top: 2rem; }
  .flow-practice-footer[data-footer-alignment="center"] .flow-practice-footer__accreditation { margin-inline: auto; }
  @media (max-width: 48rem) {
    .flow-practice-footer[data-footer-logo-placement="accreditation"] .flow-practice-footer__identity { flex-basis: auto; }
  }
}

/* Rich-text links on dark fills use the same editable foreground contract as image bands. */
@scope (.theme-canvas) {
  .flow-section[data-surface-tone="dark"] .flow-richtext a { color:var(--flow-link-on-dark, #ffffff); }
}

/* Outline follows the same dark-surface signals as the other button variants.
   Set the ink on the button itself: intermediate layout wrappers can retain
   light-surface ink even when the section declares a dark background. */
@scope (.theme-canvas) {
  [data-surface-tone="dark"] .flow-button--outline,
  .flow-section--tone-light .flow-button--outline,
  .flow-hero:not(.flow-hero--transparent) .flow-button--outline,
  .flow-hero[data-background-asset] .flow-button--outline {
    --nhs-outline-ink: var(--color-nhs-white);
  }
  .nhs-hero:not(.flow-hero--transparent):not([data-background-asset]):not([data-presentation="editorial"]) .flow-button--outline {
    --nhs-outline-ink: var(--color-nhs-blue);
  }
  .nhs-hero:not(.flow-hero--transparent):not([data-background-asset]):not([data-presentation="editorial"]) .flow-button--outline:not(:focus-visible) {
    color: var(--nhs-outline-ink);
  }
  .flow-button--outline {
    display: inline-flex;
    align-items: center;
    justify-content: space-between;
    gap: 1.5rem;
    min-height: 48px;
    padding: .7rem 1.4rem;
    border: 1px solid color-mix(in srgb, currentColor 80%, transparent);
    border-radius: 999px;
    background: transparent;
    color: var(--nhs-outline-ink, inherit);
    box-shadow: none;
    font-size: 1rem;
    line-height: 1.5;
    text-decoration: none;
  }
  .flow-button--outline:visited { color: var(--nhs-outline-ink, inherit); }
  .flow-button--outline:hover:not(:focus) {
    background: color-mix(in srgb, currentColor 10%, transparent);
    color: var(--nhs-outline-ink, inherit);
    border-color: currentColor;
    text-decoration: none;
  }
  .flow-button--outline .nhs-button__arrow { width: 20px; height: 20px; }
  @media (prefers-reduced-motion: no-preference) {
    .flow-button--outline .nhs-button__arrow { transition: transform 160ms ease; }
    .flow-button--outline:hover .nhs-button__arrow { transform: translateX(3px); }
  }
}

/* Explicit list accents win over the editorial position palette. Page overrides are inline. */
@scope (.theme-canvas) {
  .flow-liststats-widget[data-presentation="editorial"] .flow-liststats__value[data-stat-accent="accent"] { color: var(--flow-ink-accent-on-dark); }
  .flow-liststats-widget[data-presentation="editorial"] .flow-liststats__value[data-stat-accent="emphasis"] { color: var(--flow-ink-emphasis-on-dark); }
  .flow-liststats-widget[data-presentation="editorial"] .flow-liststats__value[data-stat-accent="subtle"] { color: var(--flow-ink-subtle-on-dark); }
}

/* Stats presentations: optional skins share the canonical grid and item spans.
   No new brand tokens: Spotlight reuses the existing editorial palette. */
@scope (.theme-canvas) {
  .flow-liststats-widget:not([data-presentation])[data-density="compact"] .flow-liststats__figure { padding: .75rem; gap: .25rem; }
  .flow-liststats-widget:not([data-presentation])[data-density="compact"] .flow-liststats__value { font-size: 2rem; }
  .flow-liststats-widget:not([data-presentation]) .flow-liststats__card--link:hover { background: color-mix(in srgb, currentColor 6%, transparent); }
  .flow-liststats-widget:is([data-presentation="spotlight"], [data-presentation="minimal"]) { --stats-gap: var(--space-md); --stats-padding: clamp(1.25rem, 2.5cqi, 2.25rem); --stats-size: clamp(2.5rem, 4.5cqi, 4rem); }
  .flow-liststats-widget:is([data-presentation="spotlight"], [data-presentation="minimal"])[data-density="compact"] { --stats-gap: var(--space-sm); --stats-padding: 1rem; --stats-size: clamp(2rem, 3.5cqi, 3rem); }
  .flow-liststats-widget:is([data-presentation="spotlight"], [data-presentation="minimal"]) .flow-liststats { gap: var(--stats-gap); color: inherit; background: none; border: 0; box-shadow: none; backdrop-filter: none; padding: 0; margin: 0; isolation: auto; }
  .flow-liststats-widget:is([data-presentation="spotlight"], [data-presentation="minimal"]) .flow-liststats::before { content: none; }
  .flow-liststats-widget:is([data-presentation="spotlight"], [data-presentation="minimal"]) .flow-liststats__card { padding: 0; border: 0; background: none; box-shadow: none; min-width: 0; }
  .flow-liststats-widget:is([data-presentation="spotlight"], [data-presentation="minimal"]) .flow-liststats .flow-liststats__inner { border: 0; box-shadow: none; padding: 0; color: inherit; border-radius: 0; background: none; }
  .flow-liststats-widget:is([data-presentation="spotlight"], [data-presentation="minimal"]) .flow-liststats__figure { padding: var(--stats-padding); gap: 0; justify-content: flex-start; min-width: 0; }
  .flow-liststats-widget:is([data-presentation="spotlight"], [data-presentation="minimal"]) .flow-liststats__value { font-size: var(--stats-size); font-weight: 650; line-height: 1.15; letter-spacing: -.04em; text-shadow: none; overflow-wrap: anywhere; }
  .flow-liststats-widget:is([data-presentation="spotlight"], [data-presentation="minimal"]) .flow-stat-affix { font-size: .52em; letter-spacing: -.02em; }
  .flow-liststats-widget:is([data-presentation="spotlight"], [data-presentation="minimal"]) .flow-liststats__eyebrow { color: inherit; font-size: .75rem; line-height: 1.5; letter-spacing: .08em; margin-bottom: .75rem; }
  .flow-liststats-widget:is([data-presentation="spotlight"], [data-presentation="minimal"]) .flow-liststats__label { color: inherit; text-transform: none; font-size: .9375rem; font-weight: 400; letter-spacing: normal; line-height: 1.6; margin-top: 1.25rem; }
  .flow-liststats-widget:is([data-presentation="spotlight"], [data-presentation="minimal"]) .flow-liststats__label p + p { margin-top: .35rem; font-size: .8125rem; }
  .flow-liststats-widget:is([data-presentation="spotlight"], [data-presentation="minimal"]) .flow-liststats__label strong { font-weight: 650; }
  .flow-liststats-widget[data-presentation="spotlight"] .flow-liststats .flow-liststats__inner { border-radius: 1.25rem; background: var(--flow-editorial-ground, #061b28); color: #edf5f7; border: 1px solid #ffffff30; box-shadow: 0 12px 32px #00000012; }
  .flow-liststats-widget[data-presentation="spotlight"] .flow-liststats__value { color: var(--flow-editorial-accent); }
  .flow-liststats-widget[data-presentation="spotlight"] .flow-liststats__card:nth-child(2n) .flow-liststats__value:not([data-stat-accent]) { color: var(--flow-editorial-secondary); }
  .flow-liststats-widget[data-presentation="spotlight"] .flow-liststats__card:nth-child(3n) .flow-liststats__value:not([data-stat-accent]) { color: var(--flow-editorial-tertiary); }
  .flow-liststats-widget[data-presentation="spotlight"] .flow-liststats__card:nth-child(4n) .flow-liststats__value:not([data-stat-accent]) { color: var(--flow-editorial-accent); }
  .flow-liststats-widget[data-presentation="spotlight"] .flow-liststats__value::after { content: ''; display: block; height: 3px; margin-top: 1.25rem; background: currentColor; border-radius: 2px; opacity: .8; }
  .flow-liststats-widget[data-presentation="spotlight"] .flow-liststats__label p + p { color: #b9c2d0; }
  .flow-liststats-widget[data-presentation="spotlight"] .flow-liststats__value[data-stat-accent="accent"] { color: var(--flow-ink-accent-on-dark); }
  .flow-liststats-widget[data-presentation="spotlight"] .flow-liststats__value[data-stat-accent="emphasis"] { color: var(--flow-ink-emphasis-on-dark); }
  .flow-liststats-widget[data-presentation="spotlight"] .flow-liststats__value[data-stat-accent="subtle"] { color: var(--flow-ink-subtle-on-dark); }
  .flow-liststats-widget[data-presentation="minimal"] .flow-liststats .flow-liststats__inner { border-top: 1px solid color-mix(in srgb, currentColor 30%, transparent); }
  .flow-liststats-widget[data-presentation="minimal"] .flow-liststats__figure { padding-inline: .5rem; }
  .flow-liststats-widget[data-presentation="minimal"] .flow-liststats__value { color: inherit; font-weight: 500; letter-spacing: -.055em; }
  .flow-liststats-widget[data-presentation="minimal"] .flow-liststats__value[data-stat-accent="accent"] { color: var(--flow-ink-accent); }
  .flow-liststats-widget[data-presentation="minimal"] .flow-liststats__value[data-stat-accent="emphasis"] { color: var(--flow-ink-emphasis); }
  .flow-liststats-widget[data-presentation="minimal"] .flow-liststats__value[data-stat-accent="subtle"] { color: var(--flow-ink-subtle); }
  :is(.flow-section--tone-light, [data-surface-tone="dark"]) .flow-liststats-widget[data-presentation="minimal"] .flow-liststats__value[data-stat-accent="accent"] { color: var(--flow-ink-accent-on-dark); }
  :is(.flow-section--tone-light, [data-surface-tone="dark"]) .flow-liststats-widget[data-presentation="minimal"] .flow-liststats__value[data-stat-accent="emphasis"] { color: var(--flow-ink-emphasis-on-dark); }
  :is(.flow-section--tone-light, [data-surface-tone="dark"]) .flow-liststats-widget[data-presentation="minimal"] .flow-liststats__value[data-stat-accent="subtle"] { color: var(--flow-ink-subtle-on-dark); }
  .flow-liststats-widget:is([data-presentation="spotlight"], [data-presentation="minimal"]) .flow-liststats__link:hover .flow-liststats__label { text-decoration: underline; text-underline-offset: .2em; }
  .flow-liststats-widget:is([data-presentation="spotlight"], [data-presentation="minimal"]) .flow-liststats__link:focus-visible { outline: 3px solid #ffeb3b; outline-offset: 3px; box-shadow: 0 0 0 6px #172432; }
  @container flow-stats (max-width: 479px) {
    .flow-liststats-widget:is([data-presentation="spotlight"], [data-presentation="minimal"]) .flow-liststats__value { font-size: clamp(1.5rem, 8cqi, 2.75rem); }
    .flow-liststats-widget[data-presentation="spotlight"] .flow-liststats__figure { padding: 1rem; }
  }
}

@scope (.theme-canvas) {
  .flow-liststats-widget { container-name: flow-stats; }
  .flow-liststats-widget:is([data-presentation="spotlight"], [data-presentation="minimal"]) .flow-liststats__card { container: flow-stat-card / inline-size; }
  .flow-liststats__label { overflow-wrap: anywhere; }
  @container flow-stat-card (max-width: 240px) {
    .flow-liststats-widget .flow-liststats .flow-liststats__value { font-size: clamp(1.25rem, 16cqi, 2.75rem); overflow-wrap: anywhere; }
  }
}

@scope (.theme-canvas) {
  :is(.flow-section--tone-light, [data-surface-tone="dark"]) .flow-liststats-widget[data-presentation="minimal"] { color: var(--flow-fg-on-dark, #fff); }
}

@scope (.theme-canvas) {
  /* Keep established desktop Editorial typography; only narrow strips need a
     smaller ceiling so a two-column mobile layout can hold figures and affixes. */
  @container flow-stats (max-width: 479px) {
    .flow-liststats-widget.flow-liststats-widget .flow-liststats .flow-liststats__value { font-size: clamp(1.25rem, 7cqi, 2.75rem); }
    .flow-liststats-widget.flow-liststats-widget:not([data-presentation="spotlight"]):not([data-presentation="minimal"]) .flow-liststats__figure { padding-inline: .5rem; }
  }
}

/* The NHS card owns its yellow focus ring. Keep the stat's own surface so
   authored value colours do not end up against the global yellow link fill. */
@scope (.theme-canvas) {
  .flow-liststats-widget:is([data-presentation="spotlight"], [data-presentation="editorial"]) .flow-liststats__link:focus-visible { background-color: var(--flow-editorial-ground, #061b28) !important; color: #edf5f7 !important; box-shadow: none !important; }
  .flow-liststats-widget[data-presentation="minimal"] .flow-liststats__link:focus-visible { background-color: transparent !important; color: inherit !important; box-shadow: none !important; }
}

/* A full-bleed section extends its background, not the reading width of a
   standalone stats strip. Cover the public widget and the editor block shell;
   nested column widgets continue to use their column's width. */
@scope (.theme-canvas) {
  .flow-section--width-full_bleed > .flow-section__inner > .flow-liststats-widget:not([data-presentation="editorial"]),
  .flow-section--width-full_bleed > .flow-section__inner > .flow-block > .flow-liststats-widget:not([data-presentation="editorial"]) {
    width: calc(100% - 2 * var(--container-gutter));
    max-width: calc(var(--container-max) - 2 * var(--container-gutter));
    margin-inline: auto;
  }
}

/* NHS care journey: patient tasks lead; supporting information is quiet.
   Uses the scene's existing CMS colour, composition and image-layer controls. */
@scope (.theme-canvas) {
  .flow-care-journey:is([data-practice-panels], :has([data-status-badge])) .flow-care-journey__message { position: relative; isolation: isolate; width: fit-content; max-width: 100%; margin-inline: auto; padding: 0; border: 0; border-radius: 0; background: transparent; box-shadow: none; backdrop-filter: none; }
  /* A feathered photographic scrim keeps unboxed type readable. */
  .flow-care-journey:is([data-practice-panels], :has([data-status-badge])) .flow-care-journey__shade { background: linear-gradient(180deg, var(--scene-ground), color-mix(in srgb, var(--scene-ground) 85%, transparent) 35%, transparent 80%); }

  .flow-care-journey:is([data-practice-panels], :has([data-status-badge])) .flow-care-journey__message .flow-hero__headline { font-size: clamp(2rem, 3.1cqi, 3rem); letter-spacing: -.025em; text-shadow: 0 2px 12px #07172880; }
  .flow-care-journey:is([data-practice-panels], :has([data-status-badge])) .flow-care-journey__message .flow-hero__eyebrow { margin-bottom: .8rem; font-size: .65rem; color: var(--scene-ink); }
  .flow-care-journey:is([data-practice-panels], :has([data-status-badge])) .flow-care-journey__message .flow-hero__subhead { margin-top: .9rem; font-size: .9375rem; color: var(--scene-ink); text-shadow: 0 1px 6px #071728; }
  .flow-care-journey:is([data-practice-panels], :has([data-status-badge]))[data-composition="centre"] .flow-care-journey__content { gap: 1.25rem; padding-block: 2rem; }
  .flow-care-journey:is([data-practice-panels], :has([data-status-badge]))[data-composition="centre"][data-journey-phase] .flow-care-journey__information { min-height: 8.5rem; }
  .flow-care-journey:is([data-practice-panels], :has([data-status-badge]))[data-composition="centre"][data-journey-active] .flow-care-journey__content { translate: 0 calc(-8rem - var(--journey-entry-offset, 0px) / 2); }
  .flow-care-journey:is([data-practice-panels], :has([data-status-badge])) .flow-care-journey__panel { background: color-mix(in srgb, var(--scene-ground) 94%, transparent); backdrop-filter: blur(18px); border-radius: 1rem; box-shadow: 0 1rem 3rem #04162630; }
  .flow-care-journey:is([data-practice-panels], :has([data-status-badge])) .flow-care-journey__panel::after { display: none; }
  .flow-care-journey:is([data-practice-panels], :has([data-status-badge])) .flow-care-journey__stats { background: transparent; border: 0; border-radius: 0; padding: 0; position: relative; isolation: isolate; }
  .flow-care-journey:is([data-practice-panels], :has([data-status-badge])) .flow-care-journey__stats { text-shadow: 0 1px 4px #071728, 0 2px 12px #071728; }

  .flow-care-journey:is([data-practice-panels], :has([data-status-badge]))[data-has-stats] .flow-care-journey__stats .flow-liststats-widget[data-presentation] .flow-liststats__value { font-size: clamp(1.8rem, 2.8cqi, 2.5rem); }
  .flow-care-journey:is([data-practice-panels], :has([data-status-badge]))[data-has-stats] .flow-care-journey__stats .flow-liststats-widget[data-presentation] .flow-liststats__card { padding: .65rem 1.5rem; }
  .flow-care-journey:is([data-practice-panels], :has([data-status-badge])) .flow-care-journey__stats .flow-liststats__label { font-size: .875rem; margin-top: .6rem; color: var(--scene-ink); }
  .flow-care-journey:is([data-practice-panels], :has([data-status-badge])) .flow-care-journey__stats .flow-liststats__label p + p { font-size: .75rem; }

  /* One compact information line, wrapping naturally on small screens. */
  .flow-care-journey .flow-care-journey__practice-panels { align-items: center; gap: .5rem 2rem; margin-top: 1.5rem; padding: .9rem 1.25rem; border: 1px solid color-mix(in srgb, var(--scene-ink) 18%, transparent); border-radius: .75rem; background: color-mix(in srgb, var(--scene-ground) 82%, transparent); backdrop-filter: blur(12px); box-shadow: 0 8px 24px #06142118; }
  .flow-care-journey[data-journey-active] .flow-care-journey__practice-panels { top: 1.5rem; margin-top: 0; }
  .flow-care-journey__practice-panels::before { display: none; }
  .flow-care-journey .flow-care-journey__practice-panel { align-items: center; gap: .55rem; max-width: none; width: auto; padding: 0; border: 0; border-radius: 0; background: none; box-shadow: none; backdrop-filter: none; }
  .flow-care-journey__practice-panel > div { display: flex; flex-wrap: wrap; align-items: baseline; gap: .35rem .65rem; }
  .flow-care-journey__practice-panel:not(.flow-care-journey__practice-panel--hours) .flow-care-journey__panel-label { position: absolute; width: 1px; height: 1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .flow-care-journey .flow-care-journey__practice-panel :is(p, address) { margin: 0; font-size: .875rem; line-height: 1.6; color: var(--scene-ink); }
  .flow-care-journey .flow-care-journey__practice-panel small { margin: 0; font-size: .75rem; color: color-mix(in srgb, var(--scene-ink) 82%, transparent); }
  .flow-care-journey .flow-care-journey__practice-panel svg { width: 1rem; height: 1rem; margin: 0; }
  .flow-care-journey .flow-care-journey__status-dot { width: .6rem; height: .6rem; margin: 0; }
  /* The label conveys status as well as colour; a steady halo avoids flashing. */
  .flow-care-journey .flow-care-journey__practice-panel[data-status="open"] .flow-care-journey__status-dot { background: #34d399; box-shadow: 0 0 0 4px #34d39920, 0 0 13px #34d39980; }
  .flow-care-journey .flow-care-journey__practice-panel[data-status="soon"] .flow-care-journey__status-dot { background: #fbbf24; box-shadow: 0 0 0 4px #fbbf2420, 0 0 13px #fbbf2450; }
  .flow-care-journey__practice-panel .flow-token-block, .flow-care-journey__practice-panel .flow-token-block__address { color: inherit; }
  .flow-care-journey__practice-panel .flow-token-block__address { display: block; }
  .flow-care-journey__practice-panel .flow-token-block__line { display: inline; }
  .flow-care-journey__practice-panel .flow-token-block__line:not(:last-child)::after { content: ', '; }

  /* Centre + Large gives a panoramic grounded layer; other layer choices keep
     their existing sizes. The media itself remains replaceable in the editor. */
  .flow-care-journey__media-layer[data-position="centre"][data-size="large"] { width: 100%; height: auto; aspect-ratio: 3; right: 0; bottom: -1px; mask-image: none; }
  .flow-care-journey__media-layer[data-position="centre"][data-size="large"] img { object-fit: contain; object-position: center bottom; }
  .flow-care-journey__meteors { inset: 10% auto auto 3%; width: 43%; height: 20%; overflow: hidden; mask-image: none; }
  .flow-care-journey__meteors i { height: 1.5px; background: linear-gradient(90deg, transparent, #bddfff30 25%, #ddecffb3 75%, #fff); filter: drop-shadow(0 0 2px #d5eaff80); }
  .flow-care-journey__meteors i::after { width: 3px; height: 3px; top: -.75px; background: #fff; box-shadow: 0 0 3px #fff, 0 0 9px #c9e5ffb3; }
  .flow-care-journey:not([data-journey-phase]) .flow-care-journey__ground,
  .flow-care-journey:not([data-journey-phase]) .flow-care-journey__edge { display: none; }
  @media (max-width: 999px) {
    .flow-care-journey .flow-care-journey__practice-panels { display: flex; justify-content: center; gap: .65rem; }
    .flow-care-journey .flow-care-journey__practice-panel--hours { margin-left: 0; align-items: flex-start; }
    .flow-care-journey .flow-care-journey__status-dot { margin-top: .4rem; }
  }
  @container theme-canvas (max-width: 999px) {
    .flow-care-journey .flow-care-journey__practice-panels { display: flex; justify-content: center; gap: .65rem; }
    .flow-care-journey .flow-care-journey__practice-panel--hours { margin-left: 0; align-items: flex-start; }
    .flow-care-journey .flow-care-journey__status-dot { margin-top: .4rem; }
  }
}

/* Practice header: selectable in Theme / Header. NHS identity uses original artwork,
   with its clear space included in the SVG. Menus remain Navigation-owned. */
@scope (.theme-canvas) {
  .nhs-practice-header { background:var(--flow-header-ground); color:var(--flow-header-ink); position:relative; z-index:30; }
  .nhs-practice-header__identity, .nhs-practice-header__navigation, .nhs-practice-header__mobile { max-width:1280px; margin-inline:auto; padding-inline:clamp(20px,3vw,40px); }
  .nhs-practice-header__identity { display:flex; align-items:center; justify-content:space-between; gap:24px; min-height:88px; }
  .nhs-practice-header__name { color:inherit; font-family:var(--flow-editorial-font,Georgia,serif); font-size:clamp(24px,2.6cqi,36px); font-weight:600; line-height:1.2; letter-spacing:-.025em; text-decoration:none; overflow-wrap:anywhere; padding-block:20px; }
  .nhs-practice-header__nhs { width:280px; height:auto; flex-shrink:0; display:block; background:#fff; }
  .nhs-practice-header__bar { background:var(--flow-header-navigation); border-top:1px solid color-mix(in srgb,currentColor 12%,transparent); border-bottom:1px solid color-mix(in srgb,currentColor 12%,transparent); }
  .nhs-practice-header__navigation { display:flex; align-items:center; justify-content:space-between; gap:20px; min-height:68px; }
  .nhs-practice-header .flow-nav { margin:0; padding:0; gap:4px; }
  .nhs-practice-header .flow-nav__item { margin:0; padding:0; }
  .nhs-practice-header .flow-nav__link, .nhs-practice-header .flow-nav__label, .nhs-practice-header .flow-nav__trigger, .nhs-practice-header__fallback a { display:flex; align-items:center; min-height:44px; padding:10px 12px; color:var(--flow-header-ink); font-size:15px; font-weight:600; text-decoration:none; border-radius:6px; background:transparent; }
  .nhs-practice-header .flow-nav__link:hover, .nhs-practice-header .flow-nav__trigger:hover, .nhs-practice-header .flow-header-nav .flow-nav__trigger[aria-expanded="true"] { color:#003078; background:#e0edf9; text-decoration:underline; text-underline-offset:5px; }
  .nhs-practice-header__registration { margin-left:auto; flex-shrink:0; padding-block:10px; }
  .nhs-practice-header__registration .flow-nav__link { gap:18px; border-radius:999px; padding:12px 22px; background:var(--color-nhs-blue); color:#fff; box-shadow:0 3px 0 #003e79; }
  .nhs-practice-header__registration .flow-nav__link::after { content:'→'; font-size:20px; line-height:1; }
  .nhs-practice-header__registration .flow-nav__link:hover { background:#004a91; color:#fff; }
  .nhs-practice-header a:focus-visible, .nhs-practice-header button:focus-visible { outline:3px solid #ffdd00; outline-offset:2px; background:#ffdd00; color:#212b32; box-shadow:0 3px 0 #212b32; transition:none; }
  .nhs-practice-header__menu { display:none; align-items:center; gap:9px; min-height:44px; font-size:15px; font-weight:600; background:transparent; border:1px solid color-mix(in srgb,currentColor 35%,transparent); border-radius:999px; padding:9px 14px; color:inherit; cursor:pointer; }
  .nhs-practice-header__menu:hover { background:color-mix(in srgb,currentColor 7%,transparent); }
  .nhs-practice-header__menu svg { flex-shrink:0; }
  .nhs-practice-header__mobile { padding-block:0 16px; }
  .nhs-practice-header__fallback { display:flex; flex-wrap:wrap; gap:4px; list-style:none; padding:0; }
  @media (min-width:1100px) { .nhs-practice-header__mobile { display:none; } }
  @media (max-width:1099px) { .nhs-practice-header__desktop { display:none; } .nhs-practice-header__menu { display:flex; } }
  @media (max-width:599px) {
    .nhs-practice-header__identity { flex-wrap:wrap; gap:0; justify-content:center; }
    .nhs-practice-header__name { font-size:24px; text-align:center; padding-block:20px 8px; width:100%; }
    .nhs-practice-header__identity:not(:has(img)) .nhs-practice-header__name { padding-bottom:20px; }
    .nhs-practice-header__navigation { gap:8px; }
    .nhs-practice-header__registration .flow-nav__link { padding:11px 16px; gap:10px; font-size:14px; }
  }
}

/* Practice identity uses the media library's original vector, with a text fallback. */
@scope (.theme-canvas) {
  .nhs-practice-header__name { display: flex; align-items: center; gap: 1rem; min-width: 0; }
  .nhs-practice-header__logo { display: block; max-width: 100%; height: auto; max-height: 110px; object-fit: contain; object-position: left center; }
  .nhs-practice-header .nhs-practice-header__registration .flow-nav__link:hover { text-decoration: none; }
  .nhs-practice-header .nhs-practice-header__registration .flow-nav__link:hover::after { text-decoration: none; }
  @media (max-width: 600px) {
    .nhs-practice-header__name { flex-direction: column; align-items: flex-start; gap: .5rem; }
    .nhs-practice-header__logo { max-width: min(100%, 300px); }
  }
}

@scope (.theme-canvas) {
  /* Patient tasks remain the visual centre; existing scene colours own the palette. */
  .flow-care-journey .flow-care-journey__panel { border-radius: 1.5rem; background: linear-gradient(145deg, color-mix(in srgb, var(--scene-ground) 94%, var(--scene-accent)), var(--scene-ground)); border: 1px solid color-mix(in srgb, var(--scene-accent) 30%, transparent); box-shadow: 0 20px 60px #05132330, inset 0 1px 0 color-mix(in srgb, var(--scene-ink) 10%, transparent); }
  .flow-care-journey .flow-care-journey__panel .flow-hero__actions { gap: .65rem; }
  .flow-care-journey .flow-care-journey__panel .flow-hero__cta.flow-button { border-radius: .8rem; padding-inline: 1rem; font-weight: 600; box-shadow: none; text-decoration: none; }
  .flow-care-journey .flow-care-journey__panel .flow-hero__cta.flow-button:hover { text-decoration: none; border-color: var(--scene-accent); }
  .flow-care-journey .flow-care-journey__panel .flow-hero__cta svg { flex-shrink: 0; }
  .flow-care-journey .flow-care-journey__practice-panels[data-compact] .flow-care-journey__status-dot { margin: 0; }
}

@scope (.theme-canvas) {
 @media (min-width: 1000px) and (min-height: 700px) and (prefers-reduced-motion: no-preference) {
  .flow-care-journey[data-height="compact"][data-journey-active] { height: calc(calc(var(--journey-viewport-height, 100svh) * .82) + var(--journey-travel)); }
  .flow-care-journey[data-height="compact"] .flow-care-journey__stage { min-height: calc(var(--journey-viewport-height, 100svh) * .82); }
  .flow-care-journey[data-height="compact"][data-journey-active] .flow-care-journey__stage { height: calc(var(--journey-viewport-height, 100svh) * .82); min-height: 0; }
  .flow-care-journey[data-height="compact"][data-journey-phase] .flow-care-journey__content { translate: none; }
 }
}

/* Transparent editorial heroes inherit the section surface and ink. */
@scope (.theme-canvas) {
  .flow-hero[data-presentation="editorial"].flow-hero--transparent:not([data-background-asset]) {
    background: none;
    color: inherit;
  }
  .flow-hero[data-presentation="editorial"].flow-hero--transparent:not([data-background-asset]) :is(.flow-hero__headline, .flow-hero__subhead):not([class*="flow-ink-"]) { color: inherit; }
  .flow-hero[data-presentation="editorial"].flow-hero--transparent:not([data-background-asset])::after { background: none; }
  .flow-hero.flow-hero--transparent:not([data-background-asset]) :is(.flow-hero__headline-accent, .flow-hero__eyebrow) { color: inherit; }
  .flow-hero[data-presentation="editorial"].flow-hero--transparent:not([data-background-asset]) :is(.flow-hero__headline-accent, .flow-hero__eyebrow, .flow-hero__cta.flow-button--tertiary:not(:focus-visible)) { color: inherit; }
  .flow-hero[data-presentation="editorial"].flow-hero--transparent:not([data-background-asset]) .flow-hero__cta.flow-button--tertiary:hover:not(:focus-visible) { color: inherit; background: color-mix(in srgb, currentColor 8%, transparent); border-color: currentColor; }
}

/* Constrained, editor-authored header rows. DOM order stays the reading order. */
@scope (.theme-canvas) {
.nhs-composed-header__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px 24px;
  max-width: 1280px;
  margin-inline: auto;
  padding: 16px clamp(20px, 3vw, 40px);
}
.nhs-composed-header__row + .nhs-composed-header__row {
  border-top: 1px solid color-mix(in srgb, var(--flow-header-ink) 12%, transparent);
}
.nhs-composed-header .nhs-composed-header__identity {
  width: auto;
  flex: 0 1 auto;
  max-width: 100%;
  padding-block: 4px;
  font-size: clamp(24px, 2.6cqi, 32px);
  text-align: start;
}
.nhs-composed-header__navigation { min-width: 0; max-width: 100%; }
.nhs-composed-header .nhs-practice-header__nhs { max-width: 100%; width: 210px; }
.nhs-composed-header .nhs-practice-header__registration { margin-inline-start: 0; padding-block: 4px; max-width: 100%; }
.nhs-composed-header .nhs-practice-header__registration .flow-nav__link { white-space: normal; overflow-wrap: anywhere; }
.nhs-composed-header--centre .nhs-composed-header__row { justify-content: center; }
.nhs-composed-header--centre .nhs-composed-header__identity { justify-content: center; text-align: center; }
.nhs-composed-header--compact .nhs-composed-header__row { padding-block: 10px; gap: 12px 20px; }
.nhs-composed-header--compact .nhs-composed-header__identity { font-size: 24px; flex: 1 1 180px; }
.nhs-composed-header--compact .nhs-composed-header__navigation { flex: 2 1 300px; }
.nhs-composed-header--compact .nhs-composed-header__navigation .flow-nav { flex-wrap: wrap; }
.nhs-composed-header--compact .nhs-composed-header__navigation .flow-nav__link,
.nhs-composed-header--compact .nhs-composed-header__navigation .flow-nav__trigger { padding-inline: 8px; font-size: 14px; }
.nhs-composed-header--compact .nhs-practice-header__nhs { width: 180px; }
@media (max-width: 1099px) {
  .nhs-composed-header--compact .nhs-composed-header__navigation { flex: 0 1 auto; }
}
@media (max-width: 599px) {
  .nhs-composed-header .nhs-composed-header__identity { flex-wrap:wrap; gap:10px; }
  .nhs-composed-header__row { gap: 12px 16px; }
  .nhs-composed-header .nhs-composed-header__identity { flex-basis: 100%; }
  .nhs-composed-header .nhs-practice-header__nhs { width: 180px; }
}

}
