/*
 * RAVL 2026 — THE FOUNDATIONS. Tokens, type, buttons, cards, icons, the section shell, the global
 * navigation and the global footer. PR26-743.
 *
 * WHY THIS FILE EXISTS
 *
 * All of this was written inside `home-2026.css` while the home page was the only page in the new
 * design (PR26-744). It is split out here unchanged, because every other website epic — /join,
 * /membership, /how-it-works, /safety, /events, /about, /articles, /links — depends on this epic
 * and none of them can load a stylesheet named after the home page. The split is a MOVE: no rule
 * below was altered by it, and the home page loads this file and then `home-2026.css`, in that
 * order, so its cascade is what it was.
 *
 * Everything here is namespaced `rv-`, and `styles.css` — which still dresses /about, /join,
 * /events, /articles, /safety, /beta, /profile and /offer in the pre-2026 design — is untouched.
 * When the last of those pages is rebuilt, `styles.css` can go and this becomes the only sheet.
 *
 * WHAT BELONGS IN HERE, AND WHAT DOES NOT
 *
 * A rule belongs here if a second page would want it. `.rv-band`, `.rv-btn`, `.rv-card` and the
 * nav are foundations; `.rv-hero__ghost` at `left: 24px; top: 258px` is a home page composition
 * and lives in `home-2026.css`. When a page needs a variant, add a modifier here rather than
 * copying the block into the page's own sheet — a second copy is a second thing to keep in step.
 *
 * THE PALETTE IS TOKENS ONLY. No hex literal appears below outside the `:root` block, with two
 * deliberate exceptions, both marked: white-on-accent SVG strokes and the ink-ground footer's
 * rgba() text ramp, which is an alpha over --foot rather than a colour of its own.
 */

/* ============================================================ TOKENS — PR26-755 */
:root {
    /* Grounds. */
    --page: #FFFFFF;
    --paper: #F7F9FB;
    --fog: #EDFAF7;

    /* Text and line. */
    --ink: #14171C;
    --body: #4C545F;
    --subtle: #6B7480;
    --line: #E7EBF0;

    /* The ACTION colour. CTAs and one highlighted phrase per headline. Never decorative.
       (It also drew the chapter numerals, until those were removed — see below.)

       `--accent` #0077C8 and `--ravl-blue` #11AAFF (in styles.css) are NOT the same blue and must
       never be unified. #11AAFF is the decorative swatch blue and is 2.0:1 on white — it cannot
       carry text at all. Conflating the two is the confusion behind PR26-675. */
    --accent: #0077C8;

    /* Ghost words. TWO values, not one. `--ghost` on the mint band is a difference of about four
       parts in 255 — an invisible word. Anything sitting on `--fog` uses `--ghost-on-fog`. */
    --ghost: #E4F5F0;
    --ghost-on-fog: #D5EFE7;

    /* Card tints. FILLS ONLY — none of the four pastels passes contrast for readable text or a
       functional icon. */
    --tint-1: #F0F3FE;
    --tint-2: #FDF1EC;
    --tint-3: #E7FAF4;

    /* THE TEXT-SAFE PARTNERS, and the two findings that make them load-bearing here rather than
       theoretical. Both were measured, not guessed — see the table below.

       1. `--accent` #0077C8 IS NOT A TEXT COLOUR ANYWHERE EXCEPT PURE WHITE. It is 4.70:1 on
          --page and fails AA on every other ground the design uses: 4.45 on paper, 4.39 on fog,
          4.33 on mint, 4.24 on peach and periwinkle. Large text (>=24px, or >=18.66px bold) only
          needs 3:1, so every accent-tinted HEADLINE is fine and stays blue. The small-text uses
          are not, and they take the same-hue partner of the ground they sit on. This is the same
          finding as PR26-675 and as the ravl-web-app link-colour decision.

       2. `--subtle` #6B7480 is 4.74:1 on white and fails on everything else — 4.49 on paper (the
          flow strip), 4.27-4.37 on the three tints (the testimonial company names).
          `--subtle-on-tint` is the same grey four steps darker, which is the smallest change that
          clears 4.5:1 on all six grounds and is not perceptibly a different colour. PR26-755 could
          reasonably fold this value back into `--subtle` and delete this token. */
    --on-tint-1: #2F3E9E;      /* periwinkle partner — 8.23:1 on its own tint */
    --on-tint-2: #A04E31;      /* peach partner      — 5.23:1 */
    --on-tint-3: #0E6B58;      /* mint partner       — 5.94:1, and 6.01:1 on --fog */
    --subtle-on-tint: #67707C; /* >=4.53:1 on page, paper, fog and all three tints */

    /* TEXT LINKS ARE NOT THE ACTION COLOUR. `--accent` is 4.70:1 on white and fails on every other
       ground the design uses, so a link coloured with it passes review on whichever page it was
       drawn on first and fails on the next. The periwinkle partner is 9.12:1 on white and 8.64:1
       on paper, which holds everywhere. Same decision as `ravl-web-app`'s Decision Log row 12,
       28 Aug 2026 — there it is enforced by `test/tokens.test.js`; here there is no suite, so it
       is enforced by there being one token and one rule. It is an alias rather than a second hex
       so the two can never drift apart. */
    --link: var(--on-tint-1);

    /* PR26-787. THE HOW IT WORKS HERO'S RENDER EXPORTS ON #FAFAFA, not pure white, and under the
       image-decides-the-ground rule (PR26-760) the band has to match the artwork or the image's
       rectangle edge shows as a hard straight line across the full width. 250 against 255 is
       subtle and it is still a seam.

       THIS IS A ONE-RENDER TOKEN. DO NOT REACH FOR IT AS A GENERAL BACKGROUND — four near-whites
       on one site is one too many, and this is the fourth. It exists to be deleted: re-export
       that render on the mint #EDFAF7 (best — the hero returns to mint and mint brackets the page
       again) or on pure #FFFFFF, and this token goes with it. */
    --ash: #FAFAFA;

    --foot: #14171C;

    /* Radii: 12 controls / 16-20 cards / 26 large cards / 999 pills.
       PR26-762: the 16 in "16-20 cards" had no token. The layer plate is the card type that uses
       it, and it is a different shape from `.rv-card` rather than a smaller one - 76px tall, one
       line, no body copy - so it gets its own name rather than a second value on --r-card. */
    --r-control: 12px;
    --r-plate: 16px;
    --r-card: 20px;
    --r-large: 26px;
    --r-pill: 999px;

    /* Grid. Design width 1440, page margin 100, content column 1240. The margin collapses on the
       way down; the column is what stops the page stretching on a 27in display. */
    --margin: 100px;
    --column: 1240px;

    /* Height of the fixed nav, so anchors and the hero can both reason about it. */
    --nav-h: 96px;
}

