@import url("https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@500;600;700;800&family=Instrument+Sans:wght@400;500;600;700&display=swap");

/* ═══════════════════════════════════════════════════════════════════════════
   RetinaHub — collaboreyes.ca marketing site.
   ONE stylesheet. Page authors add markup, never CSS. If a page needs
   something this file does not have, the class belongs here, added once,
   named once, reused.

   The portal at app.collaboreyes.ca ships apps/web/src/app/globals.css. The
   token NAMES and the semantic VALUES here are deliberately the same, so a
   visitor crossing from the site into the app does not feel a seam. The site
   is warmer and softer than the app on purpose: the app is read for eight
   hours in a dim exam room, the site is read once, sceptically, in ninety
   seconds.

   Rules that are not negotiable, encoded here so they cannot be forgotten:
   - The logo cyan #20b0d0 is 2.57:1 on white. It is a MARK and GRADIENT
     colour. It is never text on a light ground. --rh-brand (#13697c, 6.29:1)
     is the text hue.
   - Nothing meant to be read is invisible at rest. Reveal is opt-in and only
     arms once JS has run; see .rh-rv.
   - Every token is declared in bare :root first, then overridden in the two
     dark blocks. Never define a colour only inside a media query.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 1. Tokens ─────────────────────────────────────────────────────────── */

