/*
 * Site styles. There is no build step: this file is served exactly as written,
 * so everything the site needs is here or in the site's own additions below.
 *
 * COLOUR, TYPE AND SPACE ARE DIALS (#426). The first section is Dials
 * (github.com/joops/dials), copied verbatim between its begin and end
 * markers. It works out every colour, text size, space size and
 * corner from a few values called dials. This site sets its own dials in ONE
 * short block straight after the section, "This site's dials", and that block
 * is the only place in the file where a colour or a scale value is typed.
 *
 *   - Change the look by changing a dial: --brand for the brand colour,
 *     --size-min/--size-max and --ratio-min/--ratio-max for the type scale,
 *     --leading-*, --tracking-* and --weight-body/--weight-heading for line
 *     height, letter spacing and weight, --space-min/--space-max and
 *     --space-density for spacing, --radius-base for corners,
 *     --font-body/--font-heading for faces.
 *   - Everything else reads a token: --surface*, --text*, --border*, --link,
 *     --focus, --solid/--on-solid/--soft/--on-soft/--line (and the named
 *     groups --brand-*, --secondary-*, --tertiary-*, --success-* ...), --size-*,
 *     --leading, --tracking, --tracking-caps-total, --weight-strong,
 *     --space-*, --radius-*, --border-width-*. Never a hex, rgb(), hsl() or
 *     named colour, never a px/rem length, and never a typed line height,
 *     letter spacing or weight, anywhere else.
 *   - The rules are in refs/design/DESIGN.md ("Dials"). Every dial, token
 *     and class is listed in the reference for the version in the section's
 *     first line: github.com/joops/dials/blob/v0.3.0/docs/tokens.md. A
 *     gradient, a wash or a quiet coloured border is a pattern built from
 *     tokens (that reference, "Patterns"), never a token of its own.
 *     check-system.sh holds the section to _template's copy word for word,
 *     and fails a raw colour outside the dials block.
 */

/* ═══ Dials ═══ dials:begin ═════════════════════════════════════════════
 * Dials v0.3.0, VERBATIM. Never edit anything between this marker and the
 * end marker: check-system.sh fails the site if its copy differs from
 * _template's by a word. Each marker appears once; never write either in
 * prose. Set dials in "This site's dials" below; an upgrade
 * of Dials is a template change plus a migration of every site.
 * ═══════════════════════════════════════════════════════════════════════ */
/*! Dials v0.3.0 | MIT | https://github.com/joops/dials */
/* Dials: an AI-first CSS framework. This file is dials-colour.css, then
   dials-scale.css, then the fallback for older browsers; dials-base.css is optional.
   Default theme: Hi-Fi. Load its faces with:
   <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Michroma&family=Barlow:wght@400;700&family=Share+Tech+Mono&display=swap">
*/
/* ============================================================
   Dials: colour (dials-colour.css)
   Dials: seven colours and a few numbers, the only typed values.
   Derived: surfaces, text, lines and groups, worked out live with
   color-mix() and relative colour, in light and dark.
   Groups: .is-{group} points the ungrouped tokens at a group.
   Dials live on :root (and :host); the derived chain is declared on
   :root, [data-dials] and :host, so setting a dial on any
   [data-dials] element re-derives every token inside it.
   Needs color-mix(), light-dark() and relative colour. Don't
   register these with @property: they must resolve where they're
   used, which is what makes .is-dark bands work.
   ============================================================ */
:root, :host {
  /* ---- Colour dials: any CSS colour, preferably HSL ---- */
  --brand:     #f39c12;  /* the main colour: links, focus, primary buttons */
  --secondary: #2ec4b6;  /* a second colour: highlights and secondary actions (was --accent) */
  --success:   #3fbf55;  /* status: done, saved, live */
  --warning:   #f2c230;  /* status: check this */
  --danger:    #e0322b;  /* status: errors and destructive actions */
  --info:      #3b82c4;  /* status: neutral news */
  --grey:      hsl(42 7% 50%);  /* the hue and strength of the tint in paper and ink */

  /* ---- Number dials ---- */
  --balance: 0;              /* 1: every fill at --fill-lightness, so they carry equal weight. 0: exactly as set */
  --fill-lightness: 0.52;    /* the shared OKLCH lightness used when --balance is 1 */
  --dark-lift: 0.04;         /* how much lighter the fills are in dark */
  --tint-strength: 8%;       /* how much colour goes into a soft tint */
  --tint-vividness: 1;       /* 1-3: how saturated soft tints are, for crisper pastels */
  --text-contrast: 0;        /* 0-30: strengthens body, muted and quiet text and strong borders, for paper and ink that sit close together */
  --white-text-until: 0.179; /* fills below this luminance get white text, above it black. 0.179 gives each fill whichever contrasts more; held between 0.175 and 0.18333, where both still give 4.5:1: black needs (L + 0.05) / 0.05 >= 4.5, so L >= 0.175; white needs 1.05 / (L + 0.05) >= 4.5, so L <= 1.05 / 4.5 - 0.05 = 0.18333 */

  /* ---- Paper and ink: near-white and near-black, tinted by --grey at these OKLCH lightnesses.
     To use exact colours instead, set --paper-light, --paper-dark, --ink-light and/or
     --ink-dark (unset by default) to any colour. ---- */
  --paper-lightness: 0.922;       /* page background in light */
  --paper-dark-lightness: 0.186;  /* page background in dark */
  --ink-lightness: 0.213;         /* strongest text in light */
  --ink-dark-lightness: 0.934;    /* strongest text in dark */
}

/* Follow the visitor's light or dark setting. To force one, set
   :root { color-scheme: light; } (or dark) after dials.css. */
:root { color-scheme: light dark; }

:root, [data-dials], :host {
  /* ---- Internal: paper, ink and the six fills, worked out from the dials ---- */
  --dl-paper-light: var(--paper-light, oklch(from var(--grey) var(--paper-lightness) calc(c * 0.12) h));
  --dl-paper-dark:  var(--paper-dark,  oklch(from var(--grey) var(--paper-dark-lightness) calc(c * 0.15) h));
  --dl-ink-light:   var(--ink-light,   oklch(from var(--grey) var(--ink-lightness) calc(c * 0.25) h));
  --dl-ink-dark:    var(--ink-dark,    oklch(from var(--grey) var(--ink-dark-lightness) calc(c * 0.12) h));
  --dl-paper: light-dark(var(--dl-paper-light), var(--dl-paper-dark));
  --dl-ink:   light-dark(var(--dl-ink-light), var(--dl-ink-dark));
  --dl-paper-grey: oklch(from var(--dl-paper) l 0 h);  /* paper without its tint: soft tints mix into this, so they keep their own hue */

  --dl-secondary-dial: var(--accent, var(--secondary));  /* --accent is --secondary's old name: while a site still sets it, it wins */
  --dl-brand-base:     oklch(from var(--brand)              calc(l + (var(--fill-lightness) - l) * var(--balance)) c h);
  --dl-secondary-base: oklch(from var(--dl-secondary-dial)  calc(l + (var(--fill-lightness) - l) * var(--balance)) c h);
  --dl-success-base:   oklch(from var(--success)            calc(l + (var(--fill-lightness) - l) * var(--balance)) c h);
  --dl-warning-base:   oklch(from var(--warning)            calc(l + (var(--fill-lightness) - l) * var(--balance)) c h);
  --dl-danger-base:    oklch(from var(--danger)             calc(l + (var(--fill-lightness) - l) * var(--balance)) c h);
  --dl-info-base:      oklch(from var(--info)               calc(l + (var(--fill-lightness) - l) * var(--balance)) c h);
  --dl-brand:     light-dark(var(--dl-brand-base), oklch(from var(--dl-brand-base) calc(l + var(--dark-lift)) c h));
  --dl-secondary: light-dark(var(--dl-secondary-base), oklch(from var(--dl-secondary-base) calc(l + var(--dark-lift)) c h));
  --dl-success:   light-dark(var(--dl-success-base), oklch(from var(--dl-success-base) calc(l + var(--dark-lift)) c h));
  --dl-warning:   light-dark(var(--dl-warning-base), oklch(from var(--dl-warning-base) calc(l + var(--dark-lift)) c h));
  --dl-danger:    light-dark(var(--dl-danger-base), oklch(from var(--dl-danger-base) calc(l + var(--dark-lift)) c h));
  --dl-info:      light-dark(var(--dl-info-base), oklch(from var(--dl-info-base) calc(l + var(--dark-lift)) c h));

  /* ---- Surfaces ---- */
  --surface:         var(--dl-paper);                                            /* the page background */
  --surface-raised:  oklch(from var(--dl-paper) calc(l + 0.03) calc(c * 0.5) h);  /* cards, fields, popovers */
  --surface-lowered: color-mix(in oklab, var(--dl-ink) 4%, var(--dl-paper));     /* wells, table headers, quiet panels */
  --surface-sunken:  color-mix(in oklab, var(--dl-ink) 8%, var(--dl-paper));     /* code, inset areas, disabled fills */
  --surface-overlay: color-mix(in oklab, black 45%, transparent);                /* the scrim behind a dialog */

  /* ---- Text ---- */
  --text-strong:   var(--dl-ink);                                                                         /* headings, labels, emphasis */
  --text:          color-mix(in oklab, var(--dl-ink) calc(86% + var(--text-contrast) * 0.4%), var(--dl-paper));  /* body text */
  --text-muted:    color-mix(in oklab, var(--dl-ink) calc(70% + var(--text-contrast) * 1%), var(--dl-paper));    /* secondary text */
  --text-quiet:    color-mix(in oklab, var(--dl-ink) calc(64% + var(--text-contrast) * 1.2%), var(--dl-paper));  /* captions, dates, placeholders */
  --text-disabled: color-mix(in oklab, var(--dl-ink) 38%, var(--dl-paper));                                /* disabled controls: exempt from contrast rules */
  --link:          var(--brand-on-soft);                                                                  /* links: 4.5:1 on every surface */
  --link-hover:    light-dark(color(from var(--dl-brand-hover) srgb-linear calc(r * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) calc(g * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) calc(b * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) / 1), color(from color(from var(--dl-brand-hover) srgb-linear min(1, r * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) min(1, g * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) min(1, b * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) / alpha) srgb-linear calc(r + (1 - r) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) calc(g + (1 - g) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) calc(b + (1 - b) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) / 1));  /* links on hover: a step stronger (the link 0.08 darker in OKLCH lightness in light, lighter in dark), and on to 7:1 if that's short */

  /* ---- Lines and effects ---- */
  --border-quiet:  color-mix(in oklab, var(--dl-ink) 7%, var(--dl-paper));   /* dividers that should barely show */
  --border:        color-mix(in oklab, var(--dl-ink) 13%, var(--dl-paper));  /* card and table borders: decorative */
  --border-strong: color-mix(in oklab, var(--dl-ink) calc(46% + var(--text-contrast) * 1%), var(--dl-paper));  /* field and control borders: 3:1 on surfaces */
  --focus:         var(--brand-on-soft);                                     /* the focus ring: opaque, 4.5:1 on surfaces */
  --selection:     color-mix(in oklab, var(--dl-brand) 22%, var(--dl-paper));  /* selected text background */
  --shadow-color:  light-dark(color-mix(in oklab, black 10%, transparent), color-mix(in oklab, black 45%, transparent));  /* the colour of shadows */
  --shadow-s: 0 1px 3px var(--shadow-color);    /* a slight lift: buttons, chips */
  --shadow-m: 0 4px 14px var(--shadow-color);   /* cards */
  --shadow-l: 0 12px 32px var(--shadow-color);  /* popovers, menus, dialogs */

  /* ---- Hover and pressed: the second half of a color-mix(), from Web Awesome.
     Use as color-mix(in oklch, var(--solid), var(--mix-hover)). ---- */
  --mix-hover:  oklch(from currentColor calc(1 - l) c h) 12%;  /* hover: away from the text colour */
  --mix-active: oklch(from currentColor calc(1 - l) c h) 22%;  /* pressed: further still */

  /* ---- Groups: brand, secondary, neutral, success, warning, danger, info. Five roles each:
     solid      a solid fill
     on-solid   text on it: white or black, whichever contrasts more (its sRGB luminance, as painted, vs --white-text-until)
     soft       a tinted background: the colour, held at L 0.7 or lighter in light (0.6 or darker in dark), mixed in OKLab
                into paper with its own tint taken out, so a blue soft stays blue on cream paper
     on-soft    text on soft, and coloured text on the page: the fill, moved only as far as 4.5:1 needs
     line       borders, icons and large text (24px, or 18.66px bold, and up): the dial, moved only as far as 3:1 needs

     Coloured text and lines follow one rule: keep the colour, and move it only as far as its
     contrast target needs, on the least contrasting background it sits on: its own soft tint,
     --surface-lowered or --surface-raised (--surface always lies between them). Only its
     linear-light RGB is scaled, which keeps the channels' ratios, so hue and saturation stay
     (in dark, until a channel reaches 1).
     --link-hover is the same rule at 7:1, starting from the link a step stronger.
       Y   the colour's luminance, 0.2126 r + 0.7152 g + 0.0722 b in linear sRGB (clipped to sRGB first)
       Yb  that background's luminance, as painted (clipped to sRGB)
       T   the target, plus 0.1 headroom so painting in 8 bits can't round it under the line
       light: Yt = (Yb + 0.05) / (T + 0.1) - 0.05; scale r, g and b by min(1, Yt / Y)
       dark:  Yt = (T + 0.1) * (Yb + 0.05) - 0.05; scale r, g and b by max(1, Yt / Y), each capped
              at 1; if a capped channel leaves it short, mix towards white only as far as Yt needs:
              by (Yt - Y1) / (1 - Y1), where Y1 is the luminance after scaling
     A colour that already passes keeps its exact value. CSS works out a relative colour from
     one colour's channels only, so the steps carry their numbers in colours:
       --dl-surfaces-y       the luminance of --surface-lowered in green, of --surface-raised in blue
       --dl-{group}-under    plus the soft tint's in red, mixed 50/50: Yb is min(2r, 4g, 4b) in light, max in dark
       --dl-{group}-text,    the colour, mixed 50/50 with a black whose alpha is s Yt, where s is 3 in
       --dl-{group}-line,    light (Yt is at most 0.29 there) and 1 in dark: scaling it up means Firefox
       --dl-brand-hover      rounding a mix's alpha to three decimals costs a third as much. Mixing
                             premultiplies, so the mix has alpha a = (1 + s Yt) / 2 and channels c / 2a:
                             the colour's channels are r * 2a, and Yt is (2a - 1) / s
       on-soft, line, hover  unpack both and scale, as above ---- */
  --dl-surfaces-y: color-mix(in srgb-linear, color(from var(--surface-lowered) srgb-linear 0 calc(0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1)) 0), color(from var(--surface-raised) srgb-linear 0 0 calc(0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))));

--dl-brand-under: color-mix(in srgb-linear, color(from var(--brand-soft) srgb-linear calc(0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1)) 0 0), var(--dl-surfaces-y));
  --dl-brand-text:  color-mix(in srgb-linear, color(from var(--dl-brand-base) srgb-linear clamp(0, r, 1) clamp(0, g, 1) clamp(0, b, 1) / 1), light-dark(color(from var(--dl-brand-under) srgb-linear 0 0 0 / calc(clamp(0, 3 * ((min(2 * r, 4 * g, 4 * b) + 0.05) / (4.5 + 0.1) - 0.05), 1))), color(from var(--dl-brand-under) srgb-linear 0 0 0 / calc(clamp(0, (4.5 + 0.1) * (max(2 * r, 4 * g, 4 * b) + 0.05) - 0.05, 1)))));
  --dl-brand-line:  color-mix(in srgb-linear, color(from var(--brand) srgb-linear clamp(0, r, 1) clamp(0, g, 1) clamp(0, b, 1) / 1), light-dark(color(from var(--dl-brand-under) srgb-linear 0 0 0 / calc(clamp(0, 3 * ((min(2 * r, 4 * g, 4 * b) + 0.05) / (3 + 0.1) - 0.05), 1))), color(from var(--dl-brand-under) srgb-linear 0 0 0 / calc(clamp(0, (3 + 0.1) * (max(2 * r, 4 * g, 4 * b) + 0.05) - 0.05, 1)))));
  --brand-solid:    var(--dl-brand);
  --brand-on-solid: color(from var(--dl-brand) srgb-linear calc(clamp(0, (clamp(0.175, var(--white-text-until), 0.18333) - (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))) * 1000000, 1)) calc(clamp(0, (clamp(0.175, var(--white-text-until), 0.18333) - (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))) * 1000000, 1)) calc(clamp(0, (clamp(0.175, var(--white-text-until), 0.18333) - (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))) * 1000000, 1)) / 1);
  --brand-soft:     oklch(from color-mix(in oklab, light-dark(oklch(from var(--dl-brand) max(l, 0.7) c h), oklch(from var(--dl-brand) min(l, 0.6) c h)) var(--tint-strength), var(--dl-paper-grey)) l calc(c * var(--tint-vividness)) h);
  --brand-on-soft:  light-dark(color(from var(--dl-brand-text) srgb-linear calc(r * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) calc(g * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) calc(b * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) / 1), color(from color(from var(--dl-brand-text) srgb-linear min(1, r * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) min(1, g * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) min(1, b * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) / alpha) srgb-linear calc(r + (1 - r) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) calc(g + (1 - g) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) calc(b + (1 - b) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) / 1));
  --brand-line:     light-dark(color(from var(--dl-brand-line) srgb-linear calc(r * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) calc(g * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) calc(b * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) / 1), color(from color(from var(--dl-brand-line) srgb-linear min(1, r * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) min(1, g * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) min(1, b * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) / alpha) srgb-linear calc(r + (1 - r) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) calc(g + (1 - g) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) calc(b + (1 - b) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) / 1));

  --dl-secondary-under: color-mix(in srgb-linear, color(from var(--secondary-soft) srgb-linear calc(0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1)) 0 0), var(--dl-surfaces-y));
  --dl-secondary-text:  color-mix(in srgb-linear, color(from var(--dl-secondary-base) srgb-linear clamp(0, r, 1) clamp(0, g, 1) clamp(0, b, 1) / 1), light-dark(color(from var(--dl-secondary-under) srgb-linear 0 0 0 / calc(clamp(0, 3 * ((min(2 * r, 4 * g, 4 * b) + 0.05) / (4.5 + 0.1) - 0.05), 1))), color(from var(--dl-secondary-under) srgb-linear 0 0 0 / calc(clamp(0, (4.5 + 0.1) * (max(2 * r, 4 * g, 4 * b) + 0.05) - 0.05, 1)))));
  --dl-secondary-line:  color-mix(in srgb-linear, color(from var(--dl-secondary-dial) srgb-linear clamp(0, r, 1) clamp(0, g, 1) clamp(0, b, 1) / 1), light-dark(color(from var(--dl-secondary-under) srgb-linear 0 0 0 / calc(clamp(0, 3 * ((min(2 * r, 4 * g, 4 * b) + 0.05) / (3 + 0.1) - 0.05), 1))), color(from var(--dl-secondary-under) srgb-linear 0 0 0 / calc(clamp(0, (3 + 0.1) * (max(2 * r, 4 * g, 4 * b) + 0.05) - 0.05, 1)))));
  --secondary-solid:    var(--dl-secondary);
  --secondary-on-solid: color(from var(--dl-secondary) srgb-linear calc(clamp(0, (clamp(0.175, var(--white-text-until), 0.18333) - (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))) * 1000000, 1)) calc(clamp(0, (clamp(0.175, var(--white-text-until), 0.18333) - (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))) * 1000000, 1)) calc(clamp(0, (clamp(0.175, var(--white-text-until), 0.18333) - (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))) * 1000000, 1)) / 1);
  --secondary-soft:     oklch(from color-mix(in oklab, light-dark(oklch(from var(--dl-secondary) max(l, 0.7) c h), oklch(from var(--dl-secondary) min(l, 0.6) c h)) var(--tint-strength), var(--dl-paper-grey)) l calc(c * var(--tint-vividness)) h);
  --secondary-on-soft:  light-dark(color(from var(--dl-secondary-text) srgb-linear calc(r * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) calc(g * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) calc(b * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) / 1), color(from color(from var(--dl-secondary-text) srgb-linear min(1, r * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) min(1, g * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) min(1, b * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) / alpha) srgb-linear calc(r + (1 - r) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) calc(g + (1 - g) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) calc(b + (1 - b) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) / 1));
  --secondary-line:     light-dark(color(from var(--dl-secondary-line) srgb-linear calc(r * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) calc(g * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) calc(b * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) / 1), color(from color(from var(--dl-secondary-line) srgb-linear min(1, r * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) min(1, g * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) min(1, b * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) / alpha) srgb-linear calc(r + (1 - r) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) calc(g + (1 - g) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) calc(b + (1 - b) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) / 1));

  --neutral-solid:    var(--dl-ink);
  --neutral-on-solid: var(--dl-paper);
  --neutral-soft:     var(--surface-lowered);
  --neutral-on-soft:  var(--text);
  --neutral-line:     var(--border);

  --dl-success-under: color-mix(in srgb-linear, color(from var(--success-soft) srgb-linear calc(0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1)) 0 0), var(--dl-surfaces-y));
  --dl-success-text:  color-mix(in srgb-linear, color(from var(--dl-success-base) srgb-linear clamp(0, r, 1) clamp(0, g, 1) clamp(0, b, 1) / 1), light-dark(color(from var(--dl-success-under) srgb-linear 0 0 0 / calc(clamp(0, 3 * ((min(2 * r, 4 * g, 4 * b) + 0.05) / (4.5 + 0.1) - 0.05), 1))), color(from var(--dl-success-under) srgb-linear 0 0 0 / calc(clamp(0, (4.5 + 0.1) * (max(2 * r, 4 * g, 4 * b) + 0.05) - 0.05, 1)))));
  --dl-success-line:  color-mix(in srgb-linear, color(from var(--success) srgb-linear clamp(0, r, 1) clamp(0, g, 1) clamp(0, b, 1) / 1), light-dark(color(from var(--dl-success-under) srgb-linear 0 0 0 / calc(clamp(0, 3 * ((min(2 * r, 4 * g, 4 * b) + 0.05) / (3 + 0.1) - 0.05), 1))), color(from var(--dl-success-under) srgb-linear 0 0 0 / calc(clamp(0, (3 + 0.1) * (max(2 * r, 4 * g, 4 * b) + 0.05) - 0.05, 1)))));
  --success-solid:    var(--dl-success);
  --success-on-solid: color(from var(--dl-success) srgb-linear calc(clamp(0, (clamp(0.175, var(--white-text-until), 0.18333) - (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))) * 1000000, 1)) calc(clamp(0, (clamp(0.175, var(--white-text-until), 0.18333) - (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))) * 1000000, 1)) calc(clamp(0, (clamp(0.175, var(--white-text-until), 0.18333) - (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))) * 1000000, 1)) / 1);
  --success-soft:     oklch(from color-mix(in oklab, light-dark(oklch(from var(--dl-success) max(l, 0.7) c h), oklch(from var(--dl-success) min(l, 0.6) c h)) var(--tint-strength), var(--dl-paper-grey)) l calc(c * var(--tint-vividness)) h);
  --success-on-soft:  light-dark(color(from var(--dl-success-text) srgb-linear calc(r * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) calc(g * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) calc(b * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) / 1), color(from color(from var(--dl-success-text) srgb-linear min(1, r * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) min(1, g * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) min(1, b * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) / alpha) srgb-linear calc(r + (1 - r) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) calc(g + (1 - g) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) calc(b + (1 - b) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) / 1));
  --success-line:     light-dark(color(from var(--dl-success-line) srgb-linear calc(r * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) calc(g * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) calc(b * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) / 1), color(from color(from var(--dl-success-line) srgb-linear min(1, r * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) min(1, g * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) min(1, b * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) / alpha) srgb-linear calc(r + (1 - r) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) calc(g + (1 - g) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) calc(b + (1 - b) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) / 1));

  --dl-warning-under: color-mix(in srgb-linear, color(from var(--warning-soft) srgb-linear calc(0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1)) 0 0), var(--dl-surfaces-y));
  --dl-warning-text:  color-mix(in srgb-linear, color(from var(--dl-warning-base) srgb-linear clamp(0, r, 1) clamp(0, g, 1) clamp(0, b, 1) / 1), light-dark(color(from var(--dl-warning-under) srgb-linear 0 0 0 / calc(clamp(0, 3 * ((min(2 * r, 4 * g, 4 * b) + 0.05) / (4.5 + 0.1) - 0.05), 1))), color(from var(--dl-warning-under) srgb-linear 0 0 0 / calc(clamp(0, (4.5 + 0.1) * (max(2 * r, 4 * g, 4 * b) + 0.05) - 0.05, 1)))));
  --dl-warning-line:  color-mix(in srgb-linear, color(from var(--warning) srgb-linear clamp(0, r, 1) clamp(0, g, 1) clamp(0, b, 1) / 1), light-dark(color(from var(--dl-warning-under) srgb-linear 0 0 0 / calc(clamp(0, 3 * ((min(2 * r, 4 * g, 4 * b) + 0.05) / (3 + 0.1) - 0.05), 1))), color(from var(--dl-warning-under) srgb-linear 0 0 0 / calc(clamp(0, (3 + 0.1) * (max(2 * r, 4 * g, 4 * b) + 0.05) - 0.05, 1)))));
  --warning-solid:    var(--dl-warning);
  --warning-on-solid: color(from var(--dl-warning) srgb-linear calc(clamp(0, (clamp(0.175, var(--white-text-until), 0.18333) - (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))) * 1000000, 1)) calc(clamp(0, (clamp(0.175, var(--white-text-until), 0.18333) - (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))) * 1000000, 1)) calc(clamp(0, (clamp(0.175, var(--white-text-until), 0.18333) - (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))) * 1000000, 1)) / 1);
  --warning-soft:     oklch(from color-mix(in oklab, light-dark(oklch(from var(--dl-warning) max(l, 0.7) c h), oklch(from var(--dl-warning) min(l, 0.6) c h)) var(--tint-strength), var(--dl-paper-grey)) l calc(c * var(--tint-vividness)) h);
  --warning-on-soft:  light-dark(color(from var(--dl-warning-text) srgb-linear calc(r * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) calc(g * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) calc(b * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) / 1), color(from color(from var(--dl-warning-text) srgb-linear min(1, r * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) min(1, g * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) min(1, b * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) / alpha) srgb-linear calc(r + (1 - r) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) calc(g + (1 - g) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) calc(b + (1 - b) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) / 1));
  --warning-line:     light-dark(color(from var(--dl-warning-line) srgb-linear calc(r * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) calc(g * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) calc(b * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) / 1), color(from color(from var(--dl-warning-line) srgb-linear min(1, r * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) min(1, g * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) min(1, b * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) / alpha) srgb-linear calc(r + (1 - r) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) calc(g + (1 - g) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) calc(b + (1 - b) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) / 1));

  --dl-danger-under: color-mix(in srgb-linear, color(from var(--danger-soft) srgb-linear calc(0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1)) 0 0), var(--dl-surfaces-y));
  --dl-danger-text:  color-mix(in srgb-linear, color(from var(--dl-danger-base) srgb-linear clamp(0, r, 1) clamp(0, g, 1) clamp(0, b, 1) / 1), light-dark(color(from var(--dl-danger-under) srgb-linear 0 0 0 / calc(clamp(0, 3 * ((min(2 * r, 4 * g, 4 * b) + 0.05) / (4.5 + 0.1) - 0.05), 1))), color(from var(--dl-danger-under) srgb-linear 0 0 0 / calc(clamp(0, (4.5 + 0.1) * (max(2 * r, 4 * g, 4 * b) + 0.05) - 0.05, 1)))));
  --dl-danger-line:  color-mix(in srgb-linear, color(from var(--danger) srgb-linear clamp(0, r, 1) clamp(0, g, 1) clamp(0, b, 1) / 1), light-dark(color(from var(--dl-danger-under) srgb-linear 0 0 0 / calc(clamp(0, 3 * ((min(2 * r, 4 * g, 4 * b) + 0.05) / (3 + 0.1) - 0.05), 1))), color(from var(--dl-danger-under) srgb-linear 0 0 0 / calc(clamp(0, (3 + 0.1) * (max(2 * r, 4 * g, 4 * b) + 0.05) - 0.05, 1)))));
  --danger-solid:    var(--dl-danger);
  --danger-on-solid: color(from var(--dl-danger) srgb-linear calc(clamp(0, (clamp(0.175, var(--white-text-until), 0.18333) - (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))) * 1000000, 1)) calc(clamp(0, (clamp(0.175, var(--white-text-until), 0.18333) - (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))) * 1000000, 1)) calc(clamp(0, (clamp(0.175, var(--white-text-until), 0.18333) - (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))) * 1000000, 1)) / 1);
  --danger-soft:     oklch(from color-mix(in oklab, light-dark(oklch(from var(--dl-danger) max(l, 0.7) c h), oklch(from var(--dl-danger) min(l, 0.6) c h)) var(--tint-strength), var(--dl-paper-grey)) l calc(c * var(--tint-vividness)) h);
  --danger-on-soft:  light-dark(color(from var(--dl-danger-text) srgb-linear calc(r * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) calc(g * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) calc(b * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) / 1), color(from color(from var(--dl-danger-text) srgb-linear min(1, r * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) min(1, g * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) min(1, b * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) / alpha) srgb-linear calc(r + (1 - r) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) calc(g + (1 - g) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) calc(b + (1 - b) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) / 1));
  --danger-line:     light-dark(color(from var(--dl-danger-line) srgb-linear calc(r * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) calc(g * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) calc(b * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) / 1), color(from color(from var(--dl-danger-line) srgb-linear min(1, r * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) min(1, g * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) min(1, b * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) / alpha) srgb-linear calc(r + (1 - r) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) calc(g + (1 - g) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) calc(b + (1 - b) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) / 1));

  --dl-info-under: color-mix(in srgb-linear, color(from var(--info-soft) srgb-linear calc(0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1)) 0 0), var(--dl-surfaces-y));
  --dl-info-text:  color-mix(in srgb-linear, color(from var(--dl-info-base) srgb-linear clamp(0, r, 1) clamp(0, g, 1) clamp(0, b, 1) / 1), light-dark(color(from var(--dl-info-under) srgb-linear 0 0 0 / calc(clamp(0, 3 * ((min(2 * r, 4 * g, 4 * b) + 0.05) / (4.5 + 0.1) - 0.05), 1))), color(from var(--dl-info-under) srgb-linear 0 0 0 / calc(clamp(0, (4.5 + 0.1) * (max(2 * r, 4 * g, 4 * b) + 0.05) - 0.05, 1)))));
  --dl-info-line:  color-mix(in srgb-linear, color(from var(--info) srgb-linear clamp(0, r, 1) clamp(0, g, 1) clamp(0, b, 1) / 1), light-dark(color(from var(--dl-info-under) srgb-linear 0 0 0 / calc(clamp(0, 3 * ((min(2 * r, 4 * g, 4 * b) + 0.05) / (3 + 0.1) - 0.05), 1))), color(from var(--dl-info-under) srgb-linear 0 0 0 / calc(clamp(0, (3 + 0.1) * (max(2 * r, 4 * g, 4 * b) + 0.05) - 0.05, 1)))));
  --info-solid:    var(--dl-info);
  --info-on-solid: color(from var(--dl-info) srgb-linear calc(clamp(0, (clamp(0.175, var(--white-text-until), 0.18333) - (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))) * 1000000, 1)) calc(clamp(0, (clamp(0.175, var(--white-text-until), 0.18333) - (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))) * 1000000, 1)) calc(clamp(0, (clamp(0.175, var(--white-text-until), 0.18333) - (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))) * 1000000, 1)) / 1);
  --info-soft:     oklch(from color-mix(in oklab, light-dark(oklch(from var(--dl-info) max(l, 0.7) c h), oklch(from var(--dl-info) min(l, 0.6) c h)) var(--tint-strength), var(--dl-paper-grey)) l calc(c * var(--tint-vividness)) h);
  --info-on-soft:  light-dark(color(from var(--dl-info-text) srgb-linear calc(r * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) calc(g * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) calc(b * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) / 1), color(from color(from var(--dl-info-text) srgb-linear min(1, r * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) min(1, g * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) min(1, b * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) / alpha) srgb-linear calc(r + (1 - r) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) calc(g + (1 - g) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) calc(b + (1 - b) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) / 1));
  --info-line:     light-dark(color(from var(--dl-info-line) srgb-linear calc(r * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) calc(g * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) calc(b * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) / 1), color(from color(from var(--dl-info-line) srgb-linear min(1, r * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) min(1, g * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) min(1, b * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) / alpha) srgb-linear calc(r + (1 - r) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) calc(g + (1 - g) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) calc(b + (1 - b) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) / 1));
  --dl-brand-hover: color-mix(in srgb-linear, color(from light-dark(oklch(from var(--brand-on-soft) calc(l - 0.08) c h), oklch(from var(--brand-on-soft) calc(l + 0.08) c h)) srgb-linear clamp(0, r, 1) clamp(0, g, 1) clamp(0, b, 1) / 1), light-dark(color(from var(--dl-brand-under) srgb-linear 0 0 0 / calc(clamp(0, 3 * ((min(2 * r, 4 * g, 4 * b) + 0.05) / (7 + 0.1) - 0.05), 1))), color(from var(--dl-brand-under) srgb-linear 0 0 0 / calc(clamp(0, (7 + 0.1) * (max(2 * r, 4 * g, 4 * b) + 0.05) - 0.05, 1)))));

  /* ---- Ungrouped: components use these; .is-{group} points them at a group ---- */
  --solid:    var(--brand-solid);
  --on-solid: var(--brand-on-solid);
  --soft:     var(--brand-soft);
  --on-soft:  var(--brand-on-soft);
  --line:     var(--brand-line);

  /* ---- Deprecated: --accent's tokens, renamed --secondary-*. They still work; rename them ---- */
  --accent-solid:    var(--secondary-solid);     /* deprecated: use --secondary-solid */
  --accent-on-solid: var(--secondary-on-solid);  /* deprecated: use --secondary-on-solid */
  --accent-soft:     var(--secondary-soft);      /* deprecated: use --secondary-soft */
  --accent-on-soft:  var(--secondary-on-soft);   /* deprecated: use --secondary-on-soft */
  --accent-line:     var(--secondary-line);      /* deprecated: use --secondary-line */
}
.is-brand     { --solid: var(--brand-solid);     --on-solid: var(--brand-on-solid);     --soft: var(--brand-soft);     --on-soft: var(--brand-on-soft);     --line: var(--brand-line); }
.is-secondary { --solid: var(--secondary-solid); --on-solid: var(--secondary-on-solid); --soft: var(--secondary-soft); --on-soft: var(--secondary-on-soft); --line: var(--secondary-line); }
.is-neutral   { --solid: var(--neutral-solid);   --on-solid: var(--neutral-on-solid);   --soft: var(--neutral-soft);   --on-soft: var(--neutral-on-soft);   --line: var(--neutral-line); }
.is-success   { --solid: var(--success-solid);   --on-solid: var(--success-on-solid);   --soft: var(--success-soft);   --on-soft: var(--success-on-soft);   --line: var(--success-line); }
.is-warning   { --solid: var(--warning-solid);   --on-solid: var(--warning-on-solid);   --soft: var(--warning-soft);   --on-soft: var(--warning-on-soft);   --line: var(--warning-line); }
.is-danger    { --solid: var(--danger-solid);    --on-solid: var(--danger-on-solid);    --soft: var(--danger-soft);    --on-soft: var(--danger-on-soft);    --line: var(--danger-line); }
.is-info      { --solid: var(--info-solid);      --on-solid: var(--info-on-solid);      --soft: var(--info-soft);      --on-soft: var(--info-on-soft);      --line: var(--info-line); }
.is-accent    { --solid: var(--secondary-solid); --on-solid: var(--secondary-on-solid); --soft: var(--secondary-soft); --on-soft: var(--secondary-on-soft); --line: var(--secondary-line); }  /* deprecated: use .is-secondary */
/* A light or dark band: its own scheme, and its own background and text worked out in it */
.is-light { color-scheme: light; background-color: var(--surface); color: var(--text); }
.is-dark  { color-scheme: dark;  background-color: var(--surface); color: var(--text); }
/* ============================================================
   Dials: type and space (dials-scale.css)
   A few dials set every text size and every space size, the way
   Utopia (utopia.fyi) works them out, but the maths runs in the
   browser: change a dial and the whole scale follows. Leading,
   tracking and weight are worked out the same way, for whatever size
   they're used at. This file sets no type on any element: only
   dials-base.css does that. Dials live on
   :root (and :host); the derived scale is declared on :root,
   [data-dials] and :host, so a dial set on a [data-dials] element
   re-derives the sizes inside it.
   ============================================================ */
