/* ==========================================================================
   GoodVibes Foundation — BASE
   gvs.foundation · production CSS · Lane H1 (foundation layer)

   Reset, base element styles, the type scale as classes, links, focus,
   containers, utilities, the house motifs, the responsive ladder, print.

   REQUIRES gvs-tokens.css. Load order:
       gvs-tokens.css -> gvs-base.css -> gvs-components.css -> gvs-layout.css

   Contains no component. Buttons, cards, nav, forms and event rows belong to
   gvs-components.css (Lane H2). Page and section composition belongs to
   gvs-layout.css (Lane H3).

   No !important anywhere in this file. If you need to beat something here,
   you are in the wrong layer.

   CONTENTS
     1.  Fonts
     2.  Reset
     3.  Document
     4.  Base elements
     5.  Type scale as classes
     6.  Links
     7.  Focus
     8.  Containers
     9.  Sections and the Rasta divider
     10. Motifs: sunburst, ribbon, grain, seal, mark
     11. Icons
     12. Photographs
     13. Utilities
     14. Responsive ladder
     15. Reduced motion
     16. Print
   ========================================================================== */


/* ==========================================================================
   1. FONTS

   Nothing here loads from a CDN. Two of the three comp faces are macOS system
   fonts and cannot be shipped, so the stacks in gvs-tokens.css degrade in a
   controlled way. See FOUNDATIONS.md, "The font situation".

   TO SELF-HOST: drop the .woff2 files in  design/web/assets/fonts/  and
   uncomment the matching block. Paths are relative to THIS file.

   Inter is SIL OFL and matches the comps exactly — self-host it first, it is
   the cheapest accuracy win in the whole build. Subset to latin + latin-ext.

   Oswald is the substitute for AvenirNextCondensed-Heavy. It is narrower than
   the comp face, so verify every headline set width after enabling it.
   ========================================================================== */