/* ============================================================ RESET
   Scoped to this page's three roots rather than a bare `*`, so it cannot reach anything the old
   sheet owns. It duplicates the reset at the top of `styles.css` on purpose: this sheet is
   currently loaded alongside that one, but the whole point of namespacing was that the home page
   could eventually stop loading 67KB of CSS for six other pages, and it cannot do that while it
   silently depends on a reset defined over there. */
.rv, .rv *, .rv *::before, .rv *::after,
.rv-nav, .rv-nav *, .rv-nav *::before, .rv-nav *::after,
.rv-foot, .rv-foot *, .rv-foot *::before, .rv-foot *::after {
    box-sizing: border-box;
}

/* `:where()` is not decoration — it zeroes the specificity of everything inside it. Written as a
   plain descendant selector, `.rv p` is (0,1,1) and out-ranks every (0,1,0) component class below,
   so `margin: 0` here silently beat `.rv-body--centred { margin-inline: auto }` and un-centred the
   section 04 lede. A reset must never be able to win an argument with the rules it is resetting
   for. */
:where(.rv, .rv-nav, .rv-foot) :where(h1, h2, h3, p, ul, ol, li, blockquote, figure) {
    margin: 0;
    padding: 0;
}

:where(.rv, .rv-nav, .rv-foot) :where(ul, ol) { list-style: none; }

/* ============================================================ TYPE — PR26-756
   One face, `aktiv-grotesk` via Typekit, already loaded by `headelements.hbs`. The mockups use
   Onest and Inter because those are what a mockup can load; they are not the shipping faces.
   Display weight is 600 throughout — 700 exists in the family but sets the headlines too heavy
   against this much white. */
.rv {
    font-family: "aktiv-grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    color: var(--ink);
    background: var(--page);
    /* styles.css sets `line-height: 1.6` on body; every block below states its own. */
    line-height: 1.6;
}

.rv-h1,
.rv-h2 {
    margin: 0;
    font-weight: 600;
    color: var(--ink);
    text-wrap: balance;
}

.rv-h1 { font-size: 76px; line-height: 0.94; letter-spacing: -0.038em; }
.rv-h2 { font-size: 62px; line-height: 1.0;  letter-spacing: -0.035em; }

/* THE SIGNATURE MOVE. Every headline ends on a short phrase in the action colour and a full stop.
   It only works as the LAST phrase and never more than four words, so it is applied per headline
   in the template rather than by a rule that could catch anything else. */
.rv-accent { color: var(--accent); }

.rv-body {
    margin: 0;
    font-size: 16.5px;
    line-height: 1.8;
    color: var(--body);
}

.rv-body--centred {
    max-width: 820px;
    margin-inline: auto;
    text-align: center;
}

/* The two sentences in section 05 that carry the argument. */
.rv-lift { color: var(--ink); font-weight: 500; }

/* ============================================================ CHAPTER MARKERS — REMOVED
   `01 —— SECTION NAME` sat above every headline. All six went on 2 Sep 2026, Andy's call, and the
   rules that drew them went with them rather than being left as dead CSS — PR26-760 still
   specifies them, and that part of the ticket is superseded.

   TWO CONSEQUENCES worth knowing before anything else here is changed:

   1. The hairline rule at the top of each band is now the ONLY thing separating one white section
      from the next. It was load-bearing before and it is the whole structure now.
   2. It also removed the page's only failing contrast case that could not be fixed without a
      visible change: the `06` numeral on the mint band was --accent at 4.39:1, which fails AA at
      11px, and had been moved onto the mint text-safe partner. That deviation is gone with the
      element. `--on-tint-3` is still used, by the mint testimonial card. */