:root, :host {
  /* ---- Dials ---- */
  --screen-min: 360;       /* the screen widths the scale runs between, in px */
  --screen-max: 1240;
  --size-min: 16;          /* body text at the narrowest and widest screens, in px */
  --size-max: 18;
  --ratio-min: 1.2;        /* each step is this much bigger than the last: 1.2 minor third, */
  --ratio-max: 1.25;       /* 1.25 major third, 1.333 perfect fourth, 1.5 fifth, 1.618 golden */
  --space-min: var(--size-min);  /* --space-s at each end, in px: follows body text */
  --space-max: var(--size-max);  /* size unless you set a number */
  --space-density: 1;      /* scales every space size: 0.8 compact, 1.25 roomy */
  --radius-base: 3;        /* corner radius of cards and fields, in px (a number, not a length) */

  /* Faces: set per site, and load them yourself (each theme file names its Google Fonts link) */
  --font-body: "Barlow", ui-sans-serif, system-ui, sans-serif;  /* body text and controls */
  --font-heading: "Michroma", ui-sans-serif, system-ui, sans-serif;  /* headings */
  --font-mono: "Share Tech Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;  /* code, kbd, samp, pre */

  /* Border widths: every border and outline uses one of these */
  --border-width-s: 1px;   /* hairlines: cards, fields, tables */
  --border-width-m: 2px;   /* emphasis; outline offsets */
  --border-width-l: 3px;   /* focus rings, quote bars, active tabs */

  /* ---- Leading, tracking, weight and line length: unset by default ---- */
  /* While none is set, dials-base.css keeps v0.2's type. Set them in your own file; the value
     shown is what Dials uses for any you leave unset once you've set another. */
  /* --leading-body: 1.6;      line height at body size (--size-0), unitless */
  /* --leading-display: 1.15;  line height at the h1 step (--size-5) and above, unitless; sizes in between slide in a straight line */
  /* --tracking-small: 0;      letter spacing at the smallest size (--size--2), in em without the unit: positive loosens captions */
  /* --tracking-display: 0;    letter spacing at the h1 step (--size-5) and above, in em without the unit: negative tightens display type */
  /* --tracking-caps: 0;       extra letter spacing for all caps and small caps, in em without the unit (0.05 to 0.12 is usual) */
  /* --weight-body: 400;       body text weight */
  /* --weight-heading: 600;    heading weight */
  /* --line-length: none;      the longest line of running text, e.g. 65ch; unset, lines run the full width */
  /* --font-accent: var(--font-body);  a third face, for ledes, pull quotes or buttons; read it as var(--font-accent, var(--font-body)) */
}

:root, [data-dials], :host {
  /* ---- Internal: worked out from the dials, never edited by hand ---- */
  --dl-screen-range: calc(var(--screen-max) - var(--screen-min));
  --dl-fluid: calc((100vw - var(--screen-min) * 1px) / var(--dl-screen-range) * 16);  /* 0 at the narrowest, 16px at the widest */
  --dl-min-0: calc(var(--size-min) / 16);
  --dl-max-0: calc(var(--size-max) / 16);
  --dl-min--1: calc(var(--dl-min-0) / var(--ratio-min));
  --dl-max--1: calc(var(--dl-max-0) / var(--ratio-max));
  --dl-min--2: calc(var(--dl-min--1) / var(--ratio-min));
  --dl-max--2: calc(var(--dl-max--1) / var(--ratio-max));
  --dl-min-1: calc(var(--dl-min-0) * var(--ratio-min));
  --dl-max-1: calc(var(--dl-max-0) * var(--ratio-max));
  --dl-min-2: calc(var(--dl-min-1) * var(--ratio-min));
  --dl-max-2: calc(var(--dl-max-1) * var(--ratio-max));
  --dl-min-3: calc(var(--dl-min-2) * var(--ratio-min));
  --dl-max-3: calc(var(--dl-max-2) * var(--ratio-max));
  --dl-min-4: calc(var(--dl-min-3) * var(--ratio-min));
  --dl-max-4: calc(var(--dl-max-3) * var(--ratio-max));
  --dl-min-5: calc(var(--dl-min-4) * var(--ratio-min));
  --dl-max-5: calc(var(--dl-max-4) * var(--ratio-max));
  --dl-min-6: calc(var(--dl-min-5) * var(--ratio-min));
  --dl-max-6: calc(var(--dl-max-5) * var(--ratio-max));
  --dl-min-7: calc(var(--dl-min-6) * var(--ratio-min));
  --dl-max-7: calc(var(--dl-max-6) * var(--ratio-max));
  --dl-min-8: calc(var(--dl-min-7) * var(--ratio-min));
  --dl-max-8: calc(var(--dl-max-7) * var(--ratio-max));

  /* ---- Font sizes: --size-0 is body text; each number up or down is one step of the ratio,
     running in a straight line between its two ends ---- */
  --size--2: clamp(min(var(--dl-min--2), var(--dl-max--2)) * 1rem, var(--dl-min--2) * 1rem + (var(--dl-max--2) - var(--dl-min--2)) * var(--dl-fluid), max(var(--dl-min--2), var(--dl-max--2)) * 1rem);
  --size--1: clamp(min(var(--dl-min--1), var(--dl-max--1)) * 1rem, var(--dl-min--1) * 1rem + (var(--dl-max--1) - var(--dl-min--1)) * var(--dl-fluid), max(var(--dl-min--1), var(--dl-max--1)) * 1rem);
  --size-0: clamp(min(var(--dl-min-0), var(--dl-max-0)) * 1rem, var(--dl-min-0) * 1rem + (var(--dl-max-0) - var(--dl-min-0)) * var(--dl-fluid), max(var(--dl-min-0), var(--dl-max-0)) * 1rem);
  --size-1: clamp(min(var(--dl-min-1), var(--dl-max-1)) * 1rem, var(--dl-min-1) * 1rem + (var(--dl-max-1) - var(--dl-min-1)) * var(--dl-fluid), max(var(--dl-min-1), var(--dl-max-1)) * 1rem);
  --size-2: clamp(min(var(--dl-min-2), var(--dl-max-2)) * 1rem, var(--dl-min-2) * 1rem + (var(--dl-max-2) - var(--dl-min-2)) * var(--dl-fluid), max(var(--dl-min-2), var(--dl-max-2)) * 1rem);
  --size-3: clamp(min(var(--dl-min-3), var(--dl-max-3)) * 1rem, var(--dl-min-3) * 1rem + (var(--dl-max-3) - var(--dl-min-3)) * var(--dl-fluid), max(var(--dl-min-3), var(--dl-max-3)) * 1rem);
  --size-4: clamp(min(var(--dl-min-4), var(--dl-max-4)) * 1rem, var(--dl-min-4) * 1rem + (var(--dl-max-4) - var(--dl-min-4)) * var(--dl-fluid), max(var(--dl-min-4), var(--dl-max-4)) * 1rem);
  --size-5: clamp(min(var(--dl-min-5), var(--dl-max-5)) * 1rem, var(--dl-min-5) * 1rem + (var(--dl-max-5) - var(--dl-min-5)) * var(--dl-fluid), max(var(--dl-min-5), var(--dl-max-5)) * 1rem);
  --size-6: clamp(min(var(--dl-min-6), var(--dl-max-6)) * 1rem, var(--dl-min-6) * 1rem + (var(--dl-max-6) - var(--dl-min-6)) * var(--dl-fluid), max(var(--dl-min-6), var(--dl-max-6)) * 1rem);
  --size-7: clamp(min(var(--dl-min-7), var(--dl-max-7)) * 1rem, var(--dl-min-7) * 1rem + (var(--dl-max-7) - var(--dl-min-7)) * var(--dl-fluid), max(var(--dl-min-7), var(--dl-max-7)) * 1rem);  /* display type */
  --size-8: clamp(min(var(--dl-min-8), var(--dl-max-8)) * 1rem, var(--dl-min-8) * 1rem + (var(--dl-max-8) - var(--dl-min-8)) * var(--dl-fluid), max(var(--dl-min-8), var(--dl-max-8)) * 1rem);  /* display type: the top of the scale */

  /* ---- Leading, tracking and weight: worked out for the size of the element they're used on ---- */
  /* --leading and --tracking are lengths: apply them on each element that sets a font size, never
     on body, where they'd inherit as one fixed length. */
  --dl-leading-body: var(--leading-body, 1.6);
  --dl-leading-display: var(--leading-display, 1.15);
  --dl-tracking-small: var(--tracking-small, 0);
  --dl-tracking-display: var(--tracking-display, 0);
  /* body size over the h1 step, as a number: tan(atan2(a, b)) is a / b for two lengths
     (Firefox has no typed division) */
  --dl-type-q: tan(atan2(var(--size-0), var(--size-5)));
  /* leading runs in a straight line in size, m * size + g, through leading-body at --size-0 and leading-display at --size-5, the h1 step */
  --dl-leading-m: calc((var(--dl-leading-display) - var(--dl-leading-body) * var(--dl-type-q)) / max(1 - var(--dl-type-q), 0.000001));
  --dl-leading-g: calc(var(--size-0) * (var(--dl-leading-body) - var(--dl-leading-m)));
  /* how far up the scale this size is, from --size-0 (0) to --size-5 (1), and down it to --size--2, evenly per step */
  --dl-type-up: clamp(0, log(tan(atan2(var(--size-0), 1em))) / min(log(var(--dl-type-q)), -0.000001), 1);
  --dl-type-down: clamp(0, log(tan(atan2(1em, var(--size-0)))) / min(log(tan(atan2(var(--size--2), var(--size-0)))), -0.000001), 1);
  --leading: clamp(min(var(--dl-leading-body), var(--dl-leading-display)) * 1em, var(--dl-leading-m) * 1em + var(--dl-leading-g), max(var(--dl-leading-body), var(--dl-leading-display)) * 1em);  /* line height for the size it's on, from --leading-body at body size to --leading-display at --size-5 (h1) and above */
  --tracking: calc(1em * (var(--dl-tracking-display) * var(--dl-type-up) + var(--dl-tracking-small) * var(--dl-type-down)));  /* letter spacing for the size it's on: 0 at body size, --tracking-small at --size--2 and below, --tracking-display at --size-5 (h1) and above */
  --tracking-caps-total: calc(var(--tracking) + 1em * var(--tracking-caps, 0));  /* letter spacing for text in capitals: --tracking plus --tracking-caps */
  --weight-strong: min(900, var(--weight-body, 400) + 200);  /* bold within body text, buttons and labels: the body weight plus 200 */
  /* dials-base.css reads these, so an untouched site keeps v0.2's type: each is valid only once one of its dials is set */
  --dl-weight-strong-on: calc(var(--weight-strong) + 0 * var(--weight-body));

  /* ---- Space: multiples of the space base (Utopia's t-shirt sizes), times the density ---- */
  --dl-space-min: calc(var(--space-min) / 16 * var(--space-density));
  --dl-space-max: calc(var(--space-max) / 16 * var(--space-density));
  --space-3xs: clamp(calc(var(--dl-space-min) * 0.25rem), calc(var(--dl-space-min) * 0.25rem + (var(--dl-space-max) * 0.25 - var(--dl-space-min) * 0.25) * var(--dl-fluid)), calc(var(--dl-space-max) * 0.25rem));
  --space-2xs: clamp(calc(var(--dl-space-min) * 0.5rem), calc(var(--dl-space-min) * 0.5rem + (var(--dl-space-max) * 0.5 - var(--dl-space-min) * 0.5) * var(--dl-fluid)), calc(var(--dl-space-max) * 0.5rem));
  --space-xs: clamp(calc(var(--dl-space-min) * 0.75rem), calc(var(--dl-space-min) * 0.75rem + (var(--dl-space-max) * 0.75 - var(--dl-space-min) * 0.75) * var(--dl-fluid)), calc(var(--dl-space-max) * 0.75rem));
  --space-s: clamp(calc(var(--dl-space-min) * 1rem), calc(var(--dl-space-min) * 1rem + (var(--dl-space-max) * 1 - var(--dl-space-min) * 1) * var(--dl-fluid)), calc(var(--dl-space-max) * 1rem));
  --space-m: clamp(calc(var(--dl-space-min) * 1.5rem), calc(var(--dl-space-min) * 1.5rem + (var(--dl-space-max) * 1.5 - var(--dl-space-min) * 1.5) * var(--dl-fluid)), calc(var(--dl-space-max) * 1.5rem));
  --space-l: clamp(calc(var(--dl-space-min) * 2rem), calc(var(--dl-space-min) * 2rem + (var(--dl-space-max) * 2 - var(--dl-space-min) * 2) * var(--dl-fluid)), calc(var(--dl-space-max) * 2rem));
  --space-xl: clamp(calc(var(--dl-space-min) * 3rem), calc(var(--dl-space-min) * 3rem + (var(--dl-space-max) * 3 - var(--dl-space-min) * 3) * var(--dl-fluid)), calc(var(--dl-space-max) * 3rem));
  --space-2xl: clamp(calc(var(--dl-space-min) * 4rem), calc(var(--dl-space-min) * 4rem + (var(--dl-space-max) * 4 - var(--dl-space-min) * 4) * var(--dl-fluid)), calc(var(--dl-space-max) * 4rem));
  --space-3xl: clamp(calc(var(--dl-space-min) * 6rem), calc(var(--dl-space-min) * 6rem + (var(--dl-space-max) * 6 - var(--dl-space-min) * 6) * var(--dl-fluid)), calc(var(--dl-space-max) * 6rem));
  --space-4xl: clamp(calc(var(--dl-space-min) * 8rem), calc(var(--dl-space-min) * 8rem + (var(--dl-space-max) * 8 - var(--dl-space-min) * 8) * var(--dl-fluid)), calc(var(--dl-space-max) * 8rem));
  /* One-up pairs: small on phones, the next size up on desktops */
  --space-3xs-2xs: clamp(calc(var(--dl-space-min) * 0.25rem), calc(var(--dl-space-min) * 0.25rem + (var(--dl-space-max) * 0.5 - var(--dl-space-min) * 0.25) * var(--dl-fluid)), calc(var(--dl-space-max) * 0.5rem));
  --space-2xs-xs: clamp(calc(var(--dl-space-min) * 0.5rem), calc(var(--dl-space-min) * 0.5rem + (var(--dl-space-max) * 0.75 - var(--dl-space-min) * 0.5) * var(--dl-fluid)), calc(var(--dl-space-max) * 0.75rem));
  --space-xs-s: clamp(calc(var(--dl-space-min) * 0.75rem), calc(var(--dl-space-min) * 0.75rem + (var(--dl-space-max) * 1 - var(--dl-space-min) * 0.75) * var(--dl-fluid)), calc(var(--dl-space-max) * 1rem));
  --space-s-m: clamp(calc(var(--dl-space-min) * 1rem), calc(var(--dl-space-min) * 1rem + (var(--dl-space-max) * 1.5 - var(--dl-space-min) * 1) * var(--dl-fluid)), calc(var(--dl-space-max) * 1.5rem));
  --space-m-l: clamp(calc(var(--dl-space-min) * 1.5rem), calc(var(--dl-space-min) * 1.5rem + (var(--dl-space-max) * 2 - var(--dl-space-min) * 1.5) * var(--dl-fluid)), calc(var(--dl-space-max) * 2rem));
  --space-l-xl: clamp(calc(var(--dl-space-min) * 2rem), calc(var(--dl-space-min) * 2rem + (var(--dl-space-max) * 3 - var(--dl-space-min) * 2) * var(--dl-fluid)), calc(var(--dl-space-max) * 3rem));
  --space-xl-2xl: clamp(calc(var(--dl-space-min) * 3rem), calc(var(--dl-space-min) * 3rem + (var(--dl-space-max) * 4 - var(--dl-space-min) * 3) * var(--dl-fluid)), calc(var(--dl-space-max) * 4rem));
  --space-2xl-3xl: clamp(calc(var(--dl-space-min) * 4rem), calc(var(--dl-space-min) * 4rem + (var(--dl-space-max) * 6 - var(--dl-space-min) * 4) * var(--dl-fluid)), calc(var(--dl-space-max) * 6rem));
  --space-3xl-4xl: clamp(calc(var(--dl-space-min) * 6rem), calc(var(--dl-space-min) * 6rem + (var(--dl-space-max) * 8 - var(--dl-space-min) * 6) * var(--dl-fluid)), calc(var(--dl-space-max) * 8rem));
  /* Skip pairs, for gutters and section padding that need a bigger swing */
  --space-s-l: clamp(calc(var(--dl-space-min) * 1rem), calc(var(--dl-space-min) * 1rem + (var(--dl-space-max) * 2 - var(--dl-space-min) * 1) * var(--dl-fluid)), calc(var(--dl-space-max) * 2rem));
  --space-m-xl: clamp(calc(var(--dl-space-min) * 1.5rem), calc(var(--dl-space-min) * 1.5rem + (var(--dl-space-max) * 3 - var(--dl-space-min) * 1.5) * var(--dl-fluid)), calc(var(--dl-space-max) * 3rem));
  --space-l-2xl: clamp(calc(var(--dl-space-min) * 2rem), calc(var(--dl-space-min) * 2rem + (var(--dl-space-max) * 4 - var(--dl-space-min) * 2) * var(--dl-fluid)), calc(var(--dl-space-max) * 4rem));

  /* ---- Corners ---- */
  --radius-s: calc(var(--radius-base) * 0.5px);
  --radius-m: calc(var(--radius-base) * 1px);
  --radius-l: calc(var(--radius-base) * 1.6px);
  --radius-pill: 999px;
}

/* The leading and tracking gates need tan(), atan2() and log() (Chrome 120, Firefox 118, Safari 15.4).
   Without them the gates stay undefined, so dials-base.css keeps headings at --leading-display (or 1.15)
   and leaves letter spacing alone. */
@supports (width: calc(1px * tan(atan2(1px, 1px)) * log(2))) {
  :root, [data-dials], :host {
    --dl-leading-on: calc(var(--leading) + 0px * var(--leading-body, var(--leading-display)));
    --dl-tracking-on: calc(var(--tracking) + 0em * var(--tracking-small, var(--tracking-display)));
  }
}
/* ============================================================
   Dials: the fallback (src/fallback.css, built into the end of dials.css)
   For browsers with color-mix() but without relative colour or
   light-dark(): Chrome and Edge 111-122, Safari 16.2-17, Firefox
   113-127. They can't work out the derived chain above, so this
   block works every public colour token out again from the same
   dials, with color-mix() alone. It comes after the chain and uses
   the same selectors, so it wins there; a site's own file, loaded
   after dials.css, still wins over it. It never sets a dial.
   Approximations, held to the same contrast as the chain (the
   contrast check's --fallback mode):
   - The page is light. .is-dark bands are dark, .is-light bands light.
   - Paper and ink come from --grey at fixed mixes, so the four
     lightness dials, --balance, --dark-lift, --tint-vividness and
     --text-contrast have no effect. --paper-light and friends do.
   - on-solid text can't follow the fill's luminance: each group has a
     fixed choice, and its fill is pulled a fixed amount towards the
     other end so the text keeps 4.5:1 in every Dials theme. White on
     brand, secondary, danger and info, whose fills are darkened; black
     on success, whose fill is lightened, and warning, as set.
   - Coloured text and lines can't move only as far as their target
     needs: on-soft is the dial mixed a fixed amount into ink (so --link
     and --focus too), line a smaller amount, and --link-hover further
     still. The amounts hold 4.5:1 and 3:1 on every surface and soft
     tint, for every theme and for extreme dials, so they over-shoot for
     most colours. Ink is near-black on a light page and near-white in an
     .is-dark band, so the same mix works in both.
   - No calc() and no percentages computed inside color-mix(): only
     literal percentages and dials that are one (--tint-strength).
   ============================================================ */