:root {
  /* Type families. Display is the geometric voice; body is the portal's. */
  --rh-display: "Plus Jakarta Sans", "Instrument Sans", system-ui, -apple-system,
                "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --rh-sans: "Instrument Sans", system-ui, -apple-system, "Segoe UI", Roboto,
             "Helvetica Neue", Arial, sans-serif;

  /* Type scale. Fluid where it earns it, fixed where alignment matters. */
  --fs-display: clamp(2.5rem, 1.42rem + 3.6vw, 4.25rem);
  --fs-h1:      clamp(2.05rem, 1.5rem + 1.9vw, 3.1rem);
  --fs-h2:      clamp(1.6rem, 1.29rem + 1.05vw, 2.2rem);
  --fs-h3:      clamp(1.14rem, 1.07rem + 0.24vw, 1.32rem);
  --fs-h4:      1.02rem;
  --fs-lede:    clamp(1.06rem, 1.0rem + 0.32vw, 1.24rem);
  --fs-body:    1.0rem;
  --fs-sm:      0.905rem;
  --fs-xs:      0.815rem;
  --fs-2xs:     0.735rem;
  --fs-eyebrow: 0.72rem;

  --lh-tight: 1.06;
  --lh-head:  1.16;
  --lh-body:  1.62;

  /* Space scale. */
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px; --sp-5: 22px;
  --sp-6: 28px; --sp-7: 36px; --sp-8: 48px; --sp-9: 64px; --sp-10: 88px;
  --sp-section: clamp(56px, 6.4vw, 96px);

  /* Radius scale. 14–16px is the house radius; the reference is soft. */
  --r-xs: 6px;
  --r-sm: 10px;
  --r-md: 14px;
  --r-lg: 16px;
  --r-xl: 22px;
  --r-pill: 999px;

  /* Elevation. Always a pair: a near-transparent contact shadow that pins
     the card to the ground, and a wide ambient one that lifts it. The
     hairline border is the exception, not the rule. */
  --sh-1: 0 1px 2px rgb(9 34 45 / 5%),  0 6px 18px -10px rgb(9 34 45 / 14%);
  --sh-2: 0 1px 3px rgb(9 34 45 / 7%),  0 18px 40px -20px rgb(9 34 45 / 20%);
  --sh-3: 0 2px 6px rgb(9 34 45 / 8%),  0 34px 68px -28px rgb(9 34 45 / 26%);
  --sh-hero: 0 30px 80px -40px rgb(3 22 32 / 55%);

  /* Ground and surfaces. The page ground is a cool blue-white, never #fff:
     the white cards have to float on something. */
  --rh-ground:    #eef4f7;
  --rh-ground-2:  #e5edf1;
  --rh-surface:   #ffffff;
  --rh-surface-2: #f7fafb;
  --rh-surface-3: #e9f0f3;
  --rh-line:      #d6e1e5;
  --rh-line-soft: #e6edf0;

  /* Text. */
  --rh-ink:   #0d1c21;
  --rh-ink-2: #3a5058;
  --rh-muted: #566c73;   /* 5.00:1 on --rh-ground. The faintest readable text. */
  --rh-faint: #93a7ac;   /* rules, disabled glyphs, decoration. NEVER text. */

  /* Brand. */
  --rh-logo:        #20b0d0;  /* mark + gradient only */
  --rh-logo-grey:   #686870;
  --rh-brand:       #13697c;  /* 6.29:1 on white, 5.67:1 on --rh-ground */
  --rh-brand-hover: #0f5566;
  --rh-brand-ink:   #ffffff;
  --rh-brand-wash:  #dfeff4;
  --rh-brand-wash-2:#c9e4ed;
  --rh-focus:       #0f7d99;  /* 4.76:1 on white — a focus ring must be seen */

  /* Deep ground: hero, CTA band, footer. Drawn from the brand hue, pushed
     to navy. The lightest point of the gradient is #0f6376, which is 6.85:1
     against white; with the cyan glow composited on top it is 5.06:1. Both
     clear AA for the near-white text that crosses them. */
  --rh-deep:    #072330;
  --rh-deep-2:  #04202f;
  --rh-deep-ink:    #ffffff;
  --rh-deep-ink-2:  #cfe4ea;   /* 8.6:1 on --rh-deep */
  --rh-deep-line:   rgb(255 255 255 / 16%);
  --rh-gradient:
    radial-gradient(72rem 44rem at 82% 6%, rgb(32 176 208 / 16%), transparent 62%),
    linear-gradient(146deg, #04202f 0%, #073a4b 38%, #0d5468 68%, #0f6376 100%);
  /* Glass: over the gradient it shows the hue through; over the page ground
     below it stays dark enough that white text keeps 11:1. A strip that
     straddles the edge has to be legible on both sides of it. */
  --rh-glass:  linear-gradient(180deg, rgb(9 45 60 / 86%), rgb(4 26 38 / 93%));
  --rh-glass-line: rgb(255 255 255 / 18%);
  --rh-glass-ink:  #ffffff;
  --rh-glass-ink-2:#bcd6de;
  /* Text that sits directly on the gradient. Measured against the gradient's
     LIGHTEST point, #0f6376, which is the binding case:
       --rh-on-deep         white     6.85:1
       --rh-on-deep-2       #e6f2f6   6.00:1
       --rh-on-deep-accent  #96dff1   4.61:1
     The obvious pick for the accent was #8fdcef, sampled off the mark. It
     measures 4.45:1 there — fine for the display-size h1, a real AA failure
     for the 0.72rem eyebrow. Lightened until the small text passes too, so
     one token is safe at every size. Do not darken it back. */
  --rh-on-deep:        #ffffff;
  --rh-on-deep-2:      #e6f2f6;
  --rh-on-deep-accent: #96dff1;

  /* Semantic tints. Each is a strong hue for text and glyphs and a pale wash
     for the chip behind them. Status is never the brand hue: urgency must not
     look like a button. --rh-accent is the exception — it IS the brand, for
     the neutral "this is us" chip. */
  --rh-ok:      #1f6b45;  --rh-ok-wash:      #e2f0e8;
  --rh-info:    #0e5a86;  --rh-info-wash:    #e3eef7;
  --rh-soon:    #8a5a12;  --rh-soon-wash:    #fbf0dc;
  --rh-urgent:  #b3261e;  --rh-urgent-wash:  #fbe9e7;
  --rh-neutral: #47606a;  --rh-neutral-wash: #e8eef0;
  --rh-accent:  #13697c;  --rh-accent-wash:  #dfeff4;

  --rh-maxw: 1160px;
  --rh-maxw-narrow: 760px;
  --rh-gutter: clamp(20px, 4vw, 40px);
  /* Must match .rh-bar's min-height. The gradient hero pulls itself up by
     this amount so the sticky header floats over the gradient instead of
     sitting on the light ground above it. */
  --rh-header-h: 68px;

  color-scheme: light;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --rh-ground:    #070f12;
    --rh-ground-2:  #0b171b;
    --rh-surface:   #0e1c20;
    --rh-surface-2: #132428;
    --rh-surface-3: #1a2f34;
    --rh-line:      #24393e;
    --rh-line-soft: #1b2e33;

    --rh-ink:   #e7f0f1;
    --rh-ink-2: #b7c9cd;
    --rh-muted: #8aa0a6;
    --rh-faint: #5d757c;

    --rh-logo:        #20b0d0;
    --rh-logo-grey:   #9aa0a8;
    --rh-brand:       #57cbe5;
    --rh-brand-hover: #7ad6eb;
    --rh-brand-ink:   #052430;
    --rh-brand-wash:  #102c36;
    --rh-brand-wash-2:#16404e;
    --rh-focus:       #7ad6eb;

    --rh-deep:   #03151e;
    --rh-deep-2: #02101a;
    --rh-deep-ink-2: #c3dbe3;
    --rh-gradient:
      radial-gradient(72rem 44rem at 82% 6%, rgb(32 176 208 / 14%), transparent 62%),
      linear-gradient(146deg, #02131c 0%, #052c3a 40%, #084251 72%, #0a4e5f 100%);
    --rh-glass: linear-gradient(180deg, rgb(8 38 50 / 88%), rgb(3 20 29 / 94%));

    --rh-ok:      #77c496;  --rh-ok-wash:      #14291f;
    --rh-info:    #6fc0d8;  --rh-info-wash:    #10262e;
    --rh-soon:    #dcaf62;  --rh-soon-wash:    #2e2412;
    --rh-urgent:  #f29384;  --rh-urgent-wash:  #33191a;
    --rh-neutral: #9db2ba;  --rh-neutral-wash: #1c2c31;
    --rh-accent:  #57cbe5;  --rh-accent-wash:  #102c36;

    --sh-1: 0 1px 2px rgb(0 0 0 / 40%), 0 6px 18px -10px rgb(0 0 0 / 60%);
    --sh-2: 0 1px 3px rgb(0 0 0 / 46%), 0 18px 40px -20px rgb(0 0 0 / 70%);
    --sh-3: 0 2px 6px rgb(0 0 0 / 50%), 0 34px 68px -28px rgb(0 0 0 / 78%);
    --sh-hero: 0 30px 80px -40px rgb(0 0 0 / 80%);

    color-scheme: dark;
  }
}

:root[data-theme="dark"] {
  --rh-ground: #070f12; --rh-ground-2: #0b171b;
  --rh-surface: #0e1c20; --rh-surface-2: #132428; --rh-surface-3: #1a2f34;
  --rh-line: #24393e; --rh-line-soft: #1b2e33;
  --rh-ink: #e7f0f1; --rh-ink-2: #b7c9cd; --rh-muted: #8aa0a6; --rh-faint: #5d757c;
  --rh-logo: #20b0d0; --rh-logo-grey: #9aa0a8;
  --rh-brand: #57cbe5; --rh-brand-hover: #7ad6eb; --rh-brand-ink: #052430;
  --rh-brand-wash: #102c36; --rh-brand-wash-2: #16404e; --rh-focus: #7ad6eb;
  --rh-deep: #03151e; --rh-deep-2: #02101a; --rh-deep-ink-2: #c3dbe3;
  --rh-gradient:
    radial-gradient(72rem 44rem at 82% 6%, rgb(32 176 208 / 14%), transparent 62%),
    linear-gradient(146deg, #02131c 0%, #052c3a 40%, #084251 72%, #0a4e5f 100%);
  --rh-glass: linear-gradient(180deg, rgb(8 38 50 / 88%), rgb(3 20 29 / 94%));
  --rh-ok: #77c496; --rh-ok-wash: #14291f;
  --rh-info: #6fc0d8; --rh-info-wash: #10262e;
  --rh-soon: #dcaf62; --rh-soon-wash: #2e2412;
  --rh-urgent: #f29384; --rh-urgent-wash: #33191a;
  --rh-neutral: #9db2ba; --rh-neutral-wash: #1c2c31;
  --rh-accent: #57cbe5; --rh-accent-wash: #102c36;
  --sh-1: 0 1px 2px rgb(0 0 0 / 40%), 0 6px 18px -10px rgb(0 0 0 / 60%);
  --sh-2: 0 1px 3px rgb(0 0 0 / 46%), 0 18px 40px -20px rgb(0 0 0 / 70%);
  --sh-3: 0 2px 6px rgb(0 0 0 / 50%), 0 34px 68px -28px rgb(0 0 0 / 78%);
  --sh-hero: 0 30px 80px -40px rgb(0 0 0 / 80%);
  color-scheme: dark;
}

/* ── 2. Reset and base ─────────────────────────────────────────────────── */

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

html { scroll-behavior: smooth; scroll-padding-top: 84px; -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--rh-ground);
  color: var(--rh-ink);
  font-family: var(--rh-sans);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

h1, h2, h3, h4, h5 {
  font-family: var(--rh-display);
  font-weight: 700;
  letter-spacing: -0.022em;
  line-height: var(--lh-head);
  text-wrap: balance;
  margin: 0;
  color: var(--rh-ink);
}
h1 { font-size: var(--fs-h1); }
h2 { font-size: var(--fs-h2); }
h3 { font-size: var(--fs-h3); letter-spacing: -0.014em; }
h4 { font-size: var(--fs-h4); letter-spacing: -0.01em; }

p  { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }
ul, ol { margin: 0 0 1em; padding-left: 1.25em; }
img, svg, video { max-width: 100%; }
img { height: auto; }
strong, b { font-weight: 650; color: var(--rh-ink); }
hr { border: 0; border-top: 1px solid var(--rh-line); margin: var(--sp-7) 0; }
abbr[title] { text-decoration: underline dotted; text-underline-offset: 3px; cursor: help; }
button, input, select, textarea { font: inherit; color: inherit; }

a { color: var(--rh-brand); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--rh-brand-hover); }

/* Any digit a reader might compare lines up. */
.rh-num, .rh-stat .v, .rh-plan-price, .rh-table td, .rh-table th, .rh-figure-v {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

:focus-visible {
  outline: 2px solid var(--rh-focus);
  outline-offset: 3px;
  border-radius: 4px;
}

.rh-sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.rh-skip {
  position: absolute; left: 12px; top: -70px; z-index: 100;
  background: var(--rh-surface); color: var(--rh-brand);
  padding: .65rem 1rem; border-radius: var(--r-sm);
  box-shadow: var(--sh-2); font-weight: 600; text-decoration: none;
  transition: top .18s ease;
}
.rh-skip:focus { top: 12px; }

/* ── 3. Bilingual mechanism ────────────────────────────────────────────────
   Unchanged from the first build of this site, on purpose: every page that
   already exists uses it and the header toggle depends on it. French is the
   default presentation; English is the alternate. Charte de la langue
   française, and also simply correct for this audience.

   These three rules carry !important, which is deliberate and is the only
   place in this file that does. A bare [lang-en] selector scores (0,1,0) and
   loses to any component rule that styles a descendant element — `.rh-legend
   span` at (0,1,1) was enough to render French and English side by side in
   the loop diagram's legend. Page authors cannot edit this stylesheet and are
   not going to audit specificity against it, and showing both languages at
   once is a correctness failure rather than a cosmetic one, so this wins
   outright.

   The contract that makes !important safe: an element carrying lang-fr or
   lang-en is a PLAIN INLINE WRAPPER around text and never also carries a
   component class. Put the component on the outside, the pair inside:
     <span class="rh-badge"><span lang-fr>Envoi</span><span lang-en>Send</span></span>
   See DIRECTION.md.                                                         */

[lang-en] { display: none !important; }
html[data-lang="en"] [lang-fr] { display: none !important; }
html[data-lang="en"] [lang-en] { display: revert !important; }

/* ── 4. Layout ─────────────────────────────────────────────────────────── */

.rh-wrap { width: 100%; max-width: var(--rh-maxw); margin-inline: auto; padding-inline: var(--rh-gutter); }
.rh-wrap-narrow { width: 100%; max-width: var(--rh-maxw-narrow); margin-inline: auto; padding-inline: var(--rh-gutter); }

.rh-section { padding-block: var(--sp-section); position: relative; }
.rh-section-tint { background: var(--rh-ground-2); }
.rh-section-surface { background: var(--rh-surface); }
.rh-section-deep { background: var(--rh-deep); color: var(--rh-deep-ink); }
.rh-section-deep h2, .rh-section-deep h3 { color: var(--rh-deep-ink); }
.rh-section-tight { padding-block: clamp(36px, 4vw, 60px); }

/* Sections open the same way everywhere: eyebrow, heading, one paragraph. */
.rh-section-head { max-width: 62ch; margin-bottom: var(--sp-7); }
.rh-section-head.center { margin-inline: auto; text-align: center; }
.rh-section-head > h2 { margin-bottom: var(--sp-4); }
.rh-section-head > p { color: var(--rh-muted); font-size: var(--fs-lede); line-height: 1.55; }

.rh-eyebrow {
  display: inline-flex; align-items: center; gap: .5em;
  font-family: var(--rh-display);
  font-size: var(--fs-eyebrow); font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--rh-brand);
  margin: 0 0 var(--sp-4);
}
.rh-eyebrow::before {
  content: ""; width: 18px; height: 2px; border-radius: 2px;
  background: currentColor; opacity: .55; flex: none;
}
.rh-eyebrow.on-deep { color: var(--rh-on-deep-accent); }
.rh-eyebrow.plain::before { display: none; }

.rh-lede { font-size: var(--fs-lede); line-height: 1.55; color: var(--rh-muted); max-width: 60ch; }

/* A column of running text. Everything a person actually reads at length. */
.rh-prose { max-width: 68ch; color: var(--rh-ink-2); }
.rh-prose > * + * { margin-top: 1.05em; }
.rh-prose h2 { margin-top: 1.8em; }
.rh-prose h3 { margin-top: 1.6em; }
.rh-prose h2:first-child, .rh-prose h3:first-child { margin-top: 0; }
.rh-prose ul, .rh-prose ol { padding-left: 1.15em; }
.rh-prose li + li { margin-top: .4em; }
.rh-prose li::marker { color: var(--rh-brand); }
.rh-prose a { font-weight: 550; }

.rh-quote {
  font-family: var(--rh-display);
  font-weight: 500;
  font-size: clamp(1.16rem, 1.02rem + .6vw, 1.5rem);
  line-height: 1.44; letter-spacing: -.014em;
  color: var(--rh-ink);
  max-width: 46ch; margin: 0;
  padding-left: var(--sp-5);
  border-left: 3px solid var(--rh-brand);
}
.rh-quote cite { display: block; margin-top: .7em; font: 500 var(--fs-xs)/1.5 var(--rh-sans); font-style: normal; color: var(--rh-muted); }

.rh-stack   { display: flex; flex-direction: column; gap: var(--sp-4); }
.rh-row     { display: flex; flex-wrap: wrap; gap: var(--sp-3); align-items: center; }
.rh-center  { text-align: center; }
.rh-mt-6 { margin-top: var(--sp-6); }
.rh-mt-8 { margin-top: var(--sp-8); }

/* ── 5. Header ─────────────────────────────────────────────────────────── */

.rh-header {
  position: sticky; top: 0; z-index: 40;
  background: color-mix(in srgb, var(--rh-ground) 82%, transparent);
  backdrop-filter: blur(14px) saturate(1.4);
  -webkit-backdrop-filter: blur(14px) saturate(1.4);
  border-bottom: 1px solid transparent;
  transition: border-color .2s ease, box-shadow .2s ease, background .2s ease;
}
.rh-header.is-stuck {
  border-bottom-color: var(--rh-line-soft);
  box-shadow: 0 1px 0 rgb(9 34 45 / 3%), 0 12px 28px -22px rgb(9 34 45 / 30%);
}
/* Over a gradient hero the header starts transparent and inherits the light
   text, then flips to the normal light bar once the reader scrolls past. */
.rh-header.on-hero:not(.is-stuck) { background: transparent; }
.rh-header.on-hero:not(.is-stuck) .rh-nav-link,
.rh-header.on-hero:not(.is-stuck) .rh-iconbtn { color: var(--rh-on-deep-2); }
.rh-header.on-hero:not(.is-stuck) .rh-nav-link:hover,
.rh-header.on-hero:not(.is-stuck) .rh-iconbtn:hover { color: #fff; background: rgb(255 255 255 / 12%); }
.rh-header.on-hero:not(.is-stuck) .rh-iconbtn { border-color: rgb(255 255 255 / 24%); }
.rh-header.on-hero:not(.is-stuck) .rh-logo-img { filter: brightness(0) invert(1); }
/* The brand fill is too close to the gradient to read as a button while the
   bar is transparent, so the primary action borrows the on-deep treatment
   until the header lands on the light ground. */
.rh-header.on-hero:not(.is-stuck) .rh-btn-primary {
  background: #ffffff; color: #0b3644; border-color: #ffffff;
  box-shadow: 0 8px 24px -12px rgb(2 18 26 / 55%);
}
.rh-header.on-hero:not(.is-stuck) .rh-btn-primary:hover {
  background: #eaf6f9; border-color: #eaf6f9; color: #0b3644;
}

.rh-bar { display: flex; align-items: center; gap: var(--sp-5); min-height: 68px; }
.rh-logo { display: inline-flex; align-items: center; text-decoration: none; flex: none; }
.rh-logo-img { height: 30px; width: auto; display: block; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .rh-logo-img { filter: brightness(1.45) saturate(1.05); }
}
:root[data-theme="dark"] .rh-logo-img { filter: brightness(1.45) saturate(1.05); }

.rh-nav { display: flex; align-items: center; gap: 2px; margin-left: auto; }
.rh-nav-link {
  display: inline-flex; align-items: center; gap: .35em;
  padding: .48rem .68rem; border-radius: var(--r-sm);
  font-size: var(--fs-sm); font-weight: 550;
  color: var(--rh-ink-2); text-decoration: none;
  transition: background .16s ease, color .16s ease;
  white-space: nowrap;
}
.rh-nav-link:hover { background: var(--rh-surface-3); color: var(--rh-ink); }
.rh-nav-link[aria-current="page"] { color: var(--rh-brand); font-weight: 650; }
.rh-nav-actions { display: flex; align-items: center; gap: var(--sp-2); margin-left: var(--sp-4); }

.rh-iconbtn {
  display: inline-grid; place-items: center;
  height: 34px; min-width: 34px; padding: 0 .5rem;
  border-radius: var(--r-sm);
  border: 1px solid var(--rh-line);
  background: transparent; color: var(--rh-ink-2);
  font-size: var(--fs-2xs); font-weight: 700; letter-spacing: .06em;
  cursor: pointer;
  transition: background .16s ease, color .16s ease, border-color .16s ease;
}
.rh-iconbtn:hover { background: var(--rh-surface-3); color: var(--rh-ink); border-color: var(--rh-line); }
.rh-iconbtn svg { width: 17px; height: 17px; display: block; }

.rh-navtoggle { display: none; }
.rh-menu {
  border-top: 1px solid var(--rh-line-soft);
  background: var(--rh-surface);
  padding: var(--sp-3) 0 var(--sp-5);
}
.rh-menu[hidden] { display: none; }
.rh-menu .rh-wrap { display: flex; flex-direction: column; gap: 2px; }
.rh-menu .rh-nav-link { padding: .7rem .6rem; font-size: 1rem; }
.rh-menu .rh-btn { margin-top: var(--sp-3); justify-content: center; }

@media (max-width: 1000px) {
  .rh-nav { display: none; }
  .rh-navtoggle { display: inline-grid; }
  .rh-nav-actions { margin-left: auto; }
}
@media (min-width: 1001px) {
  .rh-menu { display: none !important; }
}
/* Below this the bar cannot hold logo + language + theme + CTA + toggle: the
   CTA was clipped by the viewport edge and the menu toggle pushed off-screen
   entirely. The CTA is the first thing inside the menu, so nothing is lost. */
@media (max-width: 560px) {
  .rh-nav-actions > .rh-btn { display: none; }
  .rh-bar { gap: var(--sp-3); }
  .rh-logo-img { height: 26px; }
}

/* ── 6. Buttons ────────────────────────────────────────────────────────── */

.rh-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  font-family: var(--rh-display);
  font-size: var(--fs-sm); font-weight: 650; letter-spacing: -.006em;
  padding: .68rem 1.15rem;
  border-radius: var(--r-sm);
  border: 1px solid transparent;
  text-decoration: none; white-space: nowrap; cursor: pointer;
  transition: background .16s ease, border-color .16s ease, color .16s ease, box-shadow .16s ease, transform .16s ease;
}
.rh-btn svg { width: 17px; height: 17px; flex: none; }
.rh-btn-lg { padding: .86rem 1.5rem; font-size: 1rem; border-radius: var(--r-md); }
.rh-btn-sm { padding: .4rem .75rem; font-size: var(--fs-xs); }

.rh-btn-primary { background: var(--rh-brand); color: var(--rh-brand-ink); border-color: var(--rh-brand); box-shadow: var(--sh-1); }
.rh-btn-primary:hover { background: var(--rh-brand-hover); border-color: var(--rh-brand-hover); color: var(--rh-brand-ink); box-shadow: var(--sh-2); transform: translateY(-1px); }

.rh-btn-ghost { background: var(--rh-surface); color: var(--rh-ink); border-color: var(--rh-line); }
.rh-btn-ghost:hover { background: var(--rh-surface-2); border-color: var(--rh-brand); color: var(--rh-brand); transform: translateY(-1px); }

.rh-btn-quiet { background: transparent; color: var(--rh-brand); border-color: transparent; }
.rh-btn-quiet:hover { background: var(--rh-brand-wash); color: var(--rh-brand-hover); }

/* On the gradient. White fill on deep ink is 12.9:1; the hairline ghost is
   62% white, which holds 3.25:1 against the brightest point it crosses. */
.rh-btn-on-deep { background: #ffffff; color: #0b3644; border-color: #ffffff; box-shadow: 0 10px 30px -12px rgb(2 18 26 / 55%); }
.rh-btn-on-deep:hover { background: #eaf6f9; border-color: #eaf6f9; color: #0b3644; transform: translateY(-1px); }
.rh-btn-on-deep-ghost { background: rgb(255 255 255 / 10%); color: #ffffff; border-color: rgb(255 255 255 / 62%); }
.rh-btn-on-deep-ghost:hover { background: rgb(255 255 255 / 18%); border-color: #ffffff; color: #ffffff; transform: translateY(-1px); }

.rh-btn[aria-disabled="true"], .rh-btn:disabled { opacity: .55; pointer-events: none; }

/* ── The "read on" link ────────────────────────────────────────────────────
   Ten pages that only link to each other from the header is a site that reads
   as ten leaflets. Every section with a deeper page ends with one of these,
   and it looks identical on all eleven, so following it feels like the same
   gesture every time. The chevron is drawn, not typed: an arrow glyph falls
   out of Plus Jakarta Sans into whatever the system has and lands crooked. */
.rh-more {
  display: inline-flex; align-items: center; gap: .5em;
  font-family: var(--rh-display);
  font-size: var(--fs-sm); font-weight: 650; letter-spacing: -.006em;
  color: var(--rh-brand); text-decoration: none;
  border-bottom: 1px solid color-mix(in srgb, var(--rh-brand) 32%, transparent);
  padding-bottom: 2px;
  transition: color .16s ease, border-color .16s ease;
}
.rh-more::after {
  content: ""; flex: none;
  width: 6px; height: 6px; margin-left: .05em;
  border-right: 1.9px solid currentColor; border-top: 1.9px solid currentColor;
  transform: rotate(45deg);
  transition: transform .16s ease;
}
.rh-more:hover { color: var(--rh-brand-hover); border-bottom-color: var(--rh-brand-hover); }
.rh-more:hover::after { transform: rotate(45deg) translate(2px, -2px); }
.rh-more.on-deep { color: var(--rh-on-deep-accent); border-bottom-color: rgb(255 255 255 / 36%); }
.rh-more.on-deep:hover { color: #fff; border-bottom-color: #fff; }
/* A row of them, when a section leads to two places. */
.rh-morerow { display: flex; flex-wrap: wrap; gap: var(--sp-4) var(--sp-7); align-items: center; }

/* The quiet "voir comment ça marche" play link. */
.rh-playlink {
  display: inline-flex; align-items: center; gap: .7rem;
  color: var(--rh-on-deep-2); text-decoration: none;
  font-size: var(--fs-sm); font-weight: 550;
  transition: color .16s ease;
}
.rh-playlink .disc {
  display: grid; place-items: center; flex: none;
  width: 38px; height: 38px; border-radius: 50%;
  border: 1px solid rgb(255 255 255 / 42%);
  background: rgb(255 255 255 / 10%);
  transition: background .16s ease, border-color .16s ease, transform .16s ease;
}
.rh-playlink .disc svg { width: 13px; height: 13px; margin-left: 2px; }
.rh-playlink:hover { color: #fff; }
.rh-playlink:hover .disc { background: rgb(255 255 255 / 22%); border-color: #fff; transform: scale(1.06); }
.rh-playlink.on-light { color: var(--rh-brand); }
.rh-playlink.on-light .disc { border-color: var(--rh-brand-wash-2); background: var(--rh-brand-wash); color: var(--rh-brand); }
.rh-playlink.on-light:hover .disc { background: var(--rh-brand-wash-2); }

/* ── 7. Hero ───────────────────────────────────────────────────────────────
   The gradient block owns everything down to --strip-bleed above its own
   bottom edge, so the stat strip's lower band sits on the page ground and
   genuinely straddles the seam. No magic padding on the next section.      */

.rh-hero {
  position: relative;
  background: var(--rh-ground);
  --strip-bleed: 54px;
  isolation: isolate;
  /* Slide up under the sticky header so the gradient runs edge to edge behind
     it; .rh-hero-inner adds the height back as padding. Without this the bar
     sits on the light page ground and its transparent on-hero state has
     nothing dark to be transparent against. */
  margin-top: calc(-1 * var(--rh-header-h));
}
.rh-hero::before {
  content: "";
  position: absolute; inset: 0 0 var(--strip-bleed) 0;
  background: var(--rh-gradient);
  z-index: 0;
}
/* A hair of extra darkness at the very bottom so the strip's top edge reads. */
.rh-hero::after {
  content: "";
  position: absolute; inset: auto 0 var(--strip-bleed) 0; height: 220px;
  background: linear-gradient(to top, rgb(2 16 24 / 34%), transparent);
  z-index: 0; pointer-events: none;
}
.rh-hero > * { position: relative; z-index: 1; }

.rh-hero-inner {
  display: grid;
  grid-template-columns: minmax(0, 1.02fr) minmax(0, 0.98fr);
  gap: clamp(28px, 4vw, 64px);
  align-items: center;
  padding-block: calc(var(--rh-header-h) + clamp(40px, 5vw, 72px)) clamp(40px, 5vw, 68px);
}
.rh-hero-copy { max-width: 34rem; }
.rh-hero h1 {
  font-size: var(--fs-display);
  line-height: var(--lh-tight);
  font-weight: 800;
  letter-spacing: -0.032em;
  color: var(--rh-on-deep);
  max-width: 16ch;
}
.rh-hero h1 .soft { color: var(--rh-on-deep-accent); font-weight: 700; }
.rh-hero-lede {
  font-size: var(--fs-lede);
  line-height: 1.58;
  color: var(--rh-on-deep-2);
  max-width: 46ch;
  margin: var(--sp-5) 0 var(--sp-7);
}
.rh-hero-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-4) var(--sp-5); }
/* Once the two buttons have stacked they must also match: two left-aligned
   pills of different widths read as a mistake, not a choice. The play link is
   not a button and keeps its natural width. */
@media (max-width: 560px) {
  .rh-hero-actions { align-items: stretch; }
  .rh-hero-actions > .rh-btn { width: 100%; }
  .rh-cta-actions { align-items: stretch; }
  .rh-cta-actions > .rh-btn { width: 100%; }
}
.rh-hero-note {
  margin-top: var(--sp-6);
  font-size: var(--fs-xs);
  color: var(--rh-on-deep-2);
  display: flex; align-items: flex-start; gap: .55em;
  max-width: 44ch;
}
.rh-hero-note svg { width: 15px; height: 15px; flex: none; margin-top: 3px; opacity: .85; }

.rh-hero-figure { position: relative; min-width: 0; }
/* overflow: hidden, not visible. The drop-shadow glow on the return arc is
   ink that escapes the element box when the SVG does not clip, and at 320px
   that pushed the document 2px wider than the viewport. Every shape in this
   figure — halos, code chip, labels — is inside the 0 0 600 600 viewBox with
   room to spare, and the glow's reach is well inside it too, so clipping
   costs the picture nothing. */
.rh-hero-figure svg { width: 100%; height: auto; display: block; overflow: hidden; }
/* A wide, very soft bloom behind the figure so it sits IN the gradient rather
   than on top of it. Purely atmospheric — nothing readable depends on it. */
.rh-hero-figure::before {
  content: "";
  position: absolute; inset: -12% -8% -8% -8%;
  background: radial-gradient(closest-side, rgb(32 176 208 / 20%), transparent 72%);
  z-index: -1; pointer-events: none;
}

@media (max-width: 900px) {
  .rh-hero-inner { grid-template-columns: 1fr; padding-block: calc(var(--rh-header-h) + clamp(28px, 6vw, 48px)) var(--sp-7); }
  .rh-hero-copy { max-width: none; }
  .rh-hero h1 { max-width: 18ch; }
  /* Copy first. This audience wants the claim before the picture, and the h1
     should not be the second thing on the page. */
  .rh-hero-figure { max-width: 440px; margin-inline: auto; margin-top: var(--sp-7); }
  /* Once the figure is centred and free to fill its column, the bloom's -8%
     horizontal inset reaches past the wrap's gutter and makes the document
     wider than the viewport — 2px of phantom horizontal scroll at 320px. The
     bloom is atmosphere, so it gives up its horizontal spread here and keeps
     its vertical one. */
  .rh-hero-figure::before { inset: -12% 0 -8% 0; }
  /* No straddle on narrow screens — the strip sits wholly inside the gradient,
     so the gradient needs its own floor under it or the strip is glued to the
     seam. */
  .rh-hero { --strip-bleed: 0px; padding-bottom: var(--sp-7); }
}

/* ── 8. Hero figure: the fundus and the loop ───────────────────────────────
   Concentric arcs for the retina, a vessel arcade radiating from the optic
   disc, and a bold ring cut into an outbound arc and a return arc that
   closes it. The figure has to be finished as it stands — there is no
   photograph coming to rescue it. */

/* The retinal ground. Without a body of its own the fundus is just linework
   floating on the gradient; this gives it the presence of an object that is
   lit from the upper left, the way a fundus photograph is. */
.rh-fundus .globe {
  fill: url(#rh-globe);
  stroke: rgb(255 255 255 / 10%);
  stroke-width: 1;
}
.rh-fundus .ring      { fill: none; stroke: rgb(255 255 255 / 18%); stroke-width: 1; }
.rh-fundus .ring-lit  { fill: none; stroke: rgb(127 227 245 / 38%); stroke-width: 1.2; }
.rh-fundus .ticks     { fill: none; stroke: rgb(255 255 255 / 26%); stroke-width: 9; }
.rh-fundus .ticks-maj { fill: none; stroke: rgb(255 255 255 / 40%); stroke-width: 16; }
/* The arcade is what makes this read as a fundus rather than a dark ball with
   a smudge on it, and it is drawn ON a near-black globe, so it needs real
   opacity. At 15% it measured as invisible in a screenshot at 1440 — the
   vessels vanished and the optic disc floated, connected to nothing.

   But the arcade must stay SUBORDINATE to the loop. Pushed to 50/72% it
   became a second ring competing with the referral arc, which is the one
   thing in this figure that has to be unmistakable. The settled hierarchy,
   brightest last: rings and ticks < vessels < lit vessels < optic disc <
   outbound arc < RETURN arc. Change one of these and check the whole ladder. */
.rh-fundus .vessel    { fill: none; stroke: rgb(206 235 245 / 40%); stroke-linecap: round; }
.rh-fundus .vessel-lit{ fill: none; stroke: rgb(150 223 241 / 55%); stroke-linecap: round; }
.rh-fundus .macula    { fill: rgb(2 22 32 / 38%); }
.rh-fundus .fovea     { fill: rgb(150 223 241 / 60%); }
/* The disc is the brightest thing inside the globe, as it is in a real fundus
   photograph, and every vessel radiates out of it. */
.rh-fundus .disc      { fill: rgb(170 230 245 / 46%); stroke: rgb(224 247 253 / 92%); stroke-width: 1.7; }
.rh-fundus .disc-core { fill: rgb(233 250 253 / 82%); }

/* ── The loop, and why the two arcs are not the same weight ───────────────
   The outbound trip is the easy half: any fax machine does it, so it is drawn
   as the thinner, quieter arc. The RETURN is the product, so it is the heavy,
   fully-saturated one with a glow, tagged with the printed return code.
   That difference has to survive the animation ending, JS never running, and
   reduced motion — the still figure must say "the return trip is the point"
   with nothing moving. Do not equalise these two rules. */
.rh-loop .arc-out  { fill: none; stroke: rgb(150 223 241 / 50%); stroke-width: 2.1; stroke-linecap: round; }
.rh-loop .arc-gap  { fill: none; stroke: rgb(255 255 255 / 26%); stroke-width: 3; stroke-linecap: round; stroke-dasharray: 2 12; }
.rh-loop .arc-back {
  fill: none; stroke: #7fe3f5; stroke-width: 5.4; stroke-linecap: round;
  filter: drop-shadow(0 0 9px rgb(64 205 232 / 62%));
}
.rh-loop .node     { fill: rgb(4 26 37 / 82%); stroke: #7fe3f5; stroke-width: 2; }
.rh-loop .node-g   { fill: none; stroke: rgb(230 247 251 / 92%); stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.rh-loop .node-halo{ fill: rgb(127 227 245 / 12%); }
.rh-loop .pkt      { fill: #b9f1fb; }
.rh-loop .pkt-halo { fill: rgb(127 227 245 / 28%); }
.rh-loop .node-dot { fill: rgb(230 247 251 / 92%); }
.rh-loop .code     { fill: rgb(4 26 37 / 88%); stroke: rgb(127 227 245 / 55%); stroke-width: 1.4; }
.rh-loop .code-bar { stroke: rgb(185 241 251 / 90%); stroke-width: 2.4; stroke-linecap: round; }
.rh-loop .lbl {
  fill: rgb(255 255 255 / 88%);
  font: 650 13px var(--rh-display);
  letter-spacing: .2em;
  text-transform: uppercase;
}

/* The arcs draw themselves once, then stop. Lengths are known: the viewBox is
   fixed, so π·244 = 766.5 user units per semicircle. No measuring needed.

   Gated on html.rh-js for the same reason .rh-rv is: an un-run script must
   never cost the reader the picture. Without the gate the ring is a pair of
   fully-offset dashes — i.e. nothing at all — and the hero is a gradient with
   a blob on it. Ungated, that is a blank figure for anyone with JS off, in a
   background tab, or behind a failed CDN. */
html.rh-js .rh-loop .arc-out,
html.rh-js .rh-loop .arc-back { stroke-dasharray: 767; stroke-dashoffset: 767; }
.rh-anim .arc-out  { animation: rh-draw 1.25s .35s cubic-bezier(.4,0,.25,1) forwards; }
.rh-anim .arc-back { animation: rh-draw 1.25s 1.75s cubic-bezier(.4,0,.25,1) forwards; }
.rh-anim .arc-gap  { animation: rh-fade .6s 1.8s ease forwards; }
@keyframes rh-draw { to { stroke-dashoffset: 0; } }
@keyframes rh-fade { to { opacity: 0; } }

/* Below this width the arc labels would render at ~7px. They are decoration
   at that size, and the figure's aria-label already carries the meaning. */
@media (max-width: 860px) { .rh-loop .lbl { display: none; } }

/* ── 9. Glass stat strip ───────────────────────────────────────────────── */

.rh-statstrip {
  position: relative; z-index: 2;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1px;
  background: var(--rh-glass-line);
  border: 1px solid var(--rh-glass-line);
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: var(--sh-hero), inset 0 1px 0 rgb(255 255 255 / 14%);
  backdrop-filter: blur(18px) saturate(1.5);
  -webkit-backdrop-filter: blur(18px) saturate(1.5);
  margin-bottom: 0;
}
.rh-statstrip > * { background: var(--rh-glass); }
.rh-stat { padding: var(--sp-5) var(--sp-5) var(--sp-5); display: flex; flex-direction: column; gap: .3rem; }
.rh-stat .v {
  font-family: var(--rh-display);
  font-size: clamp(1.7rem, 1.35rem + 1vw, 2.2rem);
  font-weight: 800; letter-spacing: -.035em; line-height: 1.05;
  color: var(--rh-glass-ink);
  display: flex; align-items: center; gap: .45rem;
}
.rh-stat .k { font-size: var(--fs-xs); line-height: 1.4; color: var(--rh-glass-ink-2); }
.rh-stat .d { font-size: var(--fs-2xs); color: var(--rh-glass-ink-2); opacity: .8; }

@media (max-width: 860px) {
  .rh-statstrip { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* Two-up survives 375px: the cell is ~150px, the value ~27px, the label wraps
   to three lines and the strip stays a strip. Going one-up here turns it into
   a 400px-tall column that pushes the whole argument below the fold. */
/* Two-up at 375px leaves ~123px of content width per cell. The display size
   has to come down or a short non-numeric value like AH‑745 overflows its
   cell rather than wrapping (it carries a non-breaking hyphen on purpose). */
@media (max-width: 460px) {
  .rh-stat { padding: var(--sp-4); }
  .rh-stat .v { font-size: 1.5rem; gap: .35rem; }
}
@media (max-width: 359px) {
  .rh-statstrip { grid-template-columns: 1fr; }
}

/* On a light section the same component reads as a card row. */
.rh-statstrip.on-light {
  background: var(--rh-line-soft);
  border-color: var(--rh-line-soft);
  box-shadow: var(--sh-2);
  backdrop-filter: none; -webkit-backdrop-filter: none;
}
.rh-statstrip.on-light > * { background: var(--rh-surface); }
.rh-statstrip.on-light .v { color: var(--rh-ink); }
.rh-statstrip.on-light .k, .rh-statstrip.on-light .d { color: var(--rh-muted); }

/* A tinted rounded-square chip beside a number, in the semantic hue. */
.rh-chip {
  display: inline-grid; place-items: center; flex: none;
  width: 1.55em; height: 1.55em;
  border-radius: .42em;
  background: var(--rh-accent-wash);
  color: var(--rh-accent);
  font-family: var(--rh-display);
  font-size: .5em; font-weight: 800; letter-spacing: 0;
  line-height: 1;
}
.rh-chip svg { width: 60%; height: 60%; }
.rh-chip-ok      { background: var(--rh-ok-wash);      color: var(--rh-ok); }
.rh-chip-info    { background: var(--rh-info-wash);    color: var(--rh-info); }
.rh-chip-soon    { background: var(--rh-soon-wash);    color: var(--rh-soon); }
.rh-chip-urgent  { background: var(--rh-urgent-wash);  color: var(--rh-urgent); }
.rh-chip-neutral { background: var(--rh-neutral-wash); color: var(--rh-neutral); }
.rh-chip-accent  { background: var(--rh-accent-wash);  color: var(--rh-accent); }
/* Inside the glass strip the pale washes would disappear; lift them. */
.rh-statstrip:not(.on-light) .rh-chip { background: rgb(127 227 245 / 16%); color: #a6e8f7; }

/* ── 10. Cards ─────────────────────────────────────────────────────────── */

.rh-card {
  background: var(--rh-surface);
  border-radius: var(--r-md);
  box-shadow: var(--sh-1);
  position: relative;
  overflow: hidden;
  transition: box-shadow .22s ease, transform .22s ease;
  /* A column so that when the grid stretches the card to the row height, the
     body takes the slack and the bottom padding stays even. Without this the
     card grows but its content stays glued to the top. */
  display: flex;
  flex-direction: column;
}
.rh-card-raised { box-shadow: var(--sh-2); }
.rh-card-bordered { border: 1px solid var(--rh-line-soft); }
.rh-card-tint { background: var(--rh-surface-2); }
.rh-card-body { padding: clamp(20px, 2.2vw, 28px); flex: 1 1 auto; }
.rh-card-body > h3 { margin-bottom: .5rem; }
.rh-card-body > p { color: var(--rh-muted); font-size: var(--fs-sm); }
.rh-card-body > p:last-child { margin-bottom: 0; }

a.rh-card, .rh-card-link { text-decoration: none; color: inherit; }
a.rh-card:hover, .rh-card-hover:hover { box-shadow: var(--sh-3); transform: translateY(-3px); }
a.rh-card:hover h3, .rh-card-hover:hover h3 { color: var(--rh-brand); }

.rh-card-meta {
  display: flex; align-items: center; flex-wrap: wrap; gap: .5rem;
  font-size: var(--fs-2xs); font-weight: 650;
  letter-spacing: .07em; text-transform: uppercase;
  color: var(--rh-muted);
  margin-bottom: .55rem;
}
.rh-card-meta .dot { width: 3px; height: 3px; border-radius: 50%; background: var(--rh-faint); }

/* The tinted icon area that sits on top of a card in the reference grid. */
.rh-card-icon {
  display: grid; place-items: center;
  aspect-ratio: 16 / 7;
  flex: none;
  background:
    radial-gradient(120% 140% at 20% 0%, var(--rh-brand-wash-2), transparent 68%),
    var(--rh-brand-wash);
  color: var(--rh-brand);
  border-bottom: 1px solid var(--rh-line-soft);
}
.rh-card-icon svg { width: 44px; height: 44px; }
.rh-card-icon.ok      { background: radial-gradient(120% 140% at 20% 0%, color-mix(in srgb, var(--rh-ok) 22%, transparent), transparent 68%), var(--rh-ok-wash); color: var(--rh-ok); }
.rh-card-icon.info    { background: radial-gradient(120% 140% at 20% 0%, color-mix(in srgb, var(--rh-info) 22%, transparent), transparent 68%), var(--rh-info-wash); color: var(--rh-info); }
.rh-card-icon.soon    { background: radial-gradient(120% 140% at 20% 0%, color-mix(in srgb, var(--rh-soon) 22%, transparent), transparent 68%), var(--rh-soon-wash); color: var(--rh-soon); }
.rh-card-icon.neutral { background: radial-gradient(120% 140% at 20% 0%, color-mix(in srgb, var(--rh-neutral) 20%, transparent), transparent 68%), var(--rh-neutral-wash); color: var(--rh-neutral); }

.rh-cardgrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 270px), 1fr));
  gap: clamp(16px, 2vw, 26px);
  /* Stretch, not start. A row of cards with ragged bottoms reads as a layout
     accident; equal heights read as a set, which is what a card grid is for.
     The card is a flex column so its body absorbs the extra height. */
  align-items: stretch;
}
.rh-cardgrid-2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr)); }
.rh-cardgrid-4 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 210px), 1fr)); }

/* ── 11. Feature row ───────────────────────────────────────────────────── */

.rh-featurerow {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(28px, 4vw, 64px);
  align-items: center;
}
.rh-featurerow + .rh-featurerow { margin-top: clamp(48px, 6vw, 88px); }
.rh-featurerow-alt > :first-child { order: 2; }
@media (max-width: 860px) {
  .rh-featurerow { grid-template-columns: 1fr; gap: var(--sp-6); }
  .rh-featurerow-alt > :first-child { order: 0; }
}

/* ── 12. Icon-led list ─────────────────────────────────────────────────── */

.rh-iconlist { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-5); }
.rh-iconlist > li { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--sp-4); align-items: start; }
.rh-iconlist h3 { font-size: var(--fs-h4); margin-bottom: .25rem; }
.rh-iconlist p  { color: var(--rh-muted); font-size: var(--fs-sm); margin: 0; }
.rh-icon {
  display: grid; place-items: center; flex: none;
  width: 40px; height: 40px; border-radius: var(--r-sm);
  background: var(--rh-brand-wash); color: var(--rh-brand);
}
.rh-icon svg { width: 21px; height: 21px; }
.rh-icon.ok      { background: var(--rh-ok-wash);      color: var(--rh-ok); }
.rh-icon.info    { background: var(--rh-info-wash);    color: var(--rh-info); }
.rh-icon.soon    { background: var(--rh-soon-wash);    color: var(--rh-soon); }
.rh-icon.urgent  { background: var(--rh-urgent-wash);  color: var(--rh-urgent); }
.rh-icon.neutral { background: var(--rh-neutral-wash); color: var(--rh-neutral); }
.rh-icon-lg { width: 52px; height: 52px; border-radius: var(--r-md); }
.rh-icon-lg svg { width: 27px; height: 27px; }

