/* GENERATED by scripts/acf/build-theme-css.py — DO NOT EDIT THIS FILE.
 * Sources: ../content/mockups/_shared/tokens.css, ../content/mockups/_shared/design-system.css
 * Edit those, or the shared modules in knowledge/webdd/css/, then rebuild.
 */
/* Elixir 360 Health — Brand tokens
 * Source: Elixir360_Internal_Handoff_Brief.md (Brand Kit V1, client-approved 2026-07-09)
 * These values are LOCKED. Do not adjust to make a contrast pair pass — route changes
 * back through the brand kit owner. See § "Margin warning" in the handoff brief.
 */

:root {
  /* --- Brand-literal palette (approved Option B, "Clinical Cool") --- */
  --pure-white:      #FFFFFF;
  --alabaster:       #F6F3EC;
  --graphite-ink:    #1E2023;
  --slate-gray:      #5B5F63;
  --harvest-gold:    #A4600D; /* adjusted from logo gold #E0891F for AA */
  --rust-red:        #B23B1E;
  --charcoal-night:  #16191C;
  --soft-white:      #F5F5F0;

  /* --- Semantic roles --- */
  --color-bg:        var(--pure-white);
  --color-surface:   var(--alabaster);
  --color-ink:       var(--graphite-ink);
  --color-ink-soft:  var(--slate-gray);
  --color-brand:     var(--harvest-gold);
  --color-accent:    var(--rust-red);
  --color-on-dark:   var(--soft-white);
  --color-dark:      var(--charcoal-night);

  /* --- Type --- */
  --font-display: "Lora", Georgia, "Times New Roman", serif;
  --font-body:    "Work Sans", system-ui, -apple-system, "Segoe UI", sans-serif;

  /* --- Layout --- */
  --maxw: 1200px;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

/* Logo source gradient, reference only — the mark keeps full saturation.
   #F3FA23 (yellow) → #F26922 (orange) → #CC1F5B (crimson).
   Never used as a text-bearing or large-fill color. */

/* HARD CONSTRAINTS (from brand kit + .claude/skills/webdd-design/rules.md)
 * 1. --color-accent (Rust Red) is CTA + small highlights ONLY. Never a section
 *    background, never a large fill, never body text.
 * 2. --color-brand (Harvest Gold) on dark clears AA by 0.01 (4.51:1). NEVER place
 *    normal-size body text on a gold fill. Gold is hairlines, rules, icons, keylines.
 * 3. Large section backgrounds use ONLY: --color-bg, --color-surface, --color-dark.
 * 4. No decorative "01 / 02 / 03" section numerals on visitor-facing pages
 *    (numbered PROCESS steps are fine — that is content, not decoration).
 */

/* ==========================================================================
   DIRECTION B — "The Arc"
   Design DNA signature
     layout system ....... layered composition, plates overlapping band edges
     eyebrow / kicker .... vertical gold rule + small caps label
     corner radius ....... soft, 10-14px
     button .............. pill, rust fill, white label. Secondary = underline link
     color usage ......... alternating charcoal-led and light, alabaster plates
     section transition .. overlap (plates break the edge above)
     image framing ....... full bleed, masked and rounded, plates composed on top
     signature motif ..... the 360 arc, drawn in SVG
   ========================================================================== */

/* ---------- Reset + base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-ink);
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 1.0625rem;
  line-height: 1.65;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { font-family: var(--font-display); font-weight: 600; line-height: 1.14; margin: 0; letter-spacing: -0.012em; }
p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
img, svg { max-width: 100%; }
a { color: inherit; }

/* ---------- Focus: visible on every interactive element ---------- */
a:focus-visible, button:focus-visible {
  outline: 3px solid var(--color-accent);
  outline-offset: 3px;
  border-radius: 4px;
}
.e-onDark a:focus-visible, .e-onDark button:focus-visible {
  outline-color: var(--color-brand);
  outline-width: 3px;
}

.e-skip {
  position: absolute; left: 1rem; top: -100px; z-index: 100;
  background: var(--color-bg); color: var(--color-ink);
  padding: 0.75rem 1.25rem; border-radius: 10px; font-weight: 600;
  text-decoration: none; transition: top 0.2s var(--ease);
}
.e-skip:focus { top: 1rem; }

/* ---------- Shared layout primitives ---------- */
.e-wrap { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: clamp(1.25rem, 5vw, 3rem); }

/* Eyebrow: vertical gold rule to the left of a small caps label. */
.e-kicker {
  display: block;
  border-left: 2px solid var(--color-brand);
  padding-left: 0.875rem;
  font-family: var(--font-body);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  line-height: 1.5;
  color: var(--color-ink-soft);
}
.e-onDark .e-kicker { color: var(--color-on-dark); border-left-color: var(--color-brand); }

/* Pill CTA: rust fill, white label. The one primary CTA. */
.e-cta {
  display: inline-flex; align-items: center; gap: 0.7rem;
  background: var(--color-accent);
  color: #FFFFFF;
  font-family: var(--font-body);
  font-size: 0.95rem; font-weight: 600; letter-spacing: 0.01em;
  padding: 1.05rem 2rem;
  border: 0; border-radius: 999px;
  text-decoration: none; cursor: pointer;
  transition: transform 0.28s var(--ease), box-shadow 0.28s var(--ease), background-color 0.28s var(--ease);
  box-shadow: 0 2px 0 rgba(30,32,35,0.10);
}
.e-cta:hover { transform: translateY(-2px); box-shadow: 0 10px 26px rgba(178,59,30,0.28); }
.e-cta__arc { flex: none; }
@media (prefers-reduced-motion: reduce) { .e-cta:hover { transform: none; } }

/* Ghost/outline pair for the primary CTA. Scoped to module-level CTA rows below the fold
   (the assessment block). The HERO still takes exactly ONE primary CTA — that rule is
   unchanged. Amended 2026-07-22 per Jeremy: the assessment module needs two peer actions
   (explore vs. book) because the tier cards no longer carry their own CTAs. */
.e-ctaRow {
  display: flex; flex-wrap: wrap; gap: 0.85rem;
  margin-top: 2rem; align-items: center;
}
.e-cta--ghost {
  background: transparent;
  color: var(--color-accent);
  box-shadow: inset 0 0 0 1.5px var(--color-accent);
}
.e-cta--ghost:hover {
  background: var(--color-accent);
  color: #FFFFFF;
  box-shadow: 0 10px 26px rgba(178,59,30,0.28);
}
/* On a dark ground the rust ghost fails contrast, so the outline + label go
   soft-white (15:1 on charcoal). Used by dark heroes that carry a secondary
   action beside the primary CTA (e.g. the contact hero's Call button). */
.e-onDark .e-cta--ghost {
  color: var(--color-on-dark);
  box-shadow: inset 0 0 0 1.5px rgba(245,245,240,0.55);
}
.e-onDark .e-cta--ghost:hover {
  background: var(--color-on-dark);
  color: var(--color-dark);
  box-shadow: none;
}

/* Elsewhere, secondary actions remain underline links rather than a second button. */
.e-link {
  display: inline-block;
  font-family: var(--font-body); font-size: 0.95rem; font-weight: 600;
  color: var(--color-accent);
  text-decoration: underline; text-underline-offset: 5px; text-decoration-thickness: 1.5px;
  transition: text-underline-offset 0.2s var(--ease);
}
.e-link:hover { text-underline-offset: 8px; }
.e-onDark .e-link { color: var(--color-on-dark); text-decoration-color: var(--color-brand); }

/* Dark surfaces */
.e-onDark { background: var(--color-dark); color: var(--color-on-dark); }
.e-onDark h1, .e-onDark h2, .e-onDark h3 { color: var(--color-on-dark); }

/* Labeled image placeholder. Reads as a deliberate plate, not a hole. */
/* CAPTION INK IS A PROPERTY OF THE GROUND, NEVER OF THE SIZE VARIANT.
   Every caption colour on this page resolves through these four variables. Exactly two
   things are allowed to set them: the plate (light by default, overridden by --onDark) and
   the scrim (always dark, so always light ink). The size variants (--stack, --tight) set
   LAYOUT ONLY and must never name a colour — a size variant that also carried a colour is
   how "light ink on a light plate" gets built, because the two modifiers combine four ways
   and only the combinations someone remembered to write get the right ink. Here all four
   are correct by construction. */
.e-photo {
  --e-cap-ink: var(--color-ink-soft);
  --e-cap-strong: var(--color-ink);
  --e-cap-chip: var(--color-accent);
  --e-cap-chip-line: rgba(178,59,30,0.75);
  position: relative;
  display: flex; flex-direction: column; justify-content: flex-end;
  margin: 0;
  border-radius: 12px;
  overflow: hidden;
  background:
    repeating-linear-gradient(135deg, rgba(30,32,35,0.030) 0 2px, transparent 2px 11px),
    var(--color-surface);
  border: 1px solid rgba(30,32,35,0.14);
  min-height: 200px;
}
/* Dashed inner keyline, not solid: across this page a DASHED rule means "real asset
   drops in here". A well-composed empty plate in a cinematic direction otherwise reads
   as intentional negative space, so every pending slot is marked, never implied. */
.e-photo::before {
  content: "";
  position: absolute; inset: 14px;
  border: 1px dashed rgba(164,96,13,0.55);
  border-radius: 6px;
  pointer-events: none;
}
.e-photo figcaption {
  position: relative;
  padding: 1.1rem 1.35rem;
  font-size: 0.72rem; font-weight: 600;
  letter-spacing: 0.1em; text-transform: uppercase;
  line-height: 1.6;
  color: var(--e-cap-ink);
}
/* Tag and slot name share the first caption line, so marking every slot costs no height. */
.e-photo__line { display: block; margin-bottom: 0.3rem; }
.e-photo figcaption b {
  font-weight: 700; color: var(--e-cap-strong);
  letter-spacing: 0.12em;
}
.e-photo__tag {
  display: inline-block; margin-right: 0.6rem;
  padding: 0.14rem 0.45rem;
  border: 1px dashed var(--e-cap-chip-line);
  border-radius: 3px;
  font-size: 0.64rem; font-weight: 700; letter-spacing: 0.13em;
  color: var(--e-cap-chip);
}
/* Ground override 1 of 2: the plate is charcoal. Rust on charcoal is only 3.0:1, so the
   chip flips to soft white with a gold keyline. */
.e-photo--onDark {
  --e-cap-ink: rgba(245,245,240,0.80);
  --e-cap-strong: var(--color-on-dark);
  --e-cap-chip: var(--color-on-dark);
  --e-cap-chip-line: rgba(164,96,13,0.9);
  background: rgba(246,243,236,0.055); border-color: rgba(246,243,236,0.20);
}
.e-photo--onDark::before { border-color: rgba(164,96,13,0.75); }

/* ---------- Stock placeholder imagery ----------
   ONE repeatable structure per slot, so the whole set maps to a single ACF image field:
     figure.e-photo > span.e-photo__media[data-img-source] > img + span.e-photo__wm

   The watermark is painted in CSS and is NEVER baked into the image file. It is drawn
   only for [data-img-source="stock"], so flipping a single attribute to "client" when the
   practice's real photography lands clears the mark with no other edit anywhere.
   The media layer paints above .e-photo::before, so the dashed "asset pending" keyline
   is covered once a real file is wired: the watermark carries that signal from here on. */
/* overflow:hidden is load-bearing: the watermark layer is deliberately oversized (inset: -60%)
   so its rotated tile covers the frame's corners, and in the caption-below variants the media
   is in normal flow, so without clipping here that overspill paints straight across the caption
   text sitting beneath it. */
.e-photo__media { position: absolute; inset: 0; display: block; overflow: hidden; }
.e-photo__media img { display: block; width: 100%; height: 100%; object-fit: cover; }

.e-photo__wm { display: none; }
/* Repeating diagonal mark. The tile is rotated as one layer rather than per-glyph, so it
   tiles seamlessly at any slot size. White fill over a dark stroke (paint-order: stroke)
   keeps it legible over the cream lab flat-lays AND the charcoal-band corridor alike. */
[data-img-source="stock"] .e-photo__wm {
  display: block;
  position: absolute; inset: -60%;
  transform: rotate(-30deg);
  pointer-events: none;
  background-repeat: repeat;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='156'%3E%3Cg font-family='Helvetica,Arial,sans-serif' font-size='14' font-weight='700' letter-spacing='1.6' paint-order='stroke' stroke='rgba(12,14,16,0.55)' stroke-width='3' stroke-linejoin='round' fill='rgba(255,255,255,0.88)'%3E%3Ctext x='6' y='40'%3ETobe Agency Stock Photo%3C/text%3E%3Ctext x='246' y='118'%3ETobe Agency Stock Photo%3C/text%3E%3C/g%3E%3C/svg%3E");
}

/* The caption now sits ON a photograph instead of an empty plate, so it carries its own
   scrim and fixed light ink rather than inheriting the plate's light/dark caption colour.
   Worst case (a blown-out cream flat-lay behind it) the scrim still composites to roughly
   rgb(52,52,52), which holds the caption well clear of AA. */
/* Ground override 2 of 2: the caption is overlaid on the scrim, not on the plate. The scrim
   is dark on every slot regardless of the plate beneath it, so ink is light here whether or
   not the figure carries --onDark. Worst case (a blown-out cream flat-lay behind it) the
   scrim still composites to roughly rgb(52,52,52). */
.e-photo__media + figcaption {
  --e-cap-ink: #F5F5F0;
  --e-cap-strong: #FFFFFF;
  --e-cap-chip: #F6F3EC;
  --e-cap-chip-line: rgba(196,132,52,0.95);
  background: linear-gradient(to top, rgba(16,18,20,0.93), rgba(16,18,20,0.82));
}

/* --- Caption-below variant, for slots too small to carry an overlaid caption ---
   In a small card an overlaid caption is not a label on a photograph, it IS the photograph:
   at the step size the scrim was taking 60-74% of the frame. Here the media takes a fixed
   height in normal flow and the caption sits beneath it on the plate. No scrim, no overlay,
   so the photograph is the dominant element and the label costs one quiet line under it.
   The dashed pending keyline is dropped with the overlay: the watermark carries that signal. */
.e-photo--stack { display: block; min-height: 0; }
.e-photo--stack::before { content: none; }
.e-photo--stack .e-photo__media { position: relative; inset: auto; height: clamp(158px, 14vw, 196px); }
/* Removing the scrim must also remove the scrim's ink, or the caption keeps light text and
   lands on the plate. `inherit` hands the four variables back to the figure, so the caption
   picks up whichever ground it is actually on — light plate or --onDark plate — with no
   colour named here. This one line is what makes all four modifier combinations safe. */
.e-photo--stack .e-photo__media + figcaption {
  --e-cap-ink: inherit; --e-cap-strong: inherit;
  --e-cap-chip: inherit; --e-cap-chip-line: inherit;
  background: none;
}

/* --- Single-line caption, for the wide bands ---
   The tag and the slot name share one line with the descriptor instead of stacking, which
   halves the caption's footprint on a band where the photograph is the point. */
.e-photo--tight .e-photo__media + figcaption { padding: 0.75rem 1.15rem; }
/* margin-right, not a space in the markup: the slot name and the descriptor are separate
   text nodes with no whitespace between them, and this survives a wrap between the two. */
.e-photo--tight .e-photo__line { display: inline; margin-bottom: 0; margin-right: 0.55rem; }

/* Below this breakpoint the wide bands are no taller than a step card while their captions
   wrap to two or three lines, which puts them right back at 56-64% caption. So they adopt
   the same caption-below treatment as the steps. Selectors are doubled up (.e-photo.e-photo--tight)
   purely to out-rank the audience-strip scrim rule further down the sheet. */
@media (max-width: 860px) {
  .e-photo.e-photo--tight { display: block; min-height: 0; }
  .e-photo.e-photo--tight::before { content: none; }
  .e-photo.e-photo--tight .e-photo__media { position: relative; inset: auto; height: clamp(158px, 26vw, 210px); }
  /* Same unset as --stack. The doubled class out-ranks the audience-strip scrim rule further
     down the sheet; no colour is named, so the light and charcoal bands each resolve right. */
  .e-photo.e-photo--tight .e-photo__media + figcaption {
    --e-cap-ink: inherit; --e-cap-strong: inherit;
    --e-cap-chip: inherit; --e-cap-chip-line: inherit;
    background: none;
  }
}

/* Scroll reveal. CSS only, progressive, reduced-motion respected. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .e-reveal {
      animation: e-rise linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 16%;
    }
  }
}
/* Transform only, never opacity. Plates in this direction overlap the dark bands
   by design (the streetlamp plate rides up over the hero, the closing plate is
   charcoal on alabaster), so a fading text layer would blend against whatever
   sits behind it and pass through a genuine low-contrast state mid-scroll.
   Animating position alone keeps the rise and the layered feel with no transient
   contrast loss. Do not reintroduce an opacity fade here. */
@keyframes e-rise { from { transform: translateY(26px); } to { transform: none; } }

/* ==========================================================================
   HEADER — continuous with the dark hero band
   ========================================================================== */
.e-header { background: var(--color-dark); }
.e-header__inner {
  display: flex; align-items: center; justify-content: space-between; gap: 1.5rem;
  padding-block: 1.5rem;
}
.e-brand { display: inline-flex; align-items: center; gap: 0.75rem; text-decoration: none; flex: none; }
/* Brand logo — the real Elixir 360 Health lockup (flask + wordmark), light artwork that
   reads on the dark header band. Height-constrained; width follows its ~2.46:1 aspect ratio.
   The <a class="e-brand"> carries the accessible name (aria-label), so the img alt is empty. */
.e-brand__logo { display: block; height: clamp(40px, 5vw, 52px); width: auto; flex: none; object-fit: contain; }
.e-nav { display: flex; align-items: center; gap: 1.85rem; }
.e-nav__list { display: flex; gap: 1.6rem; }
.e-nav__item { position: relative; }
/* Top-level links only (direct children), so the rule never touches submenu
   links (dark, on a light panel) or the CTA's white label. */
.e-nav__list > li > a {
  display: inline-flex; align-items: center;
  font-size: 0.9rem; font-weight: 500; letter-spacing: 0.02em;
  color: rgba(245,245,240,0.86); text-decoration: none; white-space: nowrap;
  padding-block: 0.35rem;
  border-bottom: 1px solid transparent;
  transition: border-color 0.25s var(--ease), color 0.25s var(--ease);
}
.e-nav__list > li > a:hover { color: var(--color-on-dark); border-bottom-color: var(--color-brand); }
/* Caret on items that own a dropdown; flips when the menu opens. */
.e-nav__item--has-menu > a::after {
  content: ""; display: inline-block; width: 6px; height: 6px; margin-left: 0.45rem;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg) translateY(-1px);
  transition: transform 0.2s var(--ease);
}
.e-nav__item--has-menu:hover > a::after,
.e-nav__item--has-menu:focus-within > a::after { transform: rotate(-135deg) translateY(-1px); }
/* Dropdown panel: a light card floating below the dark header. Closed state is
   visibility:hidden so axe skips it and it leaves the tab order; focusing the
   parent link (focus-within) or hovering reveals it, which then makes the
   submenu links focusable in sequence. */