@supports not ((color: oklch(from red l c h)) and (color: light-dark(red, red))) {
  /* ---- Internal: the scheme switches, literal percentages a band can flip ---- */
  :root, :host, .is-light {
    color-scheme: light;
    --dl-fb-dark: 0%;     /* how much of the dark paper and ink to use */
    --dl-fb-raise: 38%;   /* how much white lifts --surface-raised */
    --dl-fb-shadow: 10%;  /* the strength of shadows */
  }
  .is-dark {
    color-scheme: dark;
    --dl-fb-dark: 100%;
    --dl-fb-raise: 4%;
    --dl-fb-shadow: 45%;
  }

  /* Bands are declared here too, so every token is worked out again in a band's own scheme */
  :root, [data-dials], :host, .is-light, .is-dark {
    /* ---- Internal: paper, ink and the six fills ---- */
    --dl-paper-light: var(--paper-light, color-mix(in oklab, var(--grey) 20%, white));
    --dl-paper-dark:  var(--paper-dark,  color-mix(in oklab, var(--grey) 30%, black));
    --dl-ink-light:   var(--ink-light,   color-mix(in oklab, var(--grey) 34%, black));
    --dl-ink-dark:    var(--ink-dark,    color-mix(in oklab, var(--grey) 17%, white));
    --dl-paper: color-mix(in oklab, var(--dl-paper-dark) var(--dl-fb-dark), var(--dl-paper-light));
    --dl-ink:   color-mix(in oklab, var(--dl-ink-dark) var(--dl-fb-dark), var(--dl-ink-light));
    --dl-brand:   color-mix(in oklab, var(--brand) 72%, black);
    --dl-secondary: color-mix(in oklab, var(--accent, var(--secondary)) 67%, black);
    --dl-success: color-mix(in oklab, var(--success) 85%, white);
    --dl-warning: var(--warning);
    --dl-danger:  color-mix(in oklab, var(--danger) 78%, black);
    --dl-info:    color-mix(in oklab, var(--info) 61%, black);

    /* ---- Surfaces ---- */
    --surface:         var(--dl-paper);
    --surface-raised:  color-mix(in oklab, white var(--dl-fb-raise), var(--dl-paper));
    --surface-lowered: color-mix(in oklab, var(--dl-ink) 4%, var(--dl-paper));
    --surface-sunken:  color-mix(in oklab, var(--dl-ink) 8%, var(--dl-paper));
    --surface-overlay: color-mix(in oklab, black 45%, transparent);

    /* ---- Text: a step stronger than the chain's defaults, to cover --text-contrast ---- */
    --text-strong:   var(--dl-ink);
    --text:          color-mix(in oklab, var(--dl-ink) 94%, var(--dl-paper));
    --text-muted:    color-mix(in oklab, var(--dl-ink) 89%, var(--dl-paper));
    --text-quiet:    color-mix(in oklab, var(--dl-ink) 86%, var(--dl-paper));
    --text-disabled: color-mix(in oklab, var(--dl-ink) 38%, var(--dl-paper));
    --link:          var(--brand-on-soft);
    --link-hover:    color-mix(in oklab, var(--brand) 20%, var(--dl-ink));

    /* ---- Lines and effects ---- */
    --border-quiet:  color-mix(in oklab, var(--dl-ink) 7%, var(--dl-paper));
    --border:        color-mix(in oklab, var(--dl-ink) 13%, var(--dl-paper));
    --border-strong: color-mix(in oklab, var(--dl-ink) 64%, var(--dl-paper));
    --focus:         var(--brand-on-soft);
    --selection:     color-mix(in oklab, var(--brand) 22%, var(--dl-paper));
    --shadow-color:  color-mix(in oklab, black var(--dl-fb-shadow), transparent);
    --shadow-s: 0 1px 3px var(--shadow-color);
    --shadow-m: 0 4px 14px var(--shadow-color);
    --shadow-l: 0 12px 32px var(--shadow-color);
    --mix-hover:  black 12%;
    --mix-active: black 22%;

    /* ---- Groups: soft mixed into paper, on-soft and line mixed towards ink ---- */
    --brand-solid:    var(--dl-brand);
    --brand-on-solid: white;
    --brand-soft:     color-mix(in oklab, var(--brand) var(--tint-strength), var(--dl-paper));
    --brand-on-soft:  color-mix(in oklab, var(--brand) 26%, var(--dl-ink));
    --brand-line:     color-mix(in oklab, var(--brand) 40%, var(--dl-ink));

    --secondary-solid:    var(--dl-secondary);
    --secondary-on-solid: white;
    --secondary-soft:     color-mix(in oklab, var(--accent, var(--secondary)) var(--tint-strength), var(--dl-paper));
    --secondary-on-soft:  color-mix(in oklab, var(--accent, var(--secondary)) 26%, var(--dl-ink));
    --secondary-line:     color-mix(in oklab, var(--accent, var(--secondary)) 40%, var(--dl-ink));

    --neutral-solid:    var(--dl-ink);
    --neutral-on-solid: var(--dl-paper);
    --neutral-soft:     var(--surface-lowered);
    --neutral-on-soft:  var(--text);
    --neutral-line:     var(--border);

    --success-solid:    var(--dl-success);
    --success-on-solid: black;
    --success-soft:     color-mix(in oklab, var(--success) var(--tint-strength), var(--dl-paper));
    --success-on-soft:  color-mix(in oklab, var(--success) 26%, var(--dl-ink));
    --success-line:     color-mix(in oklab, var(--success) 40%, var(--dl-ink));

    --warning-solid:    var(--dl-warning);
    --warning-on-solid: black;
    --warning-soft:     color-mix(in oklab, var(--warning) var(--tint-strength), var(--dl-paper));
    --warning-on-soft:  color-mix(in oklab, var(--warning) 26%, var(--dl-ink));
    --warning-line:     color-mix(in oklab, var(--warning) 40%, var(--dl-ink));

    --danger-solid:    var(--dl-danger);
    --danger-on-solid: white;
    --danger-soft:     color-mix(in oklab, var(--danger) var(--tint-strength), var(--dl-paper));
    --danger-on-soft:  color-mix(in oklab, var(--danger) 26%, var(--dl-ink));
    --danger-line:     color-mix(in oklab, var(--danger) 40%, var(--dl-ink));

    --info-solid:    var(--dl-info);
    --info-on-solid: white;
    --info-soft:     color-mix(in oklab, var(--info) var(--tint-strength), var(--dl-paper));
    --info-on-soft:  color-mix(in oklab, var(--info) 26%, var(--dl-ink));
    --info-line:     color-mix(in oklab, var(--info) 40%, var(--dl-ink));

    /* ---- Ungrouped ---- */
    --solid:    var(--brand-solid);
    --on-solid: var(--brand-on-solid);
    --soft:     var(--brand-soft);
    --on-soft:  var(--brand-on-soft);
    --line:     var(--brand-line);

    /* ---- Deprecated: the old names for the secondary group ---- */
    --accent-solid:    var(--secondary-solid);
    --accent-on-solid: var(--secondary-on-solid);
    --accent-soft:     var(--secondary-soft);
    --accent-on-soft:  var(--secondary-on-soft);
    --accent-line:     var(--secondary-line);
  }
  /* the group classes again, so they still win on a [data-dials] element or a band */
  .is-brand     { --solid: var(--brand-solid);     --on-solid: var(--brand-on-solid);     --soft: var(--brand-soft);     --on-soft: var(--brand-on-soft);     --line: var(--brand-line); }
  .is-secondary { --solid: var(--secondary-solid); --on-solid: var(--secondary-on-solid); --soft: var(--secondary-soft); --on-soft: var(--secondary-on-soft); --line: var(--secondary-line); }
  .is-neutral   { --solid: var(--neutral-solid);   --on-solid: var(--neutral-on-solid);   --soft: var(--neutral-soft);   --on-soft: var(--neutral-on-soft);   --line: var(--neutral-line); }
  .is-success   { --solid: var(--success-solid);   --on-solid: var(--success-on-solid);   --soft: var(--success-soft);   --on-soft: var(--success-on-soft);   --line: var(--success-line); }
  .is-warning   { --solid: var(--warning-solid);   --on-solid: var(--warning-on-solid);   --soft: var(--warning-soft);   --on-soft: var(--warning-on-soft);   --line: var(--warning-line); }
  .is-danger    { --solid: var(--danger-solid);    --on-solid: var(--danger-on-solid);    --soft: var(--danger-soft);    --on-soft: var(--danger-on-soft);    --line: var(--danger-line); }
  .is-info      { --solid: var(--info-solid);      --on-solid: var(--info-on-solid);      --soft: var(--info-soft);      --on-soft: var(--info-on-soft);      --line: var(--info-line); }
  .is-accent    { --solid: var(--secondary-solid); --on-solid: var(--secondary-on-solid); --soft: var(--secondary-soft); --on-soft: var(--secondary-on-soft); --line: var(--secondary-line); }
}
/* Generated by tools/fallback.mjs from dials.css (src/colour.css 93ca251ad22dc853): the Hi-Fi defaults in
   the light scheme. Don't edit. The last resort, for browsers without color-mix() (Chrome and Edge
   before 111, Safari before 16.2, Firefox before 113, all 2022 or older): they can't work anything
   out, so every colour token is flat and they get the house colours, light only. Colour dials have no
   effect there; type and space work as normal. */
@supports not (color: color-mix(in srgb, red, blue)) {
  :root, [data-dials], :host, .is-light, .is-dark {
    color-scheme: light;
    --surface: #e6e5e3;
    --surface-raised: #efefee;
    --surface-lowered: #dcdcda;
    --surface-sunken: #d3d2d1;
    --surface-overlay: rgb(0 0 0 / 45%);
    --text-strong: #1a1916;
    --text: #32312e;
    --text-muted: #4f4e4c;
    --text-quiet: #5b5a58;
    --text-disabled: #91908e;
    --link: #875505;
    --link-hover: #663900;
    --border-quiet: #d5d5d3;
    --border: #c8c7c5;
    --border-strong: #807f7d;
    --focus: #875505;
    --selection: #ead6c0;
    --shadow-color: rgb(0 0 0 / 10%);
    --shadow-s: 0 1px 3px rgb(0 0 0 / 10%);
    --shadow-m: 0 4px 14px rgb(0 0 0 / 10%);
    --shadow-l: 0 12px 32px rgb(0 0 0 / 10%);
    --mix-hover: black 12%;
    --mix-active: black 22%;
    --brand-solid: #f39c12;
    --brand-on-solid: #000000;
    --brand-soft: #e7e0d8;
    --brand-on-soft: #875505;
    --brand-line: #ac6d09;
    --secondary-solid: #2ec4b6;
    --secondary-on-solid: #000000;
    --secondary-soft: #dae3e1;
    --secondary-on-soft: #156b63;
    --secondary-line: #1d897f;
    --neutral-solid: #1a1916;
    --neutral-on-solid: #e6e5e3;
    --neutral-soft: #dcdcda;
    --neutral-on-soft: #32312e;
    --neutral-line: #c8c7c5;
    --success-solid: #3fbf55;
    --success-on-solid: #000000;
    --success-soft: #dae2da;
    --success-on-soft: #206e2e;
    --success-line: #2c8c3c;
    --warning-solid: #f2c230;
    --warning-on-solid: #000000;
    --warning-soft: #e6e3da;
    --warning-on-soft: #755d12;
    --warning-line: #95771a;
    --danger-solid: #e0322b;
    --danger-on-solid: #000000;
    --danger-soft: #eadbd9;
    --danger-on-soft: #b72721;
    --danger-line: #e0322b;
    --info-solid: #3b82c4;
    --info-on-solid: #000000;
    --info-soft: #dae0e6;
    --info-on-soft: #2b6396;
    --info-line: #397ebf;
    --accent-solid: #2ec4b6;
    --accent-on-solid: #000000;
    --accent-soft: #dae3e1;
    --accent-on-soft: #156b63;
    --accent-line: #1d897f;
  }
}
/* ═══ dials:end (Dials) ═════════════════════════════════════════════════ */

/* ═══ This site's dials ═════════════════════════════════════════════════
 * The ONLY place a colour or a scale value is typed. The values reproduce
 * the site's look before Dials (its Elementor kit's brand blue, navy and
 * gold, the page cream and ink, and its --u-* scale knobs), so it looks the
 * same in light. The practice's site is light only, as the live site was.
 * ═══════════════════════════════════════════════════════════════════════ */
:root {
    color-scheme: light;   /* light only: the practice's palette has no dark version */

    /* Colour dials. Each is a group with five roles: --brand-solid,
     * --brand-on-solid, --brand-soft, --brand-on-soft and --brand-line. */
    --brand: hsl(219.1 52% 49.8%);       /* #3D6BC1, the brand blue: headings, links, hovers */
    --secondary: hsl(214.6 100% 15.3%);  /* #00214E, the brand navy: the footer, eyebrows, pills */
    --tertiary: hsl(38.4 94.1% 73.3%);   /* #FBCD7B, the brand gold: the nav bar, buttons, rules and icons */
    --success: hsl(125.4 45.9% 33.3%);   /* #2E7C35, the status colours as the site had them */
    --warning: hsl(37.3 74.1% 54.5%);    /* #E1A035 */
    --danger: hsl(5.6 63.4% 46.1%);      /* #C0392B, the contact form's required-field mark (the site's own red, close to its old status red #C13C36) */
    --info: hsl(202.4 64.4% 40.8%);      /* #2579AB */
    --grey: hsl(100 3.8% 50%);           /* the ink's own faint olive */

    /* Paper and ink, exact: the page cream, and an ink a shade under the
     * source's #2B2C29, so that body text (--text, 98% of the ink here)
     * lands on #2B2C29 itself. The source sets body text, labels and form
     * text all in that one ink, so --text-contrast is at its top. */
    --paper-light: hsl(45 100% 96.1%);   /* #FFFAEB */
    --ink-light: hsl(100 3.8% 15.5%);    /* #272926 */
    --text-contrast: 30;

    /* Type and space, fitted to the source at 390 and 1440 (2026-09-10):
     * body 16px on a 390px phone to 16.5px at 1440, each step 1.16x (phone)
     * to 1.2x (desktop) the last, which lands the source's 2.5 / 3.0 /
     * 3.5rem display sizes on --size-5/6/7; --space-s 16px to 20px, so the
     * steps land on the source's 10 / 15 / 20 / 30 / 40 / 60 / 80 / 120px
     * rhythm at 1440. */
    --screen-min: 390;
    --screen-max: 1440;
    --size-min: 16;
    --size-max: 16.5;
    --ratio-min: 1.16;
    --ratio-max: 1.2;
    --space-min: 16;
    --space-max: 20;
    --space-density: 1;

    /* Type (Dials v0.3): line height, letter spacing and weight. The source
     * sets line height by role, not by size: running text 1.5 at every size
     * (--leading-body), every heading and title 1.2 (--leading-display).
     * The site's heading and title rules read --leading-display as a
     * number, so a small heading keeps 1.2 rather than Dials' size curve
     * (--leading, which small print, eyebrows and fields use). No letter
     * spacing except the uppercase buttons' 0.04em (--tracking-caps), so
     * the other tracking dials stay unset (0). Weights: body 400, headings,
     * nav and buttons 700, labels 600 (--weight-strong, the body weight plus
     * 200). --line-length is the template's 65ch measure. */
    --leading-body: 1.5;
    --leading-display: 1.2;
    --tracking-caps: 0.04;
    --weight-body: 400;
    --weight-heading: 700;
    --line-length: 65ch;
    /* Ayr's own type tokens: two weights the source uses beyond Dials' three.
     * Dials has a body, a strong (body + 200) and a heading weight only. */
    --weight-detail: 500;          /* Work Sans and Manrope 500: the fact cards' copy, the opening-hours lines, the footer contact rows */
    --weight-contact-label: 800;   /* Manrope 800: the header contact bar's labels */

    /* Corners: --radius-s 8px (cards, photos, panels), --radius-m 16px,
     * --radius-l 25.6px. The arches are fixed px radii of their own. */
    --radius-base: 16;
    /* Accent rules, active states and the focus ring are 4px, not Dials' 3px */
    --border-width-l: 4px;

    /* Faces: IBM Plex Sans headings, nav and buttons; Work Sans body; Manrope
     * only in the header contact bar and the footer contact rows (Dials'
     * third face). Loaded in each page's <head>. */
    --font-body: "Work Sans", system-ui, sans-serif;
    --font-heading: "IBM Plex Sans", system-ui, sans-serif;
    --font-accent: "Manrope", system-ui, sans-serif;
    --font-mono: ui-monospace, SFMono-Regular, Menlo, monospace;
}

/* ── The tertiary group ───────────────────────────────────────────────────
 * A third brand colour, typically doing button and CTA work, that is neither
 * a tint of the brand nor a status colour (practices routinely have one:
 * "Button Brown", "Morning Orange"). Dials has no third brand group, so the
 * template adds one with the same five roles, worked out the way Dials v0.2.0
 * works out its own groups (each formula is Dials' brand formula with the
 * tertiary colour in it), from public tokens only. Set --tertiary above;
 * never set these. class="is-tertiary" points --solid and friends at it,
 * like .is-secondary. Declared on bands too, so a band's group follows the
 * band's own scheme.
 *
 *   --tertiary-on-soft  the fill, moved only as far as 4.5:1 needs on the
 *                       least contrasting of its soft tint, --surface-lowered
 *                       and --surface-raised; a colour that passes is kept
 *   --tertiary-line     the dial, moved only as far as 3:1 needs, the same way
 *
 * Dials carries the numbers those two need in its internal --dl-* plumbing,
 * which nothing outside Dials may read, so the template works the same
 * numbers out again from public tokens in its own --tpl-* properties: the
 * luminance of --surface-lowered and --surface-raised (Dials' --dl-surfaces-y)
 * and of the soft tint, and the colour carrying its target. They are the
 * template's plumbing: never use or set a --tpl-* property anywhere else. */
:root, [data-dials], .is-light, .is-dark {
    --tpl-tertiary-base:  oklch(from var(--tertiary) calc(l + (var(--fill-lightness) - l) * var(--balance)) c h);
    --tertiary-solid:     light-dark(var(--tpl-tertiary-base), oklch(from var(--tpl-tertiary-base) calc(l + var(--dark-lift)) c h));
    --tertiary-on-solid:  color(from var(--tertiary-solid) srgb-linear calc(clamp(0, (clamp(0.175, var(--white-text-until), 0.18333) - (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))) * 1000000, 1)) calc(clamp(0, (clamp(0.175, var(--white-text-until), 0.18333) - (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))) * 1000000, 1)) calc(clamp(0, (clamp(0.175, var(--white-text-until), 0.18333) - (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))) * 1000000, 1)) / 1);
    --tertiary-soft:      oklch(from color-mix(in oklab, light-dark(oklch(from var(--tertiary-solid) max(l, 0.7) c h), oklch(from var(--tertiary-solid) min(l, 0.6) c h)) var(--tint-strength), oklch(from var(--surface) l 0 h)) l calc(c * var(--tint-vividness)) h);
    --tpl-surfaces-y:     color-mix(in srgb-linear, color(from var(--surface-lowered) srgb-linear 0 calc(0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1)) 0), color(from var(--surface-raised) srgb-linear 0 0 calc(0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))));
    --tpl-tertiary-under: color-mix(in srgb-linear, color(from var(--tertiary-soft) srgb-linear calc(0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1)) 0 0), var(--tpl-surfaces-y));
    --tpl-tertiary-text:  color-mix(in srgb-linear, color(from var(--tpl-tertiary-base) srgb-linear clamp(0, r, 1) clamp(0, g, 1) clamp(0, b, 1) / 1), light-dark(color(from var(--tpl-tertiary-under) srgb-linear 0 0 0 / calc(clamp(0, 3 * ((min(2 * r, 4 * g, 4 * b) + 0.05) / (4.5 + 0.1) - 0.05), 1))), color(from var(--tpl-tertiary-under) srgb-linear 0 0 0 / calc(clamp(0, (4.5 + 0.1) * (max(2 * r, 4 * g, 4 * b) + 0.05) - 0.05, 1)))));
    --tpl-tertiary-line:  color-mix(in srgb-linear, color(from var(--tertiary) srgb-linear clamp(0, r, 1) clamp(0, g, 1) clamp(0, b, 1) / 1), light-dark(color(from var(--tpl-tertiary-under) srgb-linear 0 0 0 / calc(clamp(0, 3 * ((min(2 * r, 4 * g, 4 * b) + 0.05) / (3 + 0.1) - 0.05), 1))), color(from var(--tpl-tertiary-under) srgb-linear 0 0 0 / calc(clamp(0, (3 + 0.1) * (max(2 * r, 4 * g, 4 * b) + 0.05) - 0.05, 1)))));
    --tertiary-on-soft:   light-dark(color(from var(--tpl-tertiary-text) srgb-linear calc(r * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) calc(g * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) calc(b * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) / 1), color(from color(from var(--tpl-tertiary-text) srgb-linear min(1, r * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) min(1, g * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) min(1, b * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) / alpha) srgb-linear calc(r + (1 - r) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) calc(g + (1 - g) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) calc(b + (1 - b) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) / 1));
    --tertiary-line:      light-dark(color(from var(--tpl-tertiary-line) srgb-linear calc(r * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) calc(g * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) calc(b * 2 * alpha * min(1, (2 * alpha - 1) / 3 / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) / 1), color(from color(from var(--tpl-tertiary-line) srgb-linear min(1, r * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) min(1, g * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) min(1, b * 2 * alpha * max(1, (2 * alpha - 1) / max(0.000001, 2 * alpha * (0.2126 * r + 0.7152 * g + 0.0722 * b)))) / alpha) srgb-linear calc(r + (1 - r) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) calc(g + (1 - g) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) calc(b + (1 - b) * clamp(0, (2 * alpha - 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) / max(0.000001, 1 - (0.2126 * r + 0.7152 * g + 0.0722 * b)), 1)) / 1));
}
.is-tertiary { --solid: var(--tertiary-solid); --on-solid: var(--tertiary-on-solid); --soft: var(--tertiary-soft); --on-soft: var(--tertiary-on-soft); --line: var(--tertiary-line); }
/* The tertiary group in older browsers: without relative colour or
 * light-dark() (iOS 16 and 17, Safari before 18, Chrome and Edge before 123,
 * Firefox before 128) the derivation above cannot be worked out, and Dials'
 * own fallback covers only Dials' groups. So, the way Dials' fallback does
 * its groups, under the same condition and with the same selectors as the
 * derivation: the five roles again with color-mix(in oklab, ...) alone, from
 * --tertiary and the paper (--surface) and ink (--text-strong) Dials'
 * fallback has already worked out. As in Dials v0.2.0's fallback, on-soft is
 * the colour mixed 26% into ink and the line 40% into ink; neither can move
 * only as far as it needs there, so both over-shoot for most colours. Text
 * on the fill is a fixed white, with the fill pulled towards black as Dials
 * pulls --brand (72%), so it keeps 4.5:1. A site with a very light
 * --tertiary checks it: check-contrast.mjs --fallback. */
@supports not ((color: oklch(from red l c h)) and (color: light-dark(red, red))) {
    :root, [data-dials], .is-light, .is-dark {
        --tertiary-solid:    color-mix(in oklab, var(--tertiary) 72%, black);
        --tertiary-on-solid: white;
        --tertiary-soft:     color-mix(in oklab, var(--tertiary) var(--tint-strength), var(--surface));
        --tertiary-on-soft:  color-mix(in oklab, var(--tertiary) 26%, var(--text-strong));
        --tertiary-line:     color-mix(in oklab, var(--tertiary) 40%, var(--text-strong));
    }
}

/* ── The template's own tokens ────────────────────────────────────────────
 * What Dials does not cover: the narrow measure, the grid, the shared control
 * corner, the tap target, layers and motion. None of them is a colour, a text
 * size, a space size or a type setting: line height, letter spacing and
 * weight are Dials' type dials and tokens since v0.3 (the template's old
 * --leading-*, --tracking-* and --weight-* are in "Old names" below). */
:root {
    /* --- Weight -------------------------------------------------------- */
    /* THREE WEIGHTS, DELIBERATELY, all from the dials: body (--weight-body),
     * emphasis (--weight-strong: nav, labels, buttons, eyebrows, strong) and
     * headline (--weight-heading). A fourth needs a reason: the face has a
     * visibly distinct cut AND the three are not creating enough contrast. A
     * flat hierarchy is almost always a spacing or size problem, not a
     * weight problem. */

    /* --- Measure ------------------------------------------------------- */
    --measure: var(--line-length);   /* body copy: the --line-length dial */
    --measure-tight: 45ch;           /* card and caption copy */

    /* --- Grid ---------------------------------------------------------- */
    /* Deliberately minimal: the container and gutter are fluid, placement is
     * left to each layout. Use .u-container and .u-grid below. */
    --grid-max-width: 77.5rem;
    --grid-gutter: var(--space-s-l);
    --grid-columns: 12;

    /* --- Corners beyond Dials' three ----------------------------------- */
    --radius-xs: calc(var(--radius-base) * 0.333px);  /* tags, inline chips, the focus ring: a third of --radius-m, so it follows --radius-base */
    --radius-round: 50%;                   /* avatars */
    --control-radius: var(--radius-s);     /* buttons AND fields: a site sets this once, both follow */

    /* --- Touch targets ------------------------------------------------- */
    /* The smallest box a finger hits reliably: 44px (WCAG 2.5.5, Apple's
     * HIG). A fixed dimension rather than spacing, so it does not scale. */
    --target-min: 2.75rem;

    /* --- Inset shadows, from Dials' --shadow-color ------------------------ */
    --shadow-inner-s: inset 0 1px 2px 0 var(--shadow-color);
    --shadow-inner-m: inset 0 2px 6px 0 var(--shadow-color);

    /* --- Layers -------------------------------------------------------- */
    /* Six values, so z-index is never invented at the call site. */
    --layer-behind: -1;    /* decorative washes sitting behind content */
    --layer-base: 1;
    --layer-raised: 2;      /* hover cards, sticky rows */
    --layer-nav: 3;         /* sticky header */
    --layer-overlay: 4;     /* dropdowns, popovers */
    --layer-modal: 5;       /* dialogs and their backdrop */
    --layer-top: 2147483647;/* skip links, live-region alerts */

    /* --- Motion -------------------------------------------------------- */
    --duration-fast: 120ms;   /* hover, focus */
    --duration-base: 220ms;   /* most transitions */
    --duration-slow: 400ms;   /* entrances */
    --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
    --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
    --reveal-distance: 1.5rem;
}