/* A plain bulleted list with the brand tick, for inside icon-led sections. */
.rh-checklist { list-style: none; margin: 0; padding: 0; display: grid; gap: .55rem; }
.rh-checklist > li {
  position: relative; padding-left: 1.7em;
  font-size: var(--fs-sm); color: var(--rh-ink-2);
}
.rh-checklist > li::before {
  content: ""; position: absolute; left: 0; top: .42em;
  width: 15px; height: 15px; border-radius: 4px;
  background: var(--rh-ok-wash);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--rh-ok) 28%, transparent);
}
.rh-checklist > li::after {
  content: ""; position: absolute; left: 4.5px; top: .72em;
  width: 6px; height: 3px;
  border-left: 1.8px solid var(--rh-ok); border-bottom: 1.8px solid var(--rh-ok);
  transform: rotate(-45deg);
}
.rh-checklist > li.no::before { background: var(--rh-neutral-wash); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--rh-neutral) 24%, transparent); }
.rh-checklist > li.no::after { left: 4px; top: .77em; width: 7px; height: 0; border-left: 0; border-bottom: 1.8px solid var(--rh-faint); transform: none; }
.rh-checklist > li.no { color: var(--rh-muted); }

/* ── 13. Step list ─────────────────────────────────────────────────────── */

.rh-steps { display: grid; gap: clamp(16px, 2vw, 24px); grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); counter-reset: rh-step; }
.rh-step {
  position: relative;
  background: var(--rh-surface);
  border-radius: var(--r-md);
  box-shadow: var(--sh-1);
  padding: clamp(20px, 2.2vw, 28px);
}
.rh-step-n {
  display: inline-grid; place-items: center;
  width: 38px; height: 38px; border-radius: var(--r-sm);
  background: var(--rh-brand); color: var(--rh-brand-ink);
  font-family: var(--rh-display); font-weight: 800; font-size: .95rem;
  font-variant-numeric: tabular-nums;
  margin-bottom: var(--sp-4);
}
.rh-step h3 { margin-bottom: .45rem; }
.rh-step p { color: var(--rh-muted); font-size: var(--fs-sm); margin: 0; }
/* The connector between steps, on wide screens only. */
@media (min-width: 861px) {
  .rh-steps.connected .rh-step:not(:last-child)::after {
    content: ""; position: absolute; top: calc(clamp(20px, 2.2vw, 28px) + 19px);
    right: calc(-1 * clamp(16px, 2vw, 24px)); width: clamp(16px, 2vw, 24px);
    border-top: 2px dashed var(--rh-line);
  }
}