.e-nav__menu {
  position: absolute; top: calc(100% + 0.5rem); left: 0;
  min-width: 232px; padding: 0.5rem;
  list-style: none;
  background: var(--color-bg);
  border: 1px solid rgba(30,32,35,0.12);
  border-radius: 10px;
  box-shadow: 0 22px 54px -26px rgba(22,25,28,0.55);
  display: flex; flex-direction: column; gap: 0.1rem;
  opacity: 0; visibility: hidden; transform: translateY(6px);
  transition: opacity 0.2s var(--ease), transform 0.2s var(--ease), visibility 0.2s;
  z-index: 60;
}
.e-nav__item--has-menu:hover > .e-nav__menu,
.e-nav__item--has-menu:focus-within > .e-nav__menu {
  opacity: 1; visibility: visible; transform: translateY(0);
}
.e-nav__menu a {
  display: block; padding: 0.55rem 0.7rem; border-radius: 6px;
  color: var(--color-ink); text-decoration: none;
  font-size: 0.9rem; font-weight: 500; letter-spacing: 0; white-space: nowrap;
  transition: background-color 0.18s var(--ease), color 0.18s var(--ease);
}
.e-nav__menu a:hover { background: var(--color-surface); color: var(--color-accent); }
/* Group heading inside a dropdown (e.g. About's "Who We Serve" divider row). */
.e-nav__ghead {
  margin: 0; padding: 0.4rem 0.7rem 0.25rem;
  font-size: 0.66rem; letter-spacing: 0.1em; text-transform: uppercase; font-weight: 700;
  color: var(--color-ink-soft);
}
li.e-nav__ghead { margin-top: 0.4rem; }
.e-header .e-cta { padding: 0.8rem 1.5rem; font-size: 0.88rem; white-space: nowrap; }
@media (max-width: 1080px) { .e-nav__list { display: none; } }
@media (max-width: 560px) { .e-header .e-cta { display: none; } }