/* ═══ Old names ═══ aliases:begin ═══════════════════════════════════════
 * The template's token names before Dials (#426), each pointing at the Dials
 * token that replaces it, so markup, the Form controls section and any site
 * layer written against them keep working until #427 migrates the live
 * sites. NEVER use one in new work: use the name on the right. Delete this
 * whole block (down to aliases:end) once nothing reads any of them.
 *
 * Declared on [data-dials] and the .is-light/.is-dark bands as well as
 * :root, so a re-themed scope's or a band's aliases follow its own dials and
 * scheme, as Dials' own tokens do (its fallback works them out again there). Names Dials took over with a new meaning are NOT
 * here: --surface is now the PAGE (the old raised --surface is
 * --surface-raised), --secondary is the second brand colour's dial (it used
 * to be its fill: that is --secondary-solid), --accent is that dial's old
 * Dials name (deprecated in Dials v0.2.0: never set it), --success/--warning/
 * --danger/--info/--tertiary are dials (the fill is --success-solid ...), and --border, --border-strong, --space-*,
 * --radius-s/m/l, --shadow-* and --font-* are Dials' own. The --u-*,
 * --palette-*, --hue-*, --chroma-*, --l-* and --scheme dials are gone: set
 * the Dials dials instead. */
:root, [data-dials], .is-light, .is-dark {
    --primary: var(--brand-solid);
    --primary-hover: light-dark(oklch(from var(--brand-solid) calc(l - 0.07) c h), oklch(from var(--brand-solid) calc(l + 0.07) c h));
    --primary-light: oklch(from var(--brand-solid) calc(l + 0.11) c h);
    --primary-muted: color-mix(in oklab, var(--brand-solid) 15%, var(--surface));
    --primary-pale: var(--brand-soft);
    --on-primary: var(--brand-on-solid);
    --secondary-hover: light-dark(oklch(from var(--secondary-solid) calc(l - 0.07) c h), oklch(from var(--secondary-solid) calc(l + 0.07) c h));
    --secondary-light: oklch(from var(--secondary-solid) calc(l + 0.11) c h);
    --secondary-pale: var(--secondary-soft);
    --on-secondary: var(--secondary-on-solid);
    --tertiary-hover: light-dark(oklch(from var(--tertiary-solid) calc(l - 0.07) c h), oklch(from var(--tertiary-solid) calc(l + 0.07) c h));
    --tertiary-pale: var(--tertiary-soft);
    --on-tertiary: var(--tertiary-on-solid);
    --accent-dark: var(--primary-hover);
    --accent-pale: var(--brand-soft);
    --success-pale: var(--success-soft);
    --warning-pale: var(--warning-soft);
    --danger-pale: var(--danger-soft);
    --info-pale: var(--info-soft);
    --ink-strong: var(--text-strong);
    --ink: var(--text);
    --ink-mid: var(--text-muted);
    --ink-soft: var(--text-quiet);
    --bg: var(--surface);
    --on-bg: var(--text);
    --on-surface: var(--text);
    --step--2: var(--size--2);
    --step--1: var(--size--1);
    --step-0: var(--size-0);
    --step-1: var(--size-1);
    --step-2: var(--size-2);
    --step-3: var(--size-3);
    --step-4: var(--size-4);
    --step-5: var(--size-5);
    --step-6: var(--size-6);
    --step-7: var(--size-7);
    --step-8: var(--size-8);
    --border-thin: var(--border-width-s);
    --border-medium: var(--border-width-m);
    --border-thick: var(--border-width-l);

    /* The template's type ladder before Dials v0.3 (#436), FROZEN at its old
     * values, so a site layer written against it renders exactly as it did.
     * They do not follow the type dials, and the template reads none of them:
     * line height is var(--leading), letter spacing var(--tracking) (in
     * capitals var(--tracking-caps-total)), weight var(--weight-body),
     * var(--weight-strong) or var(--weight-heading). check-system.sh accepts
     * these values only exactly as written here. */
    --weight-400: 400;
    --weight-600: 600;
    --weight-700: 700;
    --leading-xs: 1.05;
    --leading-s: 1.18;
    --leading-m: 1.3;
    --leading-l: 1.5;
    --leading-xl: 1.6;
    --tracking-xs: -0.02em;
    --tracking-s: -0.01em;
    --tracking-m: 0;
    --tracking-l: 0.04em;
    --tracking-xl: 0.08em;
}
/* ═══ aliases:end (Old names) ═══════════════════════════════════════════ */

/* ═══════════════════════════════════════════════════════════════════════
 * RESET
 *
 * Josh Comeau's Custom CSS Reset (joshwcomeau.com/css/custom-css-reset/),
 * lightly adapted. Normalises browser defaults so the base layer below is
 * building on the same ground in every browser. Leave this alone; make
 * design decisions in the base layer and the tokens above it.
 * ═══════════════════════════════════════════════════════════════════════ */

*, *::before, *::after { box-sizing: border-box; }

/* Skip link. craft.md requires one as the first element in <body>; without a
 * rule here it renders as a visible link above the header on every site. It is
 * off-screen until focused, then a real control with a visible focus ring. */
.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: var(--layer-top, 2147483647);
    padding: var(--space-xs) var(--space-s);
    background: var(--solid);
    color: var(--on-solid);
    text-decoration: none;
    border-radius: 0 0 var(--radius-xs) 0;
}
.skip-link:focus, .skip-link:focus-visible {
    left: 0;   /* the ring is the global one, in Form controls & focus */
}

* { margin: 0; }

html {
    -webkit-text-size-adjust: 100%;
    -moz-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

body {
    -webkit-font-smoothing: antialiased;   /* line height: the base layer's body rule, from --leading-body */
}

/* Media is block-level and never overflows its container. */
img, picture, video, canvas, svg {
    display: block;
    max-width: 100%;
}

/* Form controls inherit typography rather than using browser chrome. */
:where(input, button, textarea, select) { font: inherit; }   /* zero specificity: "Form controls" below must win */

/* Long words and URLs wrap instead of forcing a horizontal scrollbar. */
p, h1, h2, h3, h4, h5, h6 { overflow-wrap: break-word; }

/* A new stacking context on the root, so app-level layers cannot escape. */
#root, #__next { isolation: isolate; }

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* ═══════════════════════════════════════════════════════════════════════
 * ELEMENT BASE LAYER
 *
 * Bare elements are styled here so a page is correct with no classes at
 * all. Without this, an unclassed <h2> falls back to the browser default
 * and whoever writes the page patches it with an inline style — which is
 * how a site ends up with a different heading treatment per page.
 *
 * Every heading has a matching .h1-.h6 class. Use the ELEMENT for document
 * structure (SEO, screen readers, outline) and the CLASS for appearance,
 * so an <h1> can look like an eyebrow without lying about the hierarchy:
 *
 *     <h1 class="h4">Still the page's real heading, just smaller</h1>
 *
 * Sites override these; they are a floor, not a straitjacket.
 * ═══════════════════════════════════════════════════════════════════════ */

body {
    font-family: var(--font-body);
    font-size: var(--size-0);
    font-weight: var(--weight-body);
    line-height: var(--leading-body);   /* a number, so it inherits as one; --leading is a length */
    color: var(--text);
    background: var(--surface);
}

/* Headings ─────────────────────────────────────────────────────────────
 * Margins are top-heavy on purpose: a heading belongs to what follows it,
 * so the space above is larger than the space below. */
h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
    margin: var(--space-l) 0 var(--space-s);
    font-family: var(--font-heading);
    font-weight: var(--weight-heading);
    line-height: var(--leading);        /* for each heading's own size: on the heading, never inherited */
    letter-spacing: var(--tracking);
    color: var(--text-strong);
    text-wrap: balance;
}

:where(h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6) + * {
    margin-top: 0;
}

/* A heading opening its container needs no space above it. */
:where(h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6):first-child {
    margin-top: 0;
}

h1, .h1 { font-size: var(--size-5); }
h2, .h2 { font-size: var(--size-4); }
h3, .h3 { font-size: var(--size-3); }
h4, .h4 { font-size: var(--size-2); }
h5, .h5 { font-size: var(--size-1); }
h6, .h6 {
    font-size: var(--size-0);
    letter-spacing: var(--tracking-caps-total);   /* capitals */
    text-transform: uppercase;
}

/* Dials' --leading and --tracking need log() and atan2() (Chrome and Edge
 * 120, Firefox 118, Safari 15.4). Without them Dials cannot work them out, so
 * under Dials' own condition a heading keeps --leading-display, as
 * dials-base.css does; everything else inherits the body's --leading-body,
 * and letter spacing is left alone. */
@supports not (width: calc(1px * tan(atan2(1px, 1px)) * log(2))) {
    h1, h2, h3, h4, h5, h6,
    .h1, .h2, .h3, .h4, .h5, .h6,
    .notfound__code { line-height: var(--leading-display); }
}

/* A highlighted phrase inside a heading. One mechanism, not three. */
:where(h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6) em {
    font-style: italic;
    color: var(--on-soft);   /* coloured text on the page */
}

/* Text ─────────────────────────────────────────────────────────────── */
p, ul, ol, dl, blockquote, figure, table, pre {
    margin: 0 0 var(--space-m);
}

/*
 * Line length is a container's job, not every paragraph's — capping each <p>
 * leaves text hugging the left of any column already sized for reading.
 * Use .measure (or set a width on the container) where prose needs it.
 */
.measure { max-width: var(--line-length); }
.measure-tight { max-width: var(--measure-tight); }

/* Opening paragraph: larger and looser than body copy. */
.lede {
    font-size: var(--size-1);
    line-height: var(--leading);
    letter-spacing: var(--tracking);
    color: var(--text-muted);
}

/* Small label above a heading. */
.eyebrow {
    display: block;
    margin-bottom: var(--space-2xs);
    font-size: var(--size--1);
    font-weight: var(--weight-strong);
    line-height: var(--leading);
    letter-spacing: var(--tracking-caps-total);   /* capitals */
    text-transform: uppercase;
    color: var(--on-soft);
}

small, .text-small { font-size: var(--size--1); line-height: var(--leading); letter-spacing: var(--tracking); }

strong, b { font-weight: var(--weight-strong); }

a {
    color: var(--link);
    text-decoration-thickness: var(--border-width-s);
    text-underline-offset: 0.15em;
    transition: color var(--duration-fast) var(--ease-out);
}
a:hover { color: var(--link-hover); }

/* The focus ring lives in "Form controls & focus" below. */

ul, ol { padding-left: var(--space-m); }

/*
 * List spacing applies to PROSE lists only. Navigation, button groups and
 * card grids are lists too, and flow margins on those knock flex/grid items
 * out of alignment (the site header) or balloon the spacing (the footer).
 *
 * Presence of a class is not the test — a footer nav is a nav whether or not
 * anyone put a class on it — so navigation context opts out explicitly.
 */
:where(ul, ol) > li { margin-bottom: var(--space-2xs); }
:where(ul, ol) > li:last-child { margin-bottom: 0; }

nav ul, nav ol,
header ul, header ol,
footer ul, footer ol,
menu {
    margin: 0;
    padding-left: 0;
    list-style: none;
}

nav li, header li, footer li, menu li {
    margin-bottom: 0;
}

/* A list explicitly used for layout carries no bullets, indent or margin. */
:where(ul, ol)[class] {
    margin: 0;
    padding-left: 0;
    list-style: none;
}

:where(ul, ol)[class] > li { margin-bottom: 0; }

blockquote {
    /* The quote bar is a quiet border in the group's colour: Dials' subtle
     * border pattern (tokens.md, "A subtle border in a group's colour"),
     * declared here rather than at :root so it follows an .is-* class on the
     * quote. --line itself is a strong 3:1 line since Dials v0.2.0; 30% of
     * it keeps the bar about as light as it was before (the pattern's
     * example is 40%: a step darker). Decoration: no contrast promised. */
    --quote-bar: color-mix(in oklab, var(--line) 30%, var(--border));
    padding-left: var(--space-m);
    border-left: var(--border-width-l) solid var(--quote-bar);
    color: var(--text-muted);
    font-style: italic;
}

hr {
    height: 0;
    margin: var(--space-l) 0;
    border: 0;
    border-top: var(--border-width-s) solid var(--border);
}

code, kbd, samp, pre {
    font-family: var(--font-mono);
    font-size: 0.9em;
}

/* Media ────────────────────────────────────────────────────────────────
 * Images carry NO radius and NO background plate by default.
 *
 * They used to. `img { border-radius: var(--radius-m); background: var(--surface-raised) }`
 * was added to fix one square photo on Wellbrook, and it cost far more than it
 * saved: every migration since has had to undo it, because a faithful clone of a
 * customer's live site decides its own corners, and the background plate fills
 * the transparent areas of every PNG and SVG — a logo on a dark footer renders
 * as a solid block. Ten of the thirteen sites on this box carried an override
 * for it before it was removed.
 *
 * A radius is a design decision belonging to the site's own stylesheet, next to
 * the cards it should match. Use .is-rounded (below) or a site-layer rule; do
 * not put it back here. */
img, picture, video, canvas, svg {
    height: auto;
}

/* Opt in where a photo should match the radius of the cards around it. */
img.is-rounded, .is-rounded img { border-radius: var(--radius-m); }

figure { margin-inline: 0; }

figcaption {
    margin-top: var(--space-2xs);
    font-size: var(--size--1);
    line-height: var(--leading);
    letter-spacing: var(--tracking);
    color: var(--text-quiet);
}

/* Tables ───────────────────────────────────────────────────────────── */
table {
    width: 100%;
    border-collapse: collapse;
    text-align: left;
}

th, td {
    padding: var(--space-2xs) var(--space-xs);
    border-bottom: var(--border-width-s) solid var(--border);
    vertical-align: top;
}

th {
    font-weight: var(--weight-strong);
    color: var(--text-strong);
}

tbody tr:last-child :where(th, td) { border-bottom: 0; }

/* ═══ Form controls & focus ═══ form-controls:begin ══════════════════════
 * A text field's look, and every focus ring on the site, are set ONCE,
 * here: by the --field-* and --focus-ring* tokens and a few base rules.
 * Every text-like control on the site (contact, search, careers, booking,
 * anything mediflare.js or Connect writes) inherits it, so they match by
 * construction.
 *
 * - This section is copied VERBATIM from _template and never edited in a
 *   site: check-system.sh fails the site if its copy differs by a character.
 *   A site differs only in TOKEN VALUES, set in the site layer's own :root,
 *   below this section (a later :root wins over the defaults here).
 * - Never restyle a control inside a component. A component rule may place
 *   a field (grid, margin, width) but never sets its border, radius,
 *   background or height -- check-system.sh fails the site if one does.
 * - Fields and buttons share ONE corner, --control-radius: set it in the
 *   site layer's :root and both follow. Never set --field-radius
 *   (check-system.sh fails it), except to 0px in underline mode below;
 *   pill buttons mean pill fields.
 * - The base rules are at zero specificity (:where), so any token change
 *   reaches every field and nothing here outranks a deliberate override.
 * - ONE focus ring per site, on links, buttons and fields alike: an outline
 *   in --focus-ring at --focus-ring-w. No other rule sets a focus outline,
 *   colour or box-shadow (check-system.sh fails one); outline-offset may be
 *   adjusted where a ring would be clipped.
 * - Underline-only fields: set --field-border-w: 0,
 *   --field-border-bottom: var(--border-width-s) solid <colour> and
 *   --field-radius: 0px (an underline has no corners to share; a rounded
 *   one curves at its ends, and buttons keep --control-radius); optionally
 *   --field-focus-border-bottom: var(--focus-ring-w) solid var(--focus-ring)
 *   so the underline thickens with the ring. No extra rules. Underline
 *   mode is the only time a site sets --field-radius, and check-system.sh
 *   then requires the 0px.
 * - Colours follow the band. The colour tokens are declared on the page
 *   AND on every .is-light/.is-dark band and [data-dials] scope, as Dials
 *   declares its own: a browser on Dials' fallback (no relative colour)
 *   works a token out once per scope, so declared on :root alone a field
 *   in a dark band kept the light page's border and ring. A site that
 *   changes a field COLOUR sets it on the same four selectors, after this
 *   section (:root, [data-dials], .is-light, .is-dark { --field-...: ... }),
 *   or a band keeps the default. Sizes are set on :root only.
 * - A panel on a ground that is not a Dials surface (a brand fill) re-sets
 *   the leaf colour tokens on the container, never the rules:
 *     .brand-panel {
 *         --focus-ring: var(--brand-on-solid);
 *         --field-border: var(--brand-on-solid);
 *     }
 *   --focus-ring must reach >= 3:1 against every ground it is drawn on.
 * The guard finds this section by the begin/end markers; keep both.
 * ═══════════════════════════════════════════════════════════════════════ */

:root {
    --field-h: var(--target-min);                 /* the single-line height: exact, never below the 44px target */
    --field-textarea-h: calc(var(--field-h) * 3); /* the textarea's minimum height */
    --field-pad-block: var(--space-2xs);          /* textarea only; a one-line field centres its text in --field-h */
    --field-pad-inline: var(--space-xs);
    --field-font-size: max(var(--size-0), 1rem);  /* never below 16px, or iOS zooms the page on focus */
    --field-leading: var(--leading);              /* Dials' leading, worked out at the field's own size */
    --field-weight: var(--weight-body);           /* one weight wherever the field sits */
    --field-radius: var(--control-radius);        /* = the .btn radius, by construction; never set it */
    --field-textarea-radius: min(var(--field-radius), var(--radius-l));   /* a pill textarea is a capsule; cap it */
    --field-border-w: var(--border-width-s);
    /* Unset by default, so they follow --field-border-w/--field-border:
     * --field-border-bottom          the resting bottom edge (underline mode)
     * --field-focus-border-bottom    the bottom edge while focused
     * --field-focus-outline          the field's ring; leave it to the default */
    --focus-ring-w: var(--border-width-m);        /* >= --field-border-w, so the ring covers the border */
}

/* The colours, on the bands too (see above). */
:root, [data-dials], .is-light, .is-dark {
    --field-bg: var(--surface-raised);            /* fields sit on the raised surface, as cards do */
    --field-ink: var(--text);
    --field-border: var(--border-strong);         /* Dials' control border: 3:1 on every surface */
    --field-border-hover: var(--text-quiet);
    --field-placeholder: var(--text-quiet);
    --focus-ring: var(--focus);                   /* Dials' focus ring: >= 3:1 on every surface, light and dark */
}

/* THE focus ring: every interactive element, always. Fields refine the
 * offset and radius below; nothing else sets a focus outline. */
:focus-visible {
    outline: var(--focus-ring-w) solid var(--focus-ring);
    outline-offset: 2px;
    border-radius: var(--radius-xs);
}

label {
    display: block;
    margin-bottom: var(--space-3xs);
    font-size: var(--size--1);
    font-weight: var(--weight-strong);
    line-height: var(--leading);
    letter-spacing: var(--tracking);
    color: var(--text-strong);
}

/* THE base rule. Every text-like control: text, email, tel, search, number,
 * date, url, password, select and textarea -- not checkboxes, radios,
 * ranges, files or button-type inputs. */
:where(input:not([type=checkbox],[type=radio],[type=range],[type=file],[type=color],[type=submit],[type=button],[type=reset],[type=image],[type=hidden]), select, textarea) {
    --_field-radius: var(--field-radius);
    appearance: none;
    box-sizing: border-box;
    width: 100%;
    height: var(--field-h);
    min-height: var(--field-h);
    padding: 0 var(--field-pad-inline);
    font: inherit;
    font-size: var(--field-font-size);
    font-weight: var(--field-weight);
    line-height: var(--field-leading);
    color: var(--field-ink);
    background-color: var(--field-bg);
    border: var(--field-border-w) solid var(--field-border);
    border-bottom: var(--field-border-bottom, var(--field-border-w) solid var(--field-border));
    border-radius: var(--_field-radius);
    box-shadow: none;
    transition: border-color var(--duration-fast) var(--ease-out);
}

:where(input:not([type=checkbox],[type=radio],[type=range],[type=file],[type=color],[type=submit],[type=button],[type=reset],[type=image],[type=hidden]), select, textarea):hover {
    border-color: var(--field-border-hover);
}

/* One edge on focus. The offset pulls the ring in by the border's width, so
 * it is drawn ON the border (covering it) rather than outside it; the border
 * and shadow are held at rest so nothing draws a second edge. Specificity
 * 0,1,0 and later than the global :focus-visible, so it wins over that one
 * (whose offset and radius suit links, not fields). In underline mode the
 * bottom edge may take --field-focus-border-bottom as well. */
:where(input:not([type=checkbox],[type=radio],[type=range],[type=file],[type=color],[type=submit],[type=button],[type=reset],[type=image],[type=hidden]), select, textarea):focus {
    border-color: var(--field-border);
    border-bottom: var(--field-border-bottom, var(--field-border-w) solid var(--field-border));
    box-shadow: none;
    outline: none;
}
:where(input:not([type=checkbox],[type=radio],[type=range],[type=file],[type=color],[type=submit],[type=button],[type=reset],[type=image],[type=hidden]), select, textarea):focus-visible {
    outline: var(--field-focus-outline, var(--focus-ring-w) solid var(--focus-ring));
    outline-offset: calc(var(--field-border-w) * -1);
    border-bottom: var(--field-focus-border-bottom, var(--field-border-bottom, var(--field-border-w) solid var(--field-border)));
    border-radius: var(--_field-radius);
}

:where(textarea) {
    --_field-radius: var(--field-textarea-radius);
    height: auto;
    min-height: var(--field-textarea-h);
    padding-block: var(--field-pad-block);
    resize: vertical;
}

/* The chevron is one conic-gradient wedge in --field-ink: tokens only, no
 * image, so it recolours with the palette and the scheme. (Two half-square
 * linear gradients leave a seam where they meet.) */
:where(select) {
    padding-inline-end: calc(var(--field-pad-inline) * 2 + var(--space-xs));
    background-image: conic-gradient(from -45deg at 50% 100%, var(--field-ink) 90deg, transparent 0);
    background-position: calc(100% - var(--field-pad-inline)) 50%;
    background-size: calc(var(--space-3xs) * 2.5) calc(var(--space-3xs) * 1.25);
    background-repeat: no-repeat;
    cursor: pointer;
}
:where(select[multiple], select[size]) { height: auto; padding-block: var(--field-pad-block); padding-inline-end: var(--field-pad-inline); background-image: none; }

:where(input, textarea)::placeholder { color: var(--field-placeholder); opacity: 1; }

/* The browser's own clear (x) in a search box, redrawn as a mask so it takes
 * --field-ink instead of the browser's grey. */
:where(input[type=search])::-webkit-search-cancel-button {
    -webkit-appearance: none;
    appearance: none;
    inline-size: 1em;
    block-size: 1em;
    cursor: pointer;
    background-color: var(--field-ink);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4 4l8 8M12 4l-8 8' stroke='black' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4 4l8 8M12 4l-8 8' stroke='black' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E") center / contain no-repeat;
}

input[type="checkbox"], input[type="radio"] { accent-color: var(--brand-solid); }

fieldset { margin: 0 0 var(--space-m); padding: 0; border: 0; }

/* ═══ form-controls:end (Form controls & focus) ═════════════════════════ */

/* Buttons size to their content, not to the form-control full width. */
input[type="submit"], input[type="button"] { width: auto; }

/*
 * A bare <button> is usually a UI affordance — a menu toggle, a dropdown
 * trigger — not a visual button, so it gets a reset rather than a look.
 * Add .btn when you want one that looks like a button.
 */
button {
    font: inherit;
    color: inherit;
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
}

/* Buttons ──────────────────────────────────────────────────────────────
 * .btn is opt-in — put it on a <button> or an <a> that should look like a
 * button. Variants change colour, sizes change scale; every one is at least
 * --target-min (44px) tall, the tap target. A bare <button> is
 * reset above, not styled, because most of them are menu and dropdown
 * triggers rather than visual buttons. */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-3xs);
    padding: var(--space-2xs) var(--space-s);
    font-family: inherit;
    font-size: var(--size--1);
    font-weight: var(--weight-strong);
    line-height: var(--leading);        /* at each button size's own font size (.btn--sm, .btn--lg) */
    letter-spacing: var(--tracking);
    text-align: center;
    text-decoration: none;
    white-space: nowrap;
    min-block-size: var(--target-min);   /* 44px tap target, every size and variant */
    cursor: pointer;
    border: var(--border-width-s) solid transparent;
    border-radius: var(--control-radius);   /* shared with every field; set --control-radius, not this */
    transition: background var(--duration-fast) var(--ease-out),
                border-color var(--duration-fast) var(--ease-out),
                color var(--duration-fast) var(--ease-out);
}

.btn--primary {
    background: var(--solid);
    color: var(--on-solid);
}
/* Hover and pressed mix the fill away from its text colour (Dials' --mix-*),
 * so they work on every group: <a class="btn btn--primary is-tertiary">. */
.btn--primary:hover { background: color-mix(in oklch, var(--solid), var(--mix-hover)); color: var(--on-solid); }
.btn--primary:active { background: color-mix(in oklch, var(--solid), var(--mix-active)); color: var(--on-solid); }

.btn--secondary {
    background: transparent;
    border-color: var(--solid);
    color: var(--on-soft);
}
.btn--secondary:hover { background: var(--soft); color: var(--on-soft); }

.btn--ghost {
    background: transparent;
    color: var(--text-muted);
}
.btn--ghost:hover { background: var(--soft); color: var(--on-soft); }

.btn--sm { padding: var(--space-3xs) var(--space-xs); font-size: var(--size--2); }
.btn--lg { padding: var(--space-xs) var(--space-m); font-size: var(--size-0); }

/*
 * ON A BRAND-COLOURED GROUND
 *
 * A dark band is class="is-dark" on the section: Dials works every token out
 * again in the dark scheme, so the buttons above need nothing more. On a band
 * painted with a brand fill (background: var(--solid)) they invert instead:
 * the solid button goes to the raised surface, the outline picks up a
 * translucent edge in the fill's text colour. Put .on-dark on the button or
 * any ancestor.
 */
.on-dark .btn--primary,
.btn--primary.on-dark {
    background: var(--surface-raised);
    color: var(--on-soft);
}

.on-dark .btn--primary:hover,
.btn--primary.on-dark:hover {
    background: var(--soft);
    color: var(--on-soft);
}

.on-dark .btn--secondary,
.btn--secondary.on-dark {
    color: var(--on-solid);
    border-color: color-mix(in oklab, var(--on-solid) 40%, transparent);
}

.on-dark .btn--secondary:hover,
.btn--secondary.on-dark:hover {
    background: color-mix(in oklab, var(--on-solid) 12%, transparent);
    color: var(--on-solid);
}

.btn[disabled], .btn[aria-disabled="true"] {
    opacity: 0.5;
    cursor: not-allowed;
}

/* Media frames ────────────────────────────────────────────────────────
 * A frame for an embed — map, video or photo — so the child fills a box of
 * known proportion instead of the element's natural size.
 *
 * The ratio, radius and any framing are DEFAULTS. Change them in this file
 * to suit the design; they are here so a frame is never unstyled, not to
 * fix how it should look. */
.media-frame {
    aspect-ratio: 4 / 3;
    overflow: hidden;
    border-radius: var(--radius-m);
    background: var(--surface-raised);
}

.media-frame > :where(iframe, img, video) {
    width: 100%;
    height: 100%;
    border: 0;
    display: block;
    object-fit: cover;
    border-radius: 0;
}

.media-frame--square { aspect-ratio: 1; }
.media-frame--wide { aspect-ratio: 16 / 9; }

/* Cards ────────────────────────────────────────────────────────────────
 * Deliberately minimal — a surface with a radius. Sites compose their own
 * card variants on top; modelling every one here would be guesswork. */
.card {
    padding: var(--space-m);
    background: var(--surface-raised);
    border: var(--border-width-s) solid var(--border);
    border-radius: var(--radius-m);
}

/* Utility ──────────────────────────────────────────────────────────── */
.visually-hidden, .sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/*
 * Grid utilities. .u-container centres and pads; .u-grid lays out. Placement
 * within the grid is each layout's business — see refs/design/layouts.md.
 */