/* ── 14. Pricing ───────────────────────────────────────────────────────── */

.rh-plans { display: grid; gap: clamp(18px, 2vw, 26px); grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); align-items: start; }
.rh-plan {
  background: var(--rh-surface);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-1);
  padding: clamp(22px, 2.4vw, 30px);
  display: flex; flex-direction: column; gap: var(--sp-4);
  height: 100%;
}
.rh-plan-featured {
  box-shadow: var(--sh-3);
  outline: 2px solid var(--rh-brand);
  outline-offset: -2px;
}
.rh-plan-flag {
  align-self: flex-start;
  font-size: var(--fs-2xs); font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  background: var(--rh-brand); color: var(--rh-brand-ink);
  border-radius: var(--r-pill); padding: .28em .8em;
}
.rh-plan h3 { font-size: 1.2rem; }
.rh-plan-price {
  font-family: var(--rh-display);
  font-size: clamp(2rem, 1.6rem + 1.4vw, 2.6rem);
  font-weight: 800; letter-spacing: -.04em; line-height: 1;
  color: var(--rh-ink);
}
.rh-plan-price small { font-size: .38em; font-weight: 600; letter-spacing: 0; color: var(--rh-muted); }
.rh-plan-per { font-size: var(--fs-xs); color: var(--rh-muted); margin: -.5rem 0 0; }
/* The button, not the list, takes up the slack. Pushing the checklist down
   aligned the buttons across the row but opened a 167px void under the short
   plan's price — the list has to sit with the price it belongs to. */
