/* ==========================================================================
   GoodVibes Foundation — COMPONENT LIBRARY
   design/web/css/gvs-components.css

   CASCADE POSITION (load in this order, third of four):
     gvs-tokens.css  ->  gvs-base.css  ->  THIS FILE  ->  gvs-layout.css

   OWNERSHIP
     Lane H1 owns gvs-tokens.css + gvs-base.css + assets/*.svg
     Lane H2 (this file) owns every component and all five states
     Lane H3 owns gvs-layout.css + the page templates

   SOURCE OF TRUTH
     design/exports/gvs-tokens-B-components.css   (159 classes, 304 rules)
     design/ai/gvs-guidelines-B-components.build.jsx (9 artboards, exact px)
     design/exports/gvs-landing-v1.png            (shipped geometry)

   HOUSE RULES OBEYED HERE
     * Muted / helper / placeholder type is --gvs-ink-muted #6E655B (4.73:1).
       --gvs-soft-grey #A9A29A is 2.09:1 and NEVER carries text — rules,
       dividers and disabled fills only.
     * The focus ring is PETROL, never gold. Gold on paper is 1.59:1 and
       fails the 3:1 non-text minimum (WCAG 2.2 SC 1.4.11).
     * Interaction tints are FLAT pre-mixed colours, not alpha overlays, so
       they print correctly and never stack over the Rasta bands.
     * --gvs-ray-teal #2E7F8C is decorative. Type teal is --gvs-teal-text.
     * No !important outside the reduced-motion / print escape hatches at the
       very bottom, which is where the spec puts them.
     * Every interactive selector has a :focus-visible rule. See section 2.
     * Touch targets are >= 44 x 44 CSS px. Controls whose visual box is
       smaller (sm button 36, tag 28, toggle 32) carry an invisible
       ::after hit-extender. See --gvsc-hit-min and section 3.
   ========================================================================== */

/* ==========================================================================
   1 · COMPONENT TOKEN LAYER  (owned by this file)
   --------------------------------------------------------------------------
   gvs-tokens.css (Lane H1) publishes the FOUNDATION tokens: palette,
   semantic roles, type scale, spacing, radii, focus, motion, z-index,
   seal + ray + icon geometry. Those are consumed here directly as
   var(--gvs-...) and are never redefined.

   The 60 tokens below are the COMPONENT layer of the design system
   (Volume B). H1's foundation file does not define them, so this file
   does. Values come verbatim from design/exports/gvs-tokens-B-components.css.
   ========================================================================== */
:root {

  /* --- interaction tints -------------------------------------------------
     Flat, pre-mixed, print-safe. Never alpha.
     secondary-hover / -active are petrol at 8% / 16% mixed over paper. */
  --gvs-gold-hover:        #D4A02F;
  --gvs-gold-active:       #BE8C22;
  --gvs-secondary-hover:   #E2DCC8;
  --gvs-secondary-active:  #D0D0BF;
  --gvs-red-hover:         #A81C08;
  --gvs-red-active:        #8E1F14;
  --gvs-cream-hover:       #F0E8D6;

  /* --- status roles ----------------------------------------------------- */
  --gvs-ok:      var(--gvs-rasta-green);   /* 6.00:1 cream on green        */
  --gvs-warn:    var(--gvs-gold);          /* BAR ONLY — never gold type   */
  --gvs-error:   var(--gvs-rasta-red);     /* 4.70:1 on paper              */
  --gvs-neutral: var(--gvs-petrol-deep);   /* "cancelled" is neutral       */

  /* --- buttons ---------------------------------------------------------- */
  --gvs-btn-h-lg:     56px;
  --gvs-btn-h-md:     44px;
  --gvs-btn-h-sm:     36px;
  --gvs-btn-pad-lg:   32px;
  --gvs-btn-pad-md:   24px;
  --gvs-btn-pad-sm:   16px;
  --gvs-btn-min-lg:  200px;
  --gvs-btn-min-md:  132px;
  --gvs-btn-min-sm:   96px;
  --gvs-btn-fs-lg:    17px;
  --gvs-btn-fs-md:    15px;
  --gvs-btn-fs-sm:    13px;
  --gvs-btn-icon:     16px;   /* glyph box                                 */
  --gvs-btn-icon-gap:  8px;   /* glyph -> label                            */
  --gvs-pill-h:       48px;   /* radius = h/2                              */
  --gvs-pill-pad-x:   28px;

  /* --- links ------------------------------------------------------------ */
  --gvs-underline:             2px;   /* never thinner                     */
  --gvs-underline-hover:       3px;
  --gvs-underline-offset:     10px;   /* 17-18px type (~0.55em)            */
  --gvs-underline-offset-sm:   8px;   /* 15px type                         */

  /* --- form controls ---------------------------------------------------- */
  --gvs-control:            24px;   /* checkbox / radio box                */
  --gvs-field-h:            56px;
  --gvs-field-h-compact:    44px;
  --gvs-field-pad-x:        24px;
  --gvs-textarea-h:        120px;   /* 3 rows, grows in 24px steps         */
  --gvs-toggle-w:           56px;
  --gvs-toggle-h:           32px;
  --gvs-toggle-knob:        24px;
  --gvs-upload-h:          116px;
  --gvs-stepper-w:         160px;
  --gvs-stepper-zone:       40px;

  /* --- chips, tags, badges ---------------------------------------------- */
  --gvs-chip-date:          72px;   /* shipped size; --sm 56, --lg 88      */
  --gvs-tag-h:              28px;
  --gvs-tag-pad-x:          12px;
  --gvs-tag-fs:             11px;
  --gvs-badge-h:            32px;
  --gvs-badge-pad-x:        14px;
  --gvs-badge-fs:           11px;
  --gvs-counter:            24px;
  --gvs-tracking-tag:     0.12em;

  /* --- navigation ------------------------------------------------------- */
  --gvs-nav-h-sticky:       72px;
  --gvs-nav-gap:            34px;
  --gvs-nav-indicator:       3px;
  --gvs-mega-w:            640px;
  --gvs-mobile-w:          390px;
  --gvs-mobile-nav-h:       72px;

  /* --- structure & feedback --------------------------------------------- */
  --gvs-tab-h:              48px;
  --gvs-tab-indicator:       4px;
  --gvs-accordion-h:        64px;
  --gvs-row-h:              44px;   /* table row + pagination cell         */
  --gvs-notice-h:           72px;
  --gvs-notice-bar:         10px;   /* the bar carries the meaning          */
  --gvs-toast-w:           400px;
  --gvs-modal-w:           560px;

  /* --- footer ----------------------------------------------------------- */
  --gvs-footer-h:          430px;
  --gvs-footer-col:        260px;

  /* ======================================================================
     LOCAL FALLBACKS — values H1's foundation layer does not publish.
     Two kinds, both deliberate:

     (a) FLAT MIXES. The Volume B spec wrote these as rgba()/opacity. Alpha
         over the Rasta bands and in CMYK print is unreliable, and opacity
         on a container fades its children, so each one is pre-multiplied
         to a literal here. The mix is stated in the comment so it can be
         re-derived. Swap in color-mix() once support is a given.

     (b) ACCESSIBILITY REPLACEMENTS for three spec values that measured
         below AA when I re-derived them. Flagged AA-FIX.
     ====================================================================== */

  /* (a) flat mixes ------------------------------------------------------- */
  --gvsc-keyline-cream:   #C2CAC3;  /* petrol 25% over cream. Same mix as   */
                                    /* cream 75% over petrol — see below.   */
  --gvsc-keyline-panel:   #CDD2CA;  /* petrol 20% over cream: acc/panel rule*/
  --gvsc-keyline-feature: #C9CFC7;  /* petrol 22% over cream: mega feature  */
  --gvsc-keyline-paper:   #B2B9AE;  /* petrol 30% over paper: nav + tab bar */
  --gvsc-crumb-sep:       #92A19C;  /* petrol 45% over paper. aria-hidden   */
                                    /* separator glyph — decorative only.   */
  --gvsc-icon-disc:       #E8E6DB;  /* petrol 8% over cream. The card badge */
                                    /* disc. Flat, so the icon on top stays */
                                    /* full-strength petrol.                */
  --gvsc-cream-75-petrol: #C2CAC3;  /* cream 75% over petrol   — 5.76:1     */
  --gvsc-cream-75-deep:   #C0C4BC;  /* cream 75% over deep     — 7.40:1     */
  --gvsc-cream-70-deep:   #B4BBB4;  /* cream 70% over deep     — 6.58:1     */
  --gvsc-footer-rule:     #4C666A;  /* cream 25% over deep. Decorative.     */
  --gvsc-overlay-bg:      rgba(18, 54, 64, 0.7);
                                    /* The one legitimate alpha in the file:*/
                                    /* a scrim must be see-through. Spec put*/
                                    /* opacity:.7 on .gvs-overlay, which    */
                                    /* also faded the modal inside it.      */

  /* (b) AA-FIX ----------------------------------------------------------- */
  --gvsc-petrol-recessive: #466A72; /* AA-FIX. petrol 80% over paper,       */
                                    /* 4.87:1. Spec dimmed inactive tabs to */
                                    /* 60% = 3.04:1, which fails AA.        */
  /* AA-FIX 2: the current-page breadcrumb was petrol at 70% = 3.88:1.
     It now uses --gvs-ink-muted (4.73:1). See .gvs-crumbs.
     AA-FIX 3: .gvs-page__gap already used --gvs-ink-muted. Kept. */

  /* --- hit target ------------------------------------------------------- */
  --gvsc-hit-min: 44px;             /* WCAG 2.2 SC 2.5.8 target size        */
}

/* ==========================================================================
   2 · FOCUS — one definition, applied everywhere
   --------------------------------------------------------------------------
   2px solid at 2px offset. Petrol on light grounds (8.00:1 on paper,
   5.03:1 on a gold button); cream on dark fields (11.77:1 on petrol-deep).
   GOLD IS NEVER A FOCUS RING on paper — 1.59:1 fails the 3:1 minimum for
   non-text contrast.

   :focus-visible only, so a mouse press does not paint a ring, but every
   keyboard path does. Nothing in this file sets `outline: none` without
   substituting a ring in the same breath.
   ========================================================================== */

/* The explicit component list. */
.gvs-btn:focus-visible,
.gvs-link:focus-visible,
.gvs-textlink:focus-visible,
.gvs-arrowlink:focus-visible,
.gvs-backlink:focus-visible,
.gvs-field:focus-visible,
.gvs-input:focus-visible,
.gvs-select__control:focus-visible,
.gvs-check__box:focus-visible,
.gvs-toggle:focus-visible,
.gvs-upload__input:focus-visible + .gvs-upload__face,
.gvs-stepper__btn:focus-visible,
.gvs-tag:focus-visible,
.gvs-tab:focus-visible,
.gvs-acc__btn:focus-visible,
.gvs-page:focus-visible,
.gvs-nav__link:focus-visible,
.gvs-nav__wordmark:focus-visible,
.gvs-burger:focus-visible,
.gvs-mega__list a:focus-visible,
.gvs-crumbs a:focus-visible,
.gvs-card--interactive:focus-visible,
a.gvs-card:focus-visible,
a.gvs-eventrow:focus-visible,
a.gvs-event-row:focus-visible,
.gvs-modal__close:focus-visible,
.gvs-skip:focus-visible {
  outline: var(--gvs-focus-width) solid var(--gvs-focus-ring);
  outline-offset: var(--gvs-focus-offset);
}

/* Safety net. :where() keeps specificity at zero so every override below
   still wins, but nothing interactive inside a component can ship without
   a ring — including elements Lane H3 adds to these blocks later. */
:where(.gvs-nav, .gvs-drawer, .gvs-navdrawer, .gvs-mega, .gvs-footer,
       .gvs-card, .gvs-eventrow, .gvs-event-row, .gvs-form, .gvs-newsletter,
       .gvs-table, .gvs-acc, .gvs-tabs, .gvs-pagination, .gvs-crumbs,
       .gvs-upload, .gvs-stepper, .gvs-modal, .gvs-toast, .gvs-notice,
       .gvs-empty, .gvs-empty-state, .gvs-tag-row)
  :is(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: var(--gvs-focus-width) solid var(--gvs-focus-ring);
  outline-offset: var(--gvs-focus-offset);
}