.u-container {
    max-width: var(--grid-max-width);
    margin-inline: auto;
    padding-inline: var(--grid-gutter);
}

.u-grid {
    display: grid;
    gap: var(--grid-gutter);
}

/*
 * Section rhythm. EVERY band on a page should be a .section — this is what
 * gives a page its vertical breathing room, and it is the single most
 * repeated review comment when it is missed ("this section is lacking top
 * and bottom padding", raised three separate times on one site).
 *
 * It is a class rather than a bare `section` selector because bands are not
 * always <section> elements, and because a band that deliberately runs flush
 * to its neighbour needs to say so out loud via --flush.
 *
 * Do not hand-roll the padding. --space-l-2xl is the site-wide "40px phone /
 * 80px desktop" step, already a clamp; a bespoke value breaks the rhythm.
 *
 * Verify with bandpad.mjs, which measures the real rendered ink gap between
 * adjacent bands and fails under 40px.
 */
.section { padding-block: var(--space-l-2xl); }
.section--tight { padding-block: var(--space-l); }
.section--flush { padding-block: 0; }

/* A centred intro (eyebrow + heading + standfirst) above a band's content. */
.section__head {
    max-width: 46rem;
    margin-inline: auto;
    text-align: center;
}

/*
 * Scroll entrance.
 *
 * Native scroll-driven animation — no library, no IntersectionObserver, no
 * JS. Add .reveal for a plain fade, or one of the directional modifiers.
 *
 * WHY THE WHOLE BLOCK IS INSIDE prefers-reduced-motion: a reveal implemented
 * as `opacity: 0` plus an animation leaves reduced-motion users staring at
 * invisible content when the animation never runs. Scoping the rule means
 * they simply get the content, with no trap to fall into.
 *
 * Safari and Firefox do not support animation-timeline yet, so content there
 * is simply visible. That is the correct failure for a practice site: no
 * entrance effect is always better than content that never arrives.
 */
@media (prefers-reduced-motion: no-preference) {
    .reveal {
        animation: reveal linear both;
        animation-timeline: view();
        animation-range: entry 0% cover 30%;
    }

    .reveal--up { --reveal-from: translateY(var(--reveal-distance)); }
    .reveal--down { --reveal-from: translateY(calc(var(--reveal-distance) * -1)); }
    .reveal--left { --reveal-from: translateX(var(--reveal-distance)); }
    .reveal--right { --reveal-from: translateX(calc(var(--reveal-distance) * -1)); }
}

@keyframes reveal {
    from {
        opacity: 0;
        transform: var(--reveal-from, none);
    }
}

/*
 * Doctor avatar fallback
 * Shows a gradient + person silhouette when no photo exists. The gradient
 * is Dials' band pattern (tokens.md, "Gradients are patterns"): from one
 * fill to another, decoration only, so no text is ever set on it.
 * The <img> has onerror="this.style.display='none'" which hides
 * the broken image, revealing this CSS background underneath.
 *
 * Derived from the site's own brand fill so a missing photo reads as part of
 * this practice rather than as a stray swatch.
 */
:root, [data-dials], .is-light, .is-dark {
    --avatar-shade: color-mix(in oklab, var(--brand-solid) 85%, black);   /* the avatar gradient's darker end: the brand fill, a step darker. color-mix() rather than relative colour, so Dials' fallback browsers draw it too */
}

.doctor-avatar {
    position: relative;
    aspect-ratio: 4 / 5;
    overflow: hidden;
    border-radius: var(--radius-s);
    background: linear-gradient(135deg, var(--avatar-shade), var(--brand-solid));
    display: flex;
    align-items: center;
    justify-content: center;
}

/* The silhouette is an icon on the brand fill, so it is drawn in the fill's
 * own text colour, --brand-on-solid, through a mask (the shape only), and
 * keeps 3:1 in light and dark. A white silhouette fell to 2.8:1 on a dark
 * page, where the fill is lifted (mf-websites#431). */
.doctor-avatar::after {
    content: "";
    position: absolute;
    width: 40%;
    height: 40%;
    background-color: var(--brand-on-solid);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='black' stroke-width='1.5'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M15.75 6a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0ZM4.501 20.118a7.5 7.5 0 0 1 14.998 0A17.933 17.933 0 0 1 12 21.75c-2.676 0-5.216-.584-7.499-1.632Z'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='black' stroke-width='1.5'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M15.75 6a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0ZM4.501 20.118a7.5 7.5 0 0 1 14.998 0A17.933 17.933 0 0 1 12 21.75c-2.676 0-5.216-.584-7.499-1.632Z'/%3E%3C/svg%3E") center / contain no-repeat;
}

.doctor-avatar img {
    position: relative;
    z-index: var(--layer-base);
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Hours: prevent time strings from breaking between number and am/pm */
.hours-table td:last-child,
.footer__hours-row span {
    white-space: nowrap;
}
/* ── 404 ──────────────────────────────────────────────────────────────
 * Served for any unmatched path, so it stands alone: say what happened, then
 * offer the way back rather than leaving a dead end.
 *
 * Deliberately written against fallbacks rather than this site's own token
 * names - every site in the fleet has a different vocabulary, and a 404 that
 * silently loses its layout because one variable is spelt differently is
 * worse than one that is slightly plainer. */
.notfound {
    padding-block: var(--space-3xl) var(--space-2xl);
    text-align: center;
}
.notfound__inner { max-width: 46rem; margin-inline: auto; }
.notfound__code {
    font-size: var(--size-7);   /* the site's display step, as the hero headline */
    font-weight: var(--weight-heading);
    line-height: var(--leading);
    letter-spacing: var(--tracking);
    margin: 0 0 var(--space-2xs);
    opacity: 0.55;
}
.notfound h1 { margin-top: 0; }
.notfound__lede { font-size: var(--size-1); line-height: var(--leading); letter-spacing: var(--tracking); margin-inline: auto; max-width: 40rem; }
.notfound__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-s);
    justify-content: center;
    margin-top: var(--space-l);
}
.notfound__links {
    margin-top: var(--space-xl);
    padding-top: var(--space-l);
    border-top: var(--border-width-s) solid currentColor;
    border-color: color-mix(in oklab, currentColor 22%, transparent);
}
.notfound__links-title {
    font-size: var(--size-0);
    text-transform: uppercase;
    letter-spacing: var(--tracking-caps-total);   /* capitals */
    margin: 0 0 var(--space-s);
}
.notfound__links ul {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2xs) var(--space-l);
    justify-content: center;
}
.notfound__links a {
    display: inline-block;
    min-height: 24px;   /* WCAG 2.5.8 target size */
    line-height: var(--leading);
    font-weight: var(--weight-strong);
}

/* ===== SITE LAYER: Ayr Medical Group ===== */

/* ===========================================================================
 * AYR MEDICAL GROUP — site layer
 *
 * Transcribed from https://www.ayrmedical.com.au (WordPress/Elementor kit 6)
 * on 2026-09-10. Every value below was MEASURED off the live DOM at 1440,
 * 1024, 390 and 1920 — none of it was chosen.
 *
 * THE SCALE IS DIALS', TUNED BY ITS DIALS ONLY ("This site's dials" at the
 * top of this file; owner decision 2026-10-03, carried onto Dials v0.3 on
 * 2026-11-02). Every --size-* and --space-* is worked out by the Dials
 * section; no step is redeclared and none is invented.
 *
 * Live sets a fluid root, `calc(0.74981rem + 0.31266vw)`, and states every
 * size as a plain rem multiple of it (0.75 / 0.9 / 1.0 / 1.125 / 1.25 / 1.5 /
 * 2.5 / 3.0 / 3.5rem), plus a few fixed px sizes (13 / 14 / 14.4 / 15 / 32).
 * Our root stays at 100%: the steps carry the fluidity.
 *
 * The dials are fitted at the two design widths, 390 and 1440. Body is exact
 * at both (16px phone floor, 16.5px desktop). A ratio of 1.2 at 1440 lands
 * live's three display sizes on size-5/6/7 within 2.4%; 1.16 at 390 does the
 * same for live's phone display sizes. Live sizes -> our step, at 390 / 1440:
 *
 *   0.75rem  12.0 / 12.4   size--2  11.9 / 11.5
 *   0.9rem   14.0 / 14.9   size--1  13.8 / 13.75  (and the 13/14/14.4/15px)
 *   1.0rem   16.0 / 16.5   size-0   16.0 / 16.5   <- body, 67 uses
 *   1.125rem 18.0 / 18.6   size-1   18.6 / 19.8
 *   1.25rem  20.0 / 20.6   size-1   18.6 / 19.8   <- 27 uses
 *   1.5rem   24.0 / 24.8   size-2   21.5 / 23.8
 *   32px     32   / 32     size-4   29.0 / 34.2
 *   2.5rem   33.0 / 41.3   size-5   33.6 / 41.1
 *   3.0rem   39.7 / 49.5   size-6   39.0 / 49.3
 *   3.5rem   46.3 / 57.8   size-7   45.2 / 59.1
 *
 * (Live's text sizes are shown with the 16px-root readability floor this site
 * has held since 2026-09-30: live's own root reaches a 13.2px body at 390.)
 * Above 1440 the scale holds its 1440 values. Live keeps growing to 1920
 * (18px body) and then snaps back to a fixed 16px root from 1921 up, so the
 * cap is 8% under live at exactly 1920 and 3% over it on any wider screen.
 * ======================================================================== */
:root {
    /* --- Named compositions: sums of steps, never new values ------------ */
    /* Band rhythm: live steps 60 / 80 / 120px at 390 / 1024 / 1440. The pair
     * runs 64 / 98 / 120 — exact on desktop, a ramp where live steps. */
    --space-band: var(--space-2xl-3xl);
    /* Side gutter: live 20px below 768, 40px above. Dials' gutter pair runs
     * 16 / 31 / 40 at 390 / 1024 / 1440. */
    --space-gutter: var(--space-s-l);
    --space-block: calc(var(--space-xl) + var(--space-2xs));       /* 70 — band head -> content, wide column gaps */
    --space-inset-xl: calc(var(--space-2xl) + var(--space-2xs));   /* 90 — live's card inset */
    /* Live's guides column inset is PROPORTIONAL, not fixed: measured
     * 92.25/1025, 108/1200, 129.594/1440, 172.797/1920 — exactly 9vw at every
     * one. Transcribing the 1440 value as a fixed 129.594px starved the two
     * guide columns to 144px between 1040 and 1120 and clipped the "Missed
     * Appointments" heading. This is the px-inset trap in the playbook. It is
     * geometry, not a step, so it is not named into the --space-* family. */
    --guides-inset: 9vw;
    --space-card-gap: var(--space-m);   /* 30 — grid gap, fixed on live at every width */
    --space-icon-gap: var(--space-s);   /* 20 — Elementor icon-box wrapper gap */
    --space-inset-s: var(--space-m);    /* 30 — card padding */
    --space-inset-m: calc(var(--space-l) + var(--space-2xs));      /* 50 — fact-card padding */
    --space-inset-l: var(--space-2xl);                             /* 80 — about-card top; live's 80px row gaps */
    --space-lead: calc(var(--space-2xl) + var(--space-s));         /* 100 */
    --space-hero-lead: calc(var(--space-3xl) - var(--space-3xs));  /* 115; live 116 to the first hero ink */
    --space-panel-gap: calc(var(--space-m) + var(--space-3xs));    /* 35; live 35 — CTA panel and card body */
    --space-tick-gap: var(--space-3xs);   /* 5; live 3.75 glyph->text */
    --space-tick-pad: var(--space-3xs);   /* 5; live 5 text padding in its lists */
    --space-cta-inset: calc(var(--space-3xl) + var(--space-3xl) + var(--space-2xs));   /* 250 — live's closing band top inset */
    /* The policy hero's arch panel: the first ink sits 236px down on live.
     * Re-declared per breakpoint below because the arch's radius steps there
     * too (250 / 160px): the lead is clearance under that curve. */
    --space-arch-lead: calc(var(--space-3xl) + var(--space-2xl) + var(--space-s));   /* 220 */

    /* --- Shell ------------------------------------------------------------
     * 1290px, a REAL cap: measured 1290 at both 1440 and 1920 (17 uses).
     * Verified above the design width per "measure above the cap" — at 1920
     * it holds at 1290 rather than growing, so it is a max-width and not
     * viewport-minus-padding. The header/footer use a wider 1350 shell. */
    --shell: 80.625rem;        /* 1290 */
    --shell-wide: 84.375rem;   /* 1350 — header contact bar, nav, footer */
    --shell-tiles: 90.625rem;  /* 1450 — the appointment tiles strip. Live runs
                                  it full-bleed, which strands the gold dividers
                                  on a wide monitor; owner review 2026-09-28 */
    /* The gold nav bar's height, 79px measured on live. A fixed dimension. */
    --navbar-h: 4.9375rem;

    /* --- Colour: the site's own shades, each derived from a dial ----------
     * The brand blue, navy and gold are the colour dials, the cream and ink
     * are the paper and ink, so every Dials token and template component
     * paints in the brand. The shades below are the source's own colours
     * that no Dials token gives, each mixed from a dial or a token (never a
     * -solid fill, which Dials' fallback darkens for older browsers), with
     * the colour it paints and the source's own beside it. */
    --ground-deep: color-mix(in oklch, var(--tertiary) 23%, var(--surface));     /* #FDF1D2 (source #FFF2CC): the deep-cream bands, cards and fields */
    --tick-pale: color-mix(in oklab, var(--brand) 39%, var(--surface));          /* #B1C3DE (source #A8C5DA): the pale list glyphs on navy */
    --ink-grey: color-mix(in oklab, var(--text-strong) 67%, var(--surface));     /* #676760 (source #686868): the programme numbers */
    --ink-slate: color-mix(in oklab, var(--secondary) 21%, var(--ink-grey));     /* #51595E (source #515962): the search glyph */
    /* The contact form's notice text: the source's brown (#8A6D3B) gave
     * 4.35:1 on the deep cream, under 4.5. A little deeper here: 4.75:1. */
    --notice-ink: color-mix(in oklab, var(--tertiary) 42%, var(--text-strong));  /* #79694A */

    /* THE focus ring, on links, buttons and fields alike (owner, 2026-10-06:
     * one ring per site): the brand gold's own hue and chroma, darkened until
     * it clears 3:1 (WCAG 1.4.11) against every ground it is drawn on:
     * #A3781F, white 3.99, page cream 3.82, deep cream 3.55, navy footer 3.96.
     * Older browsers without relative colour take the mix in the fallback
     * block below. The gold nav and legal bars are the grounds it cannot
     * clear: see .navbar below. */
    --focus-ring: oklch(from var(--tertiary) calc(l - 0.2714) c h);
    --focus-ring-w: var(--border-width-l);         /* 4px, the owner's ring */

    /* Buttons and fields share one corner: live's pill (.btn-pill, the
     * Book/CTA button), so every button and the contact form's borderless
     * deep-cream fields are pills. A textarea is a rectangle with the pill's
     * own corner: half the field height. Never restyle a control in a
     * component; change these. */
    --control-radius: var(--radius-pill);
    --field-h: var(--target-min);                  /* 44px; live's field was 41px, under the target */
    --field-pad-block: var(--space-2xs);
    --field-pad-inline: var(--space-s);
    --field-textarea-radius: calc(var(--field-h) / 2);
    --field-bg: var(--ground-deep);                /* on the page cream; see .topbar / overlay for deep-cream grounds */
    --field-ink: var(--text);
    /* The fields' edge. Live's fields were borderless, the deep-cream fill
     * the only edge, which is about 1.1:1 on the page cream and under the
     * 3:1 a control's boundary needs (WCAG 1.4.11). A 1px edge in the
     * ring's gold (3.55:1 on the deep cream, 3.82 on the page, 3.99 on
     * white) keeps the look; the ink on hover. */
    --field-border-w: var(--border-width-s);
    --field-border: var(--focus-ring);
    --field-border-hover: var(--text);
    --field-placeholder: color-mix(in oklab, var(--text) 80%, var(--field-bg));   /* live's near-ink placeholder, opaque */
}

/* Older browsers (no relative colour or light-dark()): Dials' own fallback
 * condition.
 * - The gold. The template's tertiary fallback pulls the fill 72% towards
 *   black and puts white on it, which suits a dark third colour; on this
 *   light gold it gives a brown nav bar and buttons that fail white text
 *   (mf-websites#438). Here the fill stays the gold with black on it, as
 *   the modern browsers paint it (Dials' own fallback rule: a fixed white or
 *   black on-solid).
 * - The focus ring, which is relative colour above: the closest mix,
 *   #987D4E, still 3.5:1 on the deep cream. */
@supports not ((color: oklch(from red l c h)) and (color: light-dark(red, red))) {
    :root, [data-dials], .is-light, .is-dark {
        --tertiary-solid: var(--tertiary);
        --tertiary-on-solid: black;
    }
    :root {
        --focus-ring: color-mix(in srgb-linear, var(--tertiary) 31%, var(--text-strong));
    }
}

/* The root stays at 100%: the steps carry the fluidity, and a fluid root
 * under fluid steps would scale everything twice. */
html { font-size: 100%; }

/* Between 1025 and ~1104 four padded tiles cannot fit; live's own tile carries
   no padding and holds four 260px columns down to 1040. Tighten ours there
   rather than dropping a column, so the band still matches live. */
@media (min-width: 1025px) and (max-width: 1140px) {
    .tiles__inner[style*="--tiles-n: 4"] .tile { padding: var(--space-inset-m) var(--space-m); }
}

/* The arch panel's lead follows its radius, which steps here (live 128px at
 * <=1024, 80px at <=480). */
@media (max-width: 1024px) {
    :root { --space-arch-lead: calc(var(--space-3xl) + var(--space-xs)); }   /* 124 at 1024 */
}
@media (max-width: 480px) {
    :root { --space-arch-lead: calc(var(--space-2xl) + var(--space-s)); }    /* 80 at 390 */
}

h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 {
    font-family: var(--font-heading);
    font-weight: var(--weight-heading);
    color: var(--brand-on-soft);
    /* Live sets every heading at 1.2, whatever its size: the display dial,
     * read as a number, not Dials' size curve (which gives a small heading
     * more). Live sets no balance on headings either; the template's would
     * change every line count. No tracking: the tracking dials are unset. */
    line-height: var(--leading-display);
    text-wrap: wrap;
}
/* The template sets h1-h4 at size-5/4/3/2; live's are 3.0 / 2.5 / 1.5 /
 * 1.25rem, which on this site's dials are size-6 / 5 / 2 / 1. */
h1, .h1 { font-size: var(--size-6); }
h2, .h2 { font-size: var(--size-5); }
h3, .h3 { font-size: var(--size-2); }
h4, .h4 { font-size: var(--size-1); }

/* Bold runs are 700 on live, the heading weight, where Dials' --weight-strong
 * (the body weight plus 200) would give 600. */
strong, b { font-weight: var(--weight-heading); }

/* ---------------------------------------------------------------------------
 * SHELL + BANDS
 * ------------------------------------------------------------------------ */
.shell {
    width: 100%;
    max-width: var(--shell);
    margin-inline: auto;
}
.shell--wide { max-width: var(--shell-wide); }

.band {
    padding-inline: var(--space-gutter);
    background: var(--surface);
}
.band__inner {
    /* flex column so a child's negative margin cannot drag the band up —
     * the Cavenagh trap */
    display: flex;
    flex-direction: column;
    padding-block: var(--space-band);
}

/* ---------------------------------------------------------------------------
 * HEADER — contact bar (deep cream, 142px @1440) + nav bar (gold, 79px)
 * ------------------------------------------------------------------------ */
.site-header { position: relative; z-index: var(--layer-nav); }

.topbar {
    background: var(--ground-deep);
    padding-inline: var(--space-gutter);
}
.topbar__inner {
    display: flex;
    align-items: center;
    gap: var(--space-m);
    padding-block: var(--space-2xs);
    min-height: 8.875rem;   /* 142px measured */
}
.site-logo { flex: 0 0 auto; display: inline-flex; padding: var(--space-2xs) 0; }
.site-logo img { width: 12.1875rem; height: auto; }   /* 195px measured */

.topbar__meta {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: var(--space-m);
}
/* Phone and email sit side by side, as live lays them out (owner,
   2026-10-05: a stacked column was tried and reverted). They are grouped so
   the folded header can treat them as one column. Nothing in the bar shrinks
   or wraps; where it no longer fits, the header folds (see HEADER FOLD). */
.topbar__meta > * { flex: none; }
.topbar__contact { display: flex; align-items: center; gap: var(--space-m); }
.meta-item { display: flex; align-items: center; gap: var(--space-2xs); }   /* live 12px */
.meta-item svg { width: 1.5rem; height: 1.5rem; flex: none; fill: var(--tertiary-solid); }
.meta-item__label {
    display: block;
    font-family: var(--font-accent, var(--font-body));
    font-size: var(--size--1);      /* 14px, fixed on live — not a rem multiple */
    font-weight: var(--weight-contact-label);
    color: var(--text);
    line-height: var(--leading);
}
.meta-item__value {
    margin: 0;
    font-family: var(--font-accent, var(--font-body));
    font-size: var(--size--1);     /* 13px, fixed on live */
    font-weight: var(--weight-strong);
    color: var(--text);
    line-height: var(--leading);
    white-space: nowrap;
}
.meta-item a { color: inherit; text-decoration: none; }
.meta-item a:hover { text-decoration: underline; }

/* ---------------------------------------------------------------------------
 * SITE SEARCH — the platform component (mediflare.js), styled to live's box.
 * Two placements: the visible box with a dropdown in the contact bar, and the
 * phone overlay opened from .topbar__search-open. The component writes the
 * markup unstyled; every rule here is this site's. The overlay and the popup
 * are styled ONLY through :not([hidden]), or they never close.
 * ------------------------------------------------------------------------ */
.topbar__search {
    --search-field: 14rem;       /* 224px measured */
    --search-glyph: 1.3125rem;   /* 21px measured */
    position: relative;
}
.topbar__search .mf-search__form {
    position: relative;
    display: grid;
    grid-template-columns: var(--search-field) auto;
    gap: var(--space-3xs);       /* 6px measured */
    align-items: center;
}
/* Live's magnifier sits inside the field. An input takes no pseudo-element,
   so it is drawn on the form, over the field's leading padding. */
.topbar__search .mf-search__form::before {
    content: "";
    position: absolute;
    inset-inline-start: var(--space-s);
    inset-block-start: calc((var(--field-h) - var(--search-glyph)) / 2);
    width: var(--search-glyph);
    height: var(--search-glyph);
    background: var(--ink-slate);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath d='M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z'/%3E%3C/svg%3E") center / contain no-repeat;
            mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath d='M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z'/%3E%3C/svg%3E") center / contain no-repeat;
    pointer-events: none;
    z-index: var(--layer-base);
}
.topbar__search .mf-search__input {
    width: 100%;
    padding: 0 var(--space-2xs) 0 calc(var(--space-s) + var(--search-glyph) + var(--space-s));   /* clears the glyph */
}
/* The header and the phone overlay are deep cream, the contact fill: a field
 * there takes the white surface, or a borderless field would vanish. A token
 * per ground, not a restyle of the control. */