/* ============================================================ GHOST WORD — PR26-760
   Enormous background wordmark. Decoration; it never carries information, and only two survive on
   this page — TONIGHT in the hero and JOIN in the closing band. Both sit BEHIND THE HEADLINE ROW,
   never behind an image: the renders are opaque white and swallow anything under them.

   It must not force horizontal scroll, hence `overflow: hidden` on both its containers. */
.rv-ghost {
    position: absolute;
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1;
    white-space: nowrap;
    user-select: none;
    pointer-events: none;
}

/* ============================================================ BUTTONS
   44px is the floor for every hit target. The pills here are 60px and 56px, which clears it, but
   the nav CTA is exactly 44 and gets there only with an explicit line-height — see the nav. */
.rv-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    min-height: 44px;
    border-radius: var(--r-pill);
    font-size: 15px;
    line-height: 20px;
    font-weight: 600;
    text-decoration: none;
    transition: background-color 0.18s ease, color 0.18s ease, border-color 0.18s ease;
}

/* Load-bearing on any pill that sits in the short column of a space-between row: flexbox will
   otherwise shrink it until "Join today" breaks over two lines and the pill goes oval. */
.rv-btn { white-space: nowrap; }

.rv-btn--primary {
    height: 60px;
    padding: 0 36px;
    background: var(--accent);
    /* The one place a literal white is right: it is the foreground ON the action fill, not a
       palette colour. --page is the same value but means "the page ground", which this is not. */
    color: #FFFFFF;
}

.rv-btn--primary:hover,
.rv-btn--primary:focus-visible { background: #005C9E; color: #FFFFFF; }

.rv-btn--ghost,
.rv-btn--pill {
    height: 60px;
    padding: 0 6px 0 24px;
    border: 1px solid var(--line);
    background: var(--page);
    color: var(--ink);
    font-size: 14.5px;
    font-weight: 500;
}

.rv-btn--pill { height: 56px; padding: 0 6px 0 26px; }

.rv-btn--ghost:hover,
.rv-btn--pill:hover,
.rv-btn--ghost:focus-visible,
.rv-btn--pill:focus-visible { border-color: var(--accent); color: var(--ink); }

.rv-btn__badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: var(--r-pill);
    border: 1px solid var(--line);
    color: var(--ink);
}

/* The one place a literal white is right, and it is the same exception as `.rv-btn--primary`
   above: it is the foreground ON the action fill, not a palette colour. `color` rather than a
   stroke in the markup, because every icon is drawn `stroke="currentColor"` (PR26-763) — which is
   what took the last hex literals out of the templates. */
.rv-btn__badge--filled { background: var(--accent); border-color: var(--accent); color: #FFFFFF; }

.rv-band__action { display: flex; justify-content: center; margin: 56px 0 0; }

/* THE DEFAULT LINK. PR26-759: "link colours must be set explicitly — an unstyled link renders
   browser-default blue and reads as a third blue on a page that already has two." Every link on
   the home page carries a class, so this rule catches nothing there; it exists for the body copy
   on the pages still to be built, where an inline link inside a paragraph is exactly the case
   that gets missed.

   Underlined by default, and `text-underline-offset` so the rule clears the descenders. Removing
   the underline on hover rather than adding it, because a link that is only distinguishable from
   its paragraph on hover is not distinguishable on a touch screen at all. `:where()` keeps the
   specificity at zero so any component class beats it without an override. */
:where(.rv) :where(p, li, dd, blockquote) a {
    color: var(--link);
    text-decoration: underline;
    text-underline-offset: 0.18em;
    text-decoration-thickness: 1px;
}

:where(.rv) :where(p, li, dd, blockquote) a:hover { text-decoration-thickness: 2px; }

/* THE DISABLED STATE. PR26-759 names it and it had been left out.

   `aria-disabled` as well as `:disabled`, because half the controls in this system are anchors —
   `.rv-btn` is an `<a>` everywhere it appears today — and an anchor cannot be `:disabled`. The
   attribute is also the one a screen reader reads; `pointer-events: none` alone produces a
   control that looks dead, announces itself as live and cannot be clicked.

   The colours are the accessible ones rather than the obvious ones: a disabled control at 40%
   opacity is the standard mistake and lands at about 2:1. `--subtle-on-tint` on `--paper` is
   4.76:1 — and >=4.5:1 on every ground in the system — so the label is still readable — which is the point, since a disabled button usually
   says what would enable it. */
.rv-btn[aria-disabled="true"],
.rv-btn:disabled,
.rv-nav__cta[aria-disabled="true"] {
    background: var(--paper);
    border: 1px solid var(--line);
    color: var(--subtle-on-tint);
    cursor: not-allowed;
    pointer-events: none;
}

.rv-btn[aria-disabled="true"] .rv-btn__badge,
.rv-btn:disabled .rv-btn__badge {
    background: transparent;
    border-color: var(--line);
    color: var(--subtle-on-tint);
}

/* CAROUSEL NEXT / PREVIOUS ARE DELIBERATELY NOT BUILT. PR26-759 lists them as the fifth control,
   and nothing on the site has a carousel: the home page's three testimonials dropped their
   prev/next circles under PR26-773 because with three cards and no fourth they controlled
   nothing. A control with no caller rots — it is styled against a layout nobody has drawn and is
   wrong by the time something needs it. Build them in the ticket that adds the first carousel;
   the anatomy is 46px, one filled in the action colour and one hairline, which is
   `.rv-btn__badge` and `.rv-btn__badge--filled` at a larger size. */

/* Focus ring. One rule for everything interactive on the page, because a focus style applied
   per-component is one that gets forgotten on the next component. */
.rv a:focus-visible,
.rv-nav a:focus-visible,
.rv-nav button:focus-visible,
.rv-foot a:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
    border-radius: 4px;
}