/* Dark grounds take the cream ring. Gold would collide with a gold keyline
   or a gold underline, so it is never used here either. */
.gvs-on-dark .gvs-btn:focus-visible,
.gvs-on-dark .gvs-link:focus-visible,
.gvs-on-dark .gvs-textlink:focus-visible,
.gvs-on-dark .gvs-arrowlink:focus-visible,
.gvs-btn--pill:focus-visible,
a.gvs-pill:focus-visible,
button.gvs-pill:focus-visible,
.gvs-footer a:focus-visible,
.gvs-drawer a:focus-visible,
.gvs-navdrawer a:focus-visible,
.gvs-drawer .gvs-btn:focus-visible,
.gvs-navdrawer .gvs-btn:focus-visible,
.gvs-toast__close:focus-visible,
.gvs-toast a:focus-visible {
  outline: var(--gvs-focus-width) solid var(--gvs-focus-ring-inverse);
  outline-offset: var(--gvs-focus-offset);
}

/* Utility: reachable by a screen reader, invisible on screen. Lane H1's base
   and Lane H3's layout both reference .gvs-vh; defining it here too is
   harmless (identical declarations) and keeps this file self-sufficient. */
.gvs-vh {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ==========================================================================
   3 · BUTTONS
   --------------------------------------------------------------------------
   Gold fill for the primary action, a 2px petrol keyline for the secondary.
   Three sizes, all on the 8px grid. Labels are Title Case, never ALL CAPS —
   ALL CAPS belongs to display headings and eyebrows.

   One primary action per view. The secondary sits 24px to its right.
   The base size is lg / 56, matching the shipped hero.

   Works identically on <button>, <a class="gvs-btn"> and
   <input type="submit" class="gvs-btn">.
   ========================================================================== */
.gvs-btn {
  position: relative;                       /* anchors the hit-extender     */
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--gvs-btn-icon-gap);
  height: var(--gvs-btn-h-lg);
  min-width: var(--gvs-btn-min-lg);
  padding: 0 var(--gvs-btn-pad-lg);
  border: 0;
  border-radius: var(--gvs-radius);
  font-family: var(--gvs-font-body);
  font-weight: var(--gvs-body-weight-em);
  font-size: var(--gvs-btn-fs-lg);
  line-height: 1;
  text-align: center;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--gvs-t) var(--gvs-ease),
              border-color var(--gvs-t) var(--gvs-ease),
              color var(--gvs-t) var(--gvs-ease);
}

/* --- sizes --------------------------------------------------------------- */
.gvs-btn--lg {
  height: var(--gvs-btn-h-lg);
  min-width: var(--gvs-btn-min-lg);
  padding: 0 var(--gvs-btn-pad-lg);
  font-size: var(--gvs-btn-fs-lg);
}
.gvs-btn--md {
  height: var(--gvs-btn-h-md);
  min-width: var(--gvs-btn-min-md);
  padding: 0 var(--gvs-btn-pad-md);
  font-size: var(--gvs-btn-fs-md);
}
.gvs-btn--sm {
  height: var(--gvs-btn-h-sm);
  min-width: var(--gvs-btn-min-sm);
  padding: 0 var(--gvs-btn-pad-sm);
  font-size: var(--gvs-btn-fs-sm);
}
.gvs-btn--block {
  display: flex;
  width: 100%;
  min-width: 0;                             /* the label stays centred      */
}

/* --- HIT TARGET ---------------------------------------------------------
   The sm button is 36 tall, 8px short of the 44 x 44 minimum in WCAG 2.2
   SC 2.5.8. The visual box stays 36 (it has to — it is specified that way
   for dense toolbars) and an invisible ::after grows the POINTER target to
   44 without moving anything in the layout. Same trick on tags and toggles.
   On a coarse pointer the visual box is promoted to 44 outright: see the
   pointer query in section 12. */
.gvs-btn--sm::after,
.gvs-btn--icon-only.gvs-btn--sm::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  height: var(--gvsc-hit-min);
  transform: translateY(-50%);
}

/* --- primary : gold fill, petrol label (5.03:1) ------------------------- */
.gvs-btn--primary {
  background-color: var(--gvs-gold);
  color: var(--gvs-text-on-gold);
}
.gvs-btn--primary:hover  { background-color: var(--gvs-gold-hover); }
.gvs-btn--primary:active { background-color: var(--gvs-gold-active); }
.gvs-btn--primary:focus-visible { background-color: var(--gvs-gold); }
.gvs-btn--primary:disabled,
.gvs-btn--primary[aria-disabled="true"] {
  background-color: var(--gvs-gold);
  color: var(--gvs-text-on-gold);
  opacity: var(--gvs-disabled-opacity);
  cursor: not-allowed;
}

/* --- secondary : 2px petrol keyline, no fill ---------------------------- */
.gvs-btn--secondary {
  background-color: transparent;
  border: var(--gvs-border-width) solid var(--gvs-petrol);
  color: var(--gvs-petrol);
}
.gvs-btn--secondary:hover  { background-color: var(--gvs-secondary-hover); }
.gvs-btn--secondary:active { background-color: var(--gvs-secondary-active); }
.gvs-btn--secondary:disabled,
.gvs-btn--secondary[aria-disabled="true"] {
  background-color: transparent;
  opacity: var(--gvs-disabled-opacity);
  cursor: not-allowed;
}

/* --- tertiary / text : label + 2px gold underline ----------------------- */
.gvs-btn--tertiary {
  min-width: 0;
  padding: 0 var(--gvs-space-1);
  background-color: transparent;
  color: var(--gvs-petrol);
  text-decoration: underline;
  text-decoration-color: var(--gvs-gold);
  text-decoration-thickness: var(--gvs-underline);
  text-underline-offset: var(--gvs-underline-offset-sm);
}
.gvs-btn--tertiary:hover {
  color: var(--gvs-petrol-deep);
  text-decoration-thickness: var(--gvs-underline-hover);
}
.gvs-btn--tertiary:active {
  color: var(--gvs-rasta-red);
  text-decoration-color: var(--gvs-rasta-red);
}
.gvs-btn--tertiary:disabled,
.gvs-btn--tertiary[aria-disabled="true"] {
  opacity: var(--gvs-disabled-opacity);
  text-decoration: none;
  cursor: not-allowed;
}

/* --- pill : 2px gold keyline on a dark field, radius = h/2 -------------
   .gvs-pill is Lane H3's name for the same object, so it is supported too —
   but ONLY on <a> / <button> and on the explicit modifiers. H1's
   gvs-base.css already uses a bare `.gvs-pill` as a border-radius utility,
   and a radius utility on a <span> must not inherit a whole button. */
.gvs-btn--pill,
a.gvs-pill,
button.gvs-pill,
.gvs-pill--community,
.gvs-pill--music {
  position: relative;
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--gvs-btn-icon-gap);
  height: var(--gvs-pill-h);
  min-width: var(--gvs-btn-min-md);
  padding: 0 var(--gvs-pill-pad-x);
  background-color: transparent;
  border: var(--gvs-border-width) solid var(--gvs-gold);
  border-radius: calc(var(--gvs-pill-h) / 2);
  font-family: var(--gvs-font-body);
  font-weight: var(--gvs-body-weight-em);
  font-size: var(--gvs-btn-fs-md);
  line-height: 1;
  color: var(--gvs-cream);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--gvs-t) var(--gvs-ease),
              color var(--gvs-t) var(--gvs-ease);
}
.gvs-btn--pill:hover,
a.gvs-pill:hover,
button.gvs-pill:hover,
.gvs-pill--community:hover,
.gvs-pill--music:hover {
  background-color: var(--gvs-gold);
  color: var(--gvs-text-on-gold);
}
.gvs-btn--pill:active,
a.gvs-pill:active,
button.gvs-pill:active,
.gvs-pill--community:active {
  background-color: var(--gvs-gold-active);
  color: var(--gvs-text-on-gold);
}
.gvs-btn--pill:disabled,
.gvs-btn--pill[aria-disabled="true"],
a.gvs-pill[aria-disabled="true"],
button.gvs-pill[aria-disabled="true"] {
  background-color: transparent;
  color: var(--gvs-cream);
  opacity: var(--gvs-disabled-opacity);
  cursor: not-allowed;
}
/* On a light ground the pill inverts to a petrol keyline + petrol label. */
.gvs-pill--music,
.gvs-pill--on-light {
  border-color: var(--gvs-petrol);
  color: var(--gvs-petrol);
}
.gvs-pill--music:hover,
.gvs-pill--on-light:hover { background-color: var(--gvs-secondary-hover); }

/* --- destructive : rasta red, cream label (5.2:1) ----------------------- */
.gvs-btn--danger,
.gvs-btn--destructive {
  background-color: var(--gvs-rasta-red);
  color: var(--gvs-cream);
}
.gvs-btn--danger:hover,
.gvs-btn--destructive:hover  { background-color: var(--gvs-red-hover); }
.gvs-btn--danger:active,
.gvs-btn--destructive:active { background-color: var(--gvs-red-active); }
.gvs-btn--danger:disabled,
.gvs-btn--danger[aria-disabled="true"],
.gvs-btn--destructive:disabled,
.gvs-btn--destructive[aria-disabled="true"] {
  background-color: var(--gvs-rasta-red);
  opacity: var(--gvs-disabled-opacity);
  cursor: not-allowed;
}
/* A destructive action is never the only affordance: pair it with a
   cancel, and confirm anything irreversible in a modal. */

/* --- icons inside a button ---------------------------------------------
   Glyph 16 x 16, 8px gap to the label, inherits the label colour. */
.gvs-btn__icon {
  width: var(--gvs-btn-icon);
  height: var(--gvs-btn-icon);
  flex: 0 0 auto;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* icon-right is markup order — put the <svg> after the label. */
.gvs-btn--icon-only {
  width: var(--gvs-btn-h-lg);
  min-width: 0;
  padding: 0;
}
.gvs-btn--icon-only.gvs-btn--md { width: var(--gvs-btn-h-md); }
.gvs-btn--icon-only.gvs-btn--sm { width: var(--gvs-btn-h-sm); }
/* An icon-only button ALWAYS needs an accessible name:
   <button class="gvs-btn gvs-btn--primary gvs-btn--icon-only"
           aria-label="Add event"> */

/* --- loading ------------------------------------------------------------
   The label stays. The glyph is swapped for a spinner. The button looks
   enabled but is inert, so it also carries aria-busy and aria-disabled. */
.gvs-btn--loading { cursor: progress; }
.gvs-btn__spinner {
  width: var(--gvs-btn-icon);
  height: var(--gvs-btn-icon);
  flex: 0 0 auto;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  animation: gvs-spin 720ms linear infinite;
}
@keyframes gvs-spin { to { transform: rotate(360deg); } }

/* --- shipped hero pairing ---------------------------------------------- */
.gvs-hero__actions { display: flex; gap: var(--gvs-space-3); }
.gvs-hero__actions .gvs-btn--primary   { min-width: 232px; }
.gvs-hero__actions .gvs-btn--secondary { min-width: 262px; }

/* --- a row of buttons -------------------------------------------------- */
.gvs-btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gvs-space-2);
  align-items: center;
}

/* ==========================================================================
   4 · LINKS & INLINE TEXT
   --------------------------------------------------------------------------
   A link is petrol with a 2px gold underline. The thickness never drops
   below 2px; the offset scales with the type size (~0.55em, so 8px at 15px
   and 10px at 17-18px). Colour alone is never the affordance.

   .gvs-link is the canonical name. .gvs-textlink is Lane H3's name for the
   same object and is kept in every selector below.
   ========================================================================== */
.gvs-link,
.gvs-textlink {
  color: var(--gvs-petrol);
  font-weight: 500;                         /* Medium inside body copy      */
  text-decoration: underline;
  text-decoration-color: var(--gvs-gold);
  text-decoration-thickness: var(--gvs-underline);
  text-underline-offset: var(--gvs-underline-offset);
  text-decoration-skip-ink: none;
  transition: color var(--gvs-t-fast) var(--gvs-ease),
              text-decoration-color var(--gvs-t-fast) var(--gvs-ease);
}
.gvs-link:hover,
.gvs-textlink:hover {
  color: var(--gvs-petrol-deep);
  text-decoration-thickness: var(--gvs-underline-hover);
}
.gvs-link:active,
.gvs-textlink:active {
  color: var(--gvs-rasta-red);
  text-decoration-color: var(--gvs-rasta-red);
}
/* Visited uses --gvs-teal-text #256A75 (5.12:1) so it stays legible.
   #2E7F8C would be 3.84:1 and is decorative only. */