.topbar, .mf-search-overlay { --field-bg: var(--surface-raised); }
.mf-search__label { margin: 0; }
.topbar__search .mf-search__label,
.mf-search--overlay .mf-search__label {   /* read out, not shown: the glyph and placeholder say it */
    position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
    overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

/* The Search button: live's gold pill, uppercase Plex. Every button on the
   site hovers brand blue (owner, round 8). */
.mf-search__submit {
    min-height: var(--field-h);   /* level with the field beside it */
    padding: 0 var(--space-m);
    background: var(--tertiary-solid);
    color: var(--text);
    font-family: var(--font-heading);
    font-weight: var(--weight-heading);
    font-size: var(--size--1);
    letter-spacing: var(--tracking-caps-total);
    text-transform: uppercase;
    border-radius: var(--control-radius);
    transition: background var(--duration-fast) var(--ease-out), color var(--duration-fast) var(--ease-out);
}
.mf-search__submit:hover, .mf-search__submit:focus-visible { background: var(--brand-solid); color: var(--surface); }

/* The floating results, beneath the box and aligned to its right edge. */
.topbar__search .mf-search__popup:not([hidden]) {
    position: absolute;
    inset-block-start: calc(100% + var(--space-2xs));
    inset-inline-end: 0;
    z-index: var(--layer-overlay);
    display: flex;
    flex-direction: column;
    gap: var(--space-2xs);
    inline-size: max(100%, min(var(--measure-tight), calc(100vw - 2 * var(--space-gutter))));
    padding: var(--space-xs);
    background: var(--surface-raised);
    border: var(--border-width-s) solid var(--tertiary-solid);
    border-radius: var(--radius-m);
    box-shadow: var(--shadow-l);
}
.topbar__search .mf-search__results:not([hidden]) {
    max-block-size: 60dvh;
    overflow-y: auto;
    overscroll-behavior: contain;
}

/* Status and results, wherever the box sits. */
.mf-search__status {
    margin: 0;
    padding-inline: var(--space-xs);
    font-size: var(--size--1);
    line-height: var(--leading);
    color: var(--text);
}
.mf-search__status:empty { display: none; }
.mf-search__results { margin: 0; padding: 0; list-style: none; }
.mf-search__results:not([hidden]) { display: flex; flex-direction: column; gap: var(--space-3xs); }
.mf-search__link {
    display: block;
    padding: var(--space-2xs) var(--space-xs);
    border-radius: var(--radius-s);
    color: var(--text);
    text-decoration: none;
    overflow-wrap: anywhere;
    transition: background var(--duration-fast) var(--ease-out);
}
.mf-search__link:hover, .mf-search__link:focus-visible { color: var(--text); background: var(--ground-deep); text-decoration: none; }
.mf-search__link:focus-visible { outline-offset: calc(var(--focus-ring-w) * -1); }   /* inset: a scrolling list clips an outset ring */
.mf-search__title {
    display: block;
    font-family: var(--font-heading);
    font-weight: var(--weight-heading);
    line-height: var(--leading-display);
    color: var(--brand-on-soft);
}
.mf-search__excerpt {
    display: block;
    margin-top: var(--space-3xs);
    font-size: var(--size--1);
    line-height: var(--leading);
    color: var(--text);
}
.mf-search__excerpt mark {
    color: var(--text);
    background: color-mix(in srgb, var(--tertiary-solid) 70%, transparent);
    border-radius: var(--radius-xs);
}

/* The phone trigger: live's white field, shrunk to its magnifier. Shown only
   where the contact bar (and so the box) is hidden — see HEADER FOLD. */
.topbar__search-open {
    display: none;
    align-items: center;
    justify-content: center;
    inline-size: var(--target-min);
    block-size: var(--target-min);
    color: var(--ink-slate);
    background: var(--surface-raised);
    border-radius: var(--radius-pill);
    transition: background var(--duration-fast) var(--ease-out), color var(--duration-fast) var(--ease-out);
}
.topbar__search-open svg { width: var(--size-1); height: var(--size-1); fill: currentColor; }
.topbar__search-open:hover,
.topbar__search-open:focus-visible,
.topbar__search-open[aria-expanded="true"] { color: var(--surface); background: var(--brand-solid); }

/* The phone overlay: the contact bar's deep cream, live's white field and
   gold Search pill, Close leading so focus order matches what is seen. One
   row holds Close, the field and Search; the results scroll below it.
   Subgrid puts the box's own children on the overlay's grid. */
.mf-search-overlay:not([hidden]) {
    position: fixed;
    inset: 0;
    z-index: var(--layer-modal);
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-rows: auto auto minmax(0, 1fr);
    gap: var(--space-xs) var(--space-2xs);
    padding-block-start: max(var(--space-s), env(safe-area-inset-top));
    padding-inline: max(var(--space-gutter), env(safe-area-inset-left)) max(var(--space-gutter), env(safe-area-inset-right));
    background: var(--ground-deep);
}
.mf-search-overlay__header { display: contents; }
.mf-search-overlay__close {
    grid-column: 1;
    grid-row: 1;
    align-self: stretch;
    position: relative;
    z-index: var(--layer-base);   /* above the box, which spans this cell too */
    min-inline-size: var(--target-min);
    min-block-size: var(--target-min);
    padding-inline: var(--space-s);
    font-family: var(--font-heading);
    font-weight: var(--weight-heading);
    color: var(--text);
    background: var(--surface-raised);
    border-radius: var(--radius-pill);
    transition: background var(--duration-fast) var(--ease-out), color var(--duration-fast) var(--ease-out);
}
.mf-search-overlay__close:hover, .mf-search-overlay__close:focus-visible { color: var(--surface); background: var(--brand-solid); }
.mf-search--overlay,
.mf-search--overlay .mf-search__form {
    grid-column: 1 / -1;
    grid-row: 1 / -1;
    display: grid;
    grid-template-columns: subgrid;
    grid-template-rows: subgrid;
    align-items: stretch;   /* Close, the field and Search share one height */
}
.mf-search--overlay .mf-search__input { grid-column: 2; grid-row: 1; }
/* Tighter than the desktop pill, so "Type to search" is not clipped at 390. */
.mf-search--overlay .mf-search__submit { grid-column: 3; grid-row: 1; min-height: var(--target-min); padding-inline: var(--space-s); }
.mf-search--overlay .mf-search__status { grid-column: 1 / -1; grid-row: 2; }
.mf-search--overlay .mf-search__results {
    grid-column: 1 / -1;
    grid-row: 3;
    align-self: stretch;
    min-block-size: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding-block-end: max(var(--space-s), env(safe-area-inset-bottom));
}
.mf-search--overlay .mf-search__link:hover,
.mf-search--overlay .mf-search__link:focus-visible { background: var(--surface-raised); }   /* the ground is already deep cream */
.nav-menu-btn:hover, .nav-menu-btn:focus-visible { background: var(--brand-solid); color: var(--surface); }
.navbar { background: var(--tertiary-solid); padding-inline: var(--space-gutter); }
/* The amber ring is only ~2.7:1 on the gold nav bar (and its dropdowns) and
 * the gold legal bar; the brand navy reaches 10.6:1 there. A token on the
 * container, not a focus rule. */
.navbar, .legalbar { --focus-ring: var(--secondary-line); }
.navbar__inner {
    display: flex; align-items: center; gap: var(--space-m);
    padding-block: var(--space-xs);   /* 15px measured */
    min-height: var(--navbar-h);      /* 79px measured */
}
.nav { display: flex; }
.nav > ul {
    display: flex; align-items: center; gap: var(--space-l);
    list-style: none; margin: 0; padding: 0;
}
.nav > ul > li { position: relative; margin: 0; }
.nav a,
.nav__toggle {
    display: inline-flex; align-items: center; gap: var(--space-3xs);
    font-family: var(--font-heading);
    font-weight: var(--weight-heading);
    font-size: var(--size-0);
    color: var(--text);
    text-decoration: none;
    padding-block: var(--space-2xs);
}
.nav a:hover { text-decoration: none; }
.nav a:focus-visible { text-decoration: underline; }
/* Live marks the current page with a 3px bar in the light cream (measured
   rgb(255,242,204), --ground-deep, 3px, full link width, bottom 0), not an underline. */
.nav > ul > li > a { position: relative; }
.nav > ul > li > a[aria-current="page"]::after {
    content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 3px;
    background: var(--ground-deep);
}
.nav__caret { width: 1rem; height: 1rem; fill: currentColor; flex: none; }

/* The toggle is a <button> so the submenu is keyboard-operable, but it must
   read as one of the nav links — it shares their rule above and only adds
   the button reset here. It previously kept `font: inherit` and picked up
   the body face and weight, so it rendered lighter than its siblings. */
.nav__toggle {
    background: none; border: 0; cursor: pointer;
}
.nav__sub {
    list-style: none; margin: 0; padding: var(--space-2xs) 0;
    position: absolute; top: 100%; left: 0; min-width: 16rem;
    background: var(--tertiary-solid);
    border-radius: 0 0 var(--radius-s) var(--radius-s);
    box-shadow: var(--shadow-m);
    display: none; z-index: var(--layer-overlay);
}
.nav__sub li { margin: 0; }
.nav__sub a { display: block; padding: var(--space-2xs) var(--space-s); }
.nav__sub a:hover, .nav__sub a:focus-visible { background: var(--ground-deep); text-decoration: none; }
.nav__item--has-sub:hover .nav__sub,
.nav__item--has-sub:focus-within .nav__sub,
.nav__sub[data-open="true"] { display: block; }

.nav-cta { margin-left: auto; }
.nav-menu-btn {
    display: none;
    margin-left: auto;
    align-items: center; gap: var(--space-2xs);
    background: none; border: 0; padding: var(--space-2xs);
    font-family: var(--font-heading); font-weight: var(--weight-heading);
    font-size: var(--size-0); color: var(--text); cursor: pointer;
}
.nav-menu-btn svg { width: 1.5rem; height: 1.5rem; fill: currentColor; }


/* Buttons. Live's pill: gold fill, ink text, 100px radius, uppercase
 * IBM Plex Sans 700. The header CTA is the pale cream fill instead. */
.btn-pill {
    display: inline-flex; align-items: center; justify-content: center;
    min-block-size: var(--target-min);   /* the 44px tap target, every size */
    background: var(--tertiary-solid); color: var(--text);
    font-family: var(--font-heading); font-weight: var(--weight-heading);
    font-size: var(--size-0);
    letter-spacing: var(--tracking-caps-total);
    text-transform: uppercase; text-decoration: none;
    border: 0; cursor: pointer;
    border-radius: var(--control-radius);
    padding: var(--space-s) var(--space-xl);
    /* live keeps every CTA on one line; the 267px app column is narrow enough
       that the default would wrap it. But nowrap on a LONG label overflows a
       phone -- the CDM "MEDICARE CHRONIC DISEASE MANAGEMENT DETAILS" button
       measured 482px in a 400px viewport -- so allow a wrap once it cannot fit. */
    white-space: nowrap;
    max-width: 100%;
}
@media (max-width: 560px) {
    .btn-pill { white-space: normal; text-align: center; }
}
/* Owner 2026-09-30: every button hovers to brand blue with cream text. */
.btn-pill:hover, .btn-pill:focus-visible { background: var(--brand-solid); color: var(--surface); }
.btn-pill--pale { background: var(--ground-deep); font-size: var(--size--1); padding: var(--space-2xs) var(--space-l); }
/* Live's header CTA hovers to brand blue with cream text. It used to hover to
   the same gold as the nav bar, which made the button disappear (owner review
   2026-09-29). */
.btn-pill--pale:hover, .btn-pill--pale:focus-visible { background: var(--brand-solid); color: var(--surface); }

/* ---------------------------------------------------------------------------
 * BAND 0 — hero. 550x550 arched photo, radius 100% 100% 0 0.
 * ------------------------------------------------------------------------ */
/* Live's hero band has NO band padding of its own: the 670px height is
 * 120px of media-column top padding plus the photo's own 550px. Measured,
 * not chosen — an inherited --space-band here made the band 178px too tall. */
.hero .band__inner { padding-block: 0; }
.hero__inner {
    display: grid;
    grid-template-columns: 1fr 1fr;      /* live: 550px 550px in a 1150 shell */
    gap: var(--space-xl) var(--space-inset-m);   /* 50px column gap: 550+50+550 = 1150 */
    align-items: start;
    max-width: 71.875rem;                /* 1150px measured */
    margin-inline: auto;
}
.hero__copy { display: flex; flex-direction: column; gap: var(--space-l); padding-top: var(--space-hero-lead); }  /* 116px to live's first ink */
/* .eyebrow sits on h1..h4 as well as p (live marks these up as headings), and a
   heading's own font-size beats a class at equal specificity by source order --
   which rendered the /health-articles/ h2 eyebrow at 41px against live's 20.6.
   Pin every property the tag could otherwise supply. */
h1.eyebrow, h2.eyebrow, h3.eyebrow, h4.eyebrow,
.eyebrow {
    font-family: var(--font-heading);
    font-weight: var(--weight-heading);
    font-size: var(--size-1);
    color: var(--secondary-on-soft);
    letter-spacing: normal;
    text-transform: none;
    margin: 0;
}
/* Line height as live: an eyebrow marked up as a heading keeps the headings'
 * 1.2, any other the body's 1.5. (The template's eyebrow takes Dials' size
 * curve instead.) */
.eyebrow { line-height: var(--leading-body); }
h1.eyebrow, h2.eyebrow, h3.eyebrow, h4.eyebrow { line-height: var(--leading-display); }
.hero__title {
    font-size: var(--size-7);            /* 3.5rem = 57.75px @1440 */
    line-height: var(--leading-display);                    /* live: 69.2967 / 57.7473 */
    margin: 0;
}
.hero__copy p { margin: 0 0 var(--space-s); max-width: 31rem; }
.hero__copy p:last-child { margin-bottom: 0; }
/* Desktop rhythm inside the copy column, measured on live at 1440: eyebrow ->
 * title 14px, title -> lead 28px, lead -> button 57px, and the button then
 * ends 117px above the tiles divider. The uniform 40px flex gap PLUS the
 * eyebrow's 20px paragraph margin stacked to 60px at the top and pushed the
 * whole column down until the button sat 36px off the divider. Owner
 * review 2026-09-28: "top align the text content". */
@media (min-width: 1025px) {
    .hero__copy { gap: 0; }
    .hero__copy .eyebrow { margin-bottom: var(--space-xs); }     /* live 14px */
    .hero__title { margin-bottom: var(--space-m); }              /* live 28px */
    .hero__copy > div + p { margin-top: var(--space-panel-gap); }      /* live 33px: the button p adds its own line-box leading, so 33 renders as live's 57 */
}
.hero__media { padding-top: var(--space-band); }    /* 120px measured; zeroed at <=1024 below */
.hero__media img {
    display: block; width: 100%; height: auto;
    border-radius: 100% 100% 0 0;        /* the one percentage arch on the page */
}

/* ---------------------------------------------------------------------------
 * BAND 1 — three appointment tiles, full bleed on the deeper cream.
 * ------------------------------------------------------------------------ */
.tiles { background: var(--ground-deep); }   /* full-bleed band; the tiles inside are capped at --shell-tiles */
/* Live runs THREE tiles on the homepage/about and FOUR on the contact and
   service pages, always in ONE row (measured: 4 x 360px, band 401px tall).
   Hard-coding three wrapped the four-tile variant onto two rows, +208px. */
.tiles__inner {
    display: grid; grid-template-columns: repeat(var(--tiles-n, 3), minmax(0, 1fr));
    max-width: var(--shell-tiles);
    margin-inline: auto;
}
/* Once the strip is narrower than the viewport its trailing rule is no longer
 * clipped by the band edge, so drop it on the last tile there. Below 1451 the
 * strip IS the viewport and the per-breakpoint rules above still hold. */
/* Owner review 2026-09-30: once the strip is narrower than the band, mark
 * its beginning and end with the same gold rule the columns use. Below 1451
 * the strip IS the viewport, so the edges are clipped as on live. */
@media (min-width: 1451px) {
    .tile:first-child { border-left: var(--border-width-s) solid var(--tertiary-solid); }
}
.tile {
    padding: var(--space-xl);            /* 60px measured, flat */
    text-align: center;
    /* Live divides the three tiles with a 1px solid gold rule, and WHICH edges
     * carry it changes per breakpoint (measured at 390/768/1024/1440):
     *   >1024   border-right          vertical rules between the columns
     *   768-1024 right + bottom       the grid is 2-col there, so both
     *   <=767   bottom only           stacked, so horizontal only
     * The trailing rule lands on the band edge and is clipped, which is why
     * live puts it on every tile rather than excluding the last. */
    border-right: var(--border-width-s) solid var(--tertiary-solid);
}
.tile svg { width: 2.8125rem; height: 2.8125rem; fill: var(--tertiary-solid); display: block; margin-inline: auto; }  /* 45px */
.tile h2 {
    font-size: var(--size-2);            /* 1.5rem = 24.75px @1440 */
    color: var(--text);
    /* live's icon-box: 20px wrapper gap, then 8.25px/16px on the title */
    margin: var(--space-icon-gap) 0 var(--space-xs);   /* live 16px */
}
.tile p { margin: 0; }

/* ---------------------------------------------------------------------------
 * BAND 2 — services. 3-col grid of 410px cards; the navy label pill rides the
 * photo's bottom edge on a NEGATIVE MARGIN, in flow (never absolute).
 * ------------------------------------------------------------------------ */
/* live: head block 213px total with a 70px bottom pad; the eyebrow's own
 * Elementor margin collapses most of the gap to the title. */
.section__head { text-align: center; padding-bottom: var(--space-block); }   /* 70px measured */
.section__head .eyebrow { margin-bottom: var(--space-3xs); line-height: var(--leading-body); }
.section-title {
    font-size: var(--size-6);            /* 3rem = 49.5px @1440 */
    line-height: var(--leading-display);                    /* live: 59.3972 / 49.4977 */
    margin: 0;
}

.svc-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-card-gap);
    margin-bottom: var(--space-inset-l);   /* 80px measured */
}
.svc { display: flex; flex-direction: column; }
/* Live's card photo is the asset's natural 4:3 (410x308 at 1440) with a 20px
 * radius; its widget carries margin-bottom: -31px, which is what makes the
 * navy label pill ride the photo's bottom edge. That is an IN-FLOW negative
 * margin, never absolute positioning — measured 31 of the pill's 69px above
 * the photo's ink edge (share 0.45; ours 0.48, both inside the owner's
 * 0.4-0.6 straddle rule). */
.svc__media {
    position: relative; z-index: var(--layer-base);
    margin-bottom: calc(-1 * var(--space-m));   /* live -31px */
}
.svc__media img {
    display: block; width: 100%; height: auto;
    /* live never scales the asset past its natural 800px: measured 410 wide at
     * 1440, 688 at 768, and 800 (not the 944 column) at 1024. */
    max-width: 800px;
    margin-inline: auto;
    border-radius: var(--radius-l);                 /* live's own, measured */
}
.svc__label {
    position: relative; z-index: var(--layer-raised);
    margin: 0 var(--space-xl);           /* 60px inset — measured */
    background: var(--secondary-solid);
    color: var(--secondary-on-solid);
    border-radius: var(--radius-pill);
    padding: var(--space-s) var(--space-m);  /* 20px vertical — live's own */
    min-height: 4.3125rem;               /* 69px measured */
    text-align: center;
}
.svc__label h3 {
    margin: 0; color: inherit;
    font-size: var(--size-1);            /* 1.25rem = 20.62px @1440 */
    line-height: var(--leading-display);
}
.svc__body { padding: var(--space-m) var(--space-m) 0; margin-bottom: calc(-1 * var(--space-s)); text-align: center; }  /* 35/30 measured */
.svc__body p { margin: 0; }

/* the wide seventh card: 420px photo + an 840px copy panel on the deeper cream */
.svc-wide {
    display: grid;
    grid-template-columns: 420fr 840fr;   /* live's own ratio, in fr so both shrink */
    gap: var(--space-card-gap);
    align-items: stretch;                 /* the photo card runs the panel's full height (owner, 2026-09-30) */
}
.svc-wide .svc__media { flex: 1; display: flex; }
.svc-wide .svc__media img { flex: 1; height: 100%; object-fit: cover; object-position: 50% 25%; }
.svc-wide__panel {
    background: var(--ground-deep);
    border-radius: var(--radius-s);
    padding: var(--space-l);
    display: flex; flex-direction: column; gap: var(--space-s);
}
.svc-wide__panel > p:first-child {
    font-family: var(--font-heading);
    font-weight: var(--weight-heading);
    font-size: var(--size-1);            /* 1.1rem = 18.15px @1440 */
    color: var(--brand-on-soft);
    margin: 0;
}
.svc-wide__panel p { margin: 0; }

/* ---------------------------------------------------------------------------
 * BAND 3 — why choose us. 455px arched photo + a 2x2 card grid.
 * The arch is border-radius on a background-image div, exactly as live: the
 * radius is FIXED px against a box that is not, so the shape legitimately
 * changes character with the viewport. Do not normalise it.
 * ------------------------------------------------------------------------ */
.why__inner { display: grid; grid-template-columns: 455fr 795fr; gap: var(--space-l); }
.why__media {
    background-image: var(--why-photo);
    background-size: cover;
    background-position: center;
    border-radius: 300px 300px 15px 15px;
    height: 39.25rem;                    /* 628px measured — fixed, live's own */
    align-self: start;
}
.why__body { display: flex; flex-direction: column; gap: var(--space-m); }  /* 30px measured */
/* Live's heading block is 65px total: Elementor collapses the eyebrow with
   margin:-2px 0 -20px and the title with -11px/-4px. Those widget margins are
   structural here, not decoration — reproducing the gaps without them made the
   band 65px too tall. */
.why__head { display: flex; flex-direction: column; }
.why__head .eyebrow { line-height: var(--leading); margin: 0 0 calc(-1 * var(--space-3xs)); }   /* live -5px */
.why__head .section-title { margin: 0; }
.why__cards { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-l) var(--space-m); }  /* 40/30 measured */
.why-card {
    background: var(--ground-deep);
    border-radius: var(--radius-s);
    padding: var(--space-inset-s);       /* 30px measured */
    min-height: 15.375rem;               /* 246px measured */
}
.why-card svg { width: 2.8125rem; height: 2.8125rem; fill: var(--tertiary-solid); }
.why-card h3 {
    font-size: var(--size-1);
    /* live's icon-box wrapper gaps 20px, then the title's own 8.25/16 */
    margin: var(--space-icon-gap) 0 var(--space-xs);   /* live 16px */
}
.why-card p { margin: 0; }

/* ---------------------------------------------------------------------------
 * BAND 4 — full-bleed photo with a quote card on the right.
 * ------------------------------------------------------------------------ */
.quote {
    background-image: var(--quote-photo);
    background-size: cover;
    background-position: center;
}
.quote__inner {
    display: grid; grid-template-columns: 1fr 1fr;
    gap: var(--space-xl);
    max-width: 71.25rem;                 /* 1140px measured */
    margin-inline: auto;
    padding-block: var(--space-l);       /* 40px measured */
    /* Below the 1140 cap there is no gutter, so the card overflowed between
       1025 and 1140 on every page carrying this band (a phase-1 defect the
       homepage-only sweep never reached). */
    padding-inline: var(--space-gutter);
    box-sizing: border-box;
    min-height: 31.375rem;               /* 502px @1440 — overridden per breakpoint below */
    align-items: center;
}
/* live: outer column 50/50/40, inner card a further 40 all round */
.quote__card { padding: var(--space-inset-xl) var(--space-inset-xl) var(--space-l); }
.quote__card em {
    display: block;
    font-style: italic; font-weight: var(--weight-heading);
    font-size: var(--size-1);
    color: var(--secondary-on-soft);
    margin-bottom: var(--space-s);
}
.quote__card p { color: var(--secondary-on-soft); margin: 0 0 var(--space-l); }

/* ---------------------------------------------------------------------------
 * BAND 5 — about. A cream arch-topped copy card with a 1px gold rule, beside
 * a stacked photo + two info cards.
 * ------------------------------------------------------------------------ */
/* live's about band pads 120 top and only 40 bottom */
.about .band__inner { padding-block: var(--space-band) var(--space-l); }
.about__inner { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-card-gap); }
.about__card {
    background: var(--surface);
    border: 1px solid var(--tertiary-solid);
    border-radius: 350px 350px 15px 15px;
    min-height: 42.4375rem;              /* 679px measured */
    padding: var(--space-inset-l) var(--space-inset-xl) var(--space-l);  /* live: 80/90/40 */
    display: flex; flex-direction: column; gap: var(--space-m);
    justify-content: center;
    text-align: center;
}
.about__card p { margin: 0; }
.about__side { display: grid; gap: var(--space-card-gap); align-content: start; }
.about__photo {
    background-image: var(--about-photo);
    background-size: cover;
    background-position: center;
    border-radius: 100px 100px 15px 15px;
    min-height: 20.3125rem;              /* 325px measured */
}
.about__facts { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-card-gap); }
.fact {
    background: var(--ground-deep);
    border-radius: var(--radius-s);
    padding: var(--space-inset-m);       /* 50px measured */
    min-height: 20.3125rem;              /* 325px measured */
}
.fact svg { width: 2.8125rem; height: 2.8125rem; fill: var(--tertiary-solid); }
.fact h3 { font-size: var(--size-1); color: var(--text); margin: var(--space-s) 0 var(--space-s); }
.fact p { margin: 0; font-weight: var(--weight-detail); }

/* ---------------------------------------------------------------------------
 * BAND 6 — patient guidelines. A left-bleeding photo arched on its RIGHT
 * side (radius 0 400px 400px 0) beside a 2x2 icon-box grid.
 * ------------------------------------------------------------------------ */
.guides { display: flex; background: var(--surface); }
.guides__media {
    flex: 0 0 44.6%;                     /* 642 of 1440 measured */
    background-image: var(--guides-photo);
    background-size: cover;
    background-position: center;
    border-radius: 0 400px 400px 0;
    margin-block: var(--space-lead);     /* 100px measured */
    height: 37.25rem;                    /* 596px measured */
    align-self: start;
}
.guides__body {
    flex: 1 1 auto;
    display: flex; flex-direction: column; gap: var(--space-s);   /* 20px measured */
    padding: var(--guides-inset);  /* 9vw — live is proportional here */
    justify-content: center;
}
.guides__body > p { margin: 0; }
.guides__body .eyebrow { line-height: var(--leading); margin: 0 0 calc(-1 * var(--space-2xs)); }
.guides__grid {
    display: grid; grid-template-columns: 1fr 1fr;
    gap: var(--space-inset-m);           /* 50px measured */
    align-items: start;
}
/* The 539px once capped here was the column's natural width at 1440
 * (798 body - 2 x 9vw), not a max-width: live's grid fills the column at
 * every width (2 x 420px at 2380). Capping it crammed the four guides into
 * two 245px columns on wide screens, made the band 256px taller than live
 * and left blank cream under the photo, before the closing CTA. */
/* Live renders the emoji INLINE in the heading text, so the heading wraps
 * normally in a narrow column. A flex row here cannot wrap and clipped
 * "Missed Appointments" between 1040 and 1120 — live's own column is the same
 * 177px there and simply wraps. */
.guide h3 {
    font-size: var(--size-1);
    margin: 0 0 var(--space-xs);         /* live 14px heading -> copy */
}
.guide h3 img {
    display: inline-block;                 /* the global img rule is block, which
                                              stacked the emoji above its heading */
    width: 1.3125rem; height: 1.3125rem;   /* 21px emoji */
    vertical-align: -0.2em;
    margin-right: 0;                       /* live separates them with the space alone */
}
.guide p { margin: 0; }

/* ---------------------------------------------------------------------------
 * BAND 7 — closing CTA. A deep-cream panel arched at its bottom-right, with
 * the photo column riding 300px ABOVE it on a negative margin (live's own
 * mechanism, in flow).
 * ------------------------------------------------------------------------ */
.cta__inner { padding-block: var(--space-cta-inset) calc(2 * var(--space-lead)); }   /* 250 / 200 measured */
.cta__row { display: flex; }
.cta__panel {
    flex: 1 1 50%;
    background: var(--ground-deep);
    border-radius: 15px 0 300px 300px;
    padding: var(--space-inset-xl) var(--space-inset-xl) calc(2 * var(--space-lead));  /* live: 90/90/200 */
    display: flex; flex-direction: column; gap: var(--space-panel-gap);   /* 35px — live's CTA panel, not on the ladder */
    align-self: start;
    min-height: 56.6875rem;              /* 907px measured */
}
.cta__panel h2 { font-size: var(--size-5); line-height: var(--leading-display); margin: 0; }   /* 41.248px, 2 lines on live */
.cta__panel .eyebrow { font-size: var(--size-1); line-height: var(--leading); }
.cta__panel p { margin: 0; }
.cta__app { display: grid; grid-template-columns: 267fr 178fr; gap: var(--space-s); align-items: start; }  /* live 267/178, 20px */
.cta__app svg { width: 2.5rem; height: 2.5rem; fill: var(--secondary-line); }
.cta__app h3 { font-size: var(--size-1); margin: var(--space-icon-gap) 0 var(--space-xs); }
.cta__qr {
    background: var(--surface); padding: var(--space-s);
    border-radius: 10px;
    display: grid; gap: var(--space-s);
    width: 11.125rem;                    /* 178px measured — a fixed panel on live */
    justify-self: end;
}
.cta__qr img { display: block; width: 8.625rem; height: 8.625rem; max-width: none; }   /* 138x138 measured */

/* iPhone / Android toggle. Live stacks both QR codes at once, which makes it
   hard to tell which is which; one at a time is clearer and keeps the panel at
   live's measured 178px width with a single 138px code showing. */
.qr-panel { margin: 0; }                 /* figure's default 1em block margins added 64px */
.qr-panel figcaption { font-size: var(--size--2); text-align: center; margin-top: var(--space-3xs); color: var(--text); }
.cta__media {
    flex: 1 1 50%;
    margin-top: calc(-5 * var(--space-xl));   /* -300px measured */
    align-self: start;
}
.cta__media img {
    display: block; width: 100%; height: auto;
    border-radius: 300px 300px 15px 0;
}

/* ---------------------------------------------------------------------------
 * FOOTER — navy block (4-col) + a gold legal bar.
 * ------------------------------------------------------------------------ */
.site-footer { background: var(--secondary-solid); color: var(--secondary-on-solid); }
.site-footer a { color: var(--secondary-on-solid); text-decoration: none; }
.site-footer a:hover, .site-footer a:focus-visible { color: var(--tertiary-solid); text-decoration: none; }
.site-footer__main { padding-inline: var(--space-gutter); }
.site-footer__grid {
    display: grid;
    grid-template-columns: 420fr 224fr 336fr 280fr;   /* live's own ratio */
    gap: var(--space-card-gap);
    padding-block: var(--space-inset-xl);
}
.site-footer h2 {
    font-family: var(--font-heading); font-weight: var(--weight-heading);
    font-size: var(--size-1);
    color: var(--secondary-on-solid);
    margin: 0 0 var(--space-m);
}
.site-footer__brand { display: flex; flex-direction: column; gap: var(--space-l); }
.site-footer__brand img.footer-logo { width: 8.75rem; height: auto; }   /* 140px */
.site-footer__brand p { margin: 0; color: var(--secondary-on-solid); }
.site-footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2xs); }
.site-footer li { margin: 0; }
.footer-contact { display: grid; gap: var(--space-m); }
.footer-contact__row { display: flex; gap: var(--space-s); align-items: start; }
.footer-contact__row svg { width: 1.625rem; height: 1.625rem; fill: var(--tertiary-solid); flex: none; }
.footer-contact__label {
    display: block;
    font-family: var(--font-heading); font-weight: var(--weight-heading);
    font-size: var(--size-0);
}
.footer-contact__value {
    margin: 0;
    font-family: var(--font-accent, var(--font-body)); font-size: var(--size--1); font-weight: var(--weight-detail);  /* 15px fixed on live */
    line-height: var(--leading-body);
}
.powered-by { display: flex; align-items: center; gap: var(--space-2xs); }
.powered-by span { font-size: var(--size--2); color: var(--surface); }
.powered-by img { width: 5rem; height: auto; }