/* ==========================================================================
   1. HERO — cinematic dark band, asymmetric plate composition
   ========================================================================== */
.e-hero { position: relative; background: var(--color-dark); padding-block: clamp(3.5rem, 8vw, 6rem) clamp(9rem, 15vw, 13rem); overflow: hidden; }
.e-hero__glow {
  position: absolute; inset: auto -12% -46% auto;
  width: min(760px, 96vw); aspect-ratio: 1;
  pointer-events: none; opacity: 0.5;
}
.e-hero__grid {
  position: relative; z-index: 2;
  display: grid; grid-template-columns: minmax(0, 1.02fr) minmax(0, 0.92fr);
  gap: clamp(2.5rem, 5vw, 4.5rem); align-items: center;
}
.e-hero__kicker { margin-bottom: 1.75rem; }
.e-hero h1 {
  font-size: clamp(2.65rem, 6.1vw, 4.35rem);
  font-weight: 600; line-height: 1.03; letter-spacing: -0.022em;
  max-width: 13ch;
}
.e-hero h1 em { font-style: italic; font-weight: 500; color: var(--color-brand); }
.e-hero__deck {
  margin-top: 1.85rem; max-width: 46ch;
  font-size: clamp(1.02rem, 1.35vw, 1.16rem);
  line-height: 1.72; color: rgba(245,245,240,0.86);
}
.e-hero__actions { margin-top: 2.5rem; }
.e-hero__figure { position: relative; }
.e-hero .e-photo { min-height: clamp(320px, 42vw, 460px); }
/* The gold arc rides the photo edge: the 360 motif introduced at first contact. */
.e-hero__arc { position: absolute; left: -46px; top: -40px; width: 150px; height: 150px; pointer-events: none; }

@media (prefers-reduced-motion: no-preference) {
  .e-hero__kicker, .e-hero h1, .e-hero__deck, .e-hero__actions, .e-hero__figure {
    animation: e-rise 0.85s var(--ease) both;
  }
  .e-hero h1 { animation-delay: 0.08s; }
  .e-hero__deck { animation-delay: 0.16s; }
  .e-hero__actions { animation-delay: 0.24s; }
  .e-hero__figure { animation-delay: 0.14s; }
}

@media (max-width: 900px) {
  .e-hero { padding-bottom: clamp(6rem, 18vw, 9rem); }
  .e-hero__grid { grid-template-columns: 1fr; gap: 2.5rem; }
  .e-hero h1 { max-width: 18ch; }
  .e-hero__arc { left: -18px; top: -26px; width: 96px; height: 96px; }
}

/* ==========================================================================
   2. STREETLAMP — alabaster plate overlapping the hero band
   Heading, body, diagram and pull quote all live inside ONE plate.
   ========================================================================== */
.e-streetlamp { background: var(--color-bg); padding-bottom: clamp(4rem, 8vw, 7rem); }
.e-streetlamp__plate {
  position: relative; z-index: 3;
  /* Gentle overlap. The aggressive -11rem pull was tuned for the home's tall
     cinematic .e-hero (13rem bottom pad of empty dark band). No inner page uses
     .e-hero — they all use the compact .e-phero — so a deep pull covers the hero
     deck (phero→streetlamp) or the audience cards (audience→streetlamp). This
     modest pull keeps the layered look and clears content on every inner page. */
  margin-top: clamp(-3.75rem, -4vw, -2.5rem);
  background: var(--color-surface);
  border: 1px solid rgba(30,32,35,0.10);
  border-radius: 14px;
  padding: clamp(2.25rem, 4.4vw, 4rem);
  box-shadow: 0 30px 70px -40px rgba(22,25,28,0.55);
}
.e-streetlamp__head { max-width: 62ch; }
.e-streetlamp h2 { margin-top: 1.4rem; font-size: clamp(1.85rem, 3.5vw, 2.85rem); max-width: 20ch; }
.e-streetlamp__body {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 0.98fr);
  gap: clamp(2rem, 4vw, 3.5rem); align-items: center;
  margin-top: clamp(2rem, 3.5vw, 3rem);
}
.e-streetlamp__body p + p { margin-top: 1.15rem; }
.e-streetlamp__body p { color: var(--color-ink); max-width: 48ch; }
.e-quote {
  margin: 2rem 0 0; padding-left: 1.5rem;
  border-left: 2px solid var(--color-brand);
  font-family: var(--font-display); font-style: italic; font-weight: 500;
  font-size: clamp(1.15rem, 2vw, 1.5rem); line-height: 1.4;
  color: var(--color-ink);
}
.e-diagram {
  margin: 0; border-radius: 12px; background: var(--color-bg);
  border: 1px solid rgba(30,32,35,0.12); padding: 1.5rem 1.25rem 1.15rem;
}
.e-diagram figcaption {
  margin-top: 0.9rem; font-size: 0.78rem; line-height: 1.6; color: var(--color-ink-soft);
  text-align: center;
}
@media (max-width: 860px) {
  .e-streetlamp__plate { margin-top: clamp(-2.75rem, -6vw, -2rem); }
  .e-streetlamp__body { grid-template-columns: 1fr; }
}

/* ==========================================================================
   3. ASSESSMENT — the product. Tier prices composed as figures.
   ========================================================================== */
.e-assessment { background: var(--color-bg); padding-block: clamp(3rem, 6vw, 5rem) clamp(4rem, 8vw, 7rem); }
.e-assessment__head {
  display: grid; grid-template-columns: minmax(0, 0.95fr) minmax(0, 1fr);
  gap: clamp(2rem, 4vw, 4rem); align-items: end;
}
.e-assessment h2 { margin-top: 1.4rem; font-size: clamp(1.85rem, 3.5vw, 2.85rem); max-width: 16ch; }
.e-assessment__body p + p { margin-top: 1.1rem; }
.e-assessment__body p { color: var(--color-ink-soft); max-width: 52ch; }
.e-tiers {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1rem, 1.8vw, 1.6rem);
  margin-top: clamp(2.25rem, 4vw, 3.25rem);
}
.e-tier {
  position: relative;
  background: var(--color-surface);
  border: 1px solid rgba(30,32,35,0.11);
  border-radius: 12px;
  padding: clamp(1.5rem, 2.4vw, 2.1rem);
  display: flex; flex-direction: column;
  transition: transform 0.3s var(--ease), box-shadow 0.3s var(--ease);
}
/* Hover/focus state, the stretched link, and reduced motion are owned by the shared
   interactive-card module (generated at the foot of this file). It only fires on a
   tier that actually contains a routing link — many tiers do not. */
.e-tier__arc { position: absolute; right: 1.25rem; top: 1.25rem; opacity: 0.9; }
.e-tier__name {
  font-family: var(--font-display); font-size: 1.22rem; font-weight: 600; line-height: 1.25;
  max-width: 19ch; padding-right: 2.5rem;
  /* Reserve three lines so the rule below every title lands on the same baseline across
     the row. Without this the titles wrap to 2/3/4 lines and the dividers step down. */
  min-height: calc(3 * 1.25em);
}
@media (max-width: 760px) { .e-tier__name { min-height: 0; } }
/* No pricing on any module — hard client rule (Raj, 2026-07-21). The brand rule that
   divided name from price now divides name from the description line, so the card keeps
   its structure without a figure. Do not reintroduce a price element here. */
.e-tier__line {
  margin-top: 1.35rem; padding-top: 1.2rem;
  border-top: 1px solid rgba(164,96,13,0.45);
  font-size: 0.95rem; line-height: 1.6; color: var(--color-ink-soft);
}
/* Optional per-card link line, used when tier cards route to their child pages (e.g. the
   SH-01 hub → TX-01/02/03). Pushed to the card foot so the links align across the row. */
.e-tier__more { margin-top: auto; padding-top: 1rem; font-size: 0.88rem; }
.e-assessment__note {
  margin-top: 1.75rem; padding-left: 1.25rem;
  border-left: 2px solid rgba(164,96,13,0.55);
  font-size: 0.92rem; line-height: 1.65; color: var(--color-ink-soft); max-width: 78ch;
}
.e-assessment__more { margin-top: 1.75rem; }
@media (max-width: 900px) { .e-assessment__head { grid-template-columns: 1fr; align-items: start; } }
@media (max-width: 760px) { .e-tiers { grid-template-columns: 1fr; } }

/* ==========================================================================
   4. METHOD — the signature 360 arc completing across four steps
   ========================================================================== */