/* ============================================================ SECTION SHELL — PR26-760
   A 1px hairline across the top of every content section below the hero, inset to the page
   margin. This is LOAD-BEARING, not decoration: most of the page is white on white and this rule
   is the only thing separating adjacent bands. Do not "fix" the run of white sections by tinting
   one of them. */
.rv-band {
    position: relative;
    padding: 110px var(--margin) 120px;
    background: var(--page);
    overflow: hidden;
}

.rv-band::before {
    content: "";
    position: absolute;
    left: var(--margin);
    right: var(--margin);
    top: 0;
    height: 1px;
    background: var(--line);
}

/* Ground modifiers. The rule is PR26-760's: THE IMAGE DECIDES THE GROUND. A band carrying a
   render exported on white must be white, because on any other ground the render's rectangle edge
   shows as a seam. Paper and mint are for bands with no image in them. */
.rv-band--paper { background: var(--paper); }
.rv-band--ash   { background: var(--ash); }

/* PR26-745. Mint, for a band with no image in it. Added as a foundation rather than in
   `join-2026.css` because /membership and /safety both specify a mint hero too, and this sheet's
   own rule is that a variant a second page would want is a modifier here rather than a copy there.

   ⚠️ Anything sitting on this ground has different contrast arithmetic from the same thing on
   white: `--accent` is 4.39:1 on `--fog` and fails AA for small text, and `--ghost` is 1.05:1 and
   is an invisible word. Use `--ghost-on-fog` and `--on-tint-3` here. `npm run check:a11y` has the
   numbers. */
.rv-band--mint  { background: var(--fog); }

.rv-band__inner { max-width: var(--column); margin-inline: auto; }
.rv-band--centred .rv-band__inner { text-align: center; }
.rv-band--centred .rv-h2 { margin-inline: auto; }
.rv-band__copy { margin-top: 8px; }

/* Artwork wells. Every render is on pure #FFFFFF with a wide white margin that IS the
   composition — never cropped to the subject, never on a tinted ground. `aspect-ratio` holds the
   space so nothing shifts when the image arrives. */
.rv-art { margin-inline: auto; }
.rv-art img { display: block; width: 100%; height: auto; aspect-ratio: 4096 / 2304; }


/* ============================================================ CARDS — PR26-762
   Two of the three card types, both used on the home page and both wanted by /how-it-works,
   /membership and /safety. The layer plate is the third and is added by PR26-762 itself. */
/* Card tints are FILLS. Text is ink or body grey, never the pastel. */
.rv-card {
    border: 1px solid var(--line);
    border-radius: var(--r-card);
    padding: 24px 28px 26px;
    text-align: left;
}

/* `.rv-card` deliberately has no background of its own, so it takes the band's. On a tinted band
   that is wrong for a card meant to sit ON the ground rather than in it — hence `--plain`, which
   is the process card without a tint. */
.rv-card--plain      { background: var(--page); }

.rv-card--periwinkle { background: var(--tint-1); }
.rv-card--peach      { background: var(--tint-2); }
.rv-card--mint       { background: var(--tint-3); }

/* The numeral and label sit above the card body on a hairline, per the design. */
.rv-card__head {
    display: flex;
    align-items: baseline;
    gap: 12px;
    margin: 0 0 16px;
    padding-bottom: 14px;
    border-bottom: 1px solid var(--line);
}

.rv-card__no { font-size: 26px; font-weight: 600; letter-spacing: -0.02em; color: var(--accent); }
.rv-card__label { font-size: 17px; font-weight: 600; color: var(--ink); }
.rv-card__title { margin: 0; font-size: 17px; font-weight: 600; line-height: 1.35; color: var(--ink); }
.rv-card__body { margin: 10px 0 0; font-size: 13px; line-height: 1.65; color: var(--body); }

/* THE CIRCULAR ARROW, PR26-762 — bottom-left of a process card.
   `.rv-icon` is the well; this places it and gives it the top margin that pushes it to the foot of
   the card without needing the card to be a flex column.

   ⚠️ NOT ON THE HOME PAGE. Those three process cards were built by PR26-744 without an arrow and
   this does not add one — that is a visible change to a live page, and this ticket has already
   dropped two things the reference showed (the diagonal stagger, and the over-photograph callout).
   Whether home was incomplete or the arrow went the same way is a question for whoever owns the
   page, not something to answer by editing it. See the note on PR26-762.

   Interactive only when a card is a link. On a static card it is a cue, so it is `aria-hidden` in
   the markup rather than given a label here. */
.rv-card__arrow {
    margin-top: 22px;
}

.rv-quote {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--line);
    border-radius: var(--r-card);
    padding: 30px 30px 26px;
    text-align: left;
}