.rh-plan .rh-checklist { padding-top: var(--sp-2); }
.rh-plan .rh-btn { width: 100%; margin-top: auto; }
.rh-plan-note { font-size: var(--fs-2xs); color: var(--rh-muted); }

/* ── 15. Tables ────────────────────────────────────────────────────────── */

.rh-tablewrap {
  overflow-x: auto;
  background: var(--rh-surface);
  border-radius: var(--r-md);
  box-shadow: var(--sh-1);
  -webkit-overflow-scrolling: touch;
}
.rh-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: var(--fs-sm); min-width: 560px; }
.rh-table caption { caption-side: top; text-align: left; padding: var(--sp-4) var(--sp-5) 0; font-size: var(--fs-xs); color: var(--rh-muted); }
.rh-table th, .rh-table td { padding: .78rem 1rem; text-align: left; vertical-align: top; }
.rh-table thead th {
  font-family: var(--rh-display);
  font-size: var(--fs-2xs); font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--rh-ink-2);
  background: var(--rh-surface-2);
  border-bottom: 1px solid var(--rh-line);
  white-space: nowrap;
}
.rh-table tbody td { border-bottom: 1px solid var(--rh-line-soft); color: var(--rh-ink-2); }
.rh-table tbody tr:last-child td { border-bottom: 0; }
.rh-table tbody th { border-bottom: 1px solid var(--rh-line-soft); font-weight: 650; color: var(--rh-ink); }
.rh-table tbody tr:last-child th { border-bottom: 0; }
.rh-table tbody tr:hover td, .rh-table tbody tr:hover th { background: var(--rh-surface-2); }
.rh-table .num { text-align: right; }
.rh-table .center { text-align: center; }
.rh-table col.hl, .rh-table .hl { background: var(--rh-brand-wash); }
.rh-yes { color: var(--rh-ok); font-weight: 700; }
.rh-no  { color: var(--rh-faint); }