.e-method { background: var(--color-surface); padding-block: clamp(3.5rem, 7vw, 6rem); }
.e-method__head { text-align: center; display: flex; flex-direction: column; align-items: center; }
.e-method__head .e-kicker { border-left: 0; border-top: 2px solid var(--color-brand); padding: 0.85rem 0 0; }
.e-method h2 { margin-top: 1rem; font-size: clamp(1.85rem, 3.5vw, 2.85rem); max-width: 18ch; }
.e-method__stage { position: relative; margin-top: clamp(2.25rem, 4vw, 3.25rem); }
.e-method__steps {
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(180px, 20vw, 260px) minmax(0, 1fr);
  gap: clamp(1rem, 2.2vw, 2rem);
  align-items: stretch;
}
.e-method__orbit {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: clamp(180px, 20vw, 260px);
  display: grid; place-items: center; pointer-events: none;
}
.e-method__orbit svg { width: 100%; height: auto; }
.e-step {
  background: var(--color-bg);
  border: 1px solid rgba(30,32,35,0.11);
  border-radius: 12px;
  padding: clamp(1.35rem, 2.2vw, 1.9rem);
  display: flex; flex-direction: column;
}
.e-step--1 { grid-column: 1; grid-row: 1; }
.e-step--2 { grid-column: 3; grid-row: 1; }
.e-step--3 { grid-column: 1; grid-row: 2; }
.e-step--4 { grid-column: 3; grid-row: 2; }
.e-step--2, .e-step--4 { text-align: left; }
.e-step__num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; flex: none;
  border: 1px solid rgba(164,96,13,0.6); border-radius: 999px;
  font-family: var(--font-display); font-size: 0.95rem; font-weight: 600;
  color: var(--color-ink);
}
.e-step__title { font-family: var(--font-display); font-size: 1.12rem; font-weight: 600; margin-top: 0.9rem; }
.e-step__text { margin-top: 0.55rem; font-size: 0.95rem; line-height: 1.62; color: var(--color-ink-soft); }
.e-step .e-photo { margin-top: 1.15rem; min-height: 116px; }
.e-step .e-photo figcaption { padding: 0.8rem 0.95rem; font-size: 0.63rem; letter-spacing: 0.08em; }
.e-method__more { margin-top: 2rem; text-align: center; }

/* 3-STEP VARIANT (e.g. /thank-you). The 2x2 orbit leaves a lopsided empty
   quadrant with only three steps, so arrange them as an equidistant triangle:
   one card centered on top, two flanking the 360 hub below. The generous
   row-gap gives the absolutely-centered orbit room to sit in the gap between
   the top card and the bottom pair, not over any card. NEW 2026-07-28. */
.e-method__steps--3 {
  grid-template-columns: minmax(0, 1fr) clamp(180px, 20vw, 260px) minmax(0, 1fr);
  grid-template-rows: auto auto;
  row-gap: clamp(200px, 22vw, 280px);
}
.e-method__steps--3 .e-step--1 {
  grid-column: 1 / -1; grid-row: 1;
  justify-self: center;
  width: min(100%, clamp(280px, 34vw, 400px));
}
.e-method__steps--3 .e-step--2 { grid-column: 1; grid-row: 2; }
.e-method__steps--3 .e-step--3 { grid-column: 3; grid-row: 2; }

@media (max-width: 940px) {
  .e-method__steps { grid-template-columns: 1fr 1fr; }
  .e-method__orbit { display: none; }
  .e-step--1 { grid-column: 1; grid-row: 1; }
  .e-step--2 { grid-column: 2; grid-row: 1; }
  .e-step--3 { grid-column: 1; grid-row: 2; }
  .e-step--4 { grid-column: 2; grid-row: 2; }
  /* 3-variant: top card spans the two columns, the other two sit below */
  .e-method__steps--3 { grid-template-columns: 1fr 1fr; row-gap: clamp(1rem, 2.2vw, 2rem); }
  .e-method__steps--3 .e-step--1 { grid-column: 1 / -1; grid-row: 1; width: auto; justify-self: stretch; }
  .e-method__steps--3 .e-step--2 { grid-column: 1; grid-row: 2; }
  .e-method__steps--3 .e-step--3 { grid-column: 2; grid-row: 2; }
}
@media (max-width: 620px) {
  .e-method__steps { grid-template-columns: 1fr; }
  .e-step--1, .e-step--2, .e-step--3, .e-step--4 { grid-column: 1; grid-row: auto; }
  .e-method__steps--3 { grid-template-columns: 1fr; }
  .e-method__steps--3 .e-step--1, .e-method__steps--3 .e-step--2, .e-method__steps--3 .e-step--3 {
    grid-column: 1; grid-row: auto; width: auto;
  }
}

/* ==========================================================================
   5. SERVICES — bordered cluster, custom gold line icons
   ========================================================================== */
.e-services { background: var(--color-bg); padding-block: clamp(3.5rem, 7vw, 6rem); }
.e-services__head {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 0.85fr);
  gap: 2rem; align-items: end;
}
.e-services h2 { margin-top: 1.35rem; font-size: clamp(1.85rem, 3.5vw, 2.85rem); max-width: 17ch; }
.e-services__lede { font-size: 0.98rem; color: var(--color-ink-soft); max-width: 44ch; }
/* 7 services + the "all services" cell = 8, so the grid divides exactly at
   4, 2 and 1 columns. Column counts are explicit rather than auto-fit so a
   3-column step can never leave an orphaned, outlined empty cell. */
.e-services__grid {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1px;
  margin-top: clamp(2rem, 3.5vw, 3rem);
  background: rgba(30,32,35,0.12);
  border: 1px solid rgba(30,32,35,0.12);
  border-radius: 12px; overflow: hidden;
}
@media (max-width: 1080px) { .e-services__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px)  { .e-services__grid { grid-template-columns: 1fr; } }
.e-service {
  position: relative;
  background: var(--color-bg);
  padding: clamp(1.4rem, 2.2vw, 1.9rem);
  display: flex; flex-direction: column; gap: 0.85rem;
  transition: background-color 0.28s var(--ease);
}
/* Minimal type indicator (Assessment / Service / Membership), top-right of the
   card. slate-gray on white/alabaster clears AA; decorative hairline border. */
.e-service__tag {
  position: absolute; top: clamp(1.4rem, 2.2vw, 1.9rem); right: clamp(1.4rem, 2.2vw, 1.9rem);
  font-size: 0.62rem; letter-spacing: 0.09em; text-transform: uppercase; font-weight: 600;
  color: var(--color-ink-soft);
  border: 1px solid rgba(30,32,35,0.18); border-radius: 999px;
  padding: 0.22rem 0.6rem; line-height: 1; white-space: nowrap;
}
/* The eighth cell: a quiet routing cell, not a second primary CTA. */
.e-service--more {
  background: var(--color-surface);
  justify-content: flex-end;
}
/* Hover/focus state owned by the interactive-card module — see the foot of this file.
   The surface tint is declared as active_bg on the binding so the :has() gate stays in
   one place. On the home teaser these cells carry no link and correctly stay static. */
.e-service__name { font-family: var(--font-display); font-size: 1.06rem; font-weight: 600; line-height: 1.3; }
.e-service__line { font-size: 0.93rem; line-height: 1.6; color: var(--color-ink-soft); }
/* Per-cell routing link, used when the grid is a services index (SH-00) rather than the home
   teaser. Pushed to the cell foot so links align across the row regardless of blurb length. */
.e-service__go { margin-top: auto; padding-top: 0.85rem; font-size: 0.86rem; }
@media (max-width: 860px) { .e-services__head { grid-template-columns: 1fr; align-items: start; } }

/* ==========================================================================
   6. AUDIENCE — one panel: heading + shared image strip + three plates
   ========================================================================== */
.e-audience { background: var(--color-surface); padding-block: clamp(3.5rem, 7vw, 6rem); }
.e-audience__panel {
  background: var(--color-bg);
  border: 1px solid rgba(30,32,35,0.11);
  border-radius: 14px;
  padding: clamp(1.75rem, 3.4vw, 3rem);
}
.e-audience h2 { margin-top: 1.3rem; font-size: clamp(1.75rem, 3.2vw, 2.6rem); max-width: 18ch; }
.e-audience__strip { position: relative; margin-top: clamp(1.75rem, 3vw, 2.5rem); }
.e-audience__strip .e-photo { min-height: clamp(160px, 20vw, 230px); }
/* The persona cards ride up over the bottom of this strip, so this is the one slot on the
   page whose bottom edge is already occupied. Its caption anchors to the top of the frame
   instead, and its scrim flips direction to match. Caption placement only: the plate, the
   strip geometry and the card overlap are untouched. */
.e-audience__strip .e-photo { justify-content: flex-start; }
.e-audience__strip .e-photo__media + figcaption {
  background: linear-gradient(to bottom, rgba(16,18,20,0.93), rgba(16,18,20,0.82));
}
.e-audience__cards {
  position: relative; z-index: 2;
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(0.9rem, 1.6vw, 1.4rem);
  margin-top: -56px;
  padding-inline: clamp(0.75rem, 2vw, 1.75rem);
}
.e-persona {
  background: var(--color-surface);
  border: 1px solid rgba(30,32,35,0.12);
  border-radius: 12px;
  padding: clamp(1.3rem, 2.1vw, 1.75rem);
  box-shadow: 0 18px 40px -32px rgba(22,25,28,0.6);
  display: flex; flex-direction: column;
}
.e-persona__rule { width: 40px; height: 2px; background: var(--color-brand); border-radius: 2px; }
.e-persona__title { font-family: var(--font-display); font-size: 1.06rem; font-weight: 600; line-height: 1.3; margin-top: 1rem; }
.e-persona__text { margin-top: 0.6rem; font-size: 0.93rem; line-height: 1.62; color: var(--color-ink-soft); }
.e-persona__more { margin-top: 1.1rem; font-size: 0.88rem; }
@media (max-width: 860px) {
  .e-audience__cards { grid-template-columns: 1fr; margin-top: -32px; }
}

/* ==========================================================================
   7. PHYSICIAN — charcoal punctuation. Slot is NOT face dependent.
   ========================================================================== */
.e-physician { padding-block: clamp(3.75rem, 7.5vw, 6.5rem); }
/* Deliberately NOT a portrait composition. Text sits in two columns above a wide,
   landscape clinical-environment strip. No slot on this page frames a face. */
.e-physician__top {
  display: grid; grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.05fr);
  gap: clamp(1.75rem, 4vw, 3.5rem); align-items: end;
}
.e-physician h2 { margin-top: 1.4rem; font-size: clamp(1.8rem, 3.4vw, 2.7rem); max-width: 17ch; }
.e-physician__body { color: rgba(245,245,240,0.86); max-width: 54ch; line-height: 1.72; }
/* CREDENTIALS — editorial, never UI.
   The previous pill treatment gave five non-interactive facts a fill, a radius and a
   border, which together read as buttons: a UX lie, and cheap against a premium brand.
   This is typography and structure only. No fill, no radius, nothing clickable-looking.
   With no physician name and no portrait available, this band IS the practice's
   authority claim, so it gets display-scale figures and a full-width arc of its own. */