.legalbar { background: var(--tertiary-solid); padding-inline: var(--space-gutter); }
.legalbar__inner {
    display: flex; flex-wrap: wrap; gap: var(--space-s) var(--space-l);
    align-items: center; justify-content: space-between;
    padding-block: var(--space-2xs);
}
.legalbar { font-size: var(--size--1); }   /* live is --size-0; stepped down at the owner's request */
.legalbar p { margin: 0; color: var(--text); }
.legalbar nav { display: flex; gap: var(--space-l); }
.legalbar a { color: var(--secondary-on-soft); text-decoration: none; }
.legalbar a:hover, .legalbar a:focus-visible { color: var(--brand-on-soft); text-decoration: none; }

/* ---------------------------------------------------------------------------
 * ENTRANCE REVEALS — one-way, IntersectionObserver, short directional travel.
 * NOT the template's scroll-linked .reveal, which plays backwards on scroll-up.
 * ------------------------------------------------------------------------ */
[data-reveal] {
    opacity: 0;
    transition: opacity 760ms cubic-bezier(0.22, 1, 0.36, 1),
                transform 760ms cubic-bezier(0.22, 1, 0.36, 1);
    transition-delay: var(--reveal-delay, 0ms);
    will-change: opacity, transform;
}
[data-reveal="up"]    { transform: translateY(26px); }
[data-reveal="down"]  { transform: translateY(-26px); }
[data-reveal="left"]  { transform: translateX(-18px); }
[data-reveal="right"] { transform: translateX(18px); }
[data-reveal="fade"]  { transform: none; }
[data-reveal][data-revealed] { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
    [data-reveal] { opacity: 1; transform: none; transition: none; }
}

/* ---------------------------------------------------------------------------
 * RESPONSIVE. Live switches to a distinct tablet layout at 1024 and a phone
 * layout at 767 — reproduced from measurements at those widths, not scaled.
 * ------------------------------------------------------------------------ */
/* ---------------------------------------------------------------------------
 * RESPONSIVE. Live switches layout at Elementor's own breakpoints (1024 and
 * 767) and gives each arch a DIFFERENT measured height at each — the boxes
 * shrink while the px radii stay put, which is exactly why the arches change
 * character. Every height below was measured on live at that width.
 *
 *   arch                    1440      1024       390
 *   hero photo           550x550   800x800   350x350
 *   why photo            455x628   984x613   350x432
 *   about card           630x679   944x413   350x476
 *   about photo          630x325   944x314   350x631  <- radius 100 -> 500
 *   guides photo         642x596   984x400   390x250
 *   cta photo            645x756   784x919   350x410
 *   cta panel            645x907   864x1039  350x1296
 * ------------------------------------------------------------------------ */
@media (max-width: 1024px) {
    /* Live collapses the nav to a burger at <=1024, not at the phone
     * breakpoint — measured: nav hidden and burger shown at 768/860/900/
     * 1000/1024, nav shown at 1025. Collapsing at 767 instead left the
     * header CTA running up to 172px off-page across 768-985. */
    .navbar__inner { flex-wrap: wrap; }
    .nav { display: none; width: 100%; }
    .nav[data-open="true"] { display: block; }
    .nav > ul { flex-direction: column; gap: 0; }
    .nav__sub { position: static; display: none; box-shadow: none; min-width: 0; }
    .nav__sub[data-open="true"] { display: block; }
    .nav-menu-btn {
        display: inline-flex; order: 1; margin-left: 0;
        background: var(--ground-deep); border-radius: var(--radius-pill);
        padding: var(--space-2xs) var(--space-s);
    }
    .nav-cta { order: 2; }
    /* The open menu wraps to its own full-width row BELOW the button and CTA.
       Before this the button carried the auto margin and the CTA sat beside
       it; opening the menu pushed the CTA to a third row and the button slid
       to the right edge. */
    .nav { order: 3; }

    .hero__inner { grid-template-columns: 1fr; }
    .hero__media { padding-top: 0; }
    .hero__copy { padding-top: var(--space-inset-xl); }   /* tablet lead-in */
    .svc-grid { grid-template-columns: 1fr; }
    .svc-wide { grid-template-columns: 1fr; }
    .site-footer__grid { grid-template-columns: 1fr 1fr; }
    .tiles__inner { grid-template-columns: 1fr 1fr; }

    .why__inner, .about__inner { grid-template-columns: 1fr; }
    /* live at 1024: the why media drops BELOW its cards (order swap) */
    .why__media { height: 38.3125rem; order: 2; }   /* 613px measured @1024 */
    .why .band__inner { padding-block: var(--space-inset-l) var(--space-l); }   /* live: 80/40 */
    .about .band__inner { padding-block: var(--space-l) var(--space-inset-l); } /* live: 40/80 */
    .about__card { min-height: 25.8125rem; padding: var(--space-lead) 0 var(--space-xl); text-align: center; }  /* live 100/0/60 */
    .about__photo { min-height: 19.625rem; }   /* 314px */
    .tile { padding: var(--space-inset-m); border-bottom: var(--border-width-s) solid var(--tertiary-solid); }   /* 50px, and live adds the horizontal rule in the 2-col grid */

    .guides__media {
        flex: none; width: 96.09%; height: 25rem;  /* 984x400 measured @1024 */
        margin-block: var(--space-lead);
    }
    .guides__body > p, .guides__grid { max-width: none; }

    /* live at 1024 keeps the CTA photo BELOW the panel and pulls it up 150px
     * (not the desktop 300) — measured. */
    .cta__row { flex-direction: column; }
    .cta__media { margin-top: calc(-2.5 * var(--space-xl)); }      /* -150px measured @1024 */
    .cta__panel {
        min-height: 64.9375rem;                /* 1039px measured @1024 */
        padding: var(--space-inset-xl) var(--space-inset-xl) calc(2 * var(--space-lead));
    }
    .cta__inner { padding-block: var(--space-l) var(--space-inset-l); }   /* live: 40/80 */

    .quote__inner { min-height: 25.6875rem; }   /* 411px measured @1024 */

    /* live at 1024 puts the guides photo BELOW its copy — measured (photo
     * y=11560 against copy y=10950). */
    .guides { flex-direction: column-reverse; }
    .guides__body { padding: 0 var(--space-l) var(--space-inset-l) var(--space-inset-xl); gap: var(--space-l); }  /* live 0/40/80/90 */
}

@media (max-width: 900px) {
    .quote__inner { grid-template-columns: 1fr; min-height: 0; }
    .quote__card { padding: var(--space-l); }
}

/* ---------------------------------------------------------------------------
 * HEADER FOLD — three header layouts and the two widths that switch them,
 * both measured (2026-10-05) from the bar's intrinsic widths: logo 195,
 * contact (phone and email side by side) 371, hours 197, search 345, gaps
 * --space-m (~28).
 *
 *   wide    >= 1280   logo | phone, email | hours | search, one row. Needs
 *                     ~1199px of shell and first fits at 1272; 1280 leaves a
 *                     few px for font rendering. (The old flex-wrap bar
 *                     dropped its search to a second row below 1280 too.)
 *   folded  1025-1279 logo centred on its own row; beneath it contact,
 *                     hours and search, space-around and centred as a group.
 *                     The row holds a full --space-m between columns down to
 *                     1059; from 1058 to 1025 it still fits, the space-around
 *                     share shrinking to ~17px between columns at 1025. It
 *                     would only overflow below ~975, inside the phone range.
 *   phone   <= 1024   logo + search trigger; Menu and Book Appointment.
 *                     1024 is where the nav already collapses to Menu (live
 *                     did the same), and the header's desktop and phone
 *                     layouts — menu, booking and search — swap at ONE width.
 *
 * The desktop box and the phone trigger therefore swap at 1024/1025: no width
 * shows both, none shows neither.
 * ------------------------------------------------------------------------ */
@media (min-width: 1025px) and (max-width: 1279px) {
    .topbar__inner { flex-direction: column; justify-content: center; gap: var(--space-xs); min-height: 0; padding-block: var(--space-s); }
    .topbar__meta { margin-left: 0; width: 100%; justify-content: space-around; }
}
/* The nav row cramps at the narrow end of the fold: at --space-l it wrapped
   "Patient Information" and "Health Info" to two lines from 1094 down
   (measured). --space-s-m holds every label on one line at 1025. */
@media (min-width: 1025px) and (max-width: 1099px) {
    .nav > ul { gap: var(--space-s-m); }
}
@media (max-width: 1024px) {
    /* Owner, 2026-09-30: on a phone the header is the logo, the Menu button
       and Book Appointment, centred — now from the menu's own breakpoint, so
       the whole header swaps at one width. The contact rows are hidden; the
       footer carries the same phone, email and hours. Search is the overlay,
       opened from the magnifier on the logo row — never inside the menu, and
       not beside Menu either: a 44px button there wraps Book Appointment to
       a second row at 390. */
    .topbar__inner {
        display: grid;
        grid-template-columns: 1fr auto 1fr;
        align-items: center;
        gap: var(--space-xs);
        min-height: 0;
        padding-block: var(--space-s);
    }
    .site-logo { grid-column: 2; padding: 0; }
    .topbar__search-open { display: inline-flex; grid-column: 3; justify-self: end; }
    .topbar__meta { display: none; }
    .navbar__inner { justify-content: center; gap: var(--space-s); }
    .nav-cta { margin-left: 0; }
    /* The buttons must not move when the menu opens (owner, 2026-10-05).
       With a min-height and align-items: center, the closed bar's one flex
       line filled the 79px and centred the 44px buttons; the open menu wraps
       to a second line, the bar outgrows its min-height, the first line
       shrinks to 44 and the buttons rose 5.5px (390) / 3.7px (1024). Padding
       the bar to the same 79px instead puts them at one place in both states. */
    .navbar__inner { min-height: 0; padding-block: calc((var(--navbar-h) - var(--target-min)) / 2); }
    /* Menu and Book Appointment share one box: the touch-target height, the
       same padding, no border. Menu's 24px glyph made it 40 tall against
       Book's 37 (measured at 390). */
    .nav-menu-btn, .nav-cta {
        box-sizing: border-box;
        min-height: var(--target-min);
        padding: 0 var(--space-s);
        border: 0;
        align-items: center;
    }
    .nav > ul { align-items: center; text-align: center; }
    .nav__sub { padding-left: 0; }
    .nav__sub a, .nav a, .nav__toggle { justify-content: center; }
}

@media (max-width: 767px) {
    .tiles__inner { grid-template-columns: 1fr; }
    .tile { padding: var(--space-inset-m) var(--space-m); border-right-width: 0; }   /* live 50/30 @390; stacked, so only the horizontal rule remains */
    .why__cards, .about__facts, .guides__grid { grid-template-columns: 1fr; }
    .site-footer__grid { grid-template-columns: 1fr; }
    .legalbar__inner { justify-content: flex-start; }

    .hero__title { font-size: var(--size-6); }   /* live drops 3.5rem -> 3rem here */
    /* live pads the hero 60px top only at 390, not the desktop 116px lead-in */
    .hero__copy { padding-top: 0; gap: var(--space-m); }   /* live gaps 30px @390 */
    .hero .band__inner { padding-block: var(--space-xl) 0; }
    .hero__inner { gap: var(--space-inset-m) 0; }   /* 50px measured @390 */
    .hero__copy p { margin-bottom: var(--space-2xs); }
    /* live gaps these 50px minus Elementor's negative widget margins; the
       rendered step is ~20px, so state that rather than the arithmetic */

    /* live keeps the guides photo BELOW the copy at 390 as well */
    .guides { flex-direction: column-reverse; }
    .why__media { height: 27rem; }               /* 432px measured @390 */
    .about__card { min-height: 29.75rem; padding: var(--space-inset-l) var(--space-s) var(--space-l); gap: var(--space-m); }  /* live 80/20/40 @390 */

    /* THE ONE GENUINE BREAKPOINT OVERRIDE ON THIS SITE. Live changes the about
     * photo's radius from 100px to 500px at the phone breakpoint — verified at
     * 390 (350x631, radius 500px 500px 15px 15px). It is a real override, not a
     * reflow; copying the desktop value here would be wrong. */
    .about__photo { border-radius: 500px 500px 15px 15px; min-height: 39.4375rem; }  /* 631px */

    .guides__media { width: 100%; height: 15.625rem; margin-block: 0; }   /* 390x250 measured @390 */
    /* live pads 60/20 and gaps its head blocks 50px MINUS Elementor's negative
       widget margins (-2/-30, -7, -20); the rendered step is ~20px, so state
       that rather than reproducing the arithmetic */
    .guides__body { padding: var(--space-xl) var(--space-s); gap: var(--space-s); }
    .guides__grid { gap: var(--space-inset-m); padding-top: var(--space-2xs); }
    .quote__inner { min-height: 21.3125rem; padding-block: var(--space-l); }   /* 341px measured @390; live pads 40/0 but the plated card needs a foot */
    /* Live sets the quote copy straight onto the photo at phone widths, where
       the column is the whole viewport and the text lands on the faces. Ours
       plates it — a deliberate legibility improvement on live, 2026-09-30. */
    .quote__card {
        background: color-mix(in srgb, var(--surface) 92%, transparent);
        border-radius: 15px;
        padding: var(--space-m) var(--space-s);
    }
    .cta__panel { min-height: 0; padding: var(--space-xl) var(--space-s) var(--space-lead); }  /* live 60/20/100 @390; live's 1296 min-height left a blank arch under the codes */
    .cta__app { grid-template-columns: 1fr; }
    /* both codes side by side, centred, instead of a 178px card hugging the right edge */
    .cta__qr { width: auto; justify-self: stretch; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); justify-items: center; }
    .qr-panel img { max-width: 100%; height: auto; }   /* 128px codes held the panel at 336 on a 320 phone */
    .cta__qr img { width: 8rem; height: 8rem; }
    /* the photo rode 150px up into a panel that no longer carries live's blank
       arch, covering the QR captions; it now rides only into the panel's padding */
    .cta__media { margin-top: calc(-1 * var(--space-xl)); }
}



/* ===========================================================================
 * PHASE 2 — the fourteen inner pages
 *
 * The same measured design language as the homepage. Components here recur
 * across several pages, so each is defined once: the two-column hero, the
 * eyebrow/title/lede band head, the bordered card grid, the prose list and
 * the contact panel. Every value measured off live at 1440/1024/390.
 * ======================================================================== */

/* --- Inner-page hero: copy beside an arched photo -------------------------
 * Live's column split varies by page and is transcribed per page as a ratio
 * (not a px track — a px track cannot shrink, which is what breaks these
 * layouts between roughly 1000 and 1300). The 100px gap is constant. */
.phero__inner {
    display: grid;
    grid-template-columns: var(--phero-cols, 1fr 1fr);
    gap: var(--space-lead);              /* 100px measured on every page */
    align-items: center;
}
.phero__copy { display: flex; flex-direction: column; gap: var(--space-panel-gap); }
.phero__copy p { margin: 0; }
.phero__title {
    font-family: var(--font-heading);
    font-weight: var(--weight-heading);
    color: var(--brand-on-soft);            /* rgb(61,107,193) measured on live */
    font-size: var(--size-7);
    line-height: var(--leading-display);
    margin: 0;
}
.phero__title--sm { font-size: var(--size-5); }
.phero__media img,
.phero__media {
    display: block; width: 100%; height: auto;
    border-radius: var(--phero-radius, 350px 350px 15px 15px);
}

/* --- Band head: eyebrow + title + optional lede --------------------------
 * Live's eyebrow carries Elementor's -2px/-25px collapse, so the rendered
 * step to the title is far tighter than the nominal 35px gap. */
.bandhead { display: flex; flex-direction: column; padding-bottom: var(--space-block); }
.bandhead .eyebrow { margin: 0 0 var(--space-3xs); line-height: var(--leading-body); }
.bandhead h2:not(.eyebrow) { font-size: var(--size-5); line-height: var(--leading-display); margin: 0; }
.bandhead p { margin: var(--space-s) 0 0; max-width: 48rem; }
.bandhead--center { text-align: center; align-items: center; }
.bandhead--center p { margin-inline: auto; }

/* --- Bordered card grid (About's doctors, the policy cards, careers) -----
 * 376px cards at 1440 in a 1290 shell with an 80px gap; 40px padding, 15px
 * radius, 1px border. Stated as fr so both tracks shrink together. */
.cardgrid {
    display: grid;
    grid-template-columns: repeat(var(--cardgrid-cols, 3), minmax(0, 1fr));
    gap: var(--space-inset-l) var(--space-card-gap);     /* 80px row gap measured */
}
.pcard {
    border: var(--border-width-s) solid var(--tertiary-solid);
    border-radius: var(--radius-s);
    padding: var(--space-l);
    display: flex; flex-direction: column; gap: var(--space-2xs);
}
.pcard h3 { font-size: var(--size-1); margin: 0 0 var(--space-2xs); }
.pcard p { margin: 0; }
.pcard--filled { background: var(--ground-deep); border-color: transparent; }
.pcard svg { width: 2.8125rem; height: 2.8125rem; fill: var(--tertiary-solid); }

/* --- Split band: copy one side, arched photo the other ------------------- */
.split { display: grid; grid-template-columns: var(--split-cols, 1fr 1fr); gap: var(--space-inset-xl); align-items: center; }
/* Grid children default to min-width:auto and refuse to shrink below their
   content, which pushed a column 5px past a 360px viewport. */
.split > * { min-width: 0; }
.phero__inner > * { min-width: 0; }
.cardgrid > * { min-width: 0; }
.split__media {
    background-size: cover; background-position: center;
    border-radius: var(--split-radius, 350px 350px 15px 15px);
}
/* Only a CSS-background split needs a height floor -- one wrapping an <img>
   takes the photo's own aspect, which is what live draws. A blanket
   min-height forced every arch to at least 480px. */
.split__media:not(:has(img)) { min-height: var(--split-h, 30rem); }
.split__media img { display: block; width: 100%; height: auto; border-radius: inherit; }

/* --- Prose list: live's tick/label rows in the policy and fees pages ----- */
.prose h2 { font-size: var(--size-2); margin: var(--space-xl) 0 var(--space-s); }
.prose h3 { font-size: var(--size-1); margin: var(--space-l) 0 var(--space-2xs); }
.prose p, .prose li { margin: 0 0 var(--space-s); }
.prose ul, .prose ol { margin: 0 0 var(--space-m); padding-left: var(--space-m); }
.prose > :first-child { margin-top: 0; }

/* --- Forms --------------------------------------------------------------- */
.form-grid { display: grid; gap: var(--space-s); }
.form-row { display: grid; gap: var(--space-3xs); }
.form-row label { font-family: var(--font-heading); font-weight: var(--weight-heading); font-size: var(--size--1); }
.form-row input, .form-row textarea, .form-row select { width: 100%; }

@media (max-width: 1024px) {
    .phero__inner { grid-template-columns: 1fr; gap: var(--space-inset-xl); }
    .split { grid-template-columns: 1fr; }
    .cardgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-inset-xl) var(--space-card-gap); }
}
@media (max-width: 767px) {
    .phero__inner { gap: var(--space-xl); }
    .cardgrid { grid-template-columns: 1fr; }
    .bandhead { padding-bottom: var(--space-xl); }
}

/* ---------- Phase 2: inner-page components ---------- */

/* Band rhythm variants. Live steps its band padding per page; --tight is the
   half-band that follows a hero, --deep the deeper cream ground. */
.band--deep  { background: var(--ground-deep); }

/* Ticked lists. Measured on /home-medicine-review/: 15px gold glyph,
   3.75px + 5px between glyph and text, 4px between rows, body at --size-0. */
.tick-list {
    list-style: none;
    margin: 0;                 /* live gives the list no top margin */
    padding: 0;
}
.tick-list li {
    display: flex;
    align-items: flex-start;
    padding-bottom: var(--space-3xs);   /* 4px, measured on live */
    line-height: var(--leading-body);
}
.tick-list li svg {
    flex: 0 0 auto;
    width: 0.9375rem;
    height: 0.9375rem;
    margin-right: var(--space-tick-gap);
    margin-top: var(--space-3xs);   /* live 0.28em: centres the glyph on the first line */
    fill: var(--tertiary-solid);
}
.tick-list li > span { padding-left: var(--space-tick-pad); }
.tick-list__title {
    margin-top: var(--space-l);
    margin-bottom: var(--space-2xs);
    font-size: var(--size-1);
}

/* Practice hours. Live uses Elementor's price-list header: flex, space-between,
   --size-1, label 700 / value 600. The rows are Rails' {{opening_hours_html}}
   table (one <tr> per day group), set as flex rows rather than a table. */
.hours { margin: var(--space-m) 0; }
.hours .hours-table, .hours .hours-table tbody { display: block; margin: 0; }
.hours tr {
    display: flex;
    justify-content: space-between;
    gap: var(--space-m);
    font-size: var(--size-1);
    padding-block: var(--space-3xs);
}
.hours td { padding: 0; border: 0; }
.hours td:first-child { font-weight: var(--weight-heading); }
.hours td:last-child { font-weight: var(--weight-strong); }

/* The same table as plain "Day: time" lines — header bar, footer and the
   homepage's hours card, where live sets the hours as lines of text. */
.hours-lines .hours-table { width: auto; margin: 0; }
.hours-lines .hours-table tr { display: block; }
.hours-lines .hours-table td { display: inline; padding: 0; border: 0; }
.hours-lines .hours-table td:first-child::after { content: ": "; }
.fact .hours-lines { font-weight: var(--weight-detail); }

/* Practitioner cards on /about/ render from Rails, where a line break inside
   qualifications or bio is stored as a newline. */
.doctor-card p { white-space: pre-line; }

/* The "what to bring" row on /appointment/ — four 45px glyphs in a row. */
.bring {
    list-style: none;
    margin: var(--space-l) 0 var(--space-inset-xl);
    padding: 0;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--space-l);
    text-align: center;
}
.bring li {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-2xs);
    font-size: var(--size-1);
    font-weight: var(--weight-detail);
}
.bring li svg { width: 2.8125rem; height: 2.8125rem; fill: var(--brand-line); }

/* A row of buttons (the /appointment/ hero runs two side by side). */
.btn-row { display: flex; flex-wrap: wrap; align-items: center; }
.btn-pill--ghost {
    background: transparent;
    color: var(--secondary-on-soft);
    box-shadow: inset 0 0 0 var(--border-width-s) var(--secondary-line);
}
.btn-pill--ghost:hover, .btn-pill--ghost:focus-visible {
    background: var(--brand-solid);
    color: var(--secondary-on-solid);
}
/* Outlined in gold, fills gold on hover — the one button that does not hover
   blue, by the owner's request for the appointment hero's Fees and Billing
   button (2026-09-30). */
.btn-pill--outline { background: transparent; color: var(--text); box-shadow: inset 0 0 0 2px var(--tertiary-solid); }
.btn-pill--outline:hover, .btn-pill--outline:focus-visible { background: var(--tertiary-solid); color: var(--text); }

/* /health-info/ leads with copy only — no hero photo beside it; its photo
   row (.phero__photos) sits below the copy. */
.phero--plain .band__inner { max-width: var(--shell); }
.phero--plain .bandhead { max-width: 46rem; }

@media (max-width: 1024px) {
    .bring { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 767px) {
    .bring { grid-template-columns: 1fr; gap: var(--space-m); text-align: left; }
    .bring li { flex-direction: row; align-items: center; gap: var(--space-s); }
    .hours tr { font-size: var(--size-0); }
}

/* Bands carrying an arched photo run on live's WIDER row (1350, not 1290).
   Measured: /health-assessment/ hero col 543 inside a 1350 row; /careers/ 595
   inside 1290. Without this every arch came out ~4.4% short. */
.phero .band__inner,
.band__inner:has(> .split) { max-width: var(--shell-wide); }

/* Groups that sit INSIDE a copy column beside a photo. Live draws these as
   bare text blocks -- no padding, no radius, no plate (measured 218px tall
   against our 351px card). See /health-assessment/ bands 2 and 3. */
.pcard--plain {
    padding: 0;
    background: none;
    border: 0;
    border-radius: 0;
    gap: var(--space-2xs);
}
/* Live's group heading carries no bottom margin -- the gap does that work. */
.pcard--plain > h2, .pcard--plain > h3, .pcard--plain > h4 { margin-bottom: 0; }
/* ...and the grid holding them uses live's own 20px row gap, not the 80px
   the between-band card rows use. */
.cardgrid:has(> .pcard--plain) { gap: var(--space-icon-gap); }

/* A centred hero with a glyph and no photo -- live uses this on
   /practice-policy/ (measured: 760px column, 45px icon, band 1038px). */
.centre-hero {
    max-width: 47.5rem;          /* 760px measured */
    margin-inline: auto;
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-m);
}
.centre-hero > svg { width: 2.8125rem; height: 2.8125rem; fill: var(--tertiary-solid); }
.centre-hero p { margin: 0; }

/* The narrow 258px "WHAT TO BRING" column on /appointment/ -- live stacks its
   four glyph rows vertically rather than spreading them across the band. */
.bring--stack { grid-template-columns: 1fr; gap: var(--space-l); }

/* Live flows some card sets down each column independently rather than in a
   uniform grid -- measured on /appointment/ band 3: a 630/630 pair with two
   cards in the left column and three in the right, 30px apart. A uniform grid
   makes every row as tall as its tallest card and ran that band 378px long. */
/* ---------- /about/ — owner review round 2 (2026-09-28) ----------
 * Measured on live at 2223: the hero copy is a 2x2 paragraph grid (371/371,
 * 50px gap, 35px above, 14px between paragraphs); the "why" band is four
 * 308px page-cream cards 20px apart, centred; the doctors grid uses an 80px
 * column gap with centred cards; the safety band is three equal 403px
 * columns on the 1350 row, 70px apart, with a hairline-divided list. */
.phero__grid {
    display: grid; grid-template-columns: 1fr 1fr;
    gap: var(--space-inset-m);           /* 50px */
    padding-top: var(--space-panel-gap); /* 35px */
}
.phero__grid p + p { margin-top: var(--space-xs); }   /* live 14px */
.cardgrid--tight { gap: var(--space-s); }      /* 20px */
.cardgrid--wide  { column-gap: var(--space-inset-l); }          /* 80px */
.pcard--light { background: var(--surface); border-color: transparent; padding: var(--space-inset-m); }
.pcard--centre { text-align: center; align-items: center; gap: var(--space-s); }
.pcard--centre h3 { margin-bottom: 0; }
.trio {
    display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-block);             /* 70px */
    align-items: start;
}
.trio__copy .bandhead { padding-bottom: var(--space-panel-gap); }
.trio__copy > p { margin: 0; }
.trio__media img {
    display: block; width: 100%; height: auto;
    aspect-ratio: 403 / 605; object-fit: cover; object-position: 50% 0;   /* heads sit at the top of these portraits */
    border-radius: 200px 200px 20px 20px;
}
.rule-list { padding-top: var(--space-l); }
.rule-list h3 { font-size: var(--size-1); margin: 0 0 var(--space-2xs); }
.rule-list p { margin: 0; }
.rule-list > div + div {
    margin-top: var(--space-panel-gap); padding-top: var(--space-panel-gap);
    border-top: var(--border-width-s) solid var(--tertiary-solid);
}
@media (max-width: 1024px) {
    .trio { grid-template-columns: 1fr; }
    .trio__media img { aspect-ratio: auto; border-radius: 200px 200px 15px 15px; }
    .cardgrid--wide { column-gap: var(--space-card-gap); }
}
@media (max-width: 767px) {
    .phero__grid { grid-template-columns: 1fr; gap: var(--space-xs); }
}

/* ---------- /appointment/ — owner review round 2 (2026-09-28) ----------
 * Measured on live at 2223. */