@font-face {
  font-family: "Inter";
  src: url("../assets/fonts/inter-regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F,
                 U+2074, U+20AC, U+2122, U+2191, U+2192, U+2212, U+2215;
}
@font-face {
  font-family: "Inter";
  src: url("../assets/fonts/inter-semibold.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("../assets/fonts/inter-bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Oswald";
  src: url("../assets/fonts/oswald-bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* If you ship Inter as a variable font instead, use ONE block and delete the
   three static ones above:

@font-face {
  font-family: "Inter var";
  src: url("../assets/fonts/inter-variable.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
*/


/* ==========================================================================
   2. RESET
   Deliberately small. Enough to make the box model and the vertical rhythm
   predictable, and nothing else.
   ========================================================================== */

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

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

/* Reset the margins we intend to own. Everything else keeps UA defaults so an
   unstyled CMS block still looks deliberate. */
body,
h1, h2, h3, h4, h5, h6,
p, figure, blockquote, dl, dd,
pre {
  margin: 0;
}

ul[class],
ol[class] {
  padding-inline-start: 0;
  list-style: none;
  margin: 0;
}

img,
picture,
video,
canvas,
svg {
  display: block;
  max-width: 100%;
}

img,
video {
  height: auto;
}

input,
button,
textarea,
select {
  font: inherit;
  color: inherit;
}

button {
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

textarea {
  resize: vertical;
}

table {
  border-collapse: collapse;
  border-spacing: 0;
}

/* Break long words rather than blow out a container. */
p,
li,
h1, h2, h3, h4, h5, h6,
dt, dd,
figcaption,
blockquote {
  overflow-wrap: break-word;
}


/* ==========================================================================
   3. DOCUMENT
   Warm paper is the ground. Never white.
   ========================================================================== */

html {
  background: var(--gvs-bg);
}

body {
  background: var(--gvs-bg);
  color: var(--gvs-text);
  font-family: var(--gvs-font-body);
  font-size: var(--gvs-fs-body);
  font-weight: var(--gvs-body-weight);
  line-height: var(--gvs-lh-body);
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-kerning: normal;
  font-variant-ligatures: common-ligatures;
  text-rendering: optimizeLegibility;
}

/* Anchor targets clear a sticky nav instead of hiding under it. */
:target {
  scroll-margin-block-start: calc(var(--gvs-nav-height) + var(--gvs-space-3));
}

::selection {
  background: var(--gvs-gold);
  color: var(--gvs-petrol);   /* 5.03:1 */
}


/* ==========================================================================
   4. BASE ELEMENTS
   Element defaults mirror the class scale in section 5, so semantic HTML with
   no classes at all already lands on the design system.
   ========================================================================== */

h1, h2, h3, h4 {
  font-family: var(--gvs-font-display);
  font-weight: var(--gvs-display-weight);
  letter-spacing: var(--gvs-tracking-display);
  text-transform: uppercase;
  text-wrap: balance;
  color: var(--gvs-text);
}

h1 { font-size: var(--gvs-fs-h1);     line-height: var(--gvs-lh-h1);     }
h2 { font-size: var(--gvs-fs-h2);     line-height: var(--gvs-lh-h2);     }
h3 { font-size: var(--gvs-fs-h3);     line-height: var(--gvs-lh-h3);     }
h4 { font-size: var(--gvs-fs-card-h); line-height: var(--gvs-lh-card-h); }

/* h5 and h6 are not display faces. They are tracked caps, like an eyebrow. */
h5, h6 {
  font-family: var(--gvs-font-body);
  font-weight: var(--gvs-body-weight-em);
  font-size: var(--gvs-fs-meta);
  line-height: var(--gvs-lh-meta);
  letter-spacing: var(--gvs-tracking-eyebrow);
  text-transform: uppercase;
  color: var(--gvs-teal-text);
}

p {
  max-width: var(--gvs-container-prose);
}

/* Flow spacing. One rule, on the 8px grid, instead of margins on every
   element. Anything that is a direct sibling gets space above it. */
.gvs-flow > * + * {
  margin-block-start: var(--gvs-space-3);
}
.gvs-flow > * + h2 { margin-block-start: var(--gvs-space-8); }
.gvs-flow > * + h3 { margin-block-start: var(--gvs-space-6); }
.gvs-flow--tight > * + * { margin-block-start: var(--gvs-space-2); }
.gvs-flow--loose > * + * { margin-block-start: var(--gvs-space-4); }

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

small {
  font-size: var(--gvs-fs-micro);
}

/* Lists that are actually prose */
.gvs-prose ul,
.gvs-prose ol {
  padding-inline-start: var(--gvs-space-3);
  margin: 0;
}
.gvs-prose li + li {
  margin-block-start: var(--gvs-space-1);
}
.gvs-prose li::marker {
  color: var(--gvs-teal-text);
}

blockquote {
  font-family: var(--gvs-font-display);
  font-weight: var(--gvs-display-weight);
  font-size: var(--gvs-fs-quote);
  line-height: var(--gvs-lh-quote);
  text-transform: uppercase;
  color: var(--gvs-text);
  border-inline-start: 6px solid var(--gvs-rasta-red);
  padding-inline-start: var(--gvs-space-4);
}

figure > figcaption {
  font-size: var(--gvs-caption-size);
  font-weight: var(--gvs-body-weight-em);
  line-height: var(--gvs-lh-meta);
  color: var(--gvs-text);
  margin-block-start: var(--gvs-space-1);
}

hr {
  border: 0;
  block-size: 1px;
  background: var(--gvs-rule);
  margin-block: var(--gvs-space-6);
}

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

code {
  background: var(--gvs-cream);
  border: 1px solid var(--gvs-rule);
  border-radius: var(--gvs-radius-sm);
  padding: 0.1em 0.35em;
}

pre {
  background: var(--gvs-cream);
  border: var(--gvs-border-width) solid var(--gvs-border);
  border-radius: var(--gvs-radius);
  padding: var(--gvs-space-3);
  overflow-x: auto;
}
pre code {
  background: none;
  border: 0;
  padding: 0;
}

abbr[title] {
  text-decoration: underline dotted;
  cursor: help;
}

/* Placeholders. #968C7E on cream is 3.02:1 — it fails AA for normal text, so
   a placeholder may NEVER be the only label for a field. Volume B owns the
   visible <label>; this only stops the UA default from being lighter still. */
::placeholder {
  color: var(--gvs-placeholder);
  opacity: 1;
}


/* ==========================================================================
   5. TYPE SCALE AS CLASSES
   Same numbers as the elements above, available without a heading level, so a
   <p> can be set as a lead and an <h2> can be demoted visually without
   breaking the document outline.
   ========================================================================== */

.gvs-display,
.gvs-h1, .gvs-h2, .gvs-h2-sm, .gvs-h3, .gvs-card-h {
  font-family: var(--gvs-font-display);
  font-weight: var(--gvs-display-weight);
  letter-spacing: var(--gvs-tracking-display);
  text-transform: uppercase;
  text-wrap: balance;
  color: var(--gvs-text);
}

.gvs-h1     { font-size: var(--gvs-fs-h1);     line-height: var(--gvs-lh-h1);     }
.gvs-h2     { font-size: var(--gvs-fs-h2);     line-height: var(--gvs-lh-h2);     }
.gvs-h2-sm  { font-size: var(--gvs-fs-h2-sm);  line-height: var(--gvs-lh-h2);     }
.gvs-h3     { font-size: var(--gvs-fs-h3);     line-height: var(--gvs-lh-h3);     }
.gvs-card-h { font-size: var(--gvs-fs-card-h); line-height: var(--gvs-lh-card-h); }

.gvs-quote {
  font-family: var(--gvs-font-display);
  font-weight: var(--gvs-display-weight);
  font-size: var(--gvs-fs-quote);
  line-height: var(--gvs-lh-quote);
  text-transform: uppercase;
  color: var(--gvs-text);
}

.gvs-lead {
  font-size: var(--gvs-fs-lead);
  line-height: var(--gvs-lh-lead);
  max-width: var(--gvs-container-prose);
}

.gvs-body-lg { font-size: var(--gvs-fs-body-lg); line-height: var(--gvs-lh-body); }
.gvs-body    { font-size: var(--gvs-fs-body);    line-height: var(--gvs-lh-body); }
.gvs-body-sm { font-size: var(--gvs-fs-body-sm); line-height: var(--gvs-lh-card); }
.gvs-card-b  { font-size: var(--gvs-fs-card);    line-height: var(--gvs-lh-card); }
.gvs-ui      { font-size: var(--gvs-fs-ui);      line-height: 1; }
.gvs-meta    { font-size: var(--gvs-fs-meta);    line-height: var(--gvs-lh-meta); }
.gvs-micro   { font-size: var(--gvs-fs-micro);   line-height: var(--gvs-lh-meta); }

/* The eyebrow. Tracked caps, 0.18em, teal-text. This is the single most
   repeated piece of type in the system. */
.gvs-eyebrow {
  display: block;
  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);          /* #256A75, 5.12:1 on paper */
}
/* Tracking adds space AFTER the last glyph. Pull it back so the eyebrow is
   optically flush left with the heading under it. */
.gvs-eyebrow::after {
  content: "";
  display: inline-block;
  inline-size: 0;
}

/* Tracked caps for nav items and button labels: less tracking than an eyebrow */
.gvs-caps {
  text-transform: uppercase;
  letter-spacing: var(--gvs-tracking-caps);
}

/* The caption / credit pair under a photograph */
.gvs-caption {
  font-size: var(--gvs-caption-size);
  font-weight: var(--gvs-body-weight-em);
  line-height: var(--gvs-lh-meta);
  color: var(--gvs-text);
}
.gvs-credit {
  font-size: var(--gvs-credit-size);
  line-height: var(--gvs-lh-meta);
  color: var(--gvs-text-muted);      /* #6E655B, 4.73:1 */
}

/* Muted type. Use this. Never colour text with --gvs-soft-grey: #A9A29A is
   2.09:1 on paper and fails AA at every size. */
.gvs-muted {
  color: var(--gvs-text-muted);
}


/* ==========================================================================
   6. LINKS
   Underline offset 10px, 2px thick, thickening to 3px on hover. Petrol on
   paper is 8.00:1, so a colour change alone is not needed to carry meaning —
   the underline does that, which keeps links legible for colour-blind readers.
   ========================================================================== */

a {
  color: var(--gvs-text);
  text-decoration-line: underline;
  text-decoration-thickness: 2px;
  text-decoration-color: var(--gvs-gold);
  text-underline-offset: 10px;
  transition: text-decoration-thickness var(--gvs-t-fast) var(--gvs-ease),
              text-decoration-color var(--gvs-t-fast) var(--gvs-ease);
}

a:hover {
  text-decoration-thickness: 3px;
  text-decoration-color: var(--gvs-rasta-red);
}

a:active {
  color: var(--gvs-petrol-deep);
}

/* A link that is really a block (a card, a row). Volume H2 restyles the
   inside; this only removes the prose underline. */
.gvs-link-block,
.gvs-link-block:hover {
  color: inherit;
  text-decoration: none;
}

/* An inline link in running copy sits tighter than a standalone one. */
.gvs-prose a {
  text-underline-offset: var(--gvs-space-1);
}

/* The "read more" pattern: label plus the arrow icon */
.gvs-link-arrow {
  display: inline-flex;
  align-items: center;
  gap: var(--gvs-space-1);
  font-weight: var(--gvs-body-weight-em);
}
.gvs-link-arrow .gvs-icon {
  inline-size: var(--gvs-icon-inline);
  block-size: var(--gvs-icon-inline);
  transition: transform var(--gvs-t) var(--gvs-ease);
}
.gvs-link-arrow:hover .gvs-icon {
  transform: translateX(3px);
}

/* Skip link. Visible only when focused, and it lands on paper, so the ring is
   petrol. */
.gvs-skip-link {
  position: absolute;
  inset-block-start: var(--gvs-space-1);
  inset-inline-start: var(--gvs-space-1);
  z-index: var(--gvs-z-toast);
  padding: var(--gvs-space-2) var(--gvs-space-3);
  background: var(--gvs-gold);
  color: var(--gvs-petrol);
  font-weight: var(--gvs-body-weight-em);
  border-radius: var(--gvs-radius);
  text-decoration: none;
  transform: translateY(calc(-100% - var(--gvs-space-4)));
  transition: transform var(--gvs-t) var(--gvs-ease);
}
.gvs-skip-link:focus {
  transform: translateY(0);
}


/* ==========================================================================
   7. FOCUS
   2px solid PETROL at 2px offset on light grounds. Cream on dark fields.

   GOLD IS NEVER A FOCUS RING: #E8B33C on #F3E9D2 is 1.59:1 and fails the 3:1
   non-text minimum (WCAG 2.2 SC 1.4.11 / 2.4.13).

   :focus-visible only, so a mouse click does not draw a ring, but every
   keyboard tab does. The :focus fallback below is for engines without
   :focus-visible — it is removed again by the @supports block, so no browser
   gets a double ring.
   ========================================================================== */

:focus {
  outline: var(--gvs-focus-width) solid var(--gvs-focus-ring);
  outline-offset: var(--gvs-focus-offset);
}

@supports selector(:focus-visible) {
  :focus {
    outline: none;                    /* replaced immediately below */
  }
  :focus-visible {
    outline: var(--gvs-focus-width) solid var(--gvs-focus-ring);
    outline-offset: var(--gvs-focus-offset);
  }
}

/* On dark fields the ring switches ink. Both .gvs-on-dark (the canonical
   name) and .gvs-bg-inverse (used by the Volume A CSS) are honoured. */
.gvs-on-dark :focus-visible,
.gvs-bg-inverse :focus-visible {
  outline-color: var(--gvs-focus-ring-inverse);
}

/* Forced-colours mode: let the OS draw it. */
@media (forced-colors: active) {
  :focus-visible {
    outline: 3px solid CanvasText;
  }
}


/* ==========================================================================
   8. CONTAINERS
   Three widths, and only three. The contract other lanes build against:

     .gvs-container            1200  the content column
     .gvs-container--narrow     880  split sections, forms, panels
     .gvs-container--prose      680  the article measure

   .gvs-wrap is a synonym kept because gvs-layout.css and the page templates
   use it. It resolves to exactly the same numbers.
   ========================================================================== */

.gvs-container,
.gvs-wrap {
  inline-size: 100%;
  max-inline-size: var(--gvs-container);
  margin-inline: auto;
  padding-inline: var(--gvs-gutter);
}

.gvs-container--narrow,
.gvs-wrap--narrow { max-inline-size: calc(var(--gvs-container-narrow) + (2 * var(--gvs-gutter))); }

.gvs-container--prose,
.gvs-wrap--prose  { max-inline-size: calc(var(--gvs-container-prose)  + (2 * var(--gvs-gutter))); }

/* Full-bleed: no max, keeps the gutter. For a band that runs edge to edge but
   whose contents still respect the margin. */
.gvs-container--bleed { max-inline-size: none; }

/* No gutter at all. Only for a band that paints its own background to the
   viewport edge and nests a real container inside. */
.gvs-container--flush { padding-inline: 0; }

/* A prose column nested inside a container that already has a gutter. */
.gvs-measure { max-inline-size: var(--gvs-container-prose); }


/* ==========================================================================
   9. THE RASTA DIVIDER
   The signature section seam. THREE HARD BUTTED BANDS, red then gold then
   green, left to right, 33.333% each. Never a smooth gradient, never
   reordered, never rotated, never a fourth band.

   Put it BETWEEN sections as its own element:
       <div class="gvs-divider" role="presentation"></div>
   Not as a border, so it survives a background change on either side.
   ========================================================================== */

.gvs-divider {
  block-size: var(--gvs-divider-height);          /* 10px */
  inline-size: 100%;
  background: var(--gvs-rasta);
  border: 0;
  margin: 0;
  flex: none;
}

/* The page foot edge: same three bands, twice as tall. */
.gvs-divider--foot {
  block-size: var(--gvs-footedge-height);         /* 20px */
}

/* A short inline tick of the tricolour, used above a page or section title.
   72 x 6 in the guideline pages. */
.gvs-tick {
  display: block;
  inline-size: 72px;
  block-size: 6px;
  background: var(--gvs-rasta);
}


/* ==========================================================================
   10. MOTIFS
   ========================================================================== */

/* ---- 10a. The sunburst ray fan --------------------------------------------
   20 rays, 18deg apart, 13deg wide (half-width 6.5deg), colour cycling
   red, orange, gold, green, teal. That cycle repeats every 5 rays, which is
   every 90deg, so the whole fan is one repeating-conic-gradient with a 90deg
   period. `from -9deg` puts ray 0 due north, exactly as drawn.

   Rays radiate from the seal centre or a page corner, NEVER an arbitrary
   point, and are ALWAYS clipped to their section. This element is the layer,
   not the section: give the parent `position: relative; overflow: hidden`
   (gvs-layout.css does that with .gvs-band__rays and friends).

   Over body copy the tint is capped at 12%. That is a legibility limit, not a
   preference.
   -------------------------------------------------------------------------- */

.gvs-sunburst {
  position: absolute;
  inset: 0;
  z-index: var(--gvs-z-base);
  pointer-events: none;
  opacity: var(--gvs-ray-tint-dark);       /* 30% default, over dark fields */
  background-image: repeating-conic-gradient(
    from -9deg at 50% 50%,
    transparent            0      2.5deg,
    var(--gvs-rasta-red)    2.5deg 15.5deg,
    transparent            15.5deg 20.5deg,
    var(--gvs-ray-orange)  20.5deg 33.5deg,
    transparent            33.5deg 38.5deg,
    var(--gvs-rasta-gold)  38.5deg 51.5deg,
    transparent            51.5deg 56.5deg,
    var(--gvs-rasta-green) 56.5deg 69.5deg,
    transparent            69.5deg 74.5deg,
    var(--gvs-ray-teal)    74.5deg 87.5deg,
    transparent            87.5deg 90deg
  );
}

/* The hub. Rays start at r=48 of r=168, so the middle 28.571% is empty.
   Masked rather than covered so the fan works over any ground. */
.gvs-sunburst--hub {
  -webkit-mask-image: radial-gradient(closest-side circle at 50% 50%,
                        transparent 28.571%, #000 28.571%);
          mask-image: radial-gradient(closest-side circle at 50% 50%,
                        transparent 28.571%, #000 28.571%);
}

/* Origins. A fan may only start at the seal centre or at a page corner. */
.gvs-sunburst--center       { background-position: 50% 50%; }
.gvs-sunburst--left         { background-position: 0    50%; background-image: repeating-conic-gradient(
    from -9deg at 0% 50%,
    transparent            0      2.5deg,
    var(--gvs-rasta-red)    2.5deg 15.5deg,
    transparent            15.5deg 20.5deg,
    var(--gvs-ray-orange)  20.5deg 33.5deg,
    transparent            33.5deg 38.5deg,
    var(--gvs-rasta-gold)  38.5deg 51.5deg,
    transparent            51.5deg 56.5deg,
    var(--gvs-rasta-green) 56.5deg 69.5deg,
    transparent            69.5deg 74.5deg,
    var(--gvs-ray-teal)    74.5deg 87.5deg,
    transparent            87.5deg 90deg
  ); }
.gvs-sunburst--right        { transform: scaleX(-1); }

/* Tints. Only these three. */
.gvs-sunburst--hero         { opacity: var(--gvs-ray-tint-hero);        /* 100% */ }
.gvs-sunburst--dark         { opacity: var(--gvs-ray-tint-dark);        /*  30% */ }
.gvs-sunburst--behind-text  { opacity: var(--gvs-ray-tint-behind-text); /*  12% MAX */ }

/* No conic-gradient support: show nothing rather than a flat colour block. */
@supports not (background-image: conic-gradient(#000, #fff)) {
  .gvs-sunburst { background-image: none; }
}


/* ---- 10b. The gold ribbon banner ------------------------------------------
   Base .gvs-ribbon is the flat gold band with a tracked-caps label — the
   "GET INVOLVED" eyebrow ribbon. Two opt-in modifiers rebuild the seal's
   version: a near-black inner field, and notched tails.

   Proportions are the seal's, expressed against --gvs-ribbon-h so the whole
   thing scales from one number:
     band 348 x 64 · field 332 x 48 · tail 36 wide x 76 tall, notch at 16.
   -------------------------------------------------------------------------- */

.gvs-ribbon {
  --gvs-ribbon-h: 32px;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-block-size: var(--gvs-ribbon-h);
  padding-inline: var(--gvs-space-3);
  background: var(--gvs-gold);
  color: var(--gvs-petrol);                  /* 5.03:1 */
  font-family: var(--gvs-font-body);
  font-weight: var(--gvs-body-weight-em);
  font-size: var(--gvs-fs-micro);
  line-height: 1;
  letter-spacing: var(--gvs-tracking-eyebrow);
  text-transform: uppercase;
}

/* The seal treatment: near-black field, cream type. 11.9:1. */
.gvs-ribbon--field {
  background: var(--gvs-near-black);
  color: var(--gvs-cream);
  border: calc(var(--gvs-ribbon-h) / 8) solid var(--gvs-gold);
  font-family: var(--gvs-font-ribbon);
}

/* Notched tails. Percentages so they scale with --gvs-ribbon-h. */
.gvs-ribbon--tailed::before,
.gvs-ribbon--tailed::after {
  content: "";
  position: absolute;
  inline-size: calc(var(--gvs-ribbon-h) * 36 / 64);
  block-size: calc(var(--gvs-ribbon-h) * 76 / 64);
  inset-block-start: 50%;
  translate: 0 -50%;
  background: var(--gvs-gold);
}
.gvs-ribbon--tailed::before {
  inset-inline-end: 100%;
  clip-path: polygon(0 0, 100% 15.79%, 100% 84.21%, 0 100%, 44.44% 50%);
}
.gvs-ribbon--tailed::after {
  inset-inline-start: 100%;
  clip-path: polygon(100% 0, 0 15.79%, 0 84.21%, 100% 100%, 55.56% 50%);
}


/* ---- 10c. Press grain -----------------------------------------------------
   2px cream rules at 10% opacity. Newsprint, NEVER a noise filter, never a
   blurred texture PNG. Clip it to the image or the field it sits on.
   -------------------------------------------------------------------------- */

.gvs-grain {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: var(--gvs-grain-opacity);        /* 0.1 */
  background-image: repeating-linear-gradient(
    to bottom,
    var(--gvs-grain-colour) 0,
    var(--gvs-grain-colour) var(--gvs-grain-rule),
    transparent             var(--gvs-grain-rule),
    transparent             var(--gvs-grain-pitch)
  );
}
.gvs-grain--tight { --gvs-grain-pitch: 12px; }


/* ---- 10d. The seal and the ring mark -------------------------------------
   assets/seal.svg is the full-colour seal, assets/seal-mono.svg the single-ink
   reduction. Both are 560 x 560 with the seal centred, and both carry OUTLINED
   type, so no webfont is involved. Scale the seal proportionally or not at all.
   -------------------------------------------------------------------------- */

.gvs-seal {
  display: block;
  inline-size: var(--gvs-seal-size);
  block-size: auto;
  aspect-ratio: 1;
}
.gvs-seal--mono  { color: var(--gvs-petrol); }
.gvs-seal--inverse { color: var(--gvs-cream); }
.gvs-seal--footer { inline-size: var(--gvs-footer-seal); }   /* 108px, mono */

/* Clear space. Nothing may enter seal-size / 8 around the seal. */
.gvs-seal-lockup {
  display: inline-block;
  padding: var(--gvs-seal-clearspace);
}

/* The ring mark: the nav-scale reduction. Below --gvs-seal-min-width (180px)
   the arched caps close up and become unreadable, so at nav and favicon sizes
   the seal is replaced by this. Drawn in CSS so it needs no asset. */
.gvs-mark {
  --gvs-mark-size: var(--gvs-nav-mark);    /* 44px */
  position: relative;
  display: inline-block;
  inline-size: var(--gvs-mark-size);
  block-size: var(--gvs-mark-size);
  border: calc(var(--gvs-mark-size) * 3 / 44) solid currentColor;
  border-radius: 50%;
  color: var(--gvs-petrol);
  flex: none;
}
.gvs-mark::before,
.gvs-mark::after {
  content: "";
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 50%;
  translate: -50% -50%;
  border-radius: 50%;
}
.gvs-mark::before {                        /* inner ring, 30 of 44 */
  inline-size: calc(var(--gvs-mark-size) * 30 / 44);
  block-size:  calc(var(--gvs-mark-size) * 30 / 44);
  border: calc(var(--gvs-mark-size) * 1.5 / 44) solid currentColor;
}
.gvs-mark::after {                         /* gold core, 14 of 44 */
  inline-size: calc(var(--gvs-mark-size) * 14 / 44);
  block-size:  calc(var(--gvs-mark-size) * 14 / 44);
  background: var(--gvs-gold);
}
.gvs-mark--inverse { color: var(--gvs-cream); }


/* ==========================================================================
   11. ICONS
   assets/icons.svg is a <symbol> sprite on a 32x32 viewBox, 2px strokes,
   round caps and joins, colour from currentColor.

   Colour is set with `color`, NOT with `stroke`. A stroke set on the outer
   <svg> does not cross into the shadow tree of a <use>, but an inherited
   `color` does, and the sprite paints itself with currentColor. This is the
   one place where the Volume A CSS (which sets `stroke`) is wrong and this
   file is right.
   ========================================================================== */

.gvs-icon {
  inline-size: var(--gvs-icon-grid);       /* 32px */
  block-size: var(--gvs-icon-grid);
  color: var(--gvs-icon-colour);
  flex: none;
  /* Fallbacks for a directly inlined <svg> that has no attributes of its own. */
  fill: none;
  stroke: currentColor;
  stroke-width: var(--gvs-icon-stroke);
  stroke-linecap: round;
  stroke-linejoin: round;
}

.gvs-icon--sm     { inline-size: 24px; block-size: 24px; }
.gvs-icon--inline {                       /* arrow and external, set with type */
  inline-size: var(--gvs-icon-inline);
  block-size: var(--gvs-icon-inline);
  display: inline-block;
  vertical-align: -0.125em;
}
.gvs-icon--lg     { inline-size: 48px; block-size: 48px; }

/* On dark fields the icons switch to cream. Stroke weight does not change. */
.gvs-on-dark .gvs-icon,
.gvs-bg-inverse .gvs-icon {
  color: var(--gvs-icon-colour-inverse);
}

/* The card icon disc: a 76px petrol disc at 8%, icon centred on it. */
.gvs-icon-disc {
  display: grid;
  place-items: center;
  inline-size: var(--gvs-icon-disc);       /* 76px */
  block-size: var(--gvs-icon-disc);
  border-radius: 50%;
  background: color-mix(in srgb, var(--gvs-petrol) 8%, transparent);
  flex: none;
}
@supports not (background: color-mix(in srgb, red 8%, transparent)) {
  .gvs-icon-disc { background: #E7E1D2; }  /* petrol 8% flattened onto paper */
}


/* ==========================================================================
   12. PHOTOGRAPHS
   Every photograph gets a 16px warm-paper mat and a 2px petrol keyline. Type
   over a photograph gets a scrim, and the scrim is not optional: at 62% cream
   reads 6.99:1, below that it does not clear AA.
   ========================================================================== */

.gvs-photo {
  display: block;
  padding: var(--gvs-photo-mat);           /* 16px */
  background: var(--gvs-paper);
  border: var(--gvs-photo-keyline) solid var(--gvs-border);
  border-radius: var(--gvs-radius);
}
.gvs-photo > img,
.gvs-photo > picture > img {
  display: block;
  inline-size: 100%;
  block-size: auto;
  border-radius: 0;                        /* never exceed --gvs-radius */
}

.gvs-photo-hero {
  position: relative;
  isolation: isolate;
}
.gvs-photo-hero::after {                   /* the scrim */
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: var(--gvs-scrim-colour);
  opacity: var(--gvs-scrim-opacity);       /* 0.62 MINIMUM */
  pointer-events: none;
}
.gvs-photo-hero__type {
  position: relative;
  z-index: 2;                              /* above the scrim */
  color: var(--gvs-text-inverse);
}

/* Placeholder field, for a comp or an empty CMS slot. #968C7E on cream is
   3.02:1, so its label must be large: 19px or more, or 16px bold. */
.gvs-placeholder-field {
  display: grid;
  place-items: center;
  background: var(--gvs-placeholder);
  color: var(--gvs-cream);
  font-size: var(--gvs-fs-body-lg);
  min-block-size: 200px;
}


/* ==========================================================================
   13. UTILITIES
   Single-purpose, no component knowledge. Prefixed, so nothing here can be
   confused with a WordPress core utility.
   ========================================================================== */

/* ---- visibility ---- */
.gvs-visually-hidden,
.gvs-vh {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
/* Same, but becomes visible on focus — for a skip target or an in-page label. */
.gvs-vh-focusable:not(:focus):not(:focus-within) {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
.gvs-hidden { display: none; }

/* ---- colour: grounds ---- */
.gvs-bg-paper   { background: var(--gvs-paper);   color: var(--gvs-text); }
.gvs-bg-panel   { background: var(--gvs-cream);   color: var(--gvs-text); }
.gvs-bg-gold    { background: var(--gvs-gold);    color: var(--gvs-text-on-gold); }

/* A dark field. Sets the ground, the ink, the muted ink and the focus ring in
   one move, because on a dark field --gvs-ink-muted is only 2.26:1 and must
   NOT be used. Muted text on dark is cream at reduced opacity instead. */
.gvs-on-dark,
.gvs-bg-inverse {
  background: var(--gvs-bg-inverse);
  color: var(--gvs-text-inverse);
  --gvs-text: var(--gvs-cream);
  --gvs-text-muted: var(--gvs-cream);
  --gvs-border: var(--gvs-gold);
  --gvs-focus-ring: var(--gvs-focus-ring-inverse);
  --gvs-icon-colour: var(--gvs-cream);
}
.gvs-on-dark .gvs-muted,
.gvs-bg-inverse .gvs-muted {
  color: var(--gvs-cream);
  opacity: 0.8;
}
.gvs-on-dark a,
.gvs-bg-inverse a {
  color: var(--gvs-cream);
  text-decoration-color: var(--gvs-gold);
}

/* The eyebrow on a dark field. --gvs-teal-text #256A75 on petrol-deep #123640
   is ~1.9:1 and unreadable, so the eyebrow switches to GOLD, which is 6.73:1
   on petrol-deep. This is the one place gold is legitimately an ink. */
.gvs-on-dark .gvs-eyebrow,
.gvs-bg-inverse .gvs-eyebrow,
.gvs-on-dark h5,
.gvs-on-dark h6 {
  color: var(--gvs-gold);
}

/* ---- colour: ink ---- */
.gvs-ink-petrol { color: var(--gvs-petrol); }
.gvs-ink-cream  { color: var(--gvs-cream);  }
.gvs-ink-teal   { color: var(--gvs-teal-text); }   /* never --gvs-ray-teal */
.gvs-ink-red    { color: var(--gvs-rasta-red); }   /* 4.70:1 on paper */

/* ---- type helpers ---- */
.gvs-center      { text-align: center; }
.gvs-right       { text-align: end; }
.gvs-nowrap      { white-space: nowrap; }
.gvs-balance     { text-wrap: balance; }
.gvs-pretty      { text-wrap: pretty; }
.gvs-truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.gvs-clamp-2,
.gvs-clamp-3 {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.gvs-clamp-2 { -webkit-line-clamp: 2; }
.gvs-clamp-3 { -webkit-line-clamp: 3; }

/* ---- primitive layout helpers (not page layout — that is H3) ---- */
.gvs-stack {
  display: flex;
  flex-direction: column;
  gap: var(--gvs-stack-gap, var(--gvs-space-3));
}
.gvs-cluster {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--gvs-cluster-gap, var(--gvs-space-2));
}
.gvs-between {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--gvs-space-3);
}

/* ---- spacing, on the 8px grid. Deliberately few. ---- */
.gvs-mbs-0 { margin-block-start: 0; }
.gvs-mbs-1 { margin-block-start: var(--gvs-space-1); }
.gvs-mbs-2 { margin-block-start: var(--gvs-space-2); }
.gvs-mbs-3 { margin-block-start: var(--gvs-space-3); }
.gvs-mbs-4 { margin-block-start: var(--gvs-space-4); }
.gvs-mbs-6 { margin-block-start: var(--gvs-space-6); }
.gvs-mbs-8 { margin-block-start: var(--gvs-space-8); }
.gvs-mbe-0 { margin-block-end: 0; }
.gvs-mbe-2 { margin-block-end: var(--gvs-space-2); }
.gvs-mbe-3 { margin-block-end: var(--gvs-space-3); }
.gvs-mbe-6 { margin-block-end: var(--gvs-space-6); }

/* ---- shape ---- */
.gvs-radius    { border-radius: var(--gvs-radius); }
.gvs-radius-sm { border-radius: var(--gvs-radius-sm); }
.gvs-pill      { border-radius: var(--gvs-radius-pill); }
.gvs-keyline   { border: var(--gvs-border-width) solid var(--gvs-border); }

/* ---- a hairline rule. Soft grey is a RULE colour, never a text colour. ---- */
.gvs-rule {
  block-size: 1px;
  inline-size: 100%;
  background: var(--gvs-rule);
  border: 0;
  margin: 0;
}

/* Positioning context for a motif layer. */
.gvs-clip {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}


/* ==========================================================================
   14. RESPONSIVE LADDER

   Breakpoints, identical to Volume C and to gvs-layout.css:

     name       range        gutter  content  grid   notes
     -------------------------------------------------------------------
     wide       >= 1440       120     1200    4 up   the drawn comp
     desktop   1200 - 1439     48     fluid   4 up   type scale unchanged
     laptop    1024 - 1199     40     fluid   3 up   H1 92 -> 72
     tablet     768 - 1023     32     fluid   2 up   split sections stack
     phone-lg   480 -  767     24     fluid   1 up   nav -> drawer, H1 48
     phone     <=  479         20      350    1 up   H1 40

   WHY THIS LADDER IS max-width AND NOT mobile-first
   :root in gvs-tokens.css holds the values as DRAWN at 1440. Those are the
   canonical design reference and they are what Volumes B and C were authored
   against — --gvs-fs-h1 must read 92px, not 40px, when a developer inspects
   it. Turning the ladder around would mean renumbering every token to its
   phone value, which breaks that contract, and it would fight the max-width
   ladder gvs-layout.css already ships. Same edges, same values, one direction.
   Component rules elsewhere in this file are written mobile-first where they
   do not touch a token.

   gvs-layout.css re-declares the --gvs-gutter and --gvs-fs-h1 steps with the
   SAME values. Identical declarations cannot conflict; whichever loads last
   wins with the same number.
   ========================================================================== */

@media (max-width: 1439.98px) {
  :root {
    --gvs-gutter: 48px;
  }
  .gvs-container,
  .gvs-wrap { max-inline-size: 100%; }
}

@media (max-width: 1199.98px) {
  :root {
    --gvs-gutter: 40px;
    --gvs-fs-h1: 72px;
    --gvs-lh-h1: 68px;
  }
}

@media (max-width: 1023.98px) {
  :root {
    --gvs-gutter: 32px;
    --gvs-fs-h2: 44px;
    --gvs-lh-h2: 48px;
    --gvs-fs-quote: 30px;
    --gvs-lh-quote: 36px;
    --gvs-section-pad: 80px;
  }
  blockquote {
    padding-inline-start: var(--gvs-space-3);
  }
}

@media (max-width: 767.98px) {
  :root {
    --gvs-gutter: 24px;
    --gvs-fs-h1: 48px;
    --gvs-lh-h1: 48px;
    --gvs-fs-h2: 34px;
    --gvs-lh-h2: 38px;
    --gvs-fs-h2-sm: 30px;
    --gvs-fs-h3: 24px;
    --gvs-lh-h3: 28px;
    --gvs-fs-lead: 18px;
    --gvs-lh-lead: 26px;
    --gvs-section-pad: 64px;
    --gvs-divider-height: 8px;
    --gvs-footedge-height: 16px;
  }
  /* The seal never exceeds the column on a phone, and it never gets cropped. */
  .gvs-seal { inline-size: min(100%, var(--gvs-seal-size)); }
}

@media (max-width: 479.98px) {
  :root {
    --gvs-gutter: 20px;
    --gvs-fs-h1: 40px;
    --gvs-lh-h1: 42px;
    --gvs-fs-h2: 30px;
    --gvs-lh-h2: 34px;
    --gvs-fs-body: 17px;
    --gvs-lh-body: 28px;
    --gvs-section-pad: 56px;
  }
  /* Below the seal's minimum width the arched caps close up. Swap in the
     ring mark instead of scaling the seal down further. */
  .gvs-seal--responsive { display: none; }
  .gvs-seal--responsive + .gvs-mark { display: inline-block; }
}

/* Fine pointers get the tighter underline offset; coarse pointers need the
   tap target, so links in running copy get a little more room. */
@media (pointer: coarse) {
  .gvs-prose a { text-underline-offset: 6px; }
}


/* ==========================================================================
   15. REDUCED MOTION
   The system has almost no motion by design. What exists is a 120-160ms
   mechanical transition. Under prefers-reduced-motion everything stops,
   including the marquee that gvs-layout.css owns and any smooth scrolling.
   ========================================================================== */

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms;
    animation-iteration-count: 1;
    transition-duration: 0.01ms;
    scroll-behavior: auto;
  }
  html { scroll-behavior: auto; }
  .gvs-link-arrow:hover .gvs-icon { transform: none; }
  .gvs-skip-link { transition: none; }
}


/* ==========================================================================
   16. PRINT
   Warm paper does not print. Fall back to white with petrol ink, drop every
   decorative motif, and keep the Rasta divider as a visible rule because it
   is the one piece of the identity that survives in one colour: it is the
   only place three distinct greys are meaningful.
   ========================================================================== */

@media print {
  :root {
    --gvs-bg: #FFFFFF;
    --gvs-bg-panel: #FFFFFF;
    --gvs-text: #000000;
    --gvs-text-muted: #444444;
    --gvs-fs-h1: 32pt;
    --gvs-lh-h1: 34pt;
    --gvs-fs-h2: 20pt;
    --gvs-lh-h2: 24pt;
    --gvs-fs-body: 11pt;
    --gvs-lh-body: 15pt;
    --gvs-section-pad: 18pt;
    --gvs-gutter: 0;
  }

  html,
  body {
    background: #FFFFFF;
    color: #000000;
  }

  /* Decoration off. */
  .gvs-sunburst,
  .gvs-grain,
  .gvs-tick,
  .gvs-photo-hero::after {
    display: none;
  }

  /* The divider stays, printed as a 2pt rule with the three bands intact so
     the tricolour still reads on a colour printer. */
  .gvs-divider {
    block-size: 2pt;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
    break-inside: avoid;
  }

  .gvs-container,
  .gvs-wrap,
  .gvs-container--narrow,
  .gvs-container--prose {
    max-inline-size: none;
    padding-inline: 0;
  }

  /* Reveal link targets in running copy. */
  .gvs-prose a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: 9pt;
    word-break: break-all;
  }

  /* Keep headings with their content. */
  h1, h2, h3, h4,
  .gvs-h1, .gvs-h2, .gvs-h3 {
    break-after: avoid;
    page-break-after: avoid;
  }
  figure,
  blockquote,
  .gvs-photo,
  table {
    break-inside: avoid;
  }
  img { max-inline-size: 100%; }

  /* Navigation, drawers and skip links are not printable content. */
  .gvs-skip-link,
  .gvs-mark {
    display: none;
  }
}

/* ==========================================================================
   END gvs-base.css
   ========================================================================== */