.e-credband {
  position: relative;
  margin-top: clamp(2.25rem, 4vw, 3rem);
  padding-top: clamp(1.75rem, 3vw, 2.25rem);
  border-top: 1px solid rgba(164,96,13,0.55);
}
/* The 360 arc at band scale: the credentials sit along its sweep. Its widest, quietest
   statement on the page, and the one section that had no arc in the first pass. */
.e-credband__arc {
  position: absolute; left: 0; right: 0; top: 0;
  width: 100%; height: clamp(104px, 12vw, 138px);
  pointer-events: none;
}
.e-creds {
  position: relative; z-index: 2;
  display: grid; grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: clamp(1rem, 2.2vw, 2rem);
}
.e-cred { display: flex; flex-direction: column; gap: 0.6rem; }
/* Gold keylines separate the credentials. Rules, not containers. */
.e-cred + .e-cred { padding-left: clamp(1rem, 2.2vw, 2rem); border-left: 1px solid rgba(164,96,13,0.5); }
.e-cred__figure {
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(1.5rem, 2.7vw, 2.15rem); line-height: 1;
  letter-spacing: -0.015em; color: var(--color-on-dark);
}
.e-cred__expand {
  font-family: var(--font-body); font-size: 0.66rem; font-weight: 600;
  letter-spacing: 0.11em; text-transform: uppercase; line-height: 1.65;
  color: rgba(245,245,240,0.80);
}
/* MD carries no expansion in the approved copy, so its slot takes the arc seal rather
   than invented words. The shortest credential is the foundational one. */
.e-cred__seal { display: block; opacity: 0.9; }
@media (max-width: 980px) {
  /* The band arc is composed for the horizontal row; once the credentials stack it
     would read as a stray curve behind the first item. */
  .e-credband__arc { display: none; }
  .e-creds { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.5rem; }
  .e-cred + .e-cred { padding-left: 0; border-left: 0; }
  .e-cred { padding-top: 1.25rem; border-top: 1px solid rgba(164,96,13,0.4); }
  .e-cred:first-child { padding-top: 0; border-top: 0; }
  .e-cred:nth-child(2) { padding-top: 0; border-top: 0; }
}
@media (max-width: 560px) {
  .e-creds { grid-template-columns: 1fr; }
  .e-cred:nth-child(2) { padding-top: 1.25rem; border-top: 1px solid rgba(164,96,13,0.4); }
}
.e-physician__more { margin-top: 1.9rem; }
/* Wide landscape strip. A 4:1 band cannot read as a headshot frame. */
.e-physician__strip { position: relative; margin-top: clamp(2rem, 3.5vw, 3rem); }
.e-physician .e-photo { min-height: clamp(150px, 17vw, 215px); }
.e-physician__arc { position: absolute; right: -30px; top: -30px; width: 120px; height: 120px; pointer-events: none; }
@media (max-width: 900px) {
  .e-physician__top { grid-template-columns: 1fr; align-items: start; }
  .e-physician__arc { right: -12px; top: -16px; width: 84px; height: 84px; }
}

/* ==========================================================================
   8. PARTNERS + PROOF
   ========================================================================== */
.e-proof { background: var(--color-bg); padding-block: clamp(3.5rem, 7vw, 6rem); }
.e-proof h2 { margin-top: 1.35rem; font-size: clamp(1.75rem, 3.2vw, 2.5rem); max-width: 18ch; }
.e-proof__body { margin-top: 1.35rem; color: var(--color-ink-soft); max-width: 58ch; }
/* PARTNER LOGOS — borrowed authority, so they have to look like real marks.
   The first pass used circular glyphs, which read as decorative iconography and
   undercut the credibility this section exists to build. These are properly
   proportioned logo plates at a true horizontal-lockup ratio (16:5). Single-ink
   and restrained, which reads more premium here and will accommodate whatever the
   real artwork turns out to be. Swapping the wordmark span for an <img> when the
   files arrive requires no restructuring: the plate owns the geometry. */
/* The partner logo-plate CSS lived here. Removed 2026-08-04: the client will not name lab,
   imaging or compounding partners publicly (he may switch vendors), so the logo strip is gone
   from every page and this rule set had no markup left. The section wrapper it shared was
   renamed .e-partners -> .e-proof, because it now carries only patient stories. */

/* PATIENT STORIES — deliberately a different device from the logo plates directly above,
   so this region does not read as one large unresolved zone. Logos are filled, wide and
   horizontal; stories are outlined, tall and quote-led. */
.e-stories {
  margin-top: clamp(2rem, 3.2vw, 2.6rem);
  padding-top: clamp(1.4rem, 2.2vw, 1.75rem);
  border-top: 2px solid rgba(164,96,13,0.55);
}
.e-stories__label {
  display: block;
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--color-ink);
}
.e-stories__note { margin-top: 0.5rem; font-size: 0.86rem; line-height: 1.6; color: var(--color-ink-soft); max-width: 62ch; }
.e-stories__grid {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1rem, 2vw, 1.6rem);
  margin-top: clamp(1.2rem, 2vw, 1.6rem);
}
/* Two real stories supplied; the third card is retired rather than left as a gap. */
.e-stories__grid--two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 820px) {
  .e-stories__grid,
  .e-stories__grid--two { grid-template-columns: 1fr; }
}
.e-story {
  position: relative;
  background: transparent;
  border: 1px solid rgba(30,32,35,0.16);
  border-radius: 12px;
  padding: 1.5rem 1.4rem;
}
/* No .e-story__mark: these are physician-authored case narratives, not patient quotes.
   A quote glyph would present them as verbatim patient speech. Do not add one back. */
.e-story__text {
  font-family: var(--font-display); font-size: 1rem; line-height: 1.6;
  color: var(--color-ink-soft);
}
/* Verbatim patient reviews (Google). UNLIKE .e-story these ARE patient speech, so the
   quote glyph + a real attribution line are correct here. Never edit the quote body. */
.e-story--review { border-left: 3px solid var(--color-accent); }
.e-story--review .e-story__text::before {
  content: "\201C"; font-family: var(--font-display); font-size: 1.9rem; line-height: 0;
  color: var(--color-accent); margin-right: 0.15rem; vertical-align: -0.28rem;
}
.e-story__cite {
  display: block; margin-top: 0.85rem; font-style: normal;
  font-size: 0.8rem; letter-spacing: 0.04em; color: var(--color-ink-soft);
}
.e-story__cite a { color: inherit; }
.e-stories__disclaimer {
  margin-top: clamp(1rem, 1.6vw, 1.3rem);
  font-size: 0.78rem; line-height: 1.6; color: var(--color-ink-soft); opacity: 0.85;
  max-width: 78ch;
}

/* ==========================================================================
   9. FAQ — one plate holds the aside AND the questions. Never a naked list.
   ========================================================================== */
.e-faq { background: var(--color-bg); padding-block: clamp(3.5rem, 7vw, 6rem); }
.e-faq__plate {
  background: var(--color-surface);
  border: 1px solid rgba(30,32,35,0.11);
  border-radius: 14px;
  padding: clamp(1.75rem, 3.4vw, 3.25rem);
  display: grid;
  grid-template-columns: minmax(0, 0.82fr) minmax(0, 1.18fr);
  gap: clamp(2rem, 4vw, 3.5rem);
  align-items: start;
}
/* Sticky aside carrying the H2 and the arc motif: the section's media-bearing device. */
.e-faq__aside { position: sticky; top: 2.5rem; align-self: start; }
.e-faq h2 { margin-top: 1.35rem; font-size: clamp(1.75rem, 3.2vw, 2.55rem); max-width: 14ch; }
.e-faq__motif { margin-top: clamp(1.75rem, 3vw, 2.5rem); max-width: 210px; }
.e-faq__motif svg { width: 100%; height: auto; display: block; }
.e-faq__more { margin-top: 1.75rem; }
.e-faq__list { border-top: 1px solid rgba(30,32,35,0.14); }
.e-faq__item { border-bottom: 1px solid rgba(30,32,35,0.14); }
.e-faq__q {
  width: 100%; display: flex; align-items: flex-start; justify-content: space-between; gap: 1.25rem;
  background: none; border: 0; margin: 0;
  padding: 1.35rem 0;
  font-family: var(--font-display); font-size: clamp(1.02rem, 1.5vw, 1.14rem); font-weight: 600;
  line-height: 1.35; text-align: left; color: var(--color-ink); cursor: pointer;
  transition: color 0.22s var(--ease);
}
.e-faq__q:hover { color: var(--color-accent); }
.e-faq__sign { flex: none; margin-top: 0.2rem; transition: transform 0.3s var(--ease); }
.e-faq__q[aria-expanded="true"] .e-faq__sign { transform: rotate(45deg); }
@media (prefers-reduced-motion: reduce) { .e-faq__sign { transition: none; } }
.e-faq__a { padding: 0 0 1.5rem; }
.e-faq__a p {
  max-width: 62ch; font-size: 0.98rem; line-height: 1.7; color: var(--color-ink-soft);
  padding-left: 1.15rem; border-left: 2px solid rgba(164,96,13,0.55);
}
@media (prefers-reduced-motion: no-preference) {
  .e-faq__a { animation: e-faqIn 0.34s var(--ease) both; }
}
/* Transform only, same rule as e-rise. Answer text is never partially transparent. */
@keyframes e-faqIn { from { transform: translateY(-6px); } to { transform: none; } }
@media (max-width: 880px) {
  .e-faq__plate { grid-template-columns: 1fr; }
  .e-faq__aside { position: static; }
  .e-faq__motif { margin-inline: auto; }
}

/* ==========================================================================
   10. CLOSING — charcoal plate floating on alabaster
   ========================================================================== */