.rv-quote__marker {
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 0 0 22px;
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--accent);
}

.rv-quote__rule { flex: 1 1 auto; height: 1px; background: var(--line); }

/* Quotes are reproduced verbatim, errors and all. `min-height` squares the three cards up without
   forcing equal text. */
.rv-quote__text {
    margin: 0;
    flex: 1 1 auto;
    min-height: 160px;
    font-size: 17px;
    line-height: 1.5;
    font-weight: 500;
    color: var(--ink);
}

.rv-quote__by {
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 26px 0 0;
    padding-top: 20px;
    border-top: 1px solid var(--line);
}

.rv-quote__avatar {
    flex: 0 0 38px;
    width: 38px;
    height: 38px;
    border-radius: var(--r-pill);
    background: var(--fog);
    border: 1px solid var(--line);
}

.rv-quote__name { display: block; font-size: 13px; font-weight: 600; color: var(--ink); }
.rv-quote__org  { display: block; margin-top: 2px; font-size: 11.5px; color: var(--subtle-on-tint); }

/* THE LIFTED PHRASE AND THE "MEMBER STORY" MARKER TAKE THE TINT'S OWN PARTNER, not --accent.
   At 17px/500 and 10.5px, --accent measures 4.24-4.33:1 on these three tints and fails AA. The
   mockup shows all three in blue; the mockup is wrong on contrast, and the brief's own rule says
   text on a tint uses the text-safe partner. Raised with Andy — it is a visible change, three
   different hues where the design has one.

   The section 03 card numerals are deliberately NOT included: at 26px/600 they are large text,
   where the threshold is 3:1 and --accent's 4.24 clears it. They stay blue. */
.rv-quote.rv-card--periwinkle .rv-accent,
.rv-quote.rv-card--periwinkle .rv-quote__marker { color: var(--on-tint-1); }
.rv-quote.rv-card--peach .rv-accent,
.rv-quote.rv-card--peach .rv-quote__marker { color: var(--on-tint-2); }
.rv-quote.rv-card--mint .rv-accent,
.rv-quote.rv-card--mint .rv-quote__marker { color: var(--on-tint-3); }

/* THE PROCESS CARD GRID — PR26-762.
   `repeat(3, minmax(0, 1fr))` with a 24px gap. The `minmax(0, …)` is load-bearing rather than
   decorative: `1fr` alone is `minmax(auto, 1fr)`, so a long unbroken word in a card body sets the
   column's minimum and the three columns stop being equal.

   The reference's diagonal stagger was tried and rejected — at this size it read as untidy rather
   than deliberate. Do not reintroduce it without a page that wants it.

   Here rather than in a page sheet because /how-it-works, /membership and /safety all want the
   same three-up. The home page keeps its own `.rv-members__cards`, which is a composition with its
   own top margin. */
.rv-cards {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 24px;
    padding: 0;
    list-style: none;
}

/* THE LAYER PLATE — PR26-762, the third card type.
   A stroke icon and a title on one line, 76px tall, white fill on a hairline. Used only in the
   safety stack (PR26-772, PR26-794), four deep.

   White FILL rather than no background, unlike `.rv-card`: the stack sits on a tinted band and a
   plate that took the band's ground would not read as a plate at all. */
.rv-plates {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.rv-plate {
    display: flex;
    align-items: center;
    gap: 16px;
    min-height: 76px;
    padding: 0 22px;
    background: var(--page);
    border: 1px solid var(--line);
    border-radius: var(--r-plate);
}

/* The icon well inside a plate is smaller than the standalone 44px one - it is decoration beside a
   title, not a target. `.rv-icon` itself is unchanged; this is a size modifier on it. */
.rv-plate .rv-icon {
    flex: 0 0 34px;
    width: 34px;
    height: 34px;
}

.rv-plate__title {
    margin: 0;
    font-size: 15px;
    font-weight: 600;
    line-height: 1.3;
    color: var(--ink);
}

/* ============================================================ CALLOUT — PR26-761
   The device that labels part of a diagram or a stack: a 7px action-blue dot, a hairline, a caps
   label, and two or three short description lines.

   LIGHT GROUND ONLY. The earlier over-photograph variant - white text with a heavy `text-shadow` -
   is deliberately NOT built. With the hero full-bleed and callout-free, nothing in the design uses
   a callout over imagery, and a variant with no caller is a variant that rots. If one is ever
   wanted again it comes back as a new ticket with a real page behind it.

   Callers: the safety layer stack (PR26-772) and its longer form on /safety (PR26-794). Nothing
   renders one yet, so this has been checked by arithmetic and not by eye.

   THE DOT AND LINE ARE DECORATION. They carry no information the label does not, so they are drawn
   by a pseudo-element rather than by markup and are invisible to a screen reader by construction.
   `--accent` is a fill here, not text: at 7px it is neither text nor a functional graphic, and the
   3:1 floor the accessibility check holds it to on every ground is met anyway. */
.rv-callout {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    /* Callouts must never overflow their container or collide with a headline. A max-width plus a
       wrap rule is what makes that true of a long label rather than merely intended. */
    max-width: 260px;
    overflow-wrap: anywhere;
}

/* The dot and the hairline, as one element: a 7px circle with a rule growing out of it. The line
   length is a custom property because the design specifies a range rather than a value - 46px to
   74px, depending on how far the callout sits from what it labels. */
.rv-callout::before {
    content: "";
    flex: 0 0 auto;
    align-self: flex-start;
    width: var(--rv-callout-line, 60px);
    height: 7px;
    margin-top: 5px;
    border-radius: var(--r-pill);
    background:
        radial-gradient(circle 3.5px at 3.5px 3.5px, var(--accent) 100%, transparent 100%) no-repeat,
        linear-gradient(var(--line), var(--line)) no-repeat;
    background-size: 7px 7px, calc(var(--rv-callout-line, 60px) - 7px) 1px;
    background-position: left center, right center;
}

.rv-callout--short { --rv-callout-line: 46px; }
.rv-callout--long  { --rv-callout-line: 74px; }

.rv-callout__label {
    display: block;
    margin: 0 0 6px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--ink);
}