.gvs-link:visited,
.gvs-textlink:visited { color: var(--gvs-teal-text); }
.gvs-link[aria-disabled="true"],
.gvs-textlink[aria-disabled="true"] {
  opacity: var(--gvs-disabled-opacity);
  text-decoration: none;
  cursor: not-allowed;
  pointer-events: none;
}
/* Smaller body copy keeps the tighter offset. */
.gvs-link--sm { text-underline-offset: var(--gvs-underline-offset-sm); }

/* --- on dark -------------------------------------------------------------
   Label cream, rule stays gold. Hover promotes the LABEL to gold and
   thickens the rule to 3px. The focus ring is cream (section 2) because
   gold would collide with the underline. */
.gvs-on-dark .gvs-link,
.gvs-on-dark .gvs-textlink,
.gvs-footer .gvs-link,
.gvs-footer .gvs-textlink,
.gvs-drawer .gvs-link,
.gvs-navdrawer .gvs-link {
  color: var(--gvs-cream);
  text-decoration-color: var(--gvs-gold);
}
.gvs-on-dark .gvs-link:hover,
.gvs-on-dark .gvs-textlink:hover,
.gvs-footer .gvs-link:hover,
.gvs-drawer .gvs-link:hover,
.gvs-navdrawer .gvs-link:hover { color: var(--gvs-gold); }
.gvs-on-dark .gvs-link:visited,
.gvs-on-dark .gvs-textlink:visited { color: var(--gvs-cream); }

/* --- arrow link : "Details ->" / "See the full programme ->" ------------
   As shipped on the landing page. The rule is exactly as wide as the label,
   which is what an inline-block + text-decoration gives you for free.
   The arrow is a real U+2192 in a ::after so it can be nudged on hover and
   is never read as part of the label by a screen reader. */
.gvs-arrowlink {
  display: inline-block;
  font-weight: var(--gvs-body-weight-em);
  font-size: var(--gvs-btn-fs-md);
  color: var(--gvs-petrol);
  text-decoration: underline;
  text-decoration-color: var(--gvs-gold);
  text-decoration-thickness: var(--gvs-underline);
  text-underline-offset: var(--gvs-underline-offset-sm);
  text-decoration-skip-ink: none;
  transition: color var(--gvs-t-fast) var(--gvs-ease);
}
.gvs-arrowlink::after {
  content: "\00a0\00a0\2192";
  transition: content var(--gvs-t-fast) var(--gvs-ease);
}
.gvs-arrowlink:hover {
  color: var(--gvs-petrol-deep);
  text-decoration-thickness: var(--gvs-underline-hover);
}
/* Hover nudges the arrow 4px right — done with an extra space so nothing
   reflows and no transform is needed on an inline box. */
.gvs-arrowlink:hover::after { content: "\00a0\00a0\00a0\2192"; }
.gvs-arrowlink:active {
  color: var(--gvs-rasta-red);
  text-decoration-color: var(--gvs-rasta-red);
}
.gvs-arrowlink[aria-disabled="true"] {
  opacity: var(--gvs-disabled-opacity);
  text-decoration: none;
  cursor: not-allowed;
  pointer-events: none;
}
/* 17px section-closing variant, rule 10px below the baseline. */
.gvs-arrowlink--lg {
  font-size: var(--gvs-fs-ui);
  text-underline-offset: var(--gvs-underline-offset);
}
.gvs-on-dark .gvs-arrowlink { color: var(--gvs-cream); }
.gvs-on-dark .gvs-arrowlink:hover { color: var(--gvs-gold); }

/* --- back link : arrow leads, 8px gap ----------------------------------- */
.gvs-backlink {
  display: inline-block;
  font-weight: var(--gvs-body-weight-em);
  font-size: var(--gvs-btn-fs-md);
  color: var(--gvs-petrol);
  text-decoration: underline;
  text-decoration-color: var(--gvs-gold);
  text-decoration-thickness: var(--gvs-underline);
  text-underline-offset: var(--gvs-underline-offset-sm);
}
.gvs-backlink::before { content: "\2190\00a0\00a0"; }
.gvs-backlink:hover { color: var(--gvs-petrol-deep); }
.gvs-backlink:active { color: var(--gvs-rasta-red); }

/* --- inline treatments --------------------------------------------------
   Emphasis is WEIGHT, never italic — the display face has no italic.
   Never underline text that is not a link, and never strip the underline
   from an inline link. */
.gvs-code {
  padding: 6px 12px;
  background-color: var(--gvs-bg-panel);
  border: var(--gvs-border-width) solid var(--gvs-petrol);
  border-radius: var(--gvs-radius-sm);
  font-family: var(--gvs-font-mono);
  font-size: 14px;
  color: var(--gvs-petrol);
}
.gvs-em { font-weight: var(--gvs-body-weight-em); font-style: normal; }

/* --- icon consumer class -----------------------------------------------
   The sprite in assets/icons.svg is 14 line-art symbols on a 32x32 view
   box. Colour comes from `color` via currentColor. Nothing else defines
   .gvs-icon, so it lives here.
     <svg class="gvs-icon" aria-hidden="true" focusable="false">
       <use href="../assets/icons.svg#gvs-icon-calendar"></use></svg> */
.gvs-icon {
  width: var(--gvs-icon-grid);
  height: var(--gvs-icon-grid);
  flex: 0 0 auto;
  fill: none;
  stroke: currentColor;
  stroke-width: var(--gvs-icon-stroke);
  stroke-linecap: round;
  stroke-linejoin: round;
}
.gvs-icon--inline {
  width: var(--gvs-icon-inline);
  height: var(--gvs-icon-inline);
  vertical-align: -2px;
}

/* ==========================================================================
   5 · FORM CONTROLS
   --------------------------------------------------------------------------
   56 tall on the 8px grid: cream ground, 2px petrol keyline, radius 8,
   24px horizontal padding. Placeholder and helper type is --gvs-ink-muted
   #6E655B (5.21:1 on cream) — never --gvs-soft-grey.

   Every field needs a real <label for>. Helper text and error messages are
   wired with aria-describedby; an invalid field also carries aria-invalid.
   .gvs-field is canonical; .gvs-input is Lane H3's alias.
   ========================================================================== */
.gvs-field,
.gvs-input {
  box-sizing: border-box;
  display: block;
  width: 100%;
  height: var(--gvs-field-h);
  padding: 0 var(--gvs-field-pad-x);
  background-color: var(--gvs-bg-panel);
  border: var(--gvs-border-width) solid var(--gvs-petrol);
  border-radius: var(--gvs-radius);
  font-family: var(--gvs-font-body);
  font-weight: var(--gvs-body-weight);
  font-size: var(--gvs-fs-ui);
  line-height: normal;
  color: var(--gvs-petrol);
  transition: border-color var(--gvs-t) var(--gvs-ease),
              background-color var(--gvs-t) var(--gvs-ease);
}
.gvs-field::placeholder,
.gvs-input::placeholder {
  color: var(--gvs-ink-muted);
  opacity: 1;                               /* Firefox dims it otherwise    */
}
.gvs-field:hover,
.gvs-input:hover { border-color: var(--gvs-petrol-deep); }
.gvs-field:active,
.gvs-input:active { background-color: var(--gvs-cream-hover); }
.gvs-field:disabled,
.gvs-input:disabled,
.gvs-field[aria-disabled="true"] {
  opacity: var(--gvs-disabled-opacity);
  cursor: not-allowed;
}
/* Disabled keeps its keyline at 40% and is not focusable. The text is NEVER
   greyed — greying it out is the one move that makes it unreadable. */
.gvs-field--compact,
.gvs-field--tight {
  height: var(--gvs-field-h-compact);
  font-size: var(--gvs-fs-card);
}
.gvs-field--textarea,
textarea.gvs-field {
  height: auto;
  min-height: var(--gvs-textarea-h);        /* 3 rows, grows in 24px steps  */
  padding: 16px var(--gvs-field-pad-x);
  line-height: var(--gvs-lh-card);
  resize: vertical;
}

/* --- label, helper, counter, message ------------------------------------ */
.gvs-label {
  display: block;
  margin-bottom: var(--gvs-space-1);
  font-weight: var(--gvs-body-weight-em);
  font-size: 12px;
  letter-spacing: var(--gvs-tracking-tag);
  text-transform: uppercase;
  color: var(--gvs-petrol);
}
.gvs-label__req {                            /* the asterisk               */
  color: var(--gvs-rasta-red);
  margin-left: 2px;
}
/* Helper text sits 8px under the field. .gvs-field__hint is H3's alias. */
.gvs-help,
.gvs-field__hint {
  display: block;
  margin-top: var(--gvs-space-1);
  font-size: var(--gvs-fs-micro);
  color: var(--gvs-ink-muted);              /* 5.21:1 on cream, 4.73 paper  */
}
.gvs-counter {
  display: block;
  margin-top: var(--gvs-space-1);
  font-size: 11px;
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: var(--gvs-teal-text);
}
.gvs-help-row {
  display: flex;
  gap: var(--gvs-space-2);
  justify-content: space-between;
  align-items: baseline;
}
.gvs-msg {
  display: flex;
  gap: 6px;
  align-items: baseline;
  margin-top: var(--gvs-space-1);
  font-weight: var(--gvs-body-weight-em);
  font-size: var(--gvs-fs-micro);
}
.gvs-msg--error,
.gvs-field__error,
.gvs-form-error   { color: var(--gvs-error); }
.gvs-msg--success { color: var(--gvs-ok); }
/* The message row is never the only signal — the keyline changes colour and
   the field carries aria-invalid="true". */
.gvs-field--error,
.gvs-field[aria-invalid="true"] { border-color: var(--gvs-error); }
.gvs-field--error:focus-visible,
.gvs-field[aria-invalid="true"]:focus-visible {
  outline-color: var(--gvs-focus-ring);      /* ring stays petrol           */
}
.gvs-field--success { border-color: var(--gvs-ok); }

.gvs-formgroup { display: block; }
.gvs-formgroup + .gvs-formgroup { margin-top: var(--gvs-space-3); }

/* --- select : 2px petrol divider 56 from the right, then the chevron ---
   Wrapper carries the ornament; the <select> itself carries the semantics.
   appearance:none removes the platform arrow — the chevron replaces it. */
.gvs-select { position: relative; display: block; }
.gvs-select .gvs-field,
.gvs-select .gvs-input,
select.gvs-field {
  appearance: none;
  padding-right: 72px;
}
.gvs-select::before {
  content: "";
  position: absolute;
  top: 2px;
  right: 56px;
  width: 2px;
  height: calc(100% - 4px);
  background-color: var(--gvsc-keyline-cream);   /* petrol 25%, flat        */
  pointer-events: none;
}
.gvs-select::after {
  content: "";
  position: absolute;
  top: 50%;
  right: 21px;
  width: 14px;
  height: 8px;
  transform: translateY(-50%);
  background-color: var(--gvs-petrol);
  clip-path: polygon(0 0, 50% 100%, 100% 0,
                     100% 3px, 50% calc(100% - 3px), 0 3px);
  pointer-events: none;
}

/* --- search : 16px magnifier inset 24, field padded 56 ------------------ */
.gvs-search { position: relative; display: block; }
.gvs-search .gvs-field,
.gvs-search .gvs-input { padding-left: 56px; }
.gvs-search__icon {
  position: absolute;
  top: 50%;
  left: 24px;
  width: 16px;
  height: 16px;
  transform: translateY(-50%);
  fill: none;
  stroke: var(--gvs-petrol);
  stroke-width: 2.5;
  stroke-linecap: round;
  pointer-events: none;
}

/* --- checkbox & radio : 24 x 24 -----------------------------------------
   Checked inverts to gold with a petrol glyph — the same move as the pill.
   The <label> wraps the control so the whole 44-tall row is clickable,
   which is how these reach the touch minimum. */