.e-closing { background: var(--color-surface); padding-block: clamp(3.5rem, 7vw, 6rem); }
.e-closing__plate {
  background: var(--color-dark); color: var(--color-on-dark);
  border-radius: 14px;
  padding: clamp(2.25rem, 4.6vw, 4rem);
  position: relative; overflow: hidden;
  box-shadow: 0 40px 80px -50px rgba(22,25,28,0.8);
}
.e-closing__arc { position: absolute; right: -80px; top: -80px; width: 320px; height: 320px; opacity: 0.55; pointer-events: none; }
.e-closing__inner { position: relative; z-index: 2; display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr); gap: clamp(2rem, 4vw, 3.5rem); }
.e-closing h2 { font-size: clamp(1.9rem, 3.6vw, 2.9rem); max-width: 14ch; }
.e-closing__body { margin-top: 1.35rem; color: rgba(245,245,240,0.86); max-width: 44ch; line-height: 1.72; }
.e-closing__actions { margin-top: 2.1rem; }
.e-details { display: flex; flex-direction: column; gap: 1.15rem; align-self: center; }
.e-detail { display: grid; grid-template-columns: 22px 1fr; gap: 0.9rem; align-items: start; }
.e-detail__label { font-size: 0.68rem; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase; color: rgba(245,245,240,0.62); }
.e-detail__value { margin-top: 0.2rem; font-size: 0.96rem; line-height: 1.55; color: var(--color-on-dark); }
.e-detail__value a { text-decoration: none; border-bottom: 1px solid rgba(164,96,13,0.7); }
.e-detail__value a:hover { border-bottom-color: var(--color-on-dark); }
.e-payment {
  margin-top: 1.6rem; padding-top: 1.4rem;
  border-top: 1px solid rgba(164,96,13,0.5);
  font-size: 0.88rem; line-height: 1.6; color: rgba(245,245,240,0.78);
}
@media (max-width: 880px) { .e-closing__inner { grid-template-columns: 1fr; } }

/* ==========================================================================
   FOOTER
   ========================================================================== */
.e-footer { background: var(--color-dark); color: var(--color-on-dark); padding-block: clamp(2.5rem, 4vw, 3.5rem); border-top: 1px solid rgba(246,243,236,0.10); }
.e-footer__inner { display: flex; flex-wrap: wrap; gap: 1.5rem 2.5rem; align-items: center; justify-content: space-between; }
.e-footer__legal { font-size: 0.8rem; color: rgba(245,245,240,0.66); max-width: 62ch; line-height: 1.65; }
.e-footer__nav { display: flex; flex-wrap: wrap; gap: 1.5rem; }
.e-footer__nav a { font-size: 0.85rem; color: rgba(245,245,240,0.86); text-decoration: none; border-bottom: 1px solid transparent; }
.e-footer__nav a:hover { border-bottom-color: var(--color-brand); }

/* ==========================================================================
   11. PAGE-HERO — compact inner-page hero (NEW for inner pages, 2026-07-22)
   A lighter variant of the home hero: dark band, breadcrumb → H1 → lede →
   single CTA, optional side image. Reuses hero tokens; no cinematic glow.
   ========================================================================== */
.e-phero { position: relative; background: var(--color-dark); overflow: hidden;
  padding-block: clamp(2.25rem, 4vw, 3.25rem) clamp(4rem, 7vw, 6rem); }
.e-phero__grid {
  display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
  gap: clamp(2rem, 4.5vw, 4rem); align-items: center;
}
.e-phero--noimg .e-phero__grid { grid-template-columns: 1fr; }
.e-phero h1 {
  margin-top: 1.4rem;
  font-size: clamp(2.15rem, 4.6vw, 3.35rem);
  font-weight: 600; line-height: 1.06; letter-spacing: -0.02em; max-width: 17ch;
}
.e-phero h1 em { font-style: italic; font-weight: 500; color: var(--color-brand); }
.e-phero__deck {
  margin-top: 1.5rem; max-width: 52ch;
  font-size: clamp(1rem, 1.3vw, 1.12rem); line-height: 1.7; color: rgba(245,245,240,0.86);
}
.e-phero__actions { margin-top: 2.1rem; }
.e-phero__figure { position: relative; }
.e-phero .e-photo { min-height: clamp(260px, 34vw, 380px); }
.e-phero__arc { position: absolute; left: -40px; top: -34px; width: 128px; height: 128px; pointer-events: none; }
@media (prefers-reduced-motion: no-preference) {
  .e-phero .e-crumb, .e-phero h1, .e-phero__deck, .e-phero__actions, .e-phero__figure {
    animation: e-rise 0.8s var(--ease) both;
  }
  .e-phero h1 { animation-delay: 0.06s; }
  .e-phero__deck { animation-delay: 0.13s; }
  .e-phero__actions { animation-delay: 0.2s; }
}
@media (max-width: 860px) {
  .e-phero__grid { grid-template-columns: 1fr; gap: 2rem; }
  .e-phero h1 { max-width: 20ch; }
  .e-phero__arc { left: -16px; top: -22px; width: 88px; height: 88px; }
}

/* Breadcrumb — used inside page-hero (or standalone). Carries BreadcrumbList schema. */
.e-crumb { font-size: 0.82rem; letter-spacing: 0.01em; }
.e-crumb ol { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
.e-crumb li { display: inline-flex; align-items: center; gap: 0.5rem; color: rgba(245,245,240,0.62); }
.e-crumb li:not(:last-child)::after { content: "/"; color: rgba(164,96,13,0.85); }
.e-crumb a { color: rgba(245,245,240,0.82); text-decoration: none; border-bottom: 1px solid transparent; }
.e-crumb a:hover { border-bottom-color: var(--color-brand); color: var(--color-on-dark); }
.e-crumb [aria-current="page"] { color: rgba(245,245,240,0.62); }
/* On a light ground (standalone crumb) flip the colors. */
.e-crumb--onLight li { color: var(--color-ink-soft); }
.e-crumb--onLight a { color: var(--color-ink); }

/* ==========================================================================
   12. PROSE — measured long-form body (legal / policy pages ONLY).
   The one deliberately text-only block; the media-device rule is waived here.
   ========================================================================== */
.e-prose { background: var(--color-bg); padding-block: clamp(3rem, 6vw, 5rem); }
.e-prose__col { max-width: 66ch; }
.e-prose__updated { font-size: 0.85rem; color: var(--color-ink-soft); margin-bottom: 2rem; }
.e-prose h2 { font-family: var(--font-display); font-size: clamp(1.35rem, 2.4vw, 1.7rem);
  font-weight: 600; margin-top: 2.5rem; margin-bottom: 0.75rem; }
.e-prose h3 { font-size: 1.1rem; font-weight: 600; margin-top: 1.75rem; margin-bottom: 0.5rem; }
.e-prose p, .e-prose li { color: var(--color-ink-soft); line-height: 1.75; }
.e-prose p + p { margin-top: 1.1rem; }
.e-prose ul, .e-prose ol { margin-top: 1rem; padding-left: 1.25rem; }
.e-prose li + li { margin-top: 0.5rem; }
.e-prose a { color: var(--color-accent); text-decoration: underline; text-underline-offset: 3px; }

/* ==========================================================================
   13. CONTACT — NAP + hours + booking panel (CN-01, NEW 2026-07-28).
   Light section, two columns: booking-first info column + locale-photo aside.
   The booking actions + detail rows are the non-prose device; the aside carries
   the required real image (locale, never a clinic interior). Reuses e-cta/
   e-ctaRow/e-kicker/e-photo; only the light-ground detail rows are new here.
   ========================================================================== */
.e-contact { background: var(--color-bg); padding-block: clamp(3rem, 6vw, 5rem); }
.e-contact__grid {
  display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: clamp(2rem, 4.5vw, 4rem); align-items: start;
}
.e-contact__info h2 {
  font-family: var(--font-display); font-size: clamp(1.7rem, 3vw, 2.3rem);
  font-weight: 600; line-height: 1.1; letter-spacing: -0.015em; margin-top: 0.9rem; max-width: 18ch;
}
.e-contact__lede { margin-top: 1.2rem; max-width: 50ch; color: var(--color-ink-soft); line-height: 1.72; }
.e-contact__actions { margin-top: 1.9rem; }
.e-contact__rows {
  margin-top: 2.2rem; display: flex; flex-direction: column; gap: 1.35rem;
  border-top: 1px solid rgba(30,32,35,0.12); padding-top: 1.9rem;
}
.e-crow { display: grid; grid-template-columns: 24px 1fr; gap: 0.9rem; align-items: start; }
.e-crow > svg { margin-top: 0.15rem; }
.e-crow__label { font-size: 0.68rem; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase; color: var(--color-ink-soft); }
.e-crow__value { margin-top: 0.25rem; font-size: 0.98rem; line-height: 1.55; color: var(--color-ink); }
.e-crow__value a { color: var(--color-accent); text-decoration: none; border-bottom: 1px solid rgba(164,96,13,0.5); }
.e-crow__value a:hover { border-bottom-color: var(--color-accent); }
.e-contact__note { margin-top: 1.9rem; font-size: 0.88rem; line-height: 1.62; color: var(--color-ink-soft); }
.e-contact__aside { position: relative; }
.e-contact__aside .e-photo { min-height: clamp(300px, 40vw, 460px); }
@media (max-width: 860px) { .e-contact__grid { grid-template-columns: 1fr; gap: 2.25rem; } }

/* ==========================================================================
   14. FORM — mockup form panel for the hero right column (CN-01 contact,
   INFO-01 labs quiz, LP-01 assessment guide). A light alabaster card that
   replaces the hero image in the phero's figure slot, so any page with a
   form surfaces it ABOVE THE FOLD. Real embed drops in at dev; the mockup
   is a fully-labelled static form (every input has a <label for>), so it
   passes axe and reads as the finished panel. NEW 2026-07-28.
   ========================================================================== */
.e-form {
  background: var(--color-surface);
  border: 1px solid rgba(30,32,35,0.10);
  border-radius: 14px;
  padding: clamp(1.5rem, 2.6vw, 2.1rem);
  box-shadow: 0 30px 70px -44px rgba(22,25,28,0.6);
  color: var(--color-ink);
}
.e-form__eyebrow {
  font-size: 0.72rem; letter-spacing: 0.11em; text-transform: uppercase;
  font-weight: 600; color: var(--color-ink-soft);
}
.e-form__title { font-family: var(--font-display); font-size: clamp(1.25rem, 2.2vw, 1.55rem);
  font-weight: 600; line-height: 1.25; margin-top: 0.5rem; color: var(--color-ink); }
.e-form__fields { display: grid; gap: 0.9rem; margin-top: 1.35rem; }
.e-form__row { display: grid; grid-template-columns: 1fr 1fr; gap: 0.9rem; }
.e-form__field { display: flex; flex-direction: column; gap: 0.35rem; }
.e-form__field label { font-size: 0.8rem; font-weight: 600; color: var(--color-ink); }
.e-form__field input, .e-form__field textarea, .e-form__field select {
  font-family: var(--font-body); font-size: 0.92rem; color: var(--color-ink);
  background: var(--color-bg);
  border: 1px solid rgba(30,32,35,0.22); border-radius: 8px;
  padding: 0.7rem 0.85rem; width: 100%;
  transition: border-color 0.2s var(--ease), box-shadow 0.2s var(--ease);
}
.e-form__field textarea { min-height: 5.5rem; resize: vertical; }
.e-form__field input:focus-visible, .e-form__field textarea:focus-visible, .e-form__field select:focus-visible {
  outline: none; border-color: var(--color-accent);
  box-shadow: 0 0 0 3px rgba(178,59,30,0.18);
}
.e-form .e-cta { margin-top: 1.35rem; width: 100%; justify-content: center; }
.e-form__note { margin-top: 1rem; font-size: 0.78rem; line-height: 1.6; color: var(--color-ink-soft); }
@media (max-width: 480px) { .e-form__row { grid-template-columns: 1fr; } }

/* Contact Form 7 output, styled into .e-form.
   CF7 wraps its <form> in <div class="wpcf7"> and wraps each generated control in
   <span class="wpcf7-form-control-wrap">. Neither is ours and neither should exist as
   a layout box, so both are collapsed with display:contents -- the wrapper keeps its
   markup for CF7's own JS while the grid in .e-form__fields / .e-form__row continues
   to see the fields as direct children. Safe for a11y: both carry no role to lose. */
.e-phero__figure > .wpcf7, .e-contact__grid > .wpcf7 { display: contents; }
.e-form__field > .wpcf7-form-control-wrap { display: contents; }

/* CF7's validation and response messaging, in the design's voice rather than its own. */
.e-form .wpcf7-not-valid-tip {
  margin-top: 0.3rem; font-size: 0.75rem; font-weight: 600; color: var(--color-brand);
}
.e-form__field input.wpcf7-not-valid, .e-form__field textarea.wpcf7-not-valid {
  border-color: var(--color-brand);
}
.e-form .wpcf7-response-output {
  margin: 1rem 0 0; padding: 0.7rem 0.85rem; border: 1px solid var(--color-rule);
  border-radius: 4px; font-size: 0.8rem; line-height: 1.55; color: var(--color-ink);
}
/* The spinner is inline-block by default and shifts the button; keep it out of flow. */
.e-form .wpcf7-spinner { position: absolute; opacity: 0; pointer-events: none; }

/* ==========================================================================
   15. JOURNAL — blog listing (RS-01). A featured latest article in the hero
   figure slot, an article-card grid below. Card = watermarked stock image +
   category/date meta + title + excerpt + Read link. Byline BLOCKED (no author
   name, per E360 constraints). NEW 2026-07-28.
   ========================================================================== */
.e-journal { background: var(--color-bg); padding-block: clamp(3rem, 6vw, 5rem); }
.e-journal__head { max-width: 60ch; }
.e-journal h2 { margin-top: 1rem; font-size: clamp(1.75rem, 3.2vw, 2.5rem); }
.e-journal__grid {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1.25rem, 2.4vw, 2rem);
  margin-top: clamp(2rem, 3.5vw, 3rem);
  list-style: none; padding: 0;
}
.e-postcard {
  display: flex; flex-direction: column;
  background: var(--color-surface);
  border: 1px solid rgba(30,32,35,0.11);
  border-radius: 12px; overflow: hidden;
  box-shadow: 0 18px 40px -34px rgba(22,25,28,0.5);
}
.e-postcard .e-photo { border: 0; border-radius: 0; }
.e-postcard .e-photo--stack .e-photo__media { height: clamp(170px, 16vw, 210px); }
.e-postcard__body { padding: clamp(1.15rem, 1.9vw, 1.5rem); display: flex; flex-direction: column; gap: 0.55rem; flex: 1; }
.e-postcard__meta { font-size: 0.72rem; letter-spacing: 0.07em; text-transform: uppercase; font-weight: 600; color: var(--color-ink-soft); }
.e-postcard__title { font-family: var(--font-display); font-size: 1.14rem; font-weight: 600; line-height: 1.32; }
.e-postcard__title a { color: var(--color-ink); text-decoration: none; }
.e-postcard__title a:hover { color: var(--color-accent); }
.e-postcard__excerpt { font-size: 0.92rem; line-height: 1.6; color: var(--color-ink-soft); }
.e-postcard__more { margin-top: auto; padding-top: 0.6rem; font-size: 0.86rem; }
/* The featured card lives inside the dark hero; reset its link off the on-dark
   inheritance so the accent link keeps contrast on the card's light surface. */