/* `--body`, not `--subtle`. The design says "subtle grey" and `--subtle` is the token for it, but
   the accessibility check only holds `--subtle` to 4.5:1 on `--page` - and both callers put these
   on a tinted band. `--body` is checked against every ground in the system. */
.rv-callout__text {
    margin: 0;
    font-size: 12.5px;
    line-height: 1.5;
    color: var(--body);
}

/* ============================================================ ICONS — PR26-763
   The 44px well every stroke icon sits in: a hairline circle on the page ground, with a
   1.5px action-blue stroke inside it. NOT a filled badge, and never a shield and tick. The
   icons themselves are drawn by `views/partials/rv-icon.hbs`. */
.rv-icon {
    display: inline-flex;
    /* The icon inside is `stroke="currentColor"`, so this is what colours it. --accent is a fill
       and a large-text colour on this palette; a 1.5px stroke on a 24 grid is neither text nor
       small text, and 4.70:1 on the page ground clears the 3:1 that a functional graphic needs. */
    color: var(--accent);
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: var(--r-pill);
    border: 1px solid var(--line);
    background: var(--page);
}

/* ============================================================ GLOBAL NAV — PR26-757
   ONE variant, ink on light, on every page.

   SCROLL BEHAVIOUR: fixed, transparent at the top of the page, solid-on-scroll. The page is about
   six thousand pixels tall and its one job is membership signup, so the "Join today" pill has to
   stay reachable — a nav that scrolls away puts the primary action off-screen for 95% of the
   page. It starts transparent because the hero is white anyway and a hard bar across the top of a
   design whose whole trick is hairline rules would fight it; past 24px it takes the page ground
   and the same hairline every section below it uses. */
.rv-nav {
    position: fixed;
    inset: 0 0 auto;
    z-index: 100;
    background: transparent;
    border-bottom: 1px solid transparent;
    transition: background-color 0.2s ease, border-color 0.2s ease;
}

.rv-nav[data-rv-scrolled] {
    background: var(--page);
    border-bottom-color: var(--line);
}

.rv-nav__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 32px;
    height: var(--nav-h);
    padding: 0 var(--margin);
}

/* `color` is what recolours the inlined wordmark — the SVG is fill: currentColor. */
.rv-nav__brand { display: inline-flex; align-items: center; color: var(--ink); }