.gvs-check {
  display: flex;
  gap: var(--gvs-space-2);
  align-items: center;
  min-height: var(--gvsc-hit-min);
  cursor: pointer;
}
.gvs-check__box {
  appearance: none;
  box-sizing: border-box;
  flex: 0 0 auto;
  width: var(--gvs-control);
  height: var(--gvs-control);
  margin: 0;
  background-color: var(--gvs-bg-panel);
  border: var(--gvs-border-width) solid var(--gvs-petrol);
  border-radius: var(--gvs-radius-sm);
  cursor: pointer;
  transition: background-color var(--gvs-t-fast) var(--gvs-ease);
}
.gvs-check__box[type="radio"] { border-radius: 50%; }
.gvs-check__box:hover { background-color: var(--gvs-cream-hover); }
.gvs-check__box:checked {
  background-color: var(--gvs-gold);
  border-color: var(--gvs-petrol);
  /* petrol tick, drawn as a data URI so no sprite dependency and no
     pseudo-element that could be defeated by a UA stylesheet */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5 12l4 4 10-10' fill='none' stroke='%231B4A5A' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-size: 20px 20px;
  background-position: center;
  background-repeat: no-repeat;
}
.gvs-check__box[type="radio"]:checked {
  background-color: var(--gvs-bg-panel);
  background-image: none;
  box-shadow: inset 0 0 0 6px var(--gvs-petrol);   /* 12px petrol dot       */
}
.gvs-check__box:disabled,
.gvs-check:has(.gvs-check__box:disabled) {
  opacity: var(--gvs-disabled-opacity);
  cursor: not-allowed;
}
.gvs-check__label {
  font-size: var(--gvs-fs-card);
  color: var(--gvs-petrol);
}
/* Groups of checkboxes or radios go in <fieldset> with a <legend>. */
.gvs-fieldset { margin: 0; padding: 0; border: 0; }
.gvs-legend {
  padding: 0;
  margin-bottom: var(--gvs-space-1);
  font-weight: var(--gvs-body-weight-em);
  font-size: 12px;
  letter-spacing: var(--gvs-tracking-tag);
  text-transform: uppercase;
  color: var(--gvs-petrol);
}

/* --- toggle switch : 56 x 32, knob 24 ----------------------------------
   A real <input type="checkbox" role="switch">, restyled. Off is a cream
   track with a petrol knob; on is a gold track with the knob at +24. */
.gvs-toggle {
  appearance: none;
  position: relative;
  box-sizing: border-box;
  flex: 0 0 auto;
  width: var(--gvs-toggle-w);
  height: var(--gvs-toggle-h);
  margin: 0;
  background-color: var(--gvs-bg-panel);
  border: var(--gvs-border-width) solid var(--gvs-petrol);
  border-radius: calc(var(--gvs-toggle-h) / 2);
  cursor: pointer;
  transition: background-color var(--gvs-t) var(--gvs-ease);
}
.gvs-toggle::before {                        /* hit-extender to 44 tall     */
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  height: var(--gvsc-hit-min);
  transform: translateY(-50%);
}
.gvs-toggle::after {                         /* the knob                    */
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: var(--gvs-toggle-knob);
  height: var(--gvs-toggle-knob);
  background-color: var(--gvs-petrol);
  border-radius: 50%;
  transition: transform var(--gvs-t) var(--gvs-ease);
}
.gvs-toggle:hover { background-color: var(--gvs-cream-hover); }
.gvs-toggle:checked { background-color: var(--gvs-gold); }
.gvs-toggle:checked::after { transform: translateX(24px); }
.gvs-toggle:active::after,
.gvs-toggle:checked:active::after { transform: scale(0.94); }
.gvs-toggle:checked:active::after { transform: translateX(24px) scale(0.94); }
.gvs-toggle:disabled {
  opacity: var(--gvs-disabled-opacity);
  cursor: not-allowed;
}

/* --- file / upload : 2px dashed petrol, 116 tall -----------------------
   The real <input type="file"> stays in the DOM, visually hidden but
   focusable; the styled face is its <label>, so click and keyboard both
   work with no JavaScript. The focus ring is drawn on the face — see the
   `.gvs-upload__input:focus-visible + .gvs-upload__face` selector in
   section 2. */
.gvs-upload { position: relative; display: block; }
.gvs-upload__input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
}
.gvs-upload__face {
  display: grid;
  place-items: center;
  gap: 6px;
  box-sizing: border-box;
  min-height: var(--gvs-upload-h);
  padding: var(--gvs-space-2);
  background-color: var(--gvs-bg-panel);
  border: var(--gvs-border-width) dashed var(--gvs-petrol);
  border-radius: var(--gvs-radius);
  text-align: center;
  cursor: pointer;
  transition: background-color var(--gvs-t) var(--gvs-ease),
              border-color var(--gvs-t) var(--gvs-ease);
}
.gvs-upload:hover .gvs-upload__face,
.gvs-upload--dragover .gvs-upload__face {
  background-color: var(--gvs-cream-hover);
  border-color: var(--gvs-petrol-deep);
}
.gvs-upload--dragover .gvs-upload__face { border-style: solid; }
.gvs-upload__label {
  font-weight: var(--gvs-body-weight-em);
  font-size: var(--gvs-fs-card);
  color: var(--gvs-petrol);
}
.gvs-upload__hint {
  font-size: var(--gvs-fs-micro);
  color: var(--gvs-ink-muted);
}
.gvs-upload[aria-disabled="true"] {
  opacity: var(--gvs-disabled-opacity);
  cursor: not-allowed;
}
.gvs-upload[aria-disabled="true"] .gvs-upload__input { pointer-events: none; }

/* --- quantity stepper : 160 x 56, two 40px zones -----------------------
   Two real <button>s around a number input. The buttons are 40 wide, so a
   ::after extends each pointer target to 44. */
.gvs-stepper {
  display: grid;
  grid-template-columns: var(--gvs-stepper-zone) 1fr var(--gvs-stepper-zone);
  align-items: stretch;
  box-sizing: border-box;
  width: var(--gvs-stepper-w);
  height: var(--gvs-field-h);
  background-color: var(--gvs-bg-panel);
  border: var(--gvs-border-width) solid var(--gvs-petrol);
  border-radius: var(--gvs-radius);
  overflow: hidden;
}
.gvs-stepper__btn {
  position: relative;
  display: grid;
  place-items: center;
  padding: 0;
  background-color: transparent;
  border: 0;
  font-size: 20px;
  line-height: 1;
  color: var(--gvs-petrol);
  cursor: pointer;
}
.gvs-stepper__btn::after {                   /* hit-extender to 44 wide     */
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: -2px;
  right: -2px;
}
.gvs-stepper__btn:hover  { background-color: var(--gvs-secondary-hover); }
.gvs-stepper__btn:active { background-color: var(--gvs-secondary-active); }
.gvs-stepper__btn:disabled {
  opacity: var(--gvs-disabled-opacity);
  cursor: not-allowed;
}
.gvs-stepper__value {
  appearance: none;
  -moz-appearance: textfield;
  width: 100%;
  height: 100%;
  padding: 0;
  background-color: transparent;
  border: 0;
  border-left: 2px solid var(--gvsc-keyline-cream);
  border-right: 2px solid var(--gvsc-keyline-cream);
  font-family: var(--gvs-font-body);
  font-weight: var(--gvs-body-weight-em);
  font-size: var(--gvs-fs-ui);
  text-align: center;
  font-variant-numeric: tabular-nums;
  color: var(--gvs-petrol);
}
.gvs-stepper__value::-webkit-outer-spin-button,
.gvs-stepper__value::-webkit-inner-spin-button {
  appearance: none;
  margin: 0;
}

/* --- form layout --------------------------------------------------------
   Fields 24px apart, submit 32px below the last field. */
.gvs-form { display: grid; gap: var(--gvs-space-3); }
.gvs-form__row2,
.gvs-form-row2 {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--gvs-space-3);
}
.gvs-form__submit { margin-top: var(--gvs-space-1); justify-self: start; }
.gvs-form__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gvs-space-2);
  margin-top: var(--gvs-space-1);
}

/* --- newsletter capture row, exactly as shipped -----------------------
   Field 680 + 24 gap + 160 button, reassurance to the right. Stacks below
   860 so the field never drops under 280. */
.gvs-newsletter {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gvs-space-3);
  align-items: center;
}
.gvs-newsletter .gvs-field,
.gvs-newsletter .gvs-input { flex: 1 1 280px; max-width: 680px; }
.gvs-newsletter .gvs-btn {
  flex: 0 0 auto;
  min-width: 160px;
}
.gvs-newsletter__reassure {
  flex: 0 1 200px;
  font-size: var(--gvs-fs-micro);
  line-height: 18px;
  color: var(--gvs-ink-muted);
}

/* ==========================================================================
   6 · CARDS & PANELS
   --------------------------------------------------------------------------
   Cream ground, 2px petrol keyline, radius 8, 24-32px padding.
   NO SHADOWS — the keyline does the lifting. Images sit flush inside the
   keyline at radius 6.

   Hover on any card: the keyline goes to --gvs-petrol-deep and the card
   lifts 2px. No shadow, ever.

   IMAGE ASPECT RATIOS (set on .gvs-card__img, so the box is reserved before
   the image loads and nothing reflows):
     post card      16 / 9
     event card      3 / 2
     wide feature   48 / 35   (the shipped renovation frame)
   ========================================================================== */
.gvs-card {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  padding: var(--gvs-space-3);
  background-color: var(--gvs-bg-panel);
  border: var(--gvs-border-width) solid var(--gvs-petrol);
  border-radius: var(--gvs-radius);
  color: var(--gvs-petrol);
  text-decoration: none;
  transition: border-color var(--gvs-t) var(--gvs-ease),
              transform var(--gvs-t) var(--gvs-ease);
}
a.gvs-card:hover,
.gvs-card--interactive:hover {
  border-color: var(--gvs-petrol-deep);
  transform: translateY(-2px);
}
a.gvs-card:active,
.gvs-card--interactive:active { transform: translateY(0); }
.gvs-card[aria-disabled="true"] {
  opacity: var(--gvs-disabled-opacity);
  pointer-events: none;
}
/* A whole-card link keeps ONE link, on the heading, and stretches it over
   the card with ::after — so the accessible name is the heading, not the
   entire card contents. See COMPONENTS.md. */
.gvs-card--linked { position: relative; }
.gvs-card--linked .gvs-card__title a::after {
  content: "";
  position: absolute;
  inset: 0;
}

.gvs-card__img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 6px;
  object-fit: cover;
}
.gvs-card__body { font-size: var(--gvs-fs-card); line-height: var(--gvs-lh-card); }
.gvs-card__foot,
.gvs-cardfoot {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gvs-space-2);
  align-items: center;
  margin-top: auto;
  padding-top: var(--gvs-space-2);
}

/* --- the shipped What-We-Do card : 282 x 336 --------------------------- */
.gvs-card--what {
  width: 100%;
  max-width: var(--gvs-card-width);         /* 282 */
  min-height: 336px;
  padding: var(--gvs-space-4);              /* 32 */
}
/* Badge disc: 76px, petrol at 8% mixed FLAT so the icon on top stays
   full-strength petrol. Opacity on the disc would fade the glyph with it. */
.gvs-card--what .gvs-card__badge,
.gvs-card--what .gvs-card__icon {
  display: grid;
  place-items: center;
  width: var(--gvs-icon-disc);              /* 76 */
  height: var(--gvs-icon-disc);
  border-radius: 50%;
  background-color: var(--gvsc-icon-disc);
  color: var(--gvs-petrol);
}
.gvs-card--what .gvs-card__head,
.gvs-card--what .gvs-card__title {
  margin-top: var(--gvs-space-4);
  font-family: var(--gvs-font-display);
  font-weight: var(--gvs-display-weight);
  font-size: var(--gvs-fs-card-h);          /* 26 */
  line-height: var(--gvs-lh-card-h);        /* 30 */
  text-transform: uppercase;
  color: var(--gvs-petrol);
}
.gvs-card--what .gvs-card__body {
  margin-top: var(--gvs-space-2);
  font-size: var(--gvs-fs-card);            /* 15 */
  line-height: var(--gvs-lh-card);          /* 22 */
}