/* ── 16. Profile / detail layout ───────────────────────────────────────── */

/* stretch, not start. The banner carries a name, a credential line and one
   paragraph; the portrait beside it is a 3/4 slot 400px tall. Left to size
   itself the banner ended a third of the way down and opened a 250px hole
   next to the picture on every persona on pour-qui.html. Stretched, with its
   contents optically centred, the pair reads as one object. */
.rh-profile {
  display: grid;
  grid-template-columns: minmax(0, 300px) minmax(0, 1fr);
  gap: clamp(20px, 3vw, 40px);
  align-items: stretch;
}
.rh-profile-portrait {
  background: var(--rh-surface);
  border-radius: var(--r-md);
  box-shadow: var(--sh-2);
  overflow: hidden;
  position: relative;
}
.rh-profile-portrait .rh-slot { border-radius: 0; box-shadow: none; }
.rh-profile-ribbon {
  background: var(--rh-brand); color: var(--rh-brand-ink);
  padding: .72rem 1rem;
  font-family: var(--rh-display); font-size: var(--fs-xs); font-weight: 650;
  display: flex; align-items: center; justify-content: space-between; gap: .6rem;
}
.rh-profile-ribbon.ok      { background: var(--rh-ok); color: #fff; }
.rh-profile-ribbon.info    { background: var(--rh-info); color: #fff; }
.rh-profile-ribbon.neutral { background: var(--rh-neutral); color: #fff; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .rh-profile-ribbon.ok,
  :root:not([data-theme="light"]) .rh-profile-ribbon.info,
  :root:not([data-theme="light"]) .rh-profile-ribbon.neutral { color: #061a1f; }
}
:root[data-theme="dark"] .rh-profile-ribbon.ok,
:root[data-theme="dark"] .rh-profile-ribbon.info,
:root[data-theme="dark"] .rh-profile-ribbon.neutral { color: #061a1f; }

.rh-profile-banner {
  background:
    radial-gradient(120% 180% at 8% 0%, var(--rh-brand-wash-2), transparent 62%),
    var(--rh-brand-wash);
  border-radius: var(--r-md);
  padding: clamp(20px, 2.6vw, 32px);
  box-shadow: var(--sh-1);
  display: flex; flex-direction: column; justify-content: center;
}
.rh-profile-banner h1, .rh-profile-banner h2, .rh-profile-banner h3 { margin-bottom: .5rem; }
.rh-profile-banner > p { max-width: 58ch; }
.rh-credential {
  display: flex; flex-wrap: wrap; gap: .45rem .8rem;
  font-size: var(--fs-sm); color: var(--rh-ink-2); margin: 0;
}
.rh-credential .sep { color: var(--rh-faint); }
/* The credential line is a caption for the name above it, not the opening of
   the paragraph below it. Without this they ran together as one block. */
.rh-credential + p { margin-top: var(--sp-5); }

.rh-profile-body { display: grid; gap: clamp(24px, 3vw, 38px); margin-top: clamp(24px, 3vw, 36px); }
.rh-profile-body section > h2, .rh-profile-body > section > h2 { font-size: var(--fs-h3); }
/* A heading over a list needs air under it, and a hairline that says where the
   group starts — the icon tiles are strong enough that without one the heading
   floats between two lists and belongs to neither. */
.rh-profile-body > section > h3 {
  margin-bottom: var(--sp-5);
  padding-bottom: var(--sp-3);
  border-bottom: 1px solid var(--rh-line-soft);
}
/* Beneath a profile the icon list has the full 1160px column to itself, which
   puts a 40px icon in front of a 150-character line. Two up brings the measure
   back to something a person reads instead of scans. */
.rh-profile-body .rh-iconlist {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 420px), 1fr));
  column-gap: clamp(24px, 3vw, 44px);
}
@media (max-width: 780px) {
  .rh-profile { grid-template-columns: 1fr; }
  .rh-profile-portrait { max-width: 320px; }
  .rh-profile-banner { justify-content: flex-start; }
}

/* ── 17. Pill filter row ───────────────────────────────────────────────── */

.rh-pills { display: flex; flex-wrap: wrap; gap: .5rem; margin: 0; padding: 0; list-style: none; }
.rh-pill {
  display: inline-flex; align-items: center; gap: .45em;
  padding: .44rem .95rem;
  border-radius: var(--r-pill);
  border: 1px solid var(--rh-line);
  background: var(--rh-surface);
  color: var(--rh-ink-2);
  font-size: var(--fs-xs); font-weight: 600;
  cursor: pointer; white-space: nowrap;
  transition: background .16s ease, color .16s ease, border-color .16s ease, box-shadow .16s ease;
}
.rh-pill:hover { border-color: var(--rh-brand); color: var(--rh-brand); }
.rh-pill[aria-pressed="true"], .rh-pill.is-active {
  background: var(--rh-brand); border-color: var(--rh-brand); color: var(--rh-brand-ink);
  box-shadow: var(--sh-1);
}
.rh-pill .n { font-variant-numeric: tabular-nums; opacity: .7; font-weight: 700; }
.rh-filter-empty { color: var(--rh-muted); font-size: var(--fs-sm); padding: var(--sp-6) 0; }
.rh-filter-empty[hidden] { display: none; }

/* ── 18. Breadcrumb ────────────────────────────────────────────────────── */

.rh-crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; margin: 0 0 var(--sp-5); padding: 0; list-style: none; font-size: var(--fs-xs); }
.rh-crumbs li { display: flex; align-items: center; gap: .4rem; color: var(--rh-muted); }
.rh-crumbs li + li::before { content: "/"; color: var(--rh-faint); }
.rh-crumbs a { color: var(--rh-muted); text-decoration: none; }
.rh-crumbs a:hover { color: var(--rh-brand); text-decoration: underline; }
.rh-crumbs [aria-current="page"] { color: var(--rh-ink); font-weight: 600; }

/* A short banner at the top of an inner page, above the breadcrumb line. */
.rh-pagehead { background: var(--rh-ground-2); padding-block: clamp(24px, 3.5vw, 44px) clamp(28px, 4vw, 52px); border-bottom: 1px solid var(--rh-line-soft); }
.rh-pagehead h1 { max-width: 22ch; }
.rh-pagehead p { color: var(--rh-muted); font-size: var(--fs-lede); max-width: 58ch; margin-top: var(--sp-4); }

/* ── 19. Tabs ──────────────────────────────────────────────────────────── */

.rh-tabs { display: flex; flex-wrap: wrap; gap: .25rem; border-bottom: 1px solid var(--rh-line); margin-bottom: var(--sp-6); }
.rh-tab {
  appearance: none; background: transparent; border: 0;
  border-bottom: 2px solid transparent;
  padding: .65rem .9rem; margin-bottom: -1px;
  font-family: var(--rh-display); font-size: var(--fs-sm); font-weight: 650;
  color: var(--rh-muted); cursor: pointer;
  transition: color .16s ease, border-color .16s ease;
}
.rh-tab:hover { color: var(--rh-ink); }
.rh-tab[aria-selected="true"] { color: var(--rh-brand); border-bottom-color: var(--rh-brand); }
.rh-tabpanel[hidden] { display: none; }

/* ── 20. FAQ disclosure ────────────────────────────────────────────────── */