.rv-nav__links {
    display: flex;
    align-items: center;
    gap: 40px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.rv-nav__link {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    font-size: 13.5px;
    font-weight: 500;
    color: var(--body);
    text-decoration: none;
}

a.rv-nav__link:hover { color: var(--ink); }


/* THE 44px HIT TARGET. `line-height: 20px` is doing the work here. Without it the flex line box
   collapses to the font's own leading and the pill measures about 38px — the single detail
   PR26-757 calls out. */
.rv-nav__cta {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    height: 44px;
    padding: 0 8px 0 22px;
    border: 1px solid var(--line);
    border-radius: var(--r-pill);
    font-size: 13.5px;
    line-height: 20px;
    font-weight: 500;
    color: var(--ink);
    text-decoration: none;
    /* Not fully opaque, so the label stays readable if a future page puts a photograph behind it. */
    background: rgba(255, 255, 255, 0.7);
}

.rv-nav__cta:hover { border-color: var(--accent); color: var(--ink); }

.rv-nav__cta-badge {
    display: inline-flex;
    color: #FFFFFF;   /* white on the action fill — same exception as `.rv-btn__badge--filled` */
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: var(--r-pill);
    background: var(--accent);
}

.rv-nav__toggle { display: none; }

/* The skip link. Visible only on focus, but always in the DOM and always first. */
.rv-skip {
    position: absolute;
    left: -9999px;
    z-index: 200;
    padding: 12px 18px;
    background: var(--ink);
    color: var(--page);
    border-radius: var(--r-control);
    font-size: 14px;
    text-decoration: none;
}

.rv-skip:focus { left: 16px; top: 16px; }

/* ============================================================ GLOBAL FOOTER — PR26-758
   Ink ground. The wordmark is the same inlined vector as the nav, given #F6F6F6 through `color`.

   Text is white at decreasing alpha rather than four more tokens, because these are opacities
   over --foot rather than colours in their own right — the ramp has to move with the ground if
   the ground ever changes. */
.rv-foot {
    background: var(--foot);
    padding: 76px var(--margin) 44px;
    font-family: "aktiv-grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

.rv-foot__inner { max-width: var(--column); margin-inline: auto; }

.rv-foot__top {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 64px;
    padding-bottom: 56px;
}

.rv-foot__brand { width: 320px; flex: 0 0 auto; }
.rv-foot__mark { display: block; margin-bottom: 24px; color: #F6F6F6; }
.rv-foot__blurb { margin: 0; font-size: 13px; line-height: 1.7; color: rgba(255, 255, 255, 0.5); }

.rv-foot__cols { display: flex; gap: 80px; }

/* A real heading, because these label a list and a screen reader user navigating by heading
   should find them. Sized down to the design's 10.5px caps rather than an h2 default. */
/* 0.4 alpha over the ink ground is 3.83:1 and fails AA at 10.5px; 0.62 is 7.46:1 and still reads
   as a quiet label rather than a link. Same reason for the bottom row below. */
.rv-foot__col-title {
    margin: 0 0 18px;
    font-size: 10.5px;
    font-weight: 500;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.62);
}

.rv-foot__col-links { display: flex; flex-direction: column; gap: 11px; margin: 0; padding: 0; list-style: none; }

.rv-foot__col-links a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    font-size: 13px;
    color: rgba(255, 255, 255, 0.78);
    text-decoration: none;
}

.rv-foot__col-links a:hover { color: #FFFFFF; text-decoration: underline; }

/* 44px targets stacked at an 11px gap would run to 55px apart; pull the box back so the rhythm
   stays the design's while the target stays the standard's. */
.rv-foot__col-links li { margin: -8px 0; }

.rv-foot__bottom {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 16px 32px;
    padding-top: 26px;
    border-top: 1px solid rgba(255, 255, 255, 0.12);
}

.rv-foot__legal,
.rv-foot__place { font-size: 11.5px; color: rgba(255, 255, 255, 0.62); }
.rv-foot__place { letter-spacing: 0.12em; text-transform: uppercase; }

.rv-foot__social { display: flex; flex-wrap: wrap; gap: 24px; margin: 0; padding: 0; list-style: none; }

.rv-foot__social a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    font-size: 11.5px;
    color: rgba(255, 255, 255, 0.62);
    text-decoration: none;
}

.rv-foot__social a:hover { color: #FFFFFF; text-decoration: underline; }


/* ============================================================ THE CLOSING BAND — PR26-774
   Mint, a ghost word, a headline, a paragraph and the one primary action. It was written for the
   home page's section 06 and moved here when /how-it-works became a second caller (PR26-787): the
   two are the same component with different words in it.

   THE GHOST WORD TAKES --ghost-on-fog, NOT --ghost. On this ground --ghost is a difference of
   about four parts in 255 and is invisible. That is why there are two tokens (PR26-755). */
.rv-close {
    position: relative;
    padding: 104px var(--margin) 110px;
    background: var(--fog);
    overflow: hidden;
}

.rv-close__ghost {
    left: 0;
    right: 0;
    top: 120px;
    text-align: center;
    font-size: 230px;
    color: var(--ghost-on-fog);
}

.rv-close__inner {
    position: relative;
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 48px;
    max-width: var(--column);
    margin-inline: auto;
}

.rv-close__h { font-size: 72px; line-height: 0.98; }
.rv-close__copy { margin-top: 28px; max-width: 400px; font-size: 14.5px; line-height: 1.7; }
/* `flex-shrink: 0` and the nowrap are both load-bearing: this column is the short side of a
   space-between row, so flexbox will happily shrink it until "Join today" breaks over two lines
   and the pill goes oval. */
.rv-close__actions {
    display: flex;
    flex: 0 0 auto;
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;
    padding-bottom: 8px;
}


/* A quiet link, so it reads as the alternative rather than a second CTA. --accent is a fill on
   this page and is not used for link text; the body grey with an underline on hover is the
   quieter and the more legible of the two. */
.rv-close__quiet {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding-left: 6px;
    font-size: 13px;
    color: var(--body);
    text-decoration: none;
}

.rv-close__quiet:hover { color: var(--ink); text-decoration: underline; }

/* ============================================================================================
   BREAKPOINTS — PR26-764, the shared half

   The design is drawn at 1440 and everything below it is decided here rather than improvised per
   page. Four steps: 1439 (the margin and the type start giving), 1099 (two-column layouts fold),
   767 (phone), 419 (small phone). Page-specific behaviour at the same widths lives in that page's
   own sheet, after this one.
   ============================================================================================ */

@media (max-width: 1439px) {
    :root { --margin: 64px; }

    .rv-h1 { font-size: clamp(52px, 5.6vw, 76px); }
    .rv-h2 { font-size: clamp(44px, 4.6vw, 62px); }

    /* The closing band travels with the foundations (PR26-774) — it is on two pages. */
    .rv-close__h { font-size: clamp(46px, 5.2vw, 72px); }
    .rv-close__ghost { font-size: 17vw; }
}

@media (max-width: 1099px) {
    :root { --margin: 40px; }

    /* Three testimonial cards side by side stop needing a floor under the quote once they are
       narrow enough to set their own height. */
    .rv-quote__text { min-height: 0; }

    /* PR26-762. Three process cards become two before they become one - three columns at this
       width put a card body on four words a line. */
    .rv-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }

    .rv-close__inner { flex-direction: column; align-items: flex-start; gap: 40px; }

    .rv-foot__top { flex-direction: column; gap: 48px; }
    .rv-foot__cols { gap: 56px; }
}

@media (max-width: 767px) {
    :root { --margin: 24px; --nav-h: 72px; }

    .rv-cards { grid-template-columns: minmax(0, 1fr); }

    /* PR26-761. ON MOBILE A CALLOUT STACKS UNDER THE THING IT LABELS RATHER THAN POINTING AT IT.
       There is no room beside anything at this width, so the dot-and-hairline stops being a
       pointer and becomes a short rule above the label - still the same decoration, no longer
       claiming to indicate a direction it cannot indicate. */
    .rv-callout {
        display: block;
        max-width: none;
    }

    .rv-callout::before {
        display: block;
        width: 46px;
        margin: 0 0 10px;
    }


    .rv-band { padding: 72px var(--margin) 80px; }

    .rv-h1 { font-size: clamp(38px, 11vw, 52px); line-height: 1.0; }
    .rv-h2 { font-size: clamp(32px, 9vw, 44px); line-height: 1.06; }
    .rv-body { font-size: 15.5px; line-height: 1.7; }

    /* The portrait crops are 4:5, a different composition rather than a smaller one, so the
       aspect-ratio has to change with them or the reserved box is wrong and the page shifts. */
    .rv-art img { aspect-ratio: 2400 / 3000; }

    .rv-close { padding: 72px var(--margin) 80px; }
    .rv-close__h { font-size: clamp(34px, 9.5vw, 46px); }
    .rv-close__ghost { font-size: 26vw; top: 96px; }
    .rv-close__actions { align-self: stretch; }
    .rv-close__actions .rv-btn { width: 100%; }

    /* ---------- NAV, phone. PR26-764 ----------
       A disclosure panel under the bar, not an overlay drawer. The bar keeps the wordmark and the
       "Join today" pill visible at all times — the pill is the site's one job and hiding it behind
       a hamburger is the wrong trade — and only the links move into the panel. */
    .rv-nav__inner { gap: 12px; padding: 0 var(--margin); }
    .rv-nav__links { display: none; }

    .rv-nav__toggle {
        order: -1;
        display: inline-flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 5px;
        width: 44px;
        height: 44px;
        margin-left: -10px;
        padding: 0;
        border: 0;
        background: none;
        cursor: pointer;
    }

    .rv-nav__toggle-bar {
        width: 20px;
        height: 1.5px;
        background: var(--ink);
        transition: transform 0.2s ease, opacity 0.2s ease;
    }

    .rv-nav__toggle[aria-expanded="true"] .rv-nav__toggle-bar:first-child { transform: translateY(3.25px) rotate(45deg); }
    .rv-nav__toggle[aria-expanded="true"] .rv-nav__toggle-bar:last-child  { transform: translateY(-3.25px) rotate(-45deg); }

    /* The brand is centred between the toggle and the CTA. */
    .rv-nav__brand { margin-inline: auto; }
    .rv-nav__cta { padding: 0 6px 0 16px; font-size: 13px; }

    /* The panel takes the page ground unconditionally, because when it is open the bar is no
       longer transparent whatever the scroll position. */
    .rv-nav__panel {
        padding: 8px var(--margin) 24px;
        background: var(--page);
        border-bottom: 1px solid var(--line);
    }

    .rv-nav__panel-links { margin: 0; padding: 0; list-style: none; }

    .rv-nav__panel-link {
        display: flex;
        align-items: center;
        min-height: 52px;
        border-bottom: 1px solid var(--line);
        font-size: 16px;
        font-weight: 500;
        color: var(--ink);
        text-decoration: none;
    }

    .rv-nav__panel-cta { width: 100%; margin-top: 20px; }

    /* Once the panel is open the bar is solid whether or not the page has scrolled. */
    .rv-nav:has(.rv-nav__panel:not([hidden]))[data-rv-nav] { background: var(--page); }

    .rv-foot { padding: 56px var(--margin) 32px; }
    .rv-foot__brand { width: 100%; }
    .rv-foot__cols { flex-direction: column; gap: 32px; }
    .rv-foot__bottom { flex-direction: column; align-items: flex-start; gap: 8px; }
    .rv-foot__social { gap: 8px 20px; }
}

@media (max-width: 419px) {
    .rv-quote { padding: 24px 22px 22px; }
    .rv-card { padding: 20px 22px 22px; }
}

/* ============================================================ REDUCED MOTION
   Everything that moves on this page is a transition — the nav's solid-on-scroll fade, the
   hamburger's rotate, the button hovers. None of it carries information, so all of it goes. */
@media (prefers-reduced-motion: reduce) {
    .rv-nav,
    .rv-nav__toggle-bar,
    .rv-btn,
    .rv *,
    .rv-foot * {
        transition-duration: 0.01ms !important;
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        scroll-behavior: auto !important;
    }
}

/* Anchor jumps must clear the fixed nav, or "How it works" lands with the marker under the bar. */
html { scroll-padding-top: calc(var(--nav-h) + 24px); }