/* --- blog post card : 340 wide, 16:9 image ---------------------------- */
.gvs-card--post,
.gvs-post-card {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 340px;
  padding: 0;
  overflow: hidden;
  background-color: var(--gvs-bg-panel);
  border: var(--gvs-border-width) solid var(--gvs-petrol);
  border-radius: var(--gvs-radius);
  color: var(--gvs-petrol);
  text-decoration: none;
}
.gvs-card--post .gvs-card__img,
.gvs-post-card .gvs-card__img {
  aspect-ratio: 16 / 9;
  border-radius: 6px 6px 0 0;
}
.gvs-card--post .gvs-card__inner,
.gvs-post-card .gvs-card__inner { padding: var(--gvs-space-3); }
/* meta = date + separator + category, teal caps 11 at 0.12em */
.gvs-card__meta {
  display: flex;
  gap: 8px;
  align-items: baseline;
  font-weight: var(--gvs-body-weight-em);
  font-size: 11px;
  letter-spacing: var(--gvs-tracking-tag);
  text-transform: uppercase;
  color: var(--gvs-teal-text);
}
.gvs-card__title {
  margin-top: var(--gvs-space-2);
  font-family: var(--gvs-font-display);
  font-weight: var(--gvs-display-weight);
  font-size: 24px;
  line-height: 27px;
  text-transform: uppercase;
  color: var(--gvs-petrol);
}
.gvs-card__title a {
  color: inherit;
  text-decoration: none;
}
.gvs-card__title a:hover { text-decoration: underline;
  text-decoration-color: var(--gvs-gold);
  text-decoration-thickness: var(--gvs-underline);
  text-underline-offset: 6px; }
.gvs-card__excerpt {
  margin-top: var(--gvs-space-1);
  font-size: var(--gvs-fs-meta);            /* 14 */
  line-height: 21px;
  color: var(--gvs-petrol);
}

/* --- event card : 340 wide, 3:2 image --------------------------------- */
.gvs-card--event {
  width: 100%;
  max-width: 340px;
  padding: 0;
  overflow: hidden;
}
.gvs-card--event .gvs-card__img {
  aspect-ratio: 3 / 2;
  border-radius: 6px 6px 0 0;
}
.gvs-card--event .gvs-card__inner { padding: var(--gvs-space-3); }

/* --- wide feature card : image left, copy right ----------------------- */
.gvs-card--feature {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--gvs-space-4);
  padding: var(--gvs-space-4);
}
.gvs-card--feature .gvs-card__img { aspect-ratio: 48 / 35; }

/* --- stat panel ------------------------------------------------------- */
.gvs-stat {
  box-sizing: border-box;
  display: grid;
  gap: 6px;
  padding: var(--gvs-space-3);
  background-color: var(--gvs-bg-panel);
  border: var(--gvs-border-width) solid var(--gvs-petrol);
  border-radius: var(--gvs-radius);
}
.gvs-stat__num {
  font-family: var(--gvs-font-display);
  font-weight: var(--gvs-display-weight);
  font-size: var(--gvs-fs-h3);              /* 30 */
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--gvs-petrol);
}
.gvs-stat__label {
  font-weight: var(--gvs-body-weight-em);
  font-size: var(--gvs-fs-micro);
  letter-spacing: var(--gvs-tracking-tag);
  text-transform: uppercase;
  color: var(--gvs-teal-text);
}
.gvs-stat__note { font-size: var(--gvs-fs-meta); color: var(--gvs-ink-muted); }

/* --- quote panel : petrol ground, 64 x 4 gold rule -------------------- */
.gvs-quote-panel {
  box-sizing: border-box;
  padding: var(--gvs-space-4);
  background-color: var(--gvs-petrol);
  border-radius: var(--gvs-radius);
  color: var(--gvs-cream);
}
.gvs-quote__text {
  margin: 0;
  font-family: var(--gvs-font-display);
  font-weight: var(--gvs-display-weight);
  font-size: 26px;
  line-height: 32px;
  text-transform: uppercase;
  color: var(--gvs-cream);
}
.gvs-quote__rule {
  width: 64px;
  height: 4px;
  margin: var(--gvs-space-3) 0;
  background-color: var(--gvs-gold);
  border: 0;
}
.gvs-quote__attr {
  font-size: var(--gvs-fs-meta);
  color: var(--gvsc-cream-75-petrol);       /* 5.76:1, flat mix not opacity  */
}

/* ==========================================================================
   7 · CHIPS, BADGES, TAGS & THE DATE CHIP
   --------------------------------------------------------------------------
   Small, dense labels. Only ONE of them is interactive:

     .gvs-tag         interactive filter  -> hover, active, focus, disabled
     .gvs-badge       output only         -> no hover, no focus, not tabbable
     .gvs-counter-badge  output only      -> ditto
     .gvs-date-chip   output only         -> ditto

   Giving a badge a hover state teaches people to click something that does
   nothing, so they deliberately have none.
   ========================================================================== */

/* --- the date chip, as shipped on event rows ---------------------------
   Petrol square, radius 4, cream day over gold time. 72 is the shipped
   size; --sm is 56 and --lg is 88. Hyphenated name only, per Lane H3's
   markup, with .gvs-datechip kept as an alias because the Volume B spec
   and the landing comp both use it. */
.gvs-date-chip,
.gvs-datechip {
  box-sizing: border-box;
  display: grid;
  place-content: center;
  gap: 2px;
  width: var(--gvs-chip-date);
  height: var(--gvs-chip-date);
  background-color: var(--gvs-petrol);
  border-radius: var(--gvs-radius-sm);
  text-align: center;
}
.gvs-date-chip__day,
.gvs-datechip__day {
  font-family: var(--gvs-font-display);
  font-weight: var(--gvs-display-weight);
  font-size: 26px;
  line-height: 1;
  text-transform: uppercase;
  color: var(--gvs-cream);                  /* 8.81:1 on petrol             */
}
.gvs-date-chip__time,
.gvs-datechip__time {
  font-weight: var(--gvs-body-weight-em);
  font-size: 11px;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--gvs-gold);                   /* 5.03:1 on petrol             */
}
.gvs-date-chip--sm,
.gvs-datechip--sm { width: 56px; height: 56px; }
.gvs-date-chip--sm .gvs-date-chip__day,
.gvs-datechip--sm .gvs-datechip__day { font-size: 20px; }
.gvs-date-chip--sm .gvs-date-chip__time,
.gvs-datechip--sm .gvs-datechip__time { font-size: 9px; }
.gvs-date-chip--lg,
.gvs-datechip--lg { width: 88px; height: 88px; }
.gvs-date-chip--lg .gvs-date-chip__day,
.gvs-datechip--lg .gvs-datechip__day { font-size: 32px; }
.gvs-date-chip--lg .gvs-date-chip__time,
.gvs-datechip--lg .gvs-datechip__time { font-size: 13px; }
/* The chip is decoration over a real date. Put the machine-readable value
   in <time datetime="..."> and hide the abbreviation from AT if the row
   already states the full date. */

/* --- the shipped event row -------------------------------------------- */
.gvs-eventrow,
.gvs-event-row {
  box-sizing: border-box;
  display: flex;
  gap: var(--gvs-space-3);
  align-items: center;
  padding: var(--gvs-space-2);
  background-color: var(--gvs-bg-panel);
  border: var(--gvs-border-width) solid var(--gvs-petrol);
  border-radius: var(--gvs-radius);
  color: var(--gvs-petrol);
  text-decoration: none;
  transition: border-color var(--gvs-t) var(--gvs-ease);
}
a.gvs-eventrow:hover,
a.gvs-event-row:hover { border-color: var(--gvs-petrol-deep); }
.gvs-eventrow__body,
.gvs-event-row__body { flex: 1 1 auto; min-width: 0; }
.gvs-eventrow__title,
.gvs-event-row__title {
  font-family: var(--gvs-font-display);
  font-weight: var(--gvs-display-weight);
  font-size: 20px;
  line-height: 24px;
  text-transform: uppercase;
  color: var(--gvs-petrol);
}
.gvs-eventrow__desc,
.gvs-event-row__desc {
  margin-top: 4px;
  font-size: var(--gvs-fs-meta);
  color: var(--gvs-petrol);
}
.gvs-eventrow__aside,
.gvs-event-row__aside { flex: 0 0 auto; margin-left: auto; }
.gvs-event-row__tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gvs-space-1);
  margin-top: var(--gvs-space-1);
}

/* --- category tags : INTERACTIVE filters ------------------------------
   Cream ground, 2px petrol keyline, radius 4, 28 tall, 11px caps at 0.12em.
   Pressed state is a real aria-pressed toggle, not a class alone.
   The visual box is 28 tall, so a ::after grows the pointer target to 44. */
.gvs-tag {
  position: relative;
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: var(--gvs-tag-h);
  padding: 0 var(--gvs-tag-pad-x);
  background-color: var(--gvs-bg-panel);
  border: var(--gvs-border-width) solid var(--gvs-petrol);
  border-radius: var(--gvs-radius-sm);
  font-family: var(--gvs-font-body);
  font-weight: var(--gvs-body-weight-em);
  font-size: var(--gvs-tag-fs);
  line-height: 1;
  letter-spacing: var(--gvs-tracking-tag);
  text-transform: uppercase;
  color: var(--gvs-petrol);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--gvs-t-fast) var(--gvs-ease),
              color var(--gvs-t-fast) var(--gvs-ease);
}
.gvs-tag::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  height: var(--gvsc-hit-min);
  transform: translateY(-50%);
}
.gvs-tag:hover  { background-color: var(--gvs-secondary-hover); }
.gvs-tag:active { background-color: var(--gvs-secondary-active); }
.gvs-tag[aria-pressed="true"],
.gvs-tag--active {
  background-color: var(--gvs-petrol);
  color: var(--gvs-cream);
}
.gvs-tag[aria-disabled="true"],
.gvs-tag:disabled {
  opacity: var(--gvs-disabled-opacity);
  cursor: not-allowed;
}
.gvs-tag-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gvs-space-1);
  align-items: center;
}

/* --- status badges : OUTPUT ONLY --------------------------------------
   One status badge per item. Sold out beats free.
   Soft grey is NEVER a badge ground — it fails against cream and petrol
   both. "Cancelled" is neutral petrol-deep, not red: red means "you cannot
   get in", not "this changed". */
.gvs-badge {
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  height: var(--gvs-badge-h);
  padding: 0 var(--gvs-badge-pad-x);
  border-radius: var(--gvs-radius-sm);
  font-family: var(--gvs-font-body);
  font-weight: var(--gvs-body-weight-em);
  font-size: var(--gvs-badge-fs);
  line-height: 1;
  letter-spacing: var(--gvs-tracking-tag);
  text-transform: uppercase;
  white-space: nowrap;
}
.gvs-badge--free {
  background-color: var(--gvs-ok);
  color: var(--gvs-cream);                  /* 6.00:1                       */
}
.gvs-badge--members {
  background-color: var(--gvs-gold);
  color: var(--gvs-text-on-gold);           /* 5.03:1                       */
}
.gvs-badge--soldout {
  background-color: var(--gvs-rasta-red);
  color: var(--gvs-cream);                  /* 5.2:1                        */
}
.gvs-badge--cancelled {
  background-color: var(--gvs-neutral);     /* petrol-deep, NOT red         */
  color: var(--gvs-cream);                  /* 11.77:1                      */
}

/* --- counter badge : OUTPUT ONLY, two digits max, then 9+ -------------
   Never on bare paper — a counter needs a field behind it. */
.gvs-counter-badge {
  box-sizing: border-box;
  display: inline-grid;
  place-items: center;
  min-width: var(--gvs-counter);
  height: var(--gvs-counter);
  padding: 0 6px;
  background-color: var(--gvs-petrol);
  border-radius: calc(var(--gvs-counter) / 2);
  font-weight: var(--gvs-body-weight-em);
  font-size: 11px;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--gvs-cream);
}
.gvs-counter-badge--sm {
  min-width: 18px;
  height: 18px;
  font-size: 10px;
}
.gvs-on-dark .gvs-counter-badge {
  background-color: var(--gvs-gold);
  color: var(--gvs-text-on-gold);
}

/* --- gold-outlined community pill on dark ----------------------------
   Non-interactive variant of the pill: a label, not a control. Use the
   <a>/<button> pill in section 3 when it is actually clickable. */