.rh-faq { display: grid; gap: var(--sp-3); max-width: 78ch; }
.rh-faq-item {
  background: var(--rh-surface);
  border-radius: var(--r-md);
  box-shadow: var(--sh-1);
  overflow: hidden;
}
.rh-faq-item > summary {
  display: flex; align-items: flex-start; gap: var(--sp-4);
  padding: var(--sp-5);
  cursor: pointer; list-style: none;
  font-family: var(--rh-display); font-weight: 650; font-size: 1.02rem;
  color: var(--rh-ink);
  transition: color .16s ease;
}
.rh-faq-item > summary::-webkit-details-marker { display: none; }
.rh-faq-item > summary:hover { color: var(--rh-brand); }
.rh-faq-item > summary::after {
  content: ""; flex: none; margin-left: auto; margin-top: .34em;
  width: 9px; height: 9px;
  border-right: 2px solid var(--rh-brand); border-bottom: 2px solid var(--rh-brand);
  transform: rotate(45deg); transform-origin: 60% 60%;
  transition: transform .22s ease;
}
.rh-faq-item[open] > summary::after { transform: rotate(-135deg); }
.rh-faq-answer { padding: 0 var(--sp-5) var(--sp-5); color: var(--rh-ink-2); font-size: var(--fs-sm); max-width: 68ch; }
.rh-faq-answer > p:first-child { margin-top: 0; }

/* ── 21. Callout ───────────────────────────────────────────────────────── */

.rh-callout {
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--sp-4);
  padding: var(--sp-5);
  border-radius: var(--r-md);
  background: var(--rh-accent-wash);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--rh-accent) 18%, transparent);
  color: var(--rh-ink-2);
  font-size: var(--fs-sm);
}
.rh-callout h3 { font-size: var(--fs-h4); margin-bottom: .3rem; color: var(--rh-ink); }
.rh-callout p:last-child { margin-bottom: 0; }
.rh-callout .rh-icon { background: color-mix(in srgb, var(--rh-accent) 16%, transparent); color: var(--rh-accent); }
.rh-callout-ok      { background: var(--rh-ok-wash);      box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--rh-ok) 20%, transparent); }
.rh-callout-ok .rh-icon      { background: color-mix(in srgb, var(--rh-ok) 16%, transparent); color: var(--rh-ok); }
.rh-callout-info    { background: var(--rh-info-wash);    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--rh-info) 20%, transparent); }
.rh-callout-info .rh-icon    { background: color-mix(in srgb, var(--rh-info) 16%, transparent); color: var(--rh-info); }
.rh-callout-soon    { background: var(--rh-soon-wash);    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--rh-soon) 22%, transparent); }
.rh-callout-soon .rh-icon    { background: color-mix(in srgb, var(--rh-soon) 18%, transparent); color: var(--rh-soon); }
.rh-callout-urgent  { background: var(--rh-urgent-wash);  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--rh-urgent) 22%, transparent); }
.rh-callout-urgent .rh-icon  { background: color-mix(in srgb, var(--rh-urgent) 16%, transparent); color: var(--rh-urgent); }
.rh-callout-neutral { background: var(--rh-neutral-wash); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--rh-neutral) 20%, transparent); }
.rh-callout-neutral .rh-icon { background: color-mix(in srgb, var(--rh-neutral) 16%, transparent); color: var(--rh-neutral); }

/* ── 22. Badge ─────────────────────────────────────────────────────────── */

.rh-badge {
  display: inline-flex; align-items: center; gap: .32rem;
  font-family: var(--rh-display);
  font-size: var(--fs-2xs); font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  padding: .22em .6em; border-radius: var(--r-xs);
  border: 1px solid transparent; white-space: nowrap;
  background: var(--rh-accent-wash); color: var(--rh-accent);
  border-color: color-mix(in srgb, var(--rh-accent) 28%, transparent);
}
.rh-badge::before { font-size: .82em; line-height: 1; }
.rh-badge-ok      { background: var(--rh-ok-wash);      color: var(--rh-ok);      border-color: color-mix(in srgb, var(--rh-ok) 30%, transparent); }
.rh-badge-ok::before { content: "\2713"; }
.rh-badge-info    { background: var(--rh-info-wash);    color: var(--rh-info);    border-color: color-mix(in srgb, var(--rh-info) 30%, transparent); }
.rh-badge-info::before { content: "\25CB"; }
.rh-badge-soon    { background: var(--rh-soon-wash);    color: var(--rh-soon);    border-color: color-mix(in srgb, var(--rh-soon) 32%, transparent); }
.rh-badge-soon::before { content: "\25C6"; }
.rh-badge-urgent  { background: var(--rh-urgent-wash);  color: var(--rh-urgent);  border-color: color-mix(in srgb, var(--rh-urgent) 32%, transparent); }
.rh-badge-urgent::before { content: "\25B2"; }
.rh-badge-neutral { background: var(--rh-neutral-wash); color: var(--rh-neutral); border-color: color-mix(in srgb, var(--rh-neutral) 30%, transparent); }
.rh-badge-neutral::before { content: "\25CF"; }
.rh-badge-plain::before { content: none; }
.rh-badge-on-deep { background: rgb(255 255 255 / 12%); color: #ffffff; border-color: rgb(255 255 255 / 34%); }
.rh-badge-on-deep::before { content: none; }

/* ── 23. Forms ─────────────────────────────────────────────────────────── */

.rh-form { display: grid; gap: var(--sp-5); }
.rh-form-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr)); gap: var(--sp-5); }
.rh-field { display: grid; gap: .35rem; }
.rh-label { font-size: var(--fs-xs); font-weight: 650; color: var(--rh-ink-2); }
.rh-label .req { color: var(--rh-urgent); margin-left: .2em; }
.rh-input, .rh-select, .rh-textarea {
  width: 100%;
  border: 1px solid var(--rh-line);
  border-radius: var(--r-sm);
  padding: .62rem .8rem;
  background: var(--rh-surface);
  color: var(--rh-ink);
  transition: border-color .14s ease, box-shadow .14s ease;
}
.rh-textarea { min-height: 8rem; resize: vertical; }
.rh-select { appearance: none; padding-right: 2.2rem;
  background-image: linear-gradient(45deg, transparent 50%, var(--rh-muted) 50%), linear-gradient(135deg, var(--rh-muted) 50%, transparent 50%);
  background-position: calc(100% - 18px) 52%, calc(100% - 12px) 52%;
  background-size: 6px 6px, 6px 6px; background-repeat: no-repeat; }
.rh-input:focus, .rh-select:focus, .rh-textarea:focus {
  outline: none; border-color: var(--rh-focus);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--rh-focus) 22%, transparent);
}
.rh-input::placeholder, .rh-textarea::placeholder { color: var(--rh-muted); opacity: 1; }
.rh-hint { font-size: var(--fs-2xs); color: var(--rh-muted); }
.rh-error { font-size: var(--fs-2xs); font-weight: 600; color: var(--rh-urgent); display: flex; align-items: center; gap: .35em; }
.rh-error::before { content: "\25B2"; font-size: .85em; }
.rh-field[data-invalid] .rh-input,
.rh-field[data-invalid] .rh-select,
.rh-field[data-invalid] .rh-textarea { border-color: var(--rh-urgent); }
.rh-field[data-invalid] .rh-input:focus { box-shadow: 0 0 0 3px color-mix(in srgb, var(--rh-urgent) 20%, transparent); }
.rh-check { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: .6rem; align-items: start; font-size: var(--fs-sm); color: var(--rh-ink-2); }
.rh-check input { margin-top: .3rem; accent-color: var(--rh-brand); width: 16px; height: 16px; }

/* ── 24. Image slot ────────────────────────────────────────────────────────
   We have no licensed photography. Every image position is therefore a real,
   designed slot at the correct ratio, with a placeholder that looks intended.
   Drop the file in as <img> inside the slot and the placeholder gets out of
   the way. See README.md for the slot table.                                */

.rh-slot {
  position: relative;
  aspect-ratio: var(--ratio, 16 / 10);
  border-radius: var(--r-md);
  overflow: hidden;
  background:
    radial-gradient(120% 120% at 22% 12%, var(--rh-brand-wash-2), transparent 62%),
    var(--rh-brand-wash);
  box-shadow: var(--sh-1);
  display: grid; place-items: center;
  isolation: isolate;
}
.rh-slot > img { width: 100%; height: 100%; object-fit: cover; display: block; grid-area: 1 / 1; z-index: 2; }
/* A fine dotted field, so the empty slot reads as a designed surface. */
.rh-slot::before {
  content: ""; position: absolute; inset: 0; z-index: 0;
  background-image: radial-gradient(circle at 1px 1px, color-mix(in srgb, var(--rh-brand) 26%, transparent) 1px, transparent 0);
  background-size: 14px 14px;
  opacity: .5;
  mask-image: radial-gradient(120% 100% at 50% 50%, #000 20%, transparent 78%);
}
.rh-slot::after {
  content: ""; position: absolute; inset: 0; z-index: 1;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--rh-brand) 16%, transparent);
  border-radius: inherit; pointer-events: none;
}
.rh-slot:has(img)::before { display: none; }
.rh-slot-mark { position: relative; z-index: 1; display: grid; justify-items: center; gap: .5rem; color: var(--rh-brand); text-align: center; padding: var(--sp-4); }
.rh-slot-mark svg { width: 40px; height: 40px; opacity: .55; }
.rh-slot-mark span { font-size: var(--fs-2xs); font-weight: 650; letter-spacing: .1em; text-transform: uppercase; opacity: .8; }
.rh-slot:has(img) .rh-slot-mark { display: none; }
.rh-slot-caption { font-size: var(--fs-2xs); color: var(--rh-muted); margin-top: .6rem; }
.rh-slot-portrait { --ratio: 3 / 4; }
.rh-slot-wide     { --ratio: 16 / 9; }
.rh-slot-square   { --ratio: 1 / 1; }
.rh-slot-banner   { --ratio: 21 / 9; }

/* ── 25. Loop diagram (section-scale) ──────────────────────────────────────
   The best idea on the old site, redrawn in the new language: it now lives on
   a white card instead of a hairline box.                                   */

.rh-diagram { background: var(--rh-surface); border-radius: var(--r-lg); box-shadow: var(--sh-2); padding: clamp(20px, 2.6vw, 34px); }
.rh-diagram svg { width: 100%; height: auto; display: block; overflow: visible; }

/* Below ~760px the 880-unit viewBox scales down far enough that the labels
   inside it render at 5px and the diagram becomes a decorative squiggle. The
   figure is the argument, so it keeps its real size and scrolls sideways
   inside its own card — the same idiom .rh-tablewrap already uses, and the
   only place on this site where sideways scrolling is allowed. The page
   itself must never scroll horizontally. */
/* Only shown once the diagram is actually scrollable — so the base rule has
   to come FIRST, or it wins the cascade over the media query and the hint
   never appears. */