.e-postcard .e-link { color: var(--color-accent); text-decoration-color: var(--color-accent); }
/* Featured card in the hero figure slot: a light card lifted off the dark hero. */
.e-phero__figure > .e-postcard { box-shadow: 0 30px 70px -44px rgba(22,25,28,0.6); }
@media (max-width: 900px) { .e-journal__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .e-journal__grid { grid-template-columns: 1fr; } }

/* ===== BEGIN generated: webdd shared modules — build-theme-css.py ===== */
/* ============================================================================
 * WEBD module — interactive-card
 * Portable across every ACF client. Rendered per client by
 * scripts/acf/build-theme-css.py from the bindings in {client}/web-acf/theme-css.json.
 *
 * WHAT THIS OWNS (portable): the behaviour + accessibility contract.
 *   - the whole card is the click target, with NO markup change
 *   - hover and keyboard focus produce the SAME state
 *   - a card with no destination never pretends to have one
 *   - reduced motion is honoured
 *
 * WHAT THIS DOES NOT OWN (per client): the look. Colour, border, and background
 * changes are brand decisions and stay in the client's own stylesheet. This
 * module only moves and shadows the card, via --card-lift / --card-shadow.
 * That split is deliberate: Superior's cards slide a bronze border-left, E360's
 * lift off an alabaster field. One shared behaviour, two different looks.
 *
 * ---------------------------------------------------------------------------
 * WHY A STRETCHED LINK RATHER THAN WRAPPING THE CARD IN AN <a>
 *
 * Wrapping means editing markup, which for an ACF client means re-extracting
 * page-specs, recomposing, and redeploying content for a purely visual change.
 * It also swallows the card's heading, image alt, and body copy into one giant
 * link name, which is worse for screen readers, not better.
 *
 * The stretched link is pure CSS: an ::after on the card's existing routing
 * link, sized to the card. The accessibility tree is untouched — the link keeps
 * its own short, meaningful name ("Explore the panel"), and the card's heading
 * stays a heading. Cursor becomes a pointer across the card for free, because
 * the overlay IS the anchor.
 *
 * KNOWN TRADE-OFF: the overlay sits above the card's text, so text inside a
 * linked card can't be drag-selected. Accepted — the card is a navigation
 * target, not a copy source. If a specific card must stay selectable, don't
 * bind it; style its link instead.
 *
 * ---------------------------------------------------------------------------
 * THE HONESTY GATE — the reason this module exists
 *
 * Every rule below is behind :has(<link>). A card only reacts if it actually
 * contains a destination. This is not defensive coding, it is the bug that
 * prompted the module: E360 shipped 8 service cards on its home page that
 * tinted on hover while 7 of them contained no link at all. The card invited a
 * click and then ate it. Because the gate is structural, that class of bug
 * cannot be reintroduced by a content edit on any client — remove a card's link
 * and the affordance leaves with it, automatically.
 *
 * :has() is required (Chrome 105+, Safari 15.4+, Firefox 121+). On a browser
 * without it the card simply stays static, which is the safe direction to fail.
 *
 * THE LIFT USES `translate`, NOT `transform: translateY()`. This is not a style
 * preference. Scroll-reveal animations commonly animate `transform`, and a running
 * animation outranks every normal declaration in the cascade — so a transform-based
 * lift is silently swallowed on any card inside a reveal wrapper, with the card
 * still reporting a perfectly valid computed transform. `translate` is an
 * independent property, so the lift composes with the reveal instead of losing to
 * it. E360's cards sit inside .e-reveal and hit exactly this. Same browser era as
 * :has() (Chrome 104+, Safari 14.1+, Firefox 72+), so it costs no extra support.
 *
 * NOTE FOR ANYONE EDITING THE TEMPLATE: __CARD_HAS__ and __CARD_LINK__ are NOT
 * interchangeable. :has() takes a RELATIVE selector, evaluated against the card's
 * descendants, so a link bound as ".card--more > a" must appear inside :has() as
 * "> a". Written in full it would look for a nested ".card--more" and silently
 * match nothing — the module would appear to do absolutely nothing, with no
 * error anywhere. The builder derives __CARD_HAS__ for this reason.
 * ========================================================================= */

/* --- interactive-card: .e-service -> .e-service__go a --- */

/* The card is the positioning context the stretched overlay resolves against.
 *
 * Colour changes are declared per binding in theme-css.json (active_bg /
 * active_border) rather than written into the client stylesheet, so the :has()
 * gate exists in exactly ONE place. A client rule would have to restate the gate
 * to stay honest, and a restated gate is a gate that drifts. */
.e-service {
  position: relative;
  transition:
    translate        var(--card-duration, 260ms) var(--card-ease, cubic-bezier(0.2, 0.6, 0.2, 1)),
    box-shadow       var(--card-duration, 260ms) var(--card-ease, cubic-bezier(0.2, 0.6, 0.2, 1)),
    border-color     var(--card-duration, 260ms) var(--card-ease, cubic-bezier(0.2, 0.6, 0.2, 1)),
    background-color var(--card-duration, 260ms) var(--card-ease, cubic-bezier(0.2, 0.6, 0.2, 1));
  --card-lift: -3px;
  --card-shadow: 0 10px 22px -10px rgba(22,25,28,0.22);
}

/* Interactive content inside the card must sit ABOVE the overlay or the overlay
 * swallows its clicks. :where() keeps this at zero added specificity so a
 * client rule always wins, and so the card-link rule below outranks it without
 * depending on source order. */
.e-service :where(a, button, input, select, textarea, label, summary, [tabindex]) {
  position: relative;
  z-index: 2;
}