.gvs-pill-label {
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  height: var(--gvs-pill-h);
  padding: 0 var(--gvs-pill-pad-x);
  border: var(--gvs-border-width) solid var(--gvs-gold);
  border-radius: calc(var(--gvs-pill-h) / 2);
  font-weight: var(--gvs-body-weight-em);
  font-size: var(--gvs-btn-fs-md);
  line-height: 1;
  color: var(--gvs-cream);
  white-space: nowrap;
}

/* ==========================================================================
   8 · NAVIGATION
   --------------------------------------------------------------------------
   Desktop bar 96 tall: small seal mark, wordmark, links with a gold active
   indicator, gold Support Us at the right. Sticky/condensed is 96 -> 72 and
   drops the mark to 32. Mobile is a 72 header plus a drawer.

   Keyboard: the mega panel and the drawer are disclosures on a real
   <button aria-expanded>. Esc closes and returns focus to the trigger.
   The current page is marked aria-current="page", which is what draws the
   gold indicator — it is not a decorative class.
   ========================================================================== */
.gvs-nav {
  box-sizing: border-box;
  display: flex;
  align-items: center;
  gap: var(--gvs-space-3);
  height: var(--gvs-nav-h);                 /* 96 */
  padding: 0 var(--gvs-space-3);
  background-color: var(--gvs-bg);
  border-bottom: var(--gvs-border-width) solid var(--gvsc-keyline-paper);
}
.gvs-nav__inner {
  display: flex;
  align-items: center;
  gap: var(--gvs-space-3);
  width: 100%;
  max-width: var(--gvs-content-width);
  margin: 0 auto;
}
.gvs-nav__brand {
  display: flex;
  gap: var(--gvs-space-2);
  align-items: center;
  text-decoration: none;
  color: var(--gvs-petrol);
}
.gvs-nav__mark {
  width: var(--gvs-nav-mark);               /* 44 — also the min mark size  */
  height: var(--gvs-nav-mark);
  flex: 0 0 auto;
}
.gvs-nav__wordmark {
  font-family: var(--gvs-font-display);
  font-weight: var(--gvs-display-weight);
  font-size: 19px;
  line-height: 1;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--gvs-petrol);
}
.gvs-nav__links,
.gvs-nav__nav {
  display: flex;
  gap: var(--gvs-nav-gap);                  /* 34 */
  align-items: center;
  margin-left: auto;
  list-style: none;
  padding: 0;
}
.gvs-nav__link {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: var(--gvsc-hit-min);
  font-weight: 500;
  font-size: var(--gvs-fs-card);
  color: var(--gvs-petrol);
  text-decoration: none;
  transition: color var(--gvs-t-fast) var(--gvs-ease);
}
.gvs-nav__link:hover { color: var(--gvs-petrol-deep); }
/* The 3px gold indicator, 10px under the label. Hover shows it, the current
   page keeps it. */
.gvs-nav__link:hover::after,
.gvs-nav__link[aria-current="page"]::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(50% - 0.5em - var(--gvs-space-2));
  height: var(--gvs-nav-indicator);
  background-color: var(--gvs-gold);
}
.gvs-nav__link:active { color: var(--gvs-rasta-red); }
.gvs-nav__link[aria-disabled="true"] {
  opacity: var(--gvs-disabled-opacity);
  cursor: not-allowed;
  pointer-events: none;
}
.gvs-nav__cta {
  flex: 0 0 auto;
  min-width: 132px;
  margin-left: var(--gvs-space-3);
}

/* --- sticky / condensed : 72 tall, mark 32, cream ground ------------- */
.gvs-nav--sticky,
.gvs-nav--condensed {
  position: sticky;
  top: 0;
  z-index: var(--gvs-z-nav);
  height: var(--gvs-nav-h-sticky);          /* 72 */
  background-color: var(--gvs-bg-panel);
  border-bottom: var(--gvs-border-width) solid var(--gvs-petrol);
}
.gvs-nav--sticky .gvs-nav__mark,
.gvs-nav--condensed .gvs-nav__mark { width: 32px; height: 32px; }
.gvs-nav--sticky .gvs-nav__wordmark,
.gvs-nav--condensed .gvs-nav__wordmark { font-size: 16px; }
.gvs-nav--sticky .gvs-nav__link,
.gvs-nav--condensed .gvs-nav__link { font-size: var(--gvs-fs-meta); }
.gvs-nav--sticky .gvs-nav__cta .gvs-btn,
.gvs-nav--condensed .gvs-nav__cta .gvs-btn {
  height: var(--gvs-btn-h-sm);
  min-width: 116px;
  font-size: var(--gvs-fs-meta);
}

/* --- mega / dropdown panel : 640 wide -------------------------------- */
.gvs-nav__disclosure { position: relative; }
.gvs-mega {
  box-sizing: border-box;
  position: absolute;
  top: calc(100% + var(--gvs-space-1));
  left: 0;
  z-index: var(--gvs-z-nav);
  width: var(--gvs-mega-w);                 /* 640 */
  max-width: calc(100vw - 2 * var(--gvs-space-3));
  padding: var(--gvs-space-4);
  background-color: var(--gvs-bg-panel);
  border: var(--gvs-border-width) solid var(--gvs-petrol);
  border-radius: var(--gvs-radius);
}
/* Closed by the hidden attribute, so it is closed for AT too, not just
   visually. No JS => the panel is simply always open and still usable. */
.gvs-mega[hidden] { display: none; }
.gvs-mega__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--gvs-space-4);
}
.gvs-mega__colh {
  font-weight: var(--gvs-body-weight-em);
  font-size: 11px;
  letter-spacing: var(--gvs-tracking-tag);
  text-transform: uppercase;
  color: var(--gvs-gold);
}
/* Gold on cream is 1.6:1, so a gold column head is only allowed at this
   size when it is a LABEL over a list whose items carry the meaning.
   On a light ground use the petrol variant instead — do that by default. */
.gvs-mega__colh { color: var(--gvs-teal-text); }   /* 5.5:1 on cream        */
.gvs-mega__list {
  margin: var(--gvs-space-2) 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 13px;
}
.gvs-mega__list a {
  display: inline-flex;
  align-items: center;
  min-height: 30px;
  font-weight: 500;
  font-size: var(--gvs-fs-card);
  color: var(--gvs-petrol);
  text-decoration: none;
}
.gvs-mega__list a:hover {
  text-decoration: underline;
  text-decoration-color: var(--gvs-gold);
  text-decoration-thickness: var(--gvs-underline);
  text-underline-offset: 6px;
}
.gvs-mega__div {
  height: 1px;
  margin: var(--gvs-space-3) 0;
  background-color: var(--gvsc-keyline-panel);
  border: 0;
}
.gvs-mega__feature {
  display: flex;
  gap: var(--gvs-space-2);
  align-items: center;
  padding: var(--gvs-space-2);
  background-color: var(--gvs-bg);
  border-radius: var(--gvs-radius-sm);
  font-size: var(--gvs-fs-meta);
  color: var(--gvs-petrol);
  text-decoration: none;
}
.gvs-mega__feature:hover { background-color: var(--gvs-secondary-hover); }

/* --- mobile header 390 + burger ------------------------------------- */
.gvs-nav--mobile {
  height: var(--gvs-mobile-nav-h);          /* 72 */
  padding: 0 var(--gvs-space-2);
}
.gvs-nav--mobile .gvs-nav__mark { width: 32px; height: 32px; }
.gvs-nav--mobile .gvs-nav__wordmark { font-size: 15px; }
.gvs-burger {
  display: grid;
  place-content: center;
  gap: 6px;
  box-sizing: border-box;
  width: var(--gvsc-hit-min);
  height: var(--gvsc-hit-min);
  margin-left: auto;
  padding: 0;
  background-color: transparent;
  border: 0;
  cursor: pointer;
}
.gvs-burger span {
  display: block;
  width: 24px;
  height: 2px;
  background-color: var(--gvs-petrol);
}
.gvs-burger:hover span { background-color: var(--gvs-petrol-deep); }

/* --- drawer ---------------------------------------------------------
   Deep petrol field, 48-tall rows, Rasta foot edge. .gvs-navdrawer is
   Lane H3's name for the same object. */
.gvs-drawer,
.gvs-navdrawer {
  box-sizing: border-box;
  position: relative;
  display: grid;
  gap: 0;
  width: 100%;
  max-width: var(--gvs-mobile-w);           /* 390 */
  padding: var(--gvs-space-3) var(--gvs-space-3) var(--gvs-space-6);
  background-color: var(--gvs-bg-inverse);
  color: var(--gvs-cream);
}
.gvs-drawer[hidden],
.gvs-navdrawer[hidden] { display: none; }
.gvs-drawer a,
.gvs-navdrawer a {
  display: flex;
  align-items: center;
  min-height: 48px;
  font-weight: 500;
  font-size: var(--gvs-fs-ui);
  color: var(--gvs-cream);
  text-decoration: none;
  border-bottom: 1px solid var(--gvsc-footer-rule);
}
.gvs-drawer a:hover,
.gvs-navdrawer a:hover { color: var(--gvs-gold); }
.gvs-drawer a[aria-current="page"],
.gvs-navdrawer a[aria-current="page"] {
  color: var(--gvs-gold);
  font-weight: var(--gvs-body-weight-em);
}
.gvs-drawer .gvs-btn,
.gvs-navdrawer .gvs-btn,
.gvs-drawer .gvs-pill,
.gvs-navdrawer__cta {
  height: 48px;
  margin-top: var(--gvs-space-3);
}
/* Rasta foot edge on the drawer, same 20px as the page foot. */
.gvs-drawer::after,
.gvs-navdrawer::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: var(--gvs-footedge-height);
  background: var(--gvs-rasta);
}

/* --- skip to content --------------------------------------------------
   Off-canvas until focused, then a real gold button at the top left.
   H1's base ships .gvs-skip-link; .gvs-skip is the Volume B name and is
   defined here so either markup works. */
.gvs-skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: var(--gvs-z-toast, 200);
  display: inline-flex;
  align-items: center;
  height: 40px;
  padding: 0 var(--gvs-space-2);
  background-color: var(--gvs-gold);
  border-radius: 0 0 var(--gvs-radius) 0;
  font-weight: var(--gvs-body-weight-em);
  font-size: var(--gvs-fs-meta);
  color: var(--gvs-text-on-gold);
  text-decoration: none;
}
.gvs-skip:focus,
.gvs-skip:focus-visible { left: 0; }

/* --- breadcrumbs -----------------------------------------------------
   <nav aria-label="Breadcrumb"> + <ol>. The separator is a decorative
   ::before on each item after the first and is hidden from AT. */
.gvs-crumbs { font-size: var(--gvs-fs-meta); }
.gvs-crumbs ol {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gvs-space-1);
  align-items: center;
  margin: 0;
  padding: 0;
  list-style: none;
}
.gvs-crumbs li + li::before {
  content: "/";
  margin-right: var(--gvs-space-1);
  color: var(--gvsc-crumb-sep);             /* decorative, aria-hidden       */
}
.gvs-crumbs a {
  color: var(--gvs-petrol);
  text-decoration: underline;
  text-decoration-color: var(--gvs-gold);
  text-decoration-thickness: var(--gvs-underline);
  text-underline-offset: 6px;
}
.gvs-crumbs a:hover { color: var(--gvs-petrol-deep); }
/* AA-FIX: the spec dimmed the current page to petrol 70% = 3.88:1.
   --gvs-ink-muted is 4.73:1 and reads as the same recessive step. */
.gvs-crumbs [aria-current="page"] {
  color: var(--gvs-ink-muted);
  font-weight: var(--gvs-body-weight-em);
}

/* ==========================================================================
   9 · STRUCTURE & FEEDBACK
   ========================================================================== */

/* --- tabs : bar 48 tall, 4px gold rule on the active tab -------------
   Real ARIA tabs: role="tablist" / role="tab" / role="tabpanel".
   Arrow keys move between tabs, Home/End jump to the ends, only the
   selected tab is in the tab sequence (tabindex="-1" on the rest).
   Requires the 12-line script in components.html. Without JS, every panel
   is visible and the page still reads top to bottom. */