.rh-diagram-hint {
  display: none;
  margin-top: var(--sp-3);
  font-size: var(--fs-2xs);
  color: var(--rh-muted);
}
@media (max-width: 760px) {
  .rh-diagram-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    margin-inline: calc(-1 * clamp(20px, 2.6vw, 34px));
    padding-inline: clamp(20px, 2.6vw, 34px);
  }
  .rh-diagram-scroll > svg { min-width: 700px; }
  .rh-diagram-hint { display: block; }
}
.rh-diagram-head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: var(--sp-4); margin-bottom: var(--sp-5); }
.rh-diagram-head h3 { font-size: var(--fs-2xs); font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--rh-muted); }
.rh-legend { display: flex; flex-wrap: wrap; gap: var(--sp-4); font-size: var(--fs-xs); color: var(--rh-muted); }
/* Direct children only. A descendant selector here also caught the inner
   lang-fr / lang-en wrappers and forced them visible. */
.rh-legend > span { display: inline-flex; align-items: center; gap: .5em; }
.rh-legend i { width: 20px; height: 0; border-top: 2.5px solid var(--rh-brand); display: inline-block; }
.rh-legend .lost i { border-top-style: dashed; border-top-color: var(--rh-faint); }

.rh-dg .box       { fill: var(--rh-surface-2); stroke: var(--rh-line); stroke-width: 1.25; }
.rh-dg .box-chip  { fill: var(--rh-brand-wash); }
.rh-dg .box-g     { fill: none; stroke: var(--rh-brand); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.rh-dg .t-name    { fill: var(--rh-ink); font: 650 15px var(--rh-display); }
.rh-dg .t-sub     { fill: var(--rh-muted); font: 400 12px var(--rh-sans); }
.rh-dg .t-path    { fill: var(--rh-muted); font: 550 12px var(--rh-sans); }
.rh-dg .t-path-hot{ fill: var(--rh-brand); font: 650 12px var(--rh-sans); }
.rh-dg .pill      { fill: var(--rh-surface); stroke: var(--rh-line-soft); stroke-width: 1; }
.rh-dg .pill-hot  { fill: var(--rh-brand-wash); stroke: color-mix(in srgb, var(--rh-brand) 30%, transparent); stroke-width: 1; }
.rh-dg .flow      { fill: none; stroke: var(--rh-brand); stroke-width: 2.5; stroke-linecap: round; }
/* .flow-back was declared in the dash-animation rules below but never given a
   paint, so it inherited fill:black and rendered as a solid blob across the
   middle of the diagram. An SVG path with no explicit fill is filled. */
.rh-dg .flow-back { fill: none; stroke: var(--rh-brand); stroke-width: 2.5; stroke-linecap: round; }
/* The dashed return — "what is lost everywhere else" — is drawn on the SAME
   geometry as the solid one, so left where it is, the solid arc covers it
   exactly and the legend advertises a line the reader cannot see. Lifting it
   into the empty band between the two arcs makes the contrast the point of
   the whole diagram: one return trip that stops being drawn, one that closes.
   It must NOT fade out — at rest, with no JS and under reduced motion, the
   comparison is the only thing the picture is for. */
.rh-dg .flow-lost {
  fill: none; stroke: var(--rh-faint); stroke-width: 2.5;
  stroke-linecap: round; stroke-dasharray: 7 7;
  transform: translateY(-19px);
  /* The path runs right-to-left, consultant back to optometrist. Fading it
     out toward the left means the lost return trip visibly peters out before
     it arrives, instead of landing like the real one and being told apart
     only by an arrowhead. If a browser ignores the mask the line simply draws
     in full, which is the old behaviour and still readable. */
  -webkit-mask-image: linear-gradient(to left, #000 40%, rgb(0 0 0 / 40%) 64%, transparent 82%);
          mask-image: linear-gradient(to left, #000 40%, rgb(0 0 0 / 40%) 64%, transparent 82%);
  /* no-repeat is load-bearing. The mask box is the path's fill box, which
     excludes the stroke, so the round line cap at the far end sticks out past
     it — and with the default mask-repeat:repeat the gradient tiles, putting
     an OPAQUE sliver of the next tile right on that cap. The result was one
     orphan dash floating beside the optometrist box. */
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
}
.rh-dg .head      { fill: var(--rh-brand); }
.rh-dg .pkt       { fill: var(--rh-brand); }
/* The printed return code, shown riding out on the referral. Light-ground
   twin of .rh-loop .code, which is drawn for the dark hero. */
.rh-dg .code      { fill: var(--rh-surface); stroke: color-mix(in srgb, var(--rh-brand) 36%, transparent); stroke-width: 1.2; }
.rh-dg .code-bar  { stroke: var(--rh-brand); stroke-width: 2.2; stroke-linecap: round; }
html.rh-js .rh-dg .flow,
html.rh-js .rh-dg .flow-back { stroke-dasharray: var(--len, 600); stroke-dashoffset: var(--len, 600); }
.rh-anim .rh-dg .flow      { animation: rh-draw 1.15s .2s cubic-bezier(.4,0,.3,1) forwards; }
.rh-anim .rh-dg .flow-back { animation: rh-draw 1.15s 1.6s cubic-bezier(.4,0,.3,1) forwards; }
/* .flow-lost deliberately has no fade-out; see the note on the rule above. */

/* ── 26. Footer ────────────────────────────────────────────────────────── */

.rh-footer { background: var(--rh-deep); color: var(--rh-deep-ink-2); padding-block: clamp(44px, 5vw, 68px) var(--sp-7); font-size: var(--fs-sm); }
/* The brand column needs a real floor. With minmax(0, 1.5fr) the auto-fit
   link columns claimed everything they could and squeezed the blurb down to
   one word per line at tablet widths. */
.rh-footer-grid {
  display: grid;
  grid-template-columns: minmax(240px, 1.6fr) repeat(auto-fit, minmax(140px, 1fr));
  gap: clamp(24px, 3vw, 48px);
}
@media (max-width: 720px) {
  .rh-footer-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .rh-footer-grid > :first-child { grid-column: 1 / -1; }
}
@media (max-width: 420px) {
  .rh-footer-grid { grid-template-columns: 1fr; }
}
.rh-footer h2 { font-family: var(--rh-display); font-size: var(--fs-2xs); font-weight: 700; letter-spacing: .11em; text-transform: uppercase; color: #ffffff; margin-bottom: var(--sp-4); }
.rh-footer-col { display: flex; flex-direction: column; gap: .55rem; align-items: flex-start; }
.rh-footer a { color: var(--rh-deep-ink-2); text-decoration: none; transition: color .16s ease; }
.rh-footer a:hover { color: #ffffff; text-decoration: underline; text-underline-offset: 3px; }
.rh-footer .rh-logo-img { height: 26px; filter: brightness(0) invert(1); opacity: .95; }
.rh-footer-blurb { max-width: 34ch; margin-top: var(--sp-4); color: var(--rh-deep-ink-2); }
.rh-footer-bottom {
  display: flex; flex-wrap: wrap; gap: var(--sp-4); align-items: baseline;
  margin-top: clamp(32px, 4vw, 52px); padding-top: var(--sp-5);
  border-top: 1px solid var(--rh-deep-line);
  font-size: var(--fs-xs);
}
.rh-footer-bottom .push { margin-left: auto; }

/* ── 27. CTA band ──────────────────────────────────────────────────────── */

.rh-cta {
  position: relative; isolation: isolate;
  background: var(--rh-gradient);
  color: var(--rh-on-deep);
  padding-block: clamp(48px, 6vw, 84px);
  overflow: hidden;
}
.rh-cta h2 { color: var(--rh-on-deep); max-width: 20ch; }
.rh-cta p { color: var(--rh-on-deep-2); max-width: 52ch; font-size: var(--fs-lede); }
.rh-cta-inner { display: grid; grid-template-columns: minmax(0, 1.2fr) auto; gap: clamp(24px, 4vw, 56px); align-items: center; }
@media (max-width: 820px) { .rh-cta-inner { grid-template-columns: 1fr; } }
.rh-cta-actions { display: flex; flex-wrap: wrap; gap: var(--sp-3); }

/* ── 28. Reveal ────────────────────────────────────────────────────────────
   Opt-in. .rh-rv does nothing until site.js puts .rh-js on <html>, so a
   reader with JS off, a headless screenshot, a background tab, or a broken
   observer sees a complete page. site.js also runs a 2.5s safety net that
   reveals everything unconditionally. This page has shipped with invisible
   content once; it will not do it again.                                    */

.rh-rv { transition: opacity .6s cubic-bezier(.2,.7,.3,1), transform .6s cubic-bezier(.2,.7,.3,1); }
html.rh-js .rh-rv { opacity: 0; transform: translateY(16px); }
html.rh-js .rh-rv.is-in { opacity: 1; transform: none; }
.rh-rv-d1 { transition-delay: .07s; }
.rh-rv-d2 { transition-delay: .14s; }
.rh-rv-d3 { transition-delay: .21s; }
.rh-rv-d4 { transition-delay: .28s; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  html.rh-js .rh-rv, html.rh-js .rh-rv.is-in { opacity: 1; transform: none; transition: none; }
  /* These carry html.rh-js so they outrank the gated hidden state above.
     Drop the prefix and the arcs stay at full dashoffset — invisible — for
     every reader who asked for less motion. */
  html.rh-js .rh-loop .arc-out,
  html.rh-js .rh-loop .arc-back { stroke-dashoffset: 0; animation: none; }
  .rh-loop .arc-gap { display: none; }
  .rh-loop .pkt, .rh-loop .pkt-halo, .rh-dg .pkt { display: none; }
  html.rh-js .rh-dg .flow,
  html.rh-js .rh-dg .flow-back { stroke-dashoffset: 0; animation: none; }
  .rh-dg .flow-lost { display: none; }
  .rh-btn:hover, a.rh-card:hover, .rh-card-hover:hover, .rh-playlink:hover .disc { transform: none; }
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
}

/* ── 29. Print ─────────────────────────────────────────────────────────── */

@media print {
  html { color-scheme: light; }
  body { background: #fff; color: #000; font-size: 11pt; }
  .rh-header, .rh-menu, .rh-cta, .rh-skip, .rh-playlink { display: none !important; }
  .rh-hero::before, .rh-hero::after { display: none; }
  .rh-hero h1, .rh-hero-lede, .rh-hero-note { color: #000; }
  .rh-card, .rh-plan, .rh-step, .rh-diagram, .rh-tablewrap { box-shadow: none; border: 1px solid #999; }
  .rh-statstrip { background: none; }
  .rh-statstrip > * { background: none; }
  .rh-stat .v, .rh-stat .k { color: #000; }
  .rh-footer { background: none; color: #000; }
  .rh-faq-item[open] .rh-faq-answer, .rh-faq-answer { display: block; }
  .rh-faq-item > summary::after { display: none; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; color: #444; }
}