.btn-row { gap: var(--space-m); }
.band--after-hero { padding-top: 0; }        /* live's row sits 80px under the hero photo */
.pcard h2 { font-size: var(--size-1); margin: 0 0 var(--space-2xs); }
.pcard--roomy { padding: var(--space-inset-m); gap: var(--space-s); }
.split--hours { gap: var(--space-m); align-items: stretch; }
.split--hours .split__media img { height: 100%; object-fit: cover; object-position: 50% 30%; }
.hours-card {
    background: var(--ground-deep); border-radius: 10px;
    padding: var(--space-inset-m);
    display: flex; flex-direction: column; gap: var(--space-panel-gap);
}
.hours-card h2 { font-size: var(--size-4); margin: 0; }       /* 32px measured */
.hours-card p { margin: 0; }
.hours-card .hours { margin: 0; }
.hours-card .hours tr { align-items: center; gap: var(--space-2xs); }
.hours-card .hours tr::after {                    /* live's price-list leader line */
    content: ""; flex: 1; order: 1;
    border-bottom: var(--border-width-s) solid var(--brand-line);
}
.hours-card .hours td:last-child { order: 2; }
.dot-list { list-style: disc; margin: 0; padding-left: var(--space-s); }
.dot-list li { padding-bottom: var(--space-3xs); padding-left: var(--space-tick-pad); }
.dot-list li::marker { color: var(--tertiary-solid); }
/* Live's chronic-conditions list: 9px rows (10px here, on the ladder) with a hairline between each */
.dot-list--rows li { padding-block: var(--space-2xs); border-bottom: var(--border-width-s) solid var(--tertiary-solid); }
.dot-list--rows li:last-child { border-bottom: 0; }
/* Two of live's lists use a pale blue glyph (rgb 168,197,218) rather than gold */
.tick-list--pale li svg { fill: var(--tick-pale); }
.dot-list--pale li::marker { color: var(--tick-pale); }
/* Live's plain browser discs (the HMR questions and "No cost" list) */
.disc-list { list-style: disc; margin: 0; padding-left: var(--space-s); }
.disc-list li { padding-bottom: var(--space-3xs); padding-left: var(--space-tick-pad); }
/* A button that follows a list or paragraph: live leaves ~57px above it */
.btn-row--lead { margin-top: var(--space-panel-gap); }
.colpair { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-card-gap); align-items: start; }
.colpair__col { display: flex; flex-direction: column; gap: var(--space-card-gap); }
.newpat {
    display: grid; grid-template-columns: 2fr 2fr 1fr;   /* 516 / 516 / 258 */
    gap: var(--space-m);
}
.newpat__card {
    background: var(--surface); border-radius: var(--radius-s);
    padding: var(--space-block);                         /* 70px measured */
    display: flex; flex-direction: column; gap: var(--space-panel-gap);
}
.newpat__card h2 { font-size: var(--size-6); margin: 0; }
.newpat__card h3 { font-size: var(--size-1); margin: 0; }
.newpat__card p { margin: 0; }
.newpat__media img {
    display: block; width: 100%; height: 100%; object-fit: cover; object-position: 50% 0;
    border-radius: 350px 350px 15px 15px;
}
.bring-panel {
    border: 2px solid var(--tertiary-solid); border-radius: 150px 150px 10px 10px;
    padding: var(--space-block) var(--space-s) var(--space-panel-gap);   /* live 75 / 20 / 35 */
    text-align: center;
}
.bring-panel h2 { font-size: var(--size-1); color: var(--secondary-on-soft); margin: 0 0 var(--space-panel-gap); }
.bring-panel .bring { margin: 0; gap: 0; }
.bring-panel .bring li { gap: var(--space-xs); padding-block: var(--space-s); font-size: var(--size-1); }
.bring-panel .bring li + li { border-top: var(--border-width-s) solid var(--tertiary-solid); }
.bring-panel .bring li svg { fill: var(--tertiary-solid); }
@media (max-width: 1024px) {
    .colpair, .newpat { grid-template-columns: 1fr; }
    .newpat__media img { height: auto; }
    .newpat__card { padding: var(--space-inset-m); }
}

/* ---------- /sample-page/ (Contact) — owner review round 2 (2026-09-28) ----------
 * Measured on live at 2223: deep-cream borderless fields (40px, radius 3,
 * 15px type), a full-width 47px gold rectangular submit, a 15px-inset notice
 * box in the brown rgb(138,109,59); the clinic band is 645/645 with the map
 * in the right column. */
.form-grid--live .form-row label { font-size: var(--size-0); color: var(--text); }
.form-grid--live .req { color: var(--danger-on-soft); }
.form-grid--live p { margin: 0; }

/* Text controls: one shape for every field (header search, the phone
 * overlay's box, the contact form) now lives in Form controls, set by the
 * --field-* tokens in :root. Focus there is ONE ring in --focus-ring, a dark
 * amber off the brand gold (owner, 2026-10-05: no ink edge; brand gold itself
 * is only ~1.3-1.5:1 on the creams). */
.form-notice {
    background: var(--ground-deep); color: var(--notice-ink);
    padding: var(--space-xs); border-radius: 3px;
}
.form-notice strong { display: block; margin-bottom: var(--space-3xs); }
.form-notice p { font-size: var(--size--1); line-height: var(--leading); margin: 0; }
.clinic { display: grid; grid-template-columns: 1fr 1fr; align-items: stretch; }
.clinic__copy { padding-right: var(--space-lead); display: flex; flex-direction: column; gap: var(--space-inset-m); }
.clinic__copy .bandhead { padding-bottom: 0; }
.clinic__cards {
    display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-s);
    padding-top: var(--space-inset-m);
    border-top: var(--border-width-s) solid var(--tertiary-solid);
}
.clinic__card { background: var(--ground-deep); border-radius: 3px; padding: var(--space-s); }
.clinic__card h3 { font-size: var(--size-1); color: var(--secondary-on-soft); margin: 0 0 var(--space-2xs); }
.clinic__card p { margin: 0; font-size: var(--size--1); }
.clinic__card a { color: var(--text); text-decoration: none; }
.clinic__card a:hover { text-decoration: underline; }
.clinic__copy .contact-note { margin: 0; }
.clinic__map { border-radius: 10px 10px 300px 300px; overflow: hidden; min-height: 30rem; }   /* live: an inverted arch, measured */
.clinic__map iframe { display: block; width: 100%; height: 100%; min-height: 30rem; border: 0; }
@media (max-width: 1024px) {
    .clinic { grid-template-columns: 1fr; gap: var(--space-xl); }
    .clinic__copy { padding-right: 0; }
    .clinic__map { border-radius: 10px 10px 150px 150px; }
}
@media (max-width: 480px) {
    .clinic__cards { grid-template-columns: 1fr; }
}

/* ---------- /fees-and-billing/ — owner review round 2 (2026-09-28) ----------
 * Measured on live at 2223. */
.lead-navy { font-family: var(--font-heading); font-weight: var(--weight-heading); font-size: var(--size-1); color: var(--secondary-on-soft); margin: 0; }
.phero__prose { display: flex; flex-direction: column; gap: var(--space-s); }
.band--flush { padding-inline: 0; }
.paysplit {
    display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-inset-m);
    align-items: stretch;
}
.paysplit__panel {
    background: var(--ground-deep); border-radius: 0 15px 15px 0;
    padding: var(--space-lead) var(--space-lead) var(--space-lead) max(var(--space-lead), calc((100vw - var(--shell-wide)) / 2 + var(--space-inset-m)));
    display: flex; flex-direction: column; gap: var(--space-panel-gap);
}
.paysplit__panel .bandhead { padding-bottom: 0; }
.paysplit__panel > p { margin: 0; }
.paysplit__pair { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-inset-m); }
.paysplit__media img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: 50% 25%; border-radius: 15px 0 0 15px; }
.payopt { display: flex; flex-direction: column; align-items: center; }
.payopt__photo { width: 100%; }
.payopt__photo img { display: block; width: 100%; height: auto; aspect-ratio: 3 / 1; object-fit: cover; border-radius: 10px; }
.payopt__card {
    width: min(100%, 59.0625rem);        /* 945px */
    margin-top: calc(-1 * var(--space-inset-l));   /* 80px overlap, measured */
    background: var(--ground-deep); border-radius: var(--radius-s);
    padding: var(--space-l); text-align: center;
    display: flex; flex-direction: column; gap: var(--space-s);
}
.payopt__card .eyebrow { font-size: var(--size-0); }
.payopt__card h3 { font-size: var(--size-4); margin: 0; }
.payopt__card p { margin: 0; }
.payopt__cols {
    width: 100%; margin-top: var(--space-block);   /* 70px */
    display: grid; grid-template-columns: 1fr 1fr; gap: 0;
}
.payopt__col {
    padding-block: var(--space-s) var(--space-l);
    display: flex; flex-direction: column; gap: var(--space-s);
}
/* one gold rule between the pair — the centre divider only, no foot rule (owner, 2026-09-30) */
.payopt__col:first-child { padding-right: var(--space-inset-m); border-right: var(--border-width-s) solid var(--tertiary-solid); }
.payopt__col:last-child { padding-left: var(--space-inset-m); }
.payopt__col .eyebrow { font-size: var(--size-0); }
.payopt__col h3 { font-size: var(--size-4); margin: 0; }
.payopt__col h4 { font-size: var(--size-1); margin: var(--space-2xs) 0 0; }
.payopt__col p { margin: 0; }
.afterhours { display: flex; flex-direction: column; gap: var(--space-panel-gap); }
.afterhours h2 { font-size: var(--size-4); margin: 0; }
.afterhours .dot-list { padding-left: var(--space-l); }
.mym { display: grid; grid-template-columns: 850fr 425fr; gap: var(--space-block); align-items: start; }   /* live 850 / 75 / 425 */
.mym__title { font-size: var(--size-7) !important; }
.mym__grid { display: grid; grid-template-columns: 355fr 444fr; gap: var(--space-inset-m); }
.mym__media img { display: block; width: 100%; height: auto; border-radius: 350px 350px 15px 15px; }
.mym__row {
    display: grid; grid-template-columns: 327fr 436fr 436fr; gap: var(--space-block);   /* live 75 */
    margin-top: var(--space-block); align-items: start;
}
.mym__thumb img { display: block; width: 100%; height: auto; border-radius: 10px; }
.chev-list { list-style: none; margin: 0; padding: 0; }
.chev-list li { position: relative; padding-left: var(--space-s); padding-bottom: var(--space-3xs); }
.chev-list li::before { content: "\203A"; position: absolute; left: 0; top: -0.1em; color: var(--tertiary-solid); font-weight: var(--weight-heading); font-size: 1.25em; }
@media (max-width: 1024px) {
    .paysplit { grid-template-columns: 1fr; }
    .paysplit__panel { border-radius: 0; padding: var(--space-inset-xl) var(--space-gutter); }
    .paysplit__media img { border-radius: 0; }
    .payopt__cols { grid-template-columns: 1fr; }
    .payopt__col:first-child { padding-right: 0; border-right: 0; }
    .payopt__col:last-child { padding-left: 0; border-top: var(--border-width-s) solid var(--tertiary-solid); }   /* the divider turns horizontal when the pair stacks */
    .mym, .mym__row { grid-template-columns: 1fr; }
    .mym__media img { border-radius: 200px 200px 15px 15px; }
}
@media (max-width: 767px) {
    .paysplit__pair, .mym__grid { grid-template-columns: 1fr; }
    .payopt__card { margin-top: var(--space-m); }
}

/* ---------- /privacy-policy/ and /terms-and-conditions/ — owner reference 2026-09-30 ----------
 * Measured on live at 1440 / 1024 / 390: a full-bleed photo 900 tall, then a
 * deep-cream band whose page-cream panel (1290 wide, radius 15, z-index 2)
 * rides 270px up over the photo with a 75px inset each side — it floats
 * between the two bands, never on the edge. Padding 100 / 70 / 50x30.
 * Title 3rem brand blue; section headings 2.5rem, navy at the owner's
 * request (live has them in rgb(51,51,51)). */
.lhero { height: 56.25rem; background-image: var(--lhero-photo); background-size: cover; background-position: center; }
.lband { background: var(--ground-deep); padding: 0 var(--space-gutter) var(--space-band); display: flow-root; }
/* flow-root matters: without it the panel's negative top margin collapsed
   THROUGH the band, so the deep-cream band itself rode up over the photo and
   the panel's top edge landed exactly on the band's — it sat on the seam
   instead of floating across it. Measured: bandTop 851 = panelTop 851. */
.lpanel {
    position: relative; z-index: var(--layer-raised);
    max-width: var(--shell); margin: calc(-3 * var(--space-inset-xl)) auto 0;   /* -270px */
    background: var(--surface); border-radius: 15px;
    padding: var(--space-lead); box-sizing: border-box;    /* 100px */
}
.lpanel h1 { font-size: var(--size-6); line-height: var(--leading-display); color: var(--secondary-on-soft); margin: 0 0 var(--space-2xs); }   /* owner: title navy, section headings blue */
.prose--legal h2 { font-size: var(--size-5); line-height: var(--leading-display); color: var(--brand-on-soft); margin: var(--space-2xs) 0 var(--space-xs); }   /* live 8/16 */
.prose--legal h3 { color: var(--brand-on-soft); }
.prose--legal p, .prose--legal li { margin: 0 0 var(--space-xs); line-height: var(--leading-body); }   /* live 0.9rem of its fluid root = 14.85px @1440 */
.prose--legal .lede { font-size: var(--size-1); color: var(--text); }   /* the template's mid-grey lede read washed-out on the cream panel (owner) */
@media (max-width: 1024px) {
    .lhero { height: 30.5rem; }                                   /* 488 measured */
    .lpanel { margin-top: calc(-1 * var(--space-lead)); padding: var(--space-block); }          /* -100 / 70 */
}
@media (max-width: 767px) {
    .lhero { height: 24rem; }
    .lpanel { padding: var(--space-inset-m) var(--space-m); }      /* 50 / 30 */
}

/* ---------- Text before picture when sections stack (owner, 2026-09-30) ----------
 * Below 1024 every two-column band is a single column. Where live puts the
 * photo on the LEFT the photo came first in the stack; the owner wants the
 * copy first everywhere on a phone. `order` on the media child only, so the
 * bands where the copy already leads are unchanged. */
@media (max-width: 1024px) {
    .phero__inner > .phero__media { order: 2; }
    .split > .split__media { order: 2; }
    .trio > .trio__media { order: 3; }
    .twoup__col > img { order: 2; }
    .about__side > .about__photo { order: 2; }
    .mym__row > .mym__thumb { order: 3; }
    .payopt > .payopt__card { order: 1; margin-top: 0; }
    .payopt > .payopt__photo { order: 2; margin-top: var(--space-m); }
    .payopt > .payopt__cols { order: 3; }
}

/* ---------- /careers/ — owner review round 2 (2026-09-28) ----------
 * Measured on live at 2223. The badge glyphs reuse the site's own icons where
 * live draws FontAwesome equivalents. */
.badge {
    display: inline-flex; align-items: center; justify-content: center;
    width: 3.125rem; height: 3.125rem; border-radius: var(--radius-round);
    background: var(--tertiary-solid); flex: none;
}
.badge svg { width: 1.375rem; height: 1.375rem; fill: var(--text); }   /* the ink, as every glyph and label on the gold (9.4:1); live's white was 1.5:1 */
.badge-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-s); padding-top: var(--space-s); }
.badge-item { display: flex; flex-direction: column; gap: var(--space-s); }
.badge-item__label { font-family: var(--font-heading); font-weight: var(--weight-heading); color: var(--brand-on-soft); }
.pcard--ink h3 { color: var(--secondary-on-soft); }
.pcard--light.pcard--ink { padding: var(--space-l); align-items: stretch; text-align: left; }
.split--why { align-items: start; }
.why-copy { display: flex; flex-direction: column; gap: var(--space-panel-gap); }
.why-copy .bandhead { padding-bottom: 0; }
.why-copy > p { margin: 0; }
.split__media--end img { width: 84%; margin-left: auto; }        /* 500 of 595 */
.twoup { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-inset-m); margin-top: var(--space-inset-l); }
.twoup__col { display: flex; flex-direction: column; gap: var(--space-inset-m); }
.twoup__col--offset { padding-top: var(--space-inset-m); }
.twoup img { display: block; width: 100%; height: auto; aspect-ratio: 620 / 426; object-fit: cover; border-radius: var(--radius-s); }
.trio--about { grid-template-columns: 1.07fr 1fr 1fr; gap: var(--space-inset-m) var(--space-xl); }   /* live 64px column gap */
.trio--about .badge { margin-bottom: var(--space-2xs); }
.guides--join .guides__media { flex-basis: 50%; height: 51.875rem; }   /* 1112 x 830 measured */
.join__title { font-size: var(--size-7); }
.dot-list--divided { padding-left: var(--space-s); }
.dot-list--divided li { padding: var(--space-xs) 0;   /* live 12.5px */ border-bottom: var(--border-width-s) solid var(--tertiary-solid); }
@media (max-width: 1024px) {
    .twoup, .trio--about { grid-template-columns: 1fr; }
    .twoup__col--offset { padding-top: 0; }
    .split__media--end img { width: 100%; }
    .guides--join .guides__media { height: 25rem; }
}
@media (max-width: 767px) {
    .badge-row { grid-template-columns: 1fr; }
}

/* ---------- Service & policy pages — owner review round 4 (2026-09-28) ----------
 * Shared pieces measured on live at 2223: a 48px section title (--size-6 here, 3rem
 * on live); navy 20px group headings (the .eyebrow rule, on h3); blue 20px
 * sub-heads (.sub); 384/384 grids of bare groups 50px apart beside a photo
 * (.cardgrid--pair); two 675px columns divided by a gold hairline
 * (.ruled-pair); and the homepage's left-bleed .guides band reused for the
 * "Service Limits" / "Reminders" / "Step-by-Step" / "Practice Environment"
 * bands, whose copy column sits at exactly the same 9vw inset on live. */
.title-xl { font-size: var(--size-6); line-height: var(--leading-display); margin: 0; }
.title-l  { font-size: var(--size-5); line-height: var(--leading-display); margin: 0; }
.title-navy { color: var(--secondary-on-soft); }
.sub { font-family: var(--font-heading); font-weight: var(--weight-heading); font-size: var(--size-1); color: var(--brand-on-soft); margin: 0; }
.pcard--plain > h3.eyebrow, .guide > h3.eyebrow { margin-bottom: 0; }
.split--start { align-items: start; }
.split--copy { gap: var(--space-inset-m); align-items: start; margin-top: var(--space-s); }
.split--copy > div > p:first-of-type { margin-top: var(--space-2xs); }   /* live 12px */
.split--copy h2 { font-size: var(--size-2); color: var(--secondary-on-soft); margin: 0 0 var(--space-2xs); line-height: var(--leading-body); }
.cardgrid.cardgrid--pair { grid-template-columns: 1fr 1fr; gap: var(--space-inset-m); margin-top: var(--space-panel-gap); }
.cardgrid--pair > .pcard--plain > p { margin: 0; }
.ruled-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 0; align-items: start; }
.ruled-pair > :first-child { padding-right: var(--space-inset-m); border-right: var(--border-width-s) solid var(--tertiary-solid); }
.ruled-pair > :last-child { padding-left: var(--space-inset-m); }
.ruled-pair .pcard--plain > h3:not(.eyebrow):not(.title-l) { font-size: var(--size-1); margin: var(--space-2xs) 0 0; }
.pcard--cream { background: var(--surface); border-color: transparent; padding: var(--space-l); margin-top: var(--space-s); }
.pcard--cream .sub { margin-bottom: var(--space-2xs); }
.num-list { list-style: decimal; margin: 0; padding-left: var(--space-l); }   /* live: decimal, 40px indent */
.num-list li { padding-bottom: var(--space-3xs); }
.wide-photo { margin-top: var(--space-block); }
.wide-photo img { display: block; width: 100%; height: auto; aspect-ratio: 3 / 1; object-fit: cover; border-radius: var(--radius-s); }
.split__media--short img { aspect-ratio: 425 / 398; object-fit: cover; object-position: 50% 30%; }
.guides__body > .guide + .guide { margin-top: var(--space-s); }   /* stacked guides only, never the grid */
/* Stacked guides (/practice-policy/ "Practice Environment") take live's own
   rhythm: 20px between eyebrow, sub-heading, copy and list, 40px between
   groups, list indented 40px — measured at 1440. The grid guides keep the
   homepage's tight eyebrow because that is what live does there. */
.guides__grid .guide > .eyebrow { margin: 0 0 var(--space-2xs); }   /* live: 10-14px to the list or copy, ours had 0 */
.guides__body > .guide { display: flex; flex-direction: column; gap: var(--space-s); }
.guides__body > .guide .eyebrow { margin: 0; }
.guides__body > .guide .dot-list { padding-left: var(--space-l); }
/* The copy column is a flex item and defaults to min-width: auto, so a long
 * ghost-button label or list line would not shrink and pushed the band past
 * the viewport on /chronic-disease-management/. */
.guides__body { min-width: 0; }
.guides__body .btn-pill { white-space: normal; text-align: center; }
.guides__body .guides__grid { max-width: none; }
.guides__body .num-list, .guides__body .dot-list { margin: 0; }
.guide .dot-list { padding-left: var(--space-s); }

/* /services/: centred hero over a 1920px-wide photo arched 110px at the top,
 * a three-part head row, six bordered service cards with gold badges, and a
 * hairline-ruled program list beside a washed-out photo. */
.services-hero { padding-bottom: 0; }
.services-hero .band__inner { padding-bottom: var(--space-inset-xl); }
.services-hero .bandhead p:not(.eyebrow) { max-width: 36rem; }
.services-hero .bandhead .phero__title { font-size: var(--size-7); }
.services-hero__media { max-width: 120rem; margin-inline: auto; padding-inline: var(--space-gutter); }
.services-hero__media img { display: block; width: 100%; height: auto; aspect-ratio: 1920 / 700; object-fit: cover; border-radius: 110px 110px 0 0; }
.svc-head { display: grid; grid-template-columns: 544fr 513fr auto; gap: var(--space-inset-m); align-items: center; margin-bottom: var(--space-xl); }
.svc-head .eyebrow { margin-bottom: var(--space-3xs); }
.svc-head h2 { font-size: var(--size-7); line-height: var(--leading-display); margin: 0; }
.svc-head > p { margin: 0; }
.pcard--svc { border-radius: 10px; padding: var(--space-inset-m); gap: var(--space-s); }
.pcard--svc h3 { font-size: var(--size-2); margin: 0; }
.pcard--svc .badge { margin-bottom: var(--space-2xs); }
.services-programs .bandhead h2 { font-size: var(--size-7); }
.progs-row { display: grid; grid-template-columns: 320fr 960fr; gap: var(--space-block); align-items: stretch; }
.progs-photo img { display: block; width: 100%; height: 100%; object-fit: cover; opacity: 0.18; border-radius: var(--radius-s); }
.progs { border-top: var(--border-width-s) solid var(--tertiary-solid); }
.prog {
    display: grid; grid-template-columns: 47fr 379fr 284fr 189fr; gap: var(--space-s);
    align-items: center; padding-block: var(--space-m);
    border-bottom: var(--border-width-s) solid var(--tertiary-solid);
}
.prog__n { font-size: var(--size--1); color: var(--ink-grey); }
.prog h3 { font-size: var(--size-2); margin: 0; }
.prog p { margin: 0; }
.btn-pill--sm { padding-block: var(--space-2xs); justify-self: end; }   /* live 12px */
.cta__app--noqr { grid-template-columns: 1fr; }

/* /practice-policy/: the hero is a cream arch panel over a full-bleed photo. */
.phero--policy { background: url('/assets/images/policy-hero.077478e8bd.webp') center / cover no-repeat; }
.phero--policy .band__inner { padding-block: var(--space-band); }
.arch-panel {
    background: var(--surface);
    border-radius: 450px 450px 15px 15px;
    padding: var(--space-arch-lead) var(--space-inset-l) var(--space-inset-l);   /* 220 / 80 / 80 */
}
.arch-panel .phero__title { font-size: var(--size-7); }
.arch-panel > p { max-width: 36rem; }
@media (max-width: 1024px) {
    .cardgrid.cardgrid--pair, .ruled-pair, .progs-row, .svc-head { grid-template-columns: 1fr; }
    .ruled-pair > :first-child { padding-right: 0; border-right: 0; }
    .ruled-pair > :last-child { padding-left: 0; padding-top: var(--space-l); }
    .progs-photo { display: none; }
    .prog { grid-template-columns: auto 1fr; }
    .prog p { grid-column: 2; }
    .btn-pill--sm { grid-column: 2; justify-self: start; }
    .arch-panel { padding: var(--space-arch-lead) var(--space-l) var(--space-xl); border-radius: 250px 250px 15px 15px; }
}
@media (max-width: 480px) {
    .arch-panel { padding: var(--space-arch-lead) var(--space-s) var(--space-l); border-radius: 160px 160px 15px 15px; width: 100%; box-sizing: border-box; }
    .phero--policy .band__inner { padding-inline: 0; }
    .services-hero__media { padding-inline: 0; }
    .services-hero__media img { border-radius: 0; }
}

/* ---------- /health-info/ (live's /health-articles/, renamed) ---------- */

/* Live's hero carries four 300x500 photos at border-radius 200px, and it
   STAGGERS them: photos 1 and 3 sit high, 2 and 4 drop by exactly 80px.
   Measured identical at 1440 and 1024 (tops 611/691 and 812/892). */
.phero__photos {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--space-card-gap);
    margin-top: var(--space-inset-xl);
    /* the drop is inside the row, so reserve it rather than letting the band grow */
    padding-bottom: var(--space-inset-l);   /* 80px measured */
    justify-items: center;
    align-items: start;
}
.phero__photos img:nth-child(even) { margin-top: var(--space-inset-l); }   /* 80px measured */
.phero__photos img {
    display: block;
    width: 100%;
    max-width: 18.75rem;                 /* 300px measured */
    height: auto;
    aspect-ratio: 300 / 500;
    object-fit: cover;
    border-radius: 200px;                /* measured on live */
}

/* Six trusted resources, static: Ayr is not a Your Health subscriber, so the
   page carries no hub and no copies of Your Health articles (2026-10-04).
   Cards are the site's filled .pcard; the heading IS the link. The grid is
   .cardgrid at three columns, folding to 2x3 at 1024 and one column at 767,
   so six cards never leave an orphan row. */
.resources { --cardgrid-cols: 3; gap: var(--space-card-gap); }
.resources h3 a { color: inherit; text-decoration: underline; text-underline-offset: 0.15em; }
.resources h3 a:hover, .resources h3 a:focus-visible { color: var(--brand-on-soft); }
.band--deep .centre-hero .btn-row { justify-content: center; }
/* The hero and the resources band share one ground, and the hero's photo row
   already reserves its 80px stagger below the last photo; without this the
   two bands stacked 120 + 80 + 120px of empty cream between them. */
.phero--plain + .band > .band__inner { padding-top: 0; }
/* `.phero .band__inner` (the wide arch row) sits later in the file at equal
   specificity and overrode the plain hero's shell width, so this hero ran
   30px wider each side than the band below it. */
.phero.phero--plain .band__inner { max-width: var(--shell); }

@media (max-width: 1024px) {
    /* live keeps all four in one row at 1024, at 213x356 with the same 80px
       stagger -- the images scale, the rhythm does not change */
    .phero__photos img { max-width: 13.3125rem; }   /* 213px measured @1024 */
}
@media (max-width: 767px) {
    /* At 390 live shows ONLY the first photo and sets display:none on the other
       three columns. Reproduced: a four-across stagger has nowhere to go on a
       phone, and live already decided this. */
    .phero__photos { grid-template-columns: 1fr; padding-bottom: 0; }
    .phero__photos img:nth-child(n + 2) { display: none; }
    .phero__photos img:nth-child(even) { margin-top: 0; }
    .phero__photos img { max-width: 18.75rem; }     /* back to 300px @390 */
}