.gvs-tabs { display: block; }
.gvs-tablist {
  display: flex;
  gap: var(--gvs-space-3);
  align-items: stretch;
  height: var(--gvs-tab-h);                 /* 48 */
  border-bottom: var(--gvs-border-width) solid var(--gvsc-keyline-paper);
}
.gvs-tab {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: var(--gvsc-hit-min);
  padding: 0;
  background-color: transparent;
  border: 0;
  font-family: var(--gvs-font-body);
  font-weight: var(--gvs-body-weight-em);
  font-size: var(--gvs-fs-meta);
  /* AA-FIX: the spec dimmed inactive tabs to 60% = 3.04:1 on paper.
     This flat mix is petrol at 80% = 4.87:1 and still reads recessive. */
  color: var(--gvsc-petrol-recessive);
  cursor: pointer;
  transition: color var(--gvs-t-fast) var(--gvs-ease);
}
.gvs-tab:hover { color: var(--gvs-petrol); }
.gvs-tab[aria-selected="true"],
.gvs-tab--active { color: var(--gvs-petrol); }
/* The 4px gold rule sits flush on the bar's bottom edge. */
.gvs-tab[aria-selected="true"]::after,
.gvs-tab--active::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(-1 * var(--gvs-border-width));
  height: var(--gvs-tab-indicator);
  background-color: var(--gvs-gold);
}
.gvs-tab:disabled,
.gvs-tab[aria-disabled="true"] {
  opacity: var(--gvs-disabled-opacity);
  cursor: not-allowed;
}
.gvs-tabpanel { padding-top: var(--gvs-space-3); }
.gvs-tabpanel[hidden] { display: none; }

/* --- accordion : 64 tall collapsed ----------------------------------
   Built on <details>/<summary>, so it opens and closes with zero JS and
   Enter/Space work natively. The marker is replaced by a drawn chevron. */
.gvs-acc { display: grid; gap: var(--gvs-space-2); }
.gvs-acc__item {
  background-color: var(--gvs-bg-panel);
  border: var(--gvs-border-width) solid var(--gvs-petrol);
  border-radius: var(--gvs-radius);
}
.gvs-acc__btn,
.gvs-acc__item > summary {
  box-sizing: border-box;
  display: flex;
  gap: var(--gvs-space-2);
  align-items: center;
  width: 100%;
  min-height: var(--gvs-accordion-h);       /* 64 */
  padding: 0 var(--gvs-space-3);
  background-color: transparent;
  border: 0;
  font-family: var(--gvs-font-body);
  font-weight: var(--gvs-body-weight-em);
  font-size: var(--gvs-fs-body-sm);
  text-align: left;
  color: var(--gvs-petrol);
  cursor: pointer;
  list-style: none;
}
.gvs-acc__item > summary::-webkit-details-marker { display: none; }
.gvs-acc__btn:hover,
.gvs-acc__item > summary:hover { background-color: var(--gvs-cream-hover); }
.gvs-acc__btn:active,
.gvs-acc__item > summary:active { background-color: var(--gvs-secondary-active); }
/* Chevron: down when closed, up when open. */
.gvs-acc__btn::after,
.gvs-acc__item > summary::after {
  content: "";
  width: 14px;
  height: 8px;
  margin-left: auto;
  flex: 0 0 auto;
  background-color: var(--gvs-petrol);
  clip-path: polygon(0 0, 50% 100%, 100% 0,
                     100% 3px, 50% calc(100% - 3px), 0 3px);
  transition: transform var(--gvs-t) var(--gvs-ease);
}
.gvs-acc__item[open] > summary::after,
.gvs-acc__btn[aria-expanded="true"]::after { transform: rotate(180deg); }
.gvs-acc__panel {
  padding: 0 var(--gvs-space-3) var(--gvs-space-3);
  border-top: 1px solid var(--gvsc-keyline-panel);
  margin-top: 0;
  padding-top: var(--gvs-space-2);
  font-size: var(--gvs-fs-meta);
  line-height: 21px;
  color: var(--gvs-petrol);
}
.gvs-acc__panel[hidden] { display: none; }

/* --- pagination : 44 cells ------------------------------------------
   <nav aria-label="Pagination"> + <ol>. The current page is
   aria-current="page" and is NOT a link. */
.gvs-pagination { display: block; }
.gvs-pagination ol {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gvs-space-1);
  align-items: center;
  margin: 0;
  padding: 0;
  list-style: none;
}
.gvs-page {
  box-sizing: border-box;
  display: inline-grid;
  place-items: center;
  min-width: var(--gvs-row-h);              /* 44 */
  height: var(--gvs-row-h);
  padding: 0 var(--gvs-space-1);
  background-color: transparent;
  border: var(--gvs-border-width) solid var(--gvs-petrol);
  border-radius: var(--gvs-radius-sm);
  font-family: var(--gvs-font-body);
  font-weight: var(--gvs-body-weight-em);
  font-size: var(--gvs-fs-meta);
  font-variant-numeric: tabular-nums;
  color: var(--gvs-petrol);
  text-decoration: none;
  cursor: pointer;
}
.gvs-page:hover  { background-color: var(--gvs-secondary-hover); }
.gvs-page:active { background-color: var(--gvs-secondary-active); }
.gvs-page[aria-current="page"] {
  background-color: var(--gvs-petrol);
  border-color: var(--gvs-petrol);
  color: var(--gvs-cream);
  cursor: default;
}
.gvs-page[aria-disabled="true"] {
  opacity: var(--gvs-disabled-opacity);
  cursor: not-allowed;
  pointer-events: none;
}
.gvs-page__gap {
  display: inline-grid;
  place-items: center;
  min-width: var(--gvs-row-h);
  height: var(--gvs-row-h);
  color: var(--gvs-ink-muted);              /* 4.73:1 — never soft grey      */
}

/* --- data table -----------------------------------------------------
   Petrol header with cream caps at 0.12em. Zebra alternates cream and
   paper — no rules between rows, the zebra separates them. Numerics are
   right-aligned tabular figures. Row height 44.
   Needs a <caption> (visually hidden is fine) and scope on every th. */
.gvs-table,
.gvs-billing-table {
  width: 100%;
  border-collapse: collapse;
  border-bottom: var(--gvs-border-width) solid var(--gvs-petrol);
  font-size: var(--gvs-fs-meta);
  color: var(--gvs-petrol);
}
.gvs-table caption {
  padding-bottom: var(--gvs-space-1);
  font-weight: var(--gvs-body-weight-em);
  font-size: var(--gvs-fs-micro);
  text-align: left;
  color: var(--gvs-ink-muted);
}
.gvs-table thead th {
  height: var(--gvs-row-h);
  padding: 0 var(--gvs-space-2);
  background-color: var(--gvs-petrol);
  font-weight: var(--gvs-body-weight-em);
  font-size: 11px;
  letter-spacing: var(--gvs-tracking-tag);
  text-transform: uppercase;
  text-align: left;
  color: var(--gvs-cream);
  white-space: nowrap;
}
.gvs-table tbody td,
.gvs-table tbody th {
  height: var(--gvs-row-h);
  padding: 0 var(--gvs-space-2);
  text-align: left;
  font-weight: var(--gvs-body-weight);
}
.gvs-table tbody tr:nth-child(odd)  { background-color: var(--gvs-bg-panel); }
.gvs-table tbody tr:nth-child(even) { background-color: var(--gvs-bg); }
.gvs-table__num,
.gvs-table td.gvs-table__num,
.gvs-table th.gvs-table__num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.gvs-table__scroll { overflow-x: auto; }

/* --- notices : the 10px left bar carries the meaning ----------------
   The ground stays cream so text contrast never drops. Titles are petrol,
   except success (green 6.0:1) and error (red 5.2:1).
   WARNING KEEPS A PETROL TITLE — gold type on cream is 1.6:1. */
.gvs-notice {
  position: relative;
  overflow: hidden;
  box-sizing: border-box;
  min-height: var(--gvs-notice-h);          /* 72 */
  padding: var(--gvs-space-2) var(--gvs-space-3) var(--gvs-space-2)
           calc(var(--gvs-notice-bar) + var(--gvs-space-3));
  background-color: var(--gvs-bg-panel);
  border: var(--gvs-border-width) solid var(--gvs-petrol);
  border-radius: var(--gvs-radius);
}
.gvs-notice::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: var(--gvs-notice-bar);             /* 10 */
  background-color: var(--gvs-petrol);
}
.gvs-notice__title {
  font-weight: var(--gvs-body-weight-em);
  font-size: var(--gvs-fs-meta);
  color: var(--gvs-petrol);
}
.gvs-notice__body {
  margin-top: 4px;
  font-size: 12px;
  color: var(--gvs-petrol);
}
.gvs-notice--success::before { background-color: var(--gvs-ok); }
.gvs-notice--success .gvs-notice__title { color: var(--gvs-ok); }
.gvs-notice--warning::before { background-color: var(--gvs-warn); }
/* deliberately no title recolour on --warning */
.gvs-notice--error::before { background-color: var(--gvs-error); }
.gvs-notice--error .gvs-notice__title { color: var(--gvs-error); }
/* An error notice that reports a form failure is role="alert"; a passive
   one is a plain <div>. Never make a decorative notice an alert. */

/* --- empty state : always exactly ONE action ----------------------- */
.gvs-empty,
.gvs-empty-state {
  box-sizing: border-box;
  display: grid;
  justify-items: center;
  gap: var(--gvs-space-2);
  padding: var(--gvs-space-4);
  background-color: var(--gvs-bg-panel);
  border: var(--gvs-border-width) solid var(--gvs-petrol);
  border-radius: var(--gvs-radius);
  text-align: center;
}
.gvs-empty__mark { width: 56px; height: 56px; }
.gvs-empty__title,
.gvs-empty-state__title {
  font-family: var(--gvs-font-display);
  font-weight: var(--gvs-display-weight);
  font-size: var(--gvs-fs-card-h);          /* 26 */
  text-transform: uppercase;
  color: var(--gvs-petrol);
}
.gvs-empty__body {
  font-size: var(--gvs-fs-meta);
  color: var(--gvs-petrol);
}

/* --- loading skeleton -----------------------------------------------
   Skeletons in layout, spinners only inside a button. The pulse is on a
   flat placeholder tint. Wrap the region in aria-busy="true" and drop it
   when the content lands. */
.gvs-skeleton {
  background-color: var(--gvs-placeholder);
  opacity: 0.35;
  border-radius: var(--gvs-radius-sm);
  animation: gvs-pulse 1400ms ease-in-out infinite;
}
.gvs-skeleton--line  { height: 14px; }
.gvs-skeleton--thumb { width: 64px; height: 64px; }
@keyframes gvs-pulse { 0%, 100% { opacity: 0.35; } 50% { opacity: 0.18; } }

/* --- toast : 400 wide, deep petrol, bottom right, 6s ---------------
   role="status" + aria-live="polite" so it is announced without stealing
   focus. Anything that needs a decision is a modal, not a toast. */