/* The card's own routing link is the exception: it must stay unpositioned so
 * its ::after resolves against the CARD, not against the link. */
.e-service__go a {
  position: static;
}

/* The stretched link itself. Invisible; it only extends the hit area.
 *
 * Deliberately NOT wrapped in :has() and NOT prefixed with the card selector.
 * This ::after hangs off the link, so the link's existence is already the gate —
 * no link, no overlay, nothing to guard. Prefixing the card here also breaks any
 * binding that already names the card (".card--more > a" became
 * ".card--more:has(> a) .card--more > a", which needs a card nested inside
 * itself and therefore matches nothing). Keep this selector flat. */
.e-service__go a::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}

/* focus-within, not just hover. Without it the affordance is mouse-only and a
 * keyboard user tabbing through a grid of cards gets no indication of where
 * they are beyond the link's own outline. The global :focus-visible outline
 * still fires on the link — this adds the card-level state around it. */
.e-service:has(.e-service__go a):hover,
.e-service:has(.e-service__go a):focus-within {
  translate: 0 var(--card-lift, -4px);
  box-shadow: var(--card-shadow, 0 22px 44px -30px rgba(22, 25, 28, 0.5));
  background-color: var(--color-surface);
}

@media (prefers-reduced-motion: reduce) {
  .e-service {
    transition: none;
  }
  .e-service:has(.e-service__go a):hover,
  .e-service:has(.e-service__go a):focus-within {
    translate: none;
  }
}


/* --- interactive-card: .e-service--more -> .e-service--more > a --- */

/* The card is the positioning context the stretched overlay resolves against.
 *
 * Colour changes are declared per binding in theme-css.json (active_bg /
 * active_border) rather than written into the client stylesheet, so the :has()
 * gate exists in exactly ONE place. A client rule would have to restate the gate
 * to stay honest, and a restated gate is a gate that drifts. */
.e-service--more {
  position: relative;
  transition:
    translate        var(--card-duration, 260ms) var(--card-ease, cubic-bezier(0.2, 0.6, 0.2, 1)),
    box-shadow       var(--card-duration, 260ms) var(--card-ease, cubic-bezier(0.2, 0.6, 0.2, 1)),
    border-color     var(--card-duration, 260ms) var(--card-ease, cubic-bezier(0.2, 0.6, 0.2, 1)),
    background-color var(--card-duration, 260ms) var(--card-ease, cubic-bezier(0.2, 0.6, 0.2, 1));
  --card-lift: -3px;
  --card-shadow: 0 10px 22px -10px rgba(22,25,28,0.22);
}

/* Interactive content inside the card must sit ABOVE the overlay or the overlay
 * swallows its clicks. :where() keeps this at zero added specificity so a
 * client rule always wins, and so the card-link rule below outranks it without
 * depending on source order. */
.e-service--more :where(a, button, input, select, textarea, label, summary, [tabindex]) {
  position: relative;
  z-index: 2;
}

/* The card's own routing link is the exception: it must stay unpositioned so
 * its ::after resolves against the CARD, not against the link. */
.e-service--more > a {
  position: static;
}

/* The stretched link itself. Invisible; it only extends the hit area.
 *
 * Deliberately NOT wrapped in :has() and NOT prefixed with the card selector.
 * This ::after hangs off the link, so the link's existence is already the gate —
 * no link, no overlay, nothing to guard. Prefixing the card here also breaks any
 * binding that already names the card (".card--more > a" became
 * ".card--more:has(> a) .card--more > a", which needs a card nested inside
 * itself and therefore matches nothing). Keep this selector flat. */
.e-service--more > a::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}

/* focus-within, not just hover. Without it the affordance is mouse-only and a
 * keyboard user tabbing through a grid of cards gets no indication of where
 * they are beyond the link's own outline. The global :focus-visible outline
 * still fires on the link — this adds the card-level state around it. */
.e-service--more:has(> a):hover,
.e-service--more:has(> a):focus-within {
  translate: 0 var(--card-lift, -4px);
  box-shadow: var(--card-shadow, 0 22px 44px -30px rgba(22, 25, 28, 0.5));
  background-color: var(--color-bg);
}

@media (prefers-reduced-motion: reduce) {
  .e-service--more {
    transition: none;
  }
  .e-service--more:has(> a):hover,
  .e-service--more:has(> a):focus-within {
    translate: none;
  }
}


/* --- interactive-card: .e-tier -> .e-tier__more a --- */

/* The card is the positioning context the stretched overlay resolves against.
 *
 * Colour changes are declared per binding in theme-css.json (active_bg /
 * active_border) rather than written into the client stylesheet, so the :has()
 * gate exists in exactly ONE place. A client rule would have to restate the gate
 * to stay honest, and a restated gate is a gate that drifts. */
.e-tier {
  position: relative;
  transition:
    translate        var(--card-duration, 260ms) var(--card-ease, cubic-bezier(0.2, 0.6, 0.2, 1)),
    box-shadow       var(--card-duration, 260ms) var(--card-ease, cubic-bezier(0.2, 0.6, 0.2, 1)),
    border-color     var(--card-duration, 260ms) var(--card-ease, cubic-bezier(0.2, 0.6, 0.2, 1)),
    background-color var(--card-duration, 260ms) var(--card-ease, cubic-bezier(0.2, 0.6, 0.2, 1));
  --card-lift: -4px;
  --card-shadow: 0 14px 28px -12px rgba(22,25,28,0.26);
}

/* Interactive content inside the card must sit ABOVE the overlay or the overlay
 * swallows its clicks. :where() keeps this at zero added specificity so a
 * client rule always wins, and so the card-link rule below outranks it without
 * depending on source order. */
.e-tier :where(a, button, input, select, textarea, label, summary, [tabindex]) {
  position: relative;
  z-index: 2;
}

/* The card's own routing link is the exception: it must stay unpositioned so
 * its ::after resolves against the CARD, not against the link. */
.e-tier__more a {
  position: static;
}

/* The stretched link itself. Invisible; it only extends the hit area.
 *
 * Deliberately NOT wrapped in :has() and NOT prefixed with the card selector.
 * This ::after hangs off the link, so the link's existence is already the gate —
 * no link, no overlay, nothing to guard. Prefixing the card here also breaks any
 * binding that already names the card (".card--more > a" became
 * ".card--more:has(> a) .card--more > a", which needs a card nested inside
 * itself and therefore matches nothing). Keep this selector flat. */
.e-tier__more a::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}

/* focus-within, not just hover. Without it the affordance is mouse-only and a
 * keyboard user tabbing through a grid of cards gets no indication of where
 * they are beyond the link's own outline. The global :focus-visible outline
 * still fires on the link — this adds the card-level state around it. */
.e-tier:has(.e-tier__more a):hover,
.e-tier:has(.e-tier__more a):focus-within {
  translate: 0 var(--card-lift, -4px);
  box-shadow: var(--card-shadow, 0 22px 44px -30px rgba(22, 25, 28, 0.5));
  border-color: rgba(178,59,30,0.45);
}

@media (prefers-reduced-motion: reduce) {
  .e-tier {
    transition: none;
  }
  .e-tier:has(.e-tier__more a):hover,
  .e-tier:has(.e-tier__more a):focus-within {
    translate: none;
  }
}


/* --- interactive-card: .e-postcard -> .e-postcard__title a --- */

/* The card is the positioning context the stretched overlay resolves against.
 *
 * Colour changes are declared per binding in theme-css.json (active_bg /
 * active_border) rather than written into the client stylesheet, so the :has()
 * gate exists in exactly ONE place. A client rule would have to restate the gate
 * to stay honest, and a restated gate is a gate that drifts. */
.e-postcard {
  position: relative;
  transition:
    translate        var(--card-duration, 260ms) var(--card-ease, cubic-bezier(0.2, 0.6, 0.2, 1)),
    box-shadow       var(--card-duration, 260ms) var(--card-ease, cubic-bezier(0.2, 0.6, 0.2, 1)),
    border-color     var(--card-duration, 260ms) var(--card-ease, cubic-bezier(0.2, 0.6, 0.2, 1)),
    background-color var(--card-duration, 260ms) var(--card-ease, cubic-bezier(0.2, 0.6, 0.2, 1));
  --card-lift: -4px;
  --card-shadow: 0 16px 32px -14px rgba(22,25,28,0.3);
}

/* Interactive content inside the card must sit ABOVE the overlay or the overlay
 * swallows its clicks. :where() keeps this at zero added specificity so a
 * client rule always wins, and so the card-link rule below outranks it without
 * depending on source order. */
.e-postcard :where(a, button, input, select, textarea, label, summary, [tabindex]) {
  position: relative;
  z-index: 2;
}

/* The card's own routing link is the exception: it must stay unpositioned so
 * its ::after resolves against the CARD, not against the link. */
.e-postcard__title a {
  position: static;
}

/* The stretched link itself. Invisible; it only extends the hit area.
 *
 * Deliberately NOT wrapped in :has() and NOT prefixed with the card selector.
 * This ::after hangs off the link, so the link's existence is already the gate —
 * no link, no overlay, nothing to guard. Prefixing the card here also breaks any
 * binding that already names the card (".card--more > a" became
 * ".card--more:has(> a) .card--more > a", which needs a card nested inside
 * itself and therefore matches nothing). Keep this selector flat. */
.e-postcard__title a::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}

/* focus-within, not just hover. Without it the affordance is mouse-only and a
 * keyboard user tabbing through a grid of cards gets no indication of where
 * they are beyond the link's own outline. The global :focus-visible outline
 * still fires on the link — this adds the card-level state around it. */
.e-postcard:has(.e-postcard__title a):hover,
.e-postcard:has(.e-postcard__title a):focus-within {
  translate: 0 var(--card-lift, -4px);
  box-shadow: var(--card-shadow, 0 22px 44px -30px rgba(22, 25, 28, 0.5));
  border-color: rgba(178,59,30,0.45);
}

@media (prefers-reduced-motion: reduce) {
  .e-postcard {
    transition: none;
  }
  .e-postcard:has(.e-postcard__title a):hover,
  .e-postcard:has(.e-postcard__title a):focus-within {
    translate: none;
  }
}

/* ===== END generated: webdd shared modules ===== */