.gvs-toast {
  position: fixed;
  right: var(--gvs-space-3);
  bottom: var(--gvs-space-3);
  z-index: var(--gvs-z-toast, 200);
  box-sizing: border-box;
  display: flex;
  gap: var(--gvs-space-2);
  align-items: center;
  width: var(--gvs-toast-w);                /* 400 */
  max-width: calc(100vw - 2 * var(--gvs-space-3));
  min-height: var(--gvs-notice-h);
  padding: var(--gvs-space-2) var(--gvs-space-3);
  background-color: var(--gvs-bg-inverse);
  border-radius: var(--gvs-radius);
  color: var(--gvs-cream);
}
.gvs-toast--static { position: static; }    /* for the library page          */
.gvs-toast__icon {
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
  fill: none;
  stroke: var(--gvs-gold);
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.gvs-toast__title {
  font-weight: var(--gvs-body-weight-em);
  font-size: var(--gvs-fs-card);
}
.gvs-toast__body {
  font-size: 12px;
  color: var(--gvsc-cream-75-deep);         /* 7.40:1, flat mix              */
}
.gvs-toast__close {
  display: grid;
  place-items: center;
  width: var(--gvsc-hit-min);
  height: var(--gvsc-hit-min);
  margin-left: auto;
  margin-right: calc(-1 * var(--gvs-space-1));
  padding: 0;
  background-color: transparent;
  border: 0;
  color: var(--gvs-cream);
  cursor: pointer;
}

/* --- modal -----------------------------------------------------------
   <dialog> with role="dialog" aria-modal="true", labelled by its own
   heading. Focus is trapped inside, Esc closes, focus returns to the
   trigger. showModal() gives all three for free; the fallback markup and
   the trap requirements are in COMPONENTS.md.
   Overlay = petrol-deep at 70%. */
.gvs-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--gvs-z-modal, 150);
  display: grid;
  place-items: center;
  padding: var(--gvs-space-3);
  /* NOT opacity: .7 — that would fade the modal inside it too. */
  background-color: var(--gvsc-overlay-bg);
}
.gvs-overlay[hidden] { display: none; }
.gvs-modal {
  position: relative;
  box-sizing: border-box;
  width: min(var(--gvs-modal-w), calc(100vw - 2 * var(--gvs-space-3)));
  margin: auto;
  padding: var(--gvs-space-4);
  background-color: var(--gvs-bg-panel);
  border: var(--gvs-border-width) solid var(--gvs-petrol);
  border-radius: var(--gvs-radius);
  color: var(--gvs-petrol);
}
dialog.gvs-modal::backdrop { background-color: var(--gvsc-overlay-bg); }
.gvs-modal__title {
  margin: 0;
  padding-right: var(--gvs-space-6);        /* clear of the close button     */
  font-family: var(--gvs-font-display);
  font-weight: var(--gvs-display-weight);
  font-size: 24px;
  text-transform: uppercase;
  color: var(--gvs-petrol);
}
.gvs-modal__body {
  margin-top: var(--gvs-space-2);
  font-size: var(--gvs-fs-meta);
  line-height: 21px;
  color: var(--gvs-petrol);
}
.gvs-modal__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gvs-space-2);
  margin-top: var(--gvs-space-4);
}
.gvs-modal__close {
  position: absolute;
  top: var(--gvs-space-2);
  right: var(--gvs-space-2);
  display: grid;
  place-items: center;
  width: var(--gvsc-hit-min);
  height: var(--gvsc-hit-min);
  padding: 0;
  background-color: transparent;
  border: 0;
  color: var(--gvs-petrol);
  cursor: pointer;
}
.gvs-modal__close:hover { color: var(--gvs-rasta-red); }

/* ==========================================================================
   10 · FOOTER & SECTION SEAMS
   --------------------------------------------------------------------------
   Footer field is --gvs-bg-inverse #123640, 430 tall. Mono seal 108, the
   wordmark under it at 20 / 22. Three 260 link columns. Column heads are
   gold caps 13 at 0.12em (6.73:1 on deep petrol — gold IS legible here,
   unlike on paper). Links cream 15 / 28. Divider 1.5px cream at 25%.
   Rasta foot edge 20 tall, three hard thirds.
   ========================================================================== */
.gvs-footer {
  position: relative;
  box-sizing: border-box;
  min-height: var(--gvs-footer-h);          /* 430 */
  padding: 58px var(--gvs-space-3) 60px;
  background-color: var(--gvs-bg-inverse);
  color: var(--gvs-text-inverse);
}
.gvs-footer__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--gvs-space-4);
  width: 100%;
  max-width: var(--gvs-content-width);
  margin: 0 auto;
}
.gvs-footer__brand { display: block; }
.gvs-footer__seal {
  width: var(--gvs-footer-seal);            /* 108 */
  height: var(--gvs-footer-seal);
}
.gvs-footer__wordmark {
  margin-top: var(--gvs-space-3);
  font-family: var(--gvs-font-display);
  font-weight: var(--gvs-display-weight);
  font-size: 20px;
  line-height: 22px;
  text-transform: uppercase;
  color: var(--gvs-cream);
}
.gvs-footer__col { display: block; }
.gvs-footer__colh,
.gvs-footer__colhead {
  font-weight: var(--gvs-body-weight-em);
  font-size: var(--gvs-fs-micro);           /* 13 */
  letter-spacing: var(--gvs-tracking-tag);
  text-transform: uppercase;
  color: var(--gvs-gold);                   /* 6.73:1 on petrol-deep         */
}
.gvs-footer__list {
  margin: var(--gvs-space-2) 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 13px;
}
.gvs-footer__list a,
.gvs-footer__col a {
  display: inline-flex;
  align-items: center;
  min-height: 28px;
  font-size: var(--gvs-fs-card);            /* 15 */
  color: var(--gvs-cream);
  text-decoration: none;
}
.gvs-footer__list a:hover,
.gvs-footer__col a:hover {
  color: var(--gvs-gold);
  text-decoration: underline;
  text-decoration-thickness: var(--gvs-underline);
  text-underline-offset: 6px;
}
.gvs-footer__rule {
  height: 1.5px;
  margin: var(--gvs-space-6) 0 var(--gvs-space-3);
  background-color: var(--gvsc-footer-rule);   /* cream 25%, flat mix        */
  border: 0;
}
.gvs-footer__legal,
.gvs-footer__social {
  font-size: var(--gvs-fs-micro);
  color: var(--gvsc-cream-70-deep);         /* 6.58:1, flat mix not opacity  */
}
.gvs-footer__social { margin-top: var(--gvs-space-2); font-size: 12px; }
.gvs-footer__social a { color: var(--gvsc-cream-70-deep); }
.gvs-footer__social a:hover { color: var(--gvs-gold); }
.gvs-footer__bottom {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gvs-space-2) var(--gvs-space-4);
  justify-content: space-between;
  width: 100%;
  max-width: var(--gvs-content-width);
  margin: 0 auto;
}
/* The 20px Rasta foot edge. Three hard butted bands, red -> gold -> green,
   never a blend, never reordered. */
.gvs-footer::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: var(--gvs-footedge-height);       /* 20 */
  background: var(--gvs-rasta);
}

/* ==========================================================================
   11 · THE SEAM KIT
   ========================================================================== */

/* The Rasta section seam, 10px. Nothing else in gvs-tokens.css or
   gvs-base.css defines .gvs-divider, so the base object lives here;
   gvs-layout.css adds the --foot modifier and the margin cancellations. */
.gvs-divider {
  height: var(--gvs-divider-height);        /* 10 */
  border: 0;
  background: var(--gvs-rasta);
}

/* A quiet petrol rule. This is NEVER a section seam — a seam is Rasta.
   Named .gvs-seam-rule, not .gvs-rule, because gvs-base.css already uses
   .gvs-rule for the soft-grey hairline. */
.gvs-seam-rule {
  height: var(--gvs-border-width);
  background-color: var(--gvsc-keyline-paper);   /* petrol 30%, flat         */
  border: 0;
}

/* The section header pattern: 56 x 4 gold tick, 38 down to the eyebrow
   (teal caps 14 at 0.18em), 66 down to the H2. */
.gvs-sectionhead { display: block; }
.gvs-sectionhead__tick {
  width: 56px;
  height: 4px;
  background-color: var(--gvs-gold);
  border: 0;
}
.gvs-sectionhead__eyebrow {
  margin-top: 34px;                         /* tick -> eyebrow = 38 total    */
  font-family: var(--gvs-font-body);
  font-weight: var(--gvs-eyebrow-weight);
  font-size: var(--gvs-eyebrow-size);
  line-height: 1;
  letter-spacing: var(--gvs-tracking-eyebrow);
  text-transform: uppercase;
  color: var(--gvs-eyebrow);                /* --gvs-teal-text, 5.12:1       */
}
.gvs-sectionhead__h2 {
  margin-top: 52px;                         /* eyebrow -> H2 = 66 total      */
  font-family: var(--gvs-font-display);
  font-weight: var(--gvs-display-weight);
  font-size: var(--gvs-fs-h2);
  line-height: var(--gvs-lh-tight);
  text-transform: uppercase;
  color: var(--gvs-petrol);
}
.gvs-sectionhead__sub {
  margin-top: var(--gvs-space-2);
  font-size: var(--gvs-fs-body);
  color: var(--gvs-petrol);
}

/* The sunburst accent. ALWAYS clipped to its section: the ray origin sits
   outside the section box and a ray must never cross a seam. 12% on paper,
   30% on a deep petrol field. Decorative, so pointer-events: none and it
   never receives focus or a name. */
.gvs-sunburst {
  position: absolute;
  inset: 0;
  overflow: hidden;                         /* the clip                      */
  opacity: 0.12;
  pointer-events: none;
  z-index: var(--gvs-z-base);
}
.gvs-on-dark .gvs-sunburst,
.gvs-bg-inverse .gvs-sunburst { opacity: 0.3; }
.gvs-sunburst > svg {
  position: absolute;
  right: -20%;
  top: 50%;
  width: 90%;
  height: auto;
  transform: translateY(-50%);
}

/* ==========================================================================
   12 · RESPONSIVE LADDER
   --------------------------------------------------------------------------
   Mobile-first. Breakpoints 480 / 768 / 1024 / 1200 / 1440, min-width, so
   the small screen is the base case and every step is an enhancement.
   ========================================================================== */

/* Coarse pointer: promote the 36 button and the 28 tag to a full 44 box
   outright rather than relying on the invisible hit-extender. */
@media (pointer: coarse) {
  .gvs-btn--sm { height: var(--gvsc-hit-min); font-size: var(--gvs-btn-fs-md); }
  .gvs-btn--icon-only.gvs-btn--sm { width: var(--gvsc-hit-min); }
  .gvs-tag { height: 36px; }
}

@media (min-width: 480px) {
  .gvs-form__row2,
  .gvs-form-row2 { grid-template-columns: 1fr 1fr; }
  .gvs-footer__grid { grid-template-columns: 1fr 1fr; }
}

@media (min-width: 768px) {
  .gvs-nav { padding: 0 var(--gvs-space-4); }
  .gvs-card--feature { grid-template-columns: 1fr 1fr; }
  .gvs-footer { padding: 58px var(--gvs-space-4) 60px; }
  .gvs-footer__grid { grid-template-columns: 260px repeat(2, 1fr); }
  .gvs-modal { padding: var(--gvs-space-4); }
}

@media (min-width: 1024px) {
  .gvs-nav { padding: 0 var(--gvs-space-6); }
  .gvs-card--what { width: var(--gvs-card-width); }
  .gvs-card--post,
  .gvs-post-card,
  .gvs-card--event { width: 340px; }
  .gvs-footer { padding: 58px var(--gvs-space-6) 60px; }
  .gvs-footer__grid {
    grid-template-columns: 260px 1fr repeat(3, var(--gvs-footer-col));
    gap: var(--gvs-space-3);
  }
  .gvs-newsletter { flex-wrap: nowrap; }
}

@media (min-width: 1200px) {
  .gvs-nav { padding: 0 var(--gvs-space-8); }
  .gvs-footer { padding: 58px var(--gvs-space-8) 60px; }
}

@media (min-width: 1440px) {
  .gvs-nav { padding: 0 var(--gvs-gutter); }      /* 120 */
  .gvs-footer { padding: 58px var(--gvs-gutter) 60px; }
}

/* Below 480 the newsletter row stacks and the button goes full width. */
@media (max-width: 479px) {
  .gvs-newsletter .gvs-btn { width: 100%; }
  .gvs-hero__actions { flex-direction: column; align-items: stretch; }
  .gvs-hero__actions .gvs-btn--primary,
  .gvs-hero__actions .gvs-btn--secondary { min-width: 0; }
  .gvs-tablist { overflow-x: auto; }
}

/* ==========================================================================
   13 · MOTION & PRINT
   --------------------------------------------------------------------------
   The two !important blocks in this file. Both are the standard escape
   hatches and both are in the Volume B spec.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  a.gvs-card:hover,
  .gvs-card--interactive:hover { transform: none; }
}

@media print {
  .gvs-nav,
  .gvs-drawer,
  .gvs-navdrawer,
  .gvs-toast,
  .gvs-overlay,
  .gvs-skip,
  .gvs-sunburst,
  .gvs-skeleton { display: none !important; }
  .gvs-btn,
  .gvs-card,
  .gvs-field,
  .gvs-input { border-color: #1B4A5A !important; }
  .gvs-footer {
    color: #123640;
    background: none;
    min-height: 0;
  }
  .gvs-footer::after { display: none; }
  .gvs-tabpanel[hidden],
  .gvs-acc__panel[hidden] { display: block !important; }
}
