/* Per-block rules.
 *
 * Every value is a token. Where the mockup used a literal, it is here as the
 * token that carries that literal — the mockup's grape is --gvl-primary, and
 * a change to the token has to reach the whole page or the token is not the
 * theming API it claims to be.
 */

/* ── Announcement bar ──────────────────────────────────────────────────── */

.gv-announce { background: var(--gvl-ink); color: #f2ecdf; font-size: 14px; }
.gv-announce__inner {
    max-width: var(--gvl-container);
    margin-inline: auto;
    padding: 9px var(--gvl-gutter);
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    justify-content: center;
}
.gv-announce__badge {
    background: var(--gvl-gold); color: var(--gvl-ink);
    font-family: var(--gvl-font-mono); font-weight: 700;
    font-size: 11px; letter-spacing: .1em;
    padding: 2px 8px; border-radius: var(--gvl-pill);
}
.gv-announce__link { color: #f2ecdf; font-weight: 600; }
.gv-announce__link:hover { color: var(--gvl-gold); }

/* ── Header ────────────────────────────────────────────────────────────── */

.gv-header {
    background: var(--gvl-paper);
    border-bottom: 1.5px solid var(--gvl-line-2);
    position: sticky; top: 0; z-index: 100;
}
.gv-header__inner { display: flex; align-items: center; gap: 28px; padding-block: 16px; }
.gv-header__logo { display: inline-flex; flex-shrink: 0; }
.gv-header__logo img { height: 34px; width: auto; }
/* A flex row, because the nav now holds two things: the Features panel's
   button and core/navigation's own list. Left as a block container they
   stacked, and the menu wrapped onto a second line under the logo. */
.gv-header__nav { margin-inline-start: auto; display: flex; align-items: center; gap: 26px; }
.gv-header__nav a { text-decoration: none; font-weight: 600; }
.gv-header__actions { display: flex; align-items: center; gap: 14px; flex-shrink: 0; }
.gv-header__login { font-weight: 600; text-decoration: none; }
/* Matched to the hamburger beside it in the header — see --gvl-control. */
.gv-btn--sm { padding: .5rem .9rem; font-size: .95rem; min-height: var(--gvl-control); }

/* ── One menu at a time ────────────────────────────────────────────────
 *
 * Two things can show the feature pages: the floating Features panel, and
 * core/navigation's overlay. The panel is better on a wide screen and is a
 * sheet that runs off the side of a phone, so each is hidden at the size the
 * other is showing and only ever one is on the page.
 *
 * core collapses its own menu at 600px. The rest of this header changes at
 * 860px, and a menu that rearranges at a different width from everything
 * beside it reads as a bug — so the collapse is moved to match.
 */
@media (max-width: 860px) {
    .gv-header__inner { gap: 12px; }
    .gv-header__login { display: none; }

    /* The panel stands aside; its links are in the overlay instead.
     *
     * Scoped through the nav rather than written as a bare .gv-fmenu: the
     * panel's own `display: inline-flex` is declared further down this file,
     * and at equal specificity the later rule wins — so the bare version lost
     * and Features stayed on screen at 390px. */
    .gv-header__nav .gv-fmenu { display: none; }

    /* Force core's hamburger on, up to our breakpoint rather than its own. */
    .gv-header .wp-block-navigation__responsive-container-open:not(.always-shown) {
        display: inline-flex;
    }
    .gv-header .wp-block-navigation__responsive-container:not(.hidden-by-default):not(.is-menu-open) {
        display: none;
    }
}

/* Above it, the panel is the Features menu, so the core one would be a second
   thing with the same name. */
@media (min-width: 861px) {
    .gv-header__nav > .wp-block-navigation .wp-block-navigation-submenu { display: none; }
}

/* The hamburger, sized to the button beside it.
 *
 * They sit on the same line and are the only two controls in the bar, so one
 * being a bare glyph and the other a solid button made the pair look
 * unfinished. Same height, same radius, same ink border. */
.gv-header .wp-block-navigation__responsive-container-open {
    /* NO display here.
     *
     * It was `display: inline-flex`, which out-specifies core's own rule
     * hiding this button above 600px — so the hamburger appeared on desktop
     * beside the full menu, and the nav wrapped onto two lines under the
     * logo. Whether it shows is decided in the media query above; this rule
     * only says what it looks like when it does. */
    width: var(--gvl-control); height: var(--gvl-control);
    align-items: center; justify-content: center;
    border: var(--gvl-border); border-radius: var(--gvl-radius-sm);
    background: var(--gvl-card);
}
.gv-header .wp-block-navigation__responsive-container-open:hover { background: var(--gvl-paper-2); }
.gv-header .wp-block-navigation__responsive-container-open:focus-visible {
    outline: 2px solid var(--gvl-primary); outline-offset: 2px;
}

/* core/navigation's overlay button, in this theme's ink. */
.gv-header .wp-block-navigation__responsive-container-open,
.gv-header .wp-block-navigation__responsive-container-close { color: var(--gvl-ink); }
.gv-header .wp-block-navigation__responsive-container.is-menu-open {
    background: var(--gvl-paper);
    color: var(--gvl-ink);
    padding: 24px;
}
.gv-header .wp-block-navigation__responsive-container.is-menu-open a { font-size: 1.3rem; }

/* ── The Features panel ────────────────────────────────────────────────── */

.gv-fmenu { position: relative; display: inline-flex; }

.gv-fmenu__toggle {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 6px 2px;
    /* Matched to the links beside it, which take font-weight 600 from
       .gv-header__nav a. A button does not inherit that rule, and it had a
       font-size of its own that the links do not — so Features sat in a
       different weight AND a different size from everything next to it. */
    font: inherit; font-weight: 600; color: var(--gvl-ink);
    background: transparent; border: 0; cursor: pointer;
}
.gv-fmenu__toggle:hover,
.gv-fmenu__toggle.is-current { color: var(--gvl-primary-dark); }
.gv-fmenu__toggle:focus-visible { outline: 2px solid var(--gvl-primary); outline-offset: 4px; border-radius: 4px; }

/* The caret, drawn rather than a glyph so it inherits colour and lines up
   with the cap height at any size. */
.gv-fmenu__caret {
    width: 7px; height: 7px;
    border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
    transform: translateY(-2px) rotate(45deg);
    transition: transform .14s ease;
}
.gv-fmenu__toggle[aria-expanded="true"] .gv-fmenu__caret { transform: translateY(1px) rotate(-135deg); }

.gv-fmenu__panel {
    position: absolute; top: calc(100% + 14px); left: 50%;
    transform: translateX(-50%);
    z-index: 60;
    width: min(760px, calc(100vw - 32px));
    padding: 26px 26px 24px;
    display: grid; gap: 0 30px;
    grid-template-columns: minmax(0, 1fr) 190px;
    grid-template-areas: "label side" "grid side";
    box-shadow: var(--gvl-shadow);
}
/* The panel hangs below the header, and the header sits above the page. */
.gv-header { position: relative; z-index: 50; }

.gv-fmenu__label {
    grid-area: label;
    margin: 0 0 14px;
    font-family: var(--gvl-font-mono); font-size: 10.5px;
    letter-spacing: .14em; text-transform: uppercase; color: var(--gvl-ink-2);
}
.gv-fmenu__grid {
    grid-area: grid;
    list-style: none; margin: 0; padding: 0;
    display: grid; gap: 6px; grid-template-columns: repeat(2, minmax(0, 1fr));
}
.gv-fmenu__item {
    display: grid; grid-template-columns: 38px minmax(0, 1fr); gap: 12px;
    padding: 11px 12px; border-radius: 12px;
    color: inherit; text-decoration: none;
    border: 1.5px solid transparent;
}
.gv-fmenu__item:hover { background: var(--gvl-paper-2); }
.gv-fmenu__item.is-current { border-color: var(--gvl-primary); background: var(--gvl-primary-light); }
.gv-fmenu__item:focus-visible { outline: 2px solid var(--gvl-primary); outline-offset: 1px; }

.gv-fmenu__ico {
    display: inline-flex; align-items: center; justify-content: center;
    width: 38px; height: 38px; border-radius: 10px;
    border: 1.5px solid var(--gvl-line-2);
    color: var(--gvl-primary-dark);
}
.gv-fmenu__item.is-current .gv-fmenu__ico { border-color: var(--gvl-primary); }
.gv-fmenu__words { display: grid; gap: 2px; min-width: 0; align-content: center; }
.gv-fmenu__words strong { font-size: 15px; }
.gv-fmenu__words small { font-size: 13px; color: var(--gvl-ink-2); line-height: 1.45; }

.gv-fmenu__side {
    grid-area: side;
    border-left: 1.5px dashed var(--gvl-line-2);
    padding-left: 26px;
}
.gv-fmenu__side ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.gv-fmenu__side a { color: var(--gvl-ink); text-decoration: none; font-size: 14.5px; }
.gv-fmenu__side a:hover { color: var(--gvl-primary-dark); text-decoration: underline; }

/* Below a comfortable width, the panel is anchored to the VIEWPORT rather
   than to the button.
   
   Anchored to the button it cannot be made to fit: the button sits wherever
   the menu happens to put it, and a 760px sheet centred on something near
   the left of the bar hangs off the left edge — measured at -4px on an 880px
   screen. Pinned to the viewport with a margin each side, it fits at every
   width by construction.
   
   top clears the sticky site header, which is 72px. */
@media (max-width: 1100px) {
    .gv-fmenu__panel {
        position: fixed;
        top: 82px;
        left: 12px; right: 12px;
        width: auto; max-width: none;
        transform: none;
    }
}

/* Narrower still, it stacks. Below 860 it is not shown at all — the links
   live in core/navigation's overlay there instead. */
@media (max-width: 1000px) {
    .gv-fmenu__panel {
        grid-template-columns: 1fr;
        grid-template-areas: "label" "grid" "side";
        padding: 18px;
    }
    .gv-fmenu__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .gv-fmenu__side { border-left: 0; border-top: 1.5px dashed var(--gvl-line-2); padding: 16px 0 0; margin-top: 16px; }
}

/* Tight on a phone: the words still fit, the gap does not. */
@media (max-width: 420px) {
    .gv-header__nav { gap: 14px; }
}

@media (prefers-reduced-motion: reduce) { .gv-fmenu__caret { transition: none; } }

/* ── Hero ──────────────────────────────────────────────────────────────── */

.gv-hero { position: relative; overflow: hidden; }
.gv-hero__field {
    position: absolute; inset: 0 0 0 auto;
    width: 46%; opacity: .8; pointer-events: none;
}
.gv-hero__inner {
    position: relative;
    padding-block: 84px 90px;
    display: flex; flex-wrap: wrap; gap: 56px; align-items: center;
}
.gv-hero__text { flex: 1 1 520px; min-width: 0; }
.gv-hero__art  { flex: 1 1 440px; min-width: 0; display: flex; justify-content: center; }
.gv-hero .gv-h1 { text-wrap: balance; }
.gv-hero__lede { margin: 28px 0 0; font-size: 20px; color: var(--gvl-ink-2); max-width: 34em; }
.gv-hero__actions { margin-top: 36px; display: flex; gap: 14px; flex-wrap: wrap; align-items: center; }
.gv-hero__note { margin: 20px 0 0; font-size: 14.5px; color: var(--gvl-ink-2); }

@media (max-width: 760px) { .gv-hero__inner { padding-block: 52px 56px; gap: 32px; } }

/* ── Course card ───────────────────────────────────────────────────────── */

.gv-coursecard {
    position: relative; width: 100%; max-width: 470px;
    background: var(--gvl-card);
    border: var(--gvl-border); border-radius: 22px;
    box-shadow: 7px 7px 0 var(--gvl-ink);
}
.gv-coursecard__bar {
    display: flex; align-items: center; gap: 8px;
    padding: 12px 16px;
    border-bottom: 1.5px solid var(--gvl-ink);
    font-family: var(--gvl-font-mono); font-size: 12px; color: var(--gvl-ink-2);
}
.gv-coursecard__url { margin-inline-start: 8px; }
.gv-coursecard__body { padding: 22px 22px 24px; }
.gv-coursecard__meta {
    margin: 0; font-family: var(--gvl-font-mono); font-size: 11.5px;
    letter-spacing: .12em; text-transform: uppercase; color: var(--gvl-ink-2);
}
.gv-coursecard__title {
    margin: 6px 0 0; font-family: var(--gvl-font-display); font-weight: 800;
    font-size: 28px; letter-spacing: -.03em; line-height: 1.05;
}
.gv-coursecard__progress { margin: 6px 0 0; font-size: 13px; color: var(--gvl-ink-2); }
.gv-coursecard__stamp { position: absolute; right: 14px; bottom: -14px; font-size: 1rem; background: var(--gvl-card); }
.gv-coursecard__mark { position: absolute; left: -18px; bottom: -18px; width: 44px; height: 44px; }

.gv-progress {
    margin-top: 16px; height: 12px;
    border: 1.5px solid var(--gvl-ink); border-radius: var(--gvl-pill);
    overflow: hidden; background: var(--gvl-paper-2);
}
.gv-progress__fill { display: block; height: 100%; background: var(--gvl-primary); border-right: 1.5px solid var(--gvl-ink); }

.gv-lessons { list-style: none; margin: 18px 0 0; padding: 0; display: grid; gap: 8px; }
.gv-lesson {
    display: flex; align-items: center; gap: 10px; justify-content: space-between;
    border: 1.5px solid var(--gvl-line); border-radius: var(--gvl-radius-sm);
    padding: 9px 11px; font-size: 14px; background: #fff;
}
.gv-lesson__name { min-width: 0; }
/* Gold marks the row the learner is on, and nothing else on this card. */
.gv-lesson.is-here { background: var(--gvl-gold-wash); border-color: var(--gvl-gold); }
.gv-lesson.is-done .gv-lesson__name { color: var(--gvl-ink-2); }

/* ── Audience strip ────────────────────────────────────────────────────── */

.gv-audience { background: var(--gvl-paper-2); border-block: 1.5px solid var(--gvl-line); padding-block: 36px; }
.gv-audience__label { margin-bottom: 18px; }
.gv-audience__list {
    list-style: none; margin: 0; padding: 0;
    display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 20px;
}
.gv-audience__item { display: grid; gap: 4px; min-width: 0; }
.gv-audience__name { font-family: var(--gvl-font-display); font-weight: 800; font-size: 16px; letter-spacing: -.02em; }
.gv-audience__text { font-size: 14px; color: var(--gvl-ink-2); }

@media (max-width: 1060px) { .gv-audience__list { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 620px)  { .gv-audience__list { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* ── Section heading ───────────────────────────────────────────────────── */

.gv-sechead { max-width: 940px; margin-bottom: 44px; }
.gv-sechead.is-center { margin-inline: auto; text-align: center; }
.gv-sechead.is-center .gv-kicker { justify-content: center; }
.gv-sechead__row { display: flex; align-items: center; gap: 20px; }
.gv-sechead.is-center .gv-sechead__row { justify-content: center; }
.gv-sechead__icon { width: 56px; height: 56px; flex-shrink: 0; }

/* ── Feature groups ────────────────────────────────────────────────────── */

.gv-group { margin-top: 64px; display: grid; gap: 22px; }
/* A second row of cards belongs to the group above it, so it keeps the gap
 * and loses the rule. */
.gv-group.is-headless { margin-top: 18px; }
.gv-group__head {
    display: grid; grid-template-columns: 200px minmax(0, 1fr); gap: 8px 28px;
    align-items: start; border-top: var(--gvl-border); padding-top: 18px;
}
.gv-group__label { margin: 4px 0 0; }
.gv-group__text { margin: 8px 0 0; color: var(--gvl-ink-2); max-width: 44em; }

.gv-grid { display: grid; gap: 18px; }
.gv-grid--1 { grid-template-columns: minmax(0, 1fr); }
.gv-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.gv-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.gv-grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

@media (max-width: 1060px) { .gv-grid--4, .gv-grid--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 700px) {
    .gv-grid--4, .gv-grid--3, .gv-grid--2 { grid-template-columns: minmax(0, 1fr); }
    .gv-group__head { grid-template-columns: minmax(0, 1fr); }
}

.gv-fcard {
    background: var(--gvl-card); border: var(--gvl-border); border-radius: 18px;
    overflow: hidden; display: flex; flex-direction: column; min-width: 0;
}
.gv-fcard__mock { padding: 20px; border-bottom: var(--gvl-border); flex: 1; }
.gv-fcard__text { padding: 16px 18px 20px; }
.gv-fcard__title { margin: 0 0 4px; font-size: 19px; letter-spacing: -.02em; }
.gv-fcard__text p { margin: 0; color: var(--gvl-ink-2); font-size: 15px; }

/* ── The mocks ─────────────────────────────────────────────────────────── */

.gv-mock {
    background: var(--gvl-card); border: var(--gvl-border); border-radius: 13px;
    /* Ink, not vine. A vine shadow on a mock that sits inside a bordered card
     * put a green edge outside the card it lives in. */
    box-shadow: 4px 4px 0 var(--gvl-ink);
    padding: 14px; display: grid; gap: 8px; font-size: 13px; min-width: 0;
}
.gv-mono { font-family: var(--gvl-font-mono); font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--gvl-ink-2); }

.gv-chip {
    display: inline-flex; align-items: center; justify-content: center; gap: .3rem;
    border: 1.5px solid var(--gvl-line-2); border-radius: var(--gvl-radius-sm);
    padding: 5px 10px; font-size: 12.5px; background: #fff; font-weight: 600;
}
.gv-chip.is-action  { background: var(--gvl-primary); color: #fff; border-color: var(--gvl-ink); }
.gv-chip.is-chosen  { background: var(--gvl-primary-light); border-color: var(--gvl-primary-dark); color: var(--gvl-primary-dark); }
.gv-chip.is-done    { background: var(--gvl-success-wash); border-color: var(--gvl-success); color: var(--gvl-success); }
.gv-chip.is-wide    { width: 100%; }

.gv-tag {
    font-family: var(--gvl-font-mono); font-size: 9.5px; letter-spacing: .1em;
    border: 1.5px solid var(--gvl-line); border-radius: 5px; padding: 1px 5px;
    color: var(--gvl-ink-2); flex-shrink: 0;
}

/* Lesson player */

/*
 * Narrower than the band it sits in, and centred.
 *
 * At full width the panel is 1240px of chrome around a video and a paragraph,
 * which makes the player look like the page rather than like a thing on it.
 * Three fifths is enough for the two columns to still read side by side and
 * little enough that the paper around it does the framing.
 *
 * Below 860px it takes the full width: 60% of a phone is not a player, it is
 * a postage stamp.
 */
.gv-player {
    max-width: 60%;
    margin-inline: auto;
}

@media (max-width: 860px) {
    .gv-player { max-width: 100%; }
}

.gv-player__top { display: flex; justify-content: space-between; gap: 10px; }

/* Video left, the lesson's own text right — which is what the player does with
 * a lesson that has both. Below 760px they stack, video first. */
.gv-player__split {
    display: grid;
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
    gap: 16px;
    align-items: start;
}

@media (max-width: 760px) {
    .gv-player__split { grid-template-columns: minmax(0, 1fr); }
}

.gv-player__video {
    position: relative;
    border: 1.5px solid var(--gvl-ink);
    border-radius: var(--gvl-radius-sm);
    overflow: hidden;
    background: var(--gvl-card);
}

.gv-player__scene { display: block; width: 100%; height: auto; }

/* The play control, centred over the scene. A disc rather than a bare
 * triangle: on a cream ground a lone triangle reads as part of the drawing. */
.gv-player__play {
    position: absolute;
    top: 50%; left: 50%;
    transform: translate(-50%, -50%);
    width: 46px; height: 46px;
    border-radius: 50%;
    background: var(--gvl-primary);
    border: 2.5px solid var(--gvl-ink);
    box-shadow: 3px 3px 0 var(--gvl-ink);
}

.gv-player__play::after {
    content: "";
    position: absolute;
    top: 50%; left: 54%;
    transform: translate(-50%, -50%);
    width: 0; height: 0;
    border-left: 14px solid #fff;
    border-block: 9px solid transparent;
}

.gv-player__scrub {
    position: absolute;
    left: 8px; right: 8px; bottom: 7px;
    display: flex; align-items: center; gap: 8px;
}

/* The scrub sits on the drawing, so it needs its own ground to stay legible. */
.gv-player__scrub .gv-mono {
    background: var(--gvl-card);
    border-radius: 4px;
    padding: 0 4px;
    color: var(--gvl-ink-2);
}

.gv-player__track {
    flex: 1;
    height: 5px;
    border-radius: var(--gvl-pill);
    background: var(--gvl-card);
    border: 1.5px solid var(--gvl-ink);
    overflow: hidden;
}

.gv-player__played { display: block; width: 38%; height: 100%; background: var(--gvl-gold); }

.gv-player__text { display: grid; gap: 6px; align-content: start; }
.gv-player__kicker { margin: 0; }
.gv-player__title { margin: 0; font-size: 19px; line-height: 1.15; letter-spacing: -.02em; }
.gv-player__body { margin: 0; color: var(--gvl-ink-2); }
/* Previous left, Next right, as the real player has them. */
.gv-player__nav {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    justify-content: space-between;
}

/* Quizzes */
.gv-quiz__q { margin: 0; font-family: var(--gvl-font-display); font-size: 16px; line-height: 1.2; }
.gv-quiz__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.gv-quiz__row {
    display: flex; gap: 8px; align-items: center;
    border: 1.5px solid var(--gvl-line); border-radius: var(--gvl-radius-sm);
    padding: 6px 9px; background: #fff;
}
/* Success green, fixed whatever the brand colour: done always looks done. */
.gv-quiz__row.is-right { border-color: var(--gvl-success); background: var(--gvl-success-wash); }
.gv-quiz__tick { color: var(--gvl-success); font-weight: 700; margin-left: auto; }
.gv-quiz__label { min-width: 0; }

/* The marker's shape is the rule: round means one answer, square means several.
 * A reader should know what they may pick before reading the kicker. */
.gv-quiz__marker {
    width: 13px; height: 13px;
    border: 1.5px solid var(--gvl-line-2);
    background: #fff;
    flex-shrink: 0;
}

.gv-quiz--single .gv-quiz__marker,
.gv-quiz--truefalse .gv-quiz__marker { border-radius: 50%; }
.gv-quiz--multi .gv-quiz__marker { border-radius: 3px; }

.gv-quiz__row.is-right .gv-quiz__marker {
    background: var(--gvl-success);
    border-color: var(--gvl-success);
}

/* True and false are a pair of opposites, so they sit side by side. Stacked,
 * they read as a list that happens to be short. */
.gv-quiz--truefalse .gv-quiz__list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}
.gv-quiz__grip { color: var(--gvl-ink-2); }
.gv-quiz__arrow { color: var(--gvl-ink-2); }
.gv-quiz__term { font-weight: 600; }
.gv-quiz__select { color: var(--gvl-ink-2); border-bottom: 1.5px dashed var(--gvl-line-2); }
.gv-quiz__cloze { margin: 0; line-height: 1.9; }
.gv-quiz__blank {
    display: inline-block; width: 5.5em; height: 1.1em;
    border-bottom: 2px solid var(--gvl-primary); vertical-align: -.2em;
}

/* Grading */
.gv-grading { position: relative; }
.gv-grading__who { display: flex; align-items: center; gap: 10px; }
.gv-avatar {
    display: inline-grid; place-items: center; width: 34px; height: 34px;
    border-radius: 50%; background: var(--gvl-primary); color: #fff;
    border: 1.5px solid var(--gvl-ink); box-shadow: 2px 2px 0 var(--gvl-vine);
    font-family: var(--gvl-font-display); font-weight: 800; font-size: 13px; flex-shrink: 0;
}
.gv-grading__name { display: block; font-size: 14px; }
.gv-grading__meta { display: block; }
.gv-grading__score {
    display: flex; align-items: baseline; gap: 8px;
    border: 1.5px solid var(--gvl-line); border-radius: var(--gvl-radius-sm);
    padding: 8px 10px; background: #fff;
}
.gv-grading__score b { font-family: var(--gvl-font-display); font-size: 20px; }
.gv-grading__feedback { margin: 0; color: var(--gvl-ink-2); padding-right: 5.5rem; }
.gv-grading__stamp { position: absolute; right: 8px; bottom: 8px; font-size: .95rem; background: var(--gvl-card); }

/* Reflection */
.gv-reflection__q { margin: 0; font-family: var(--gvl-font-display); font-size: 16px; line-height: 1.2; }
.gv-reflection__msg {
    border: 1.5px solid var(--gvl-line); border-radius: var(--gvl-radius-sm);
    padding: 8px 10px; background: #fff; display: grid; gap: 3px;
}
.gv-reflection__msg p { margin: 0; }
.gv-reflection__msg.is-reply { background: var(--gvl-primary-light); border-color: var(--gvl-primary); }

/* Checkout */
.gv-checkout__line { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.gv-checkout__line b { font-family: var(--gvl-font-display); font-size: 19px; }
.gv-checkout__fields { display: grid; gap: 6px; }
.gv-checkout__pair { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.gv-field {
    border: 1.5px solid var(--gvl-line); border-radius: var(--gvl-radius-sm);
    padding: 7px 9px; background: #fff; color: var(--gvl-ink-2); font-size: 12px;
}

/* Membership */
.gv-membership__top, .gv-seats__top, .gv-builder__top, .gv-report__top {
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
}
.gv-membership__name { margin: 0; font-family: var(--gvl-font-display); font-weight: 800; font-size: 18px; }
.gv-membership__scope { margin: 0; color: var(--gvl-ink-2); }
.gv-membership__price { margin: 2px 0 0; font-family: var(--gvl-font-display); font-size: 22px; }
.gv-membership__until, .gv-membership__note { margin: 0; }

/* Seats */
.gv-seats__org { font-weight: 600; }
.gv-seats__label { display: flex; justify-content: space-between; gap: 10px; margin: 0; }
.gv-seats__code { display: flex; align-items: center; gap: 8px; }
.gv-seats__code code {
    font-family: var(--gvl-font-mono); font-size: 12px;
    border: 1.5px solid var(--gvl-line); border-radius: 6px; padding: 3px 7px;
    background: #fff; color: var(--gvl-ink);
}

/* Report */
.gv-report__figures {
    list-style: none; margin: 0; padding: 0;
    display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px;
}
.gv-report__figures li {
    border: 1.5px solid var(--gvl-line); border-radius: var(--gvl-radius-sm);
    padding: 7px 8px; background: #fff; display: grid; gap: 2px; min-width: 0;
}
.gv-report__figures b { font-family: var(--gvl-font-display); font-size: 17px; }
.gv-report__label { margin: 4px 0 0; }
.gv-report__charthead { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.gv-report__key { margin: 4px 0 0; display: flex; gap: 10px; }

.gv-key {
    display: inline-flex; align-items: center; gap: 5px;
    font-family: var(--gvl-font-mono); font-size: 9.5px;
    letter-spacing: .08em; text-transform: uppercase; color: var(--gvl-ink-2);
}
.gv-key::before {
    content: ""; width: 9px; height: 9px; border-radius: 2px;
    border: 1.5px solid var(--gvl-ink);
}
.gv-key--a::before { background: var(--gvl-primary); }
.gv-key--b::before { background: var(--gvl-vine); }

.gv-report__chart {
    display: flex; align-items: flex-end; gap: 6px; height: 88px;
    border-bottom: 2px solid var(--gvl-ink);
    margin-bottom: 4px;
}

/* One pair of bars per week, the two touching so they read as one reading
 * taken twice rather than as two separate weeks. */
/* height: 100% is load-bearing. The bars size themselves as a percentage,
 * and a percentage resolves against the parent's height — which on an auto
 * parent is nothing at all, so every bar fell back to its 4px minimum. */
.gv-report__pair {
    flex: 1;
    height: 100%;
    display: flex;
    align-items: flex-end;
    gap: 1px;
    min-width: 0;
}

.gv-report__bar {
    flex: 1;
    border: 1.5px solid var(--gvl-ink);
    border-bottom: 0;
    border-radius: 3px 3px 0 0;
    min-height: 4px;
}
.gv-report__bar--a { background: var(--gvl-primary); }
.gv-report__bar--b { background: var(--gvl-vine); }
.gv-report__stalls { list-style: none; margin: 0; padding: 0; display: grid; gap: 5px; }
.gv-report__stalls li { display: grid; grid-template-columns: 5.5em 1fr 1.5em; gap: 8px; align-items: center; }
.gv-report__stallbar { height: 9px; background: var(--gvl-paper-2); border: 1.5px solid var(--gvl-line); border-radius: var(--gvl-pill); overflow: hidden; }
.gv-report__stallbar span { display: block; height: 100%; background: var(--gvl-gold); }

@media (max-width: 520px) { .gv-report__figures { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* Builder / access / progress chart */
.gv-builder__rows { list-style: none; margin: 0; padding: 0; display: grid; gap: 5px; }
.gv-builder__rows li {
    display: flex; align-items: center; gap: 8px;
    border: 1.5px solid var(--gvl-line); border-radius: var(--gvl-radius-sm);
    padding: 6px 9px; background: #fff;
}
.gv-builder__add { color: var(--gvl-primary-dark); }

.gv-access__q { margin: 0; font-family: var(--gvl-font-display); font-size: 15px; }
.gv-access__options { display: flex; flex-wrap: wrap; gap: 6px; }
.gv-access__settings { margin: 2px 0 0; display: grid; gap: 5px; }
.gv-access__settings div { display: flex; justify-content: space-between; gap: 10px; }
.gv-access__settings dt, .gv-access__settings dd { margin: 0; }
.gv-access__settings dd { color: var(--gvl-ink); font-weight: 700; }

.gv-progresschart__bars { display: flex; align-items: flex-end; gap: 4px; height: 58px; }
.gv-progresschart__bars span { flex: 1; background: var(--gvl-vine); border: 1.5px solid var(--gvl-ink); border-bottom: 0; border-radius: 3px 3px 0 0; min-height: 4px; }
.gv-progresschart__note { margin: 0; font-size: 12px; color: var(--gvl-ink-2); }

/* ── Where people stall ────────────────────────────────────────────────── */

.gv-funnel { display: flex; flex-direction: column; gap: 14px; }
.gv-funnel__top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.gv-funnel__chart {
    display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
    gap: 7px; align-items: end;
    height: 132px;
}
.gv-funnel__col { display: grid; grid-template-rows: 1fr auto; gap: 6px; align-items: end; height: 100%; min-width: 0; }
.gv-funnel__bar {
    display: block; width: 100%; align-self: end;
    background: var(--gvl-primary); border: 1.5px solid var(--gvl-ink);
    border-radius: 4px 4px 0 0;
}
/* The cliff. Gold means "this is the one", which is exactly what it means
   here — not decoration, and only ever one column. */
.gv-funnel__col.is-drop .gv-funnel__bar { background: var(--gvl-gold); }
.gv-funnel__tick { font-size: 10px; color: var(--gvl-ink-2); text-align: center; }
.gv-funnel__note { margin: 0; font-size: 14px; color: var(--gvl-ink-2); }

/* ── Hardest questions ─────────────────────────────────────────────────── */

.gv-qscores { display: flex; flex-direction: column; gap: 12px; }
.gv-qscores__top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.gv-qscores__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.gv-qscores__row {
    display: grid; grid-template-columns: minmax(0, 1fr) 72px 40px;
    gap: 10px; align-items: center;
}
.gv-qscores__q {
    font-size: 13.5px; min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.gv-qscores__bar {
    height: 8px; border-radius: 99px;
    background: rgba(31, 27, 36, .1); overflow: hidden;
}
.gv-qscores__bar > span { display: block; height: 100%; background: var(--gvl-primary); }
.gv-qscores__row.is-worst .gv-qscores__bar > span { background: var(--gvl-gold); }
.gv-qscores__pc { font-family: var(--gvl-font-mono); font-size: 12.5px; text-align: right; }
.gv-qscores__note { margin: 0; font-size: 13px; color: var(--gvl-ink-2); }

/* ── Customer sites ────────────────────────────────────────────────────── */

.gv-reseller { display: flex; flex-direction: column; gap: 12px; }
.gv-reseller__top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.gv-reseller__add {
    font-size: 12px; font-weight: 600; color: var(--gvl-primary-dark);
    border: 1.5px solid var(--gvl-primary-dark); border-radius: var(--gvl-pill);
    padding: 3px 10px; white-space: nowrap;
}
.gv-reseller__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.gv-reseller__list li {
    display: grid; grid-template-columns: minmax(0, 1fr) auto;
    gap: 2px 10px; align-items: baseline;
    padding: 10px 12px;
    background: #fff; border: 1.5px solid var(--gvl-line); border-radius: var(--gvl-radius-sm);
}
.gv-reseller__name { font-size: 14.5px; font-weight: 600; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gv-reseller__count { font-size: 12px; color: var(--gvl-ink-2); text-align: right; white-space: nowrap; }
.gv-reseller__url {
    grid-column: 1 / -1;
    font-size: 11.5px; color: var(--gvl-primary-dark);
    min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ── Copy a course out ─────────────────────────────────────────────────── */

.gv-copy { display: flex; flex-direction: column; gap: 10px; }
.gv-copy__source {
    display: flex; align-items: center; gap: 9px;
    padding: 11px 13px;
    background: var(--gvl-primary-light);
    border: 1.5px solid var(--gvl-primary-dark); border-radius: var(--gvl-radius-sm);
}
.gv-copy__dot { width: 9px; height: 9px; border-radius: 50%; background: var(--gvl-primary); flex: none; }
.gv-copy__name { font-size: 14.5px; font-weight: 600; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gv-copy__label { margin: 2px 0 0; font-size: 10.5px; letter-spacing: .12em; color: var(--gvl-ink-2); }

.gv-copy__targets { list-style: none; margin: 0; padding: 0 0 0 14px; display: grid; gap: 7px; }
.gv-copy__targets li {
    position: relative;
    display: grid; grid-template-columns: minmax(0, 1fr) auto;
    gap: 10px; align-items: center;
    padding: 9px 12px;
    background: #fff; border: 1.5px solid var(--gvl-line); border-radius: var(--gvl-radius-sm);
}
/* The branch: one elbow per row, drawn rather than imaged, so the one-to-many
   shape reads without a diagram. */
.gv-copy__branch {
    position: absolute; left: -14px; top: 50%; width: 14px; height: 1.5px;
    background: var(--gvl-line-2);
}
.gv-copy__branch::before {
    content: ""; position: absolute; left: 0; bottom: 0;
    width: 1.5px; height: 40px; background: var(--gvl-line-2);
}
.gv-copy__targets li:first-child .gv-copy__branch::before { height: 26px; }
.gv-copy__site { font-size: 14px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gv-copy__price {
    font-size: 12px; font-weight: 700; color: var(--gvl-primary-dark);
    white-space: nowrap;
}

/* ── Who can do what ───────────────────────────────────────────────────── */

.gv-roles { display: flex; flex-direction: column; gap: 12px; }
.gv-roles__title { margin: 0; font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: var(--gvl-ink-2); }
.gv-roles__grid { width: 100%; border-collapse: collapse; font-size: 13px; }
.gv-roles__grid thead th {
    font-family: var(--gvl-font-mono); font-size: 9.5px; font-weight: 400;
    letter-spacing: .06em; text-transform: uppercase; color: var(--gvl-ink-2);
    vertical-align: bottom; padding: 0 4px 9px; text-align: center;
    line-height: 1.25;
}
.gv-roles__grid thead th:first-child { width: 34%; }
.gv-roles__grid tbody th {
    text-align: left; font-weight: 600; font-size: 13.5px;
    padding: 9px 8px 9px 0; border-top: 1px solid var(--gvl-line);
}
.gv-roles__grid tbody td {
    text-align: center; padding: 9px 4px; border-top: 1px solid var(--gvl-line);
}
.gv-roles__yes { color: var(--gvl-primary); font-size: 13px; }
.gv-roles__no  { color: var(--gvl-line-2); font-size: 15px; opacity: .45; }

/* ── Steps ─────────────────────────────────────────────────────────────── */

.gv-step__mock { margin-top: 1.4rem; }

/* ── Brand showcase ────────────────────────────────────────────────────── */

.gv-showcase { background: var(--gvl-paper-2); padding-block: var(--gvl-section-y); }
.gv-showcase__inner { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 48px; align-items: center; }
.gv-showcase__art { border: var(--gvl-border); border-radius: var(--gvl-radius-lg); padding: 28px; }
.gv-showcase__body { color: var(--gvl-ink-2); }

.gv-brandsite { background: var(--gvl-card); border: var(--gvl-border); border-radius: 14px; box-shadow: var(--gvl-shadow); overflow: hidden; }
.gv-brandsite__bar { display: flex; align-items: center; gap: 9px; padding: 11px 14px; border-bottom: 1.5px solid var(--gvl-ink); }
.gv-brandsite__mark {
    width: 24px; height: 24px; border-radius: 6px; display: grid; place-items: center;
    background: var(--gvl-primary); color: #fff;
    font-family: var(--gvl-font-display); font-weight: 800; font-size: 13px;
}
.gv-brandsite__name { font-family: var(--gvl-font-display); font-weight: 800; font-size: 15px; letter-spacing: -.02em; }
.gv-brandsite__body { padding: 16px 14px; display: grid; gap: 9px; }
.gv-brandsite__line { height: 9px; border-radius: var(--gvl-pill); background: var(--gvl-paper-2); }
.gv-brandsite__line.is-short { width: 62%; }
.gv-brandsite__foot { display: flex; align-items: center; gap: 7px; padding: 10px 14px; border-top: 1.5px solid var(--gvl-line); }

@media (max-width: 860px) { .gv-showcase__inner { grid-template-columns: minmax(0, 1fr); gap: 32px; } }

/* ── Pricing teaser ────────────────────────────────────────────────────── */

.gv-teaser { padding-block: var(--gvl-section-y); }
.gv-teaser__plans { margin-top: 36px; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; }
.gv-teaser__plan { padding: 26px; display: grid; gap: 6px; align-content: start; }
.gv-teaser__name { margin: 0; font-size: 21px; }
.gv-teaser__price { margin: 4px 0 0; font-family: var(--gvl-font-display); font-weight: 800; font-size: 32px; letter-spacing: -.03em; }
.gv-teaser__suffix { margin: 0; }
.gv-teaser__text { margin: 10px 0 0; color: var(--gvl-ink-2); }
.gv-teaser__more { margin-top: 26px; font-weight: 600; }

@media (max-width: 760px) { .gv-teaser__plans { grid-template-columns: minmax(0, 1fr); } }

/* ── CTA band ──────────────────────────────────────────────────────────── */

.gv-cta { background: var(--gvl-primary); color: #fff; padding-block: 76px; }
.gv-cta__inner { display: flex; align-items: center; gap: 48px; justify-content: space-between; }
.gv-cta__heading { color: #fff; max-width: 16em; }
.gv-cta__body { color: var(--gvl-primary-light); max-width: 38em; margin: 0 0 28px; }
.gv-cta__actions { display: flex; gap: 14px; flex-wrap: wrap; }
.gv-cta__logo { width: 150px; height: auto; flex-shrink: 0; }
/* On grape, the outline button reverses: an ink border would disappear. */
.gv-btn--reverse { border-color: #fff; color: #fff; background: transparent; }
.gv-btn--reverse:hover { background: rgba(255, 255, 255, .12); color: #fff; }

/* ── Page hero ─────────────────────────────────────────────────────────── */

.gv-pagehero { padding-block: 84px 72px; border-bottom: 1.5px solid var(--gvl-line); }
.gv-pagehero__inner { max-width: 820px; margin-inline: auto; text-align: center; }
.gv-pagehero__kicker { justify-content: center; }
.gv-pagehero__lede { margin: 24px auto 0; font-size: 19px; color: var(--gvl-ink-2); max-width: 46em; }

/* Left, for the feature pages. A centred hero suits a page that is mostly
   its headline; these are long reads, and the chapters under them all start
   at the left margin — a centred opener makes the eye begin in one place and
   then move, every time. */
.gv-pagehero.is-left .gv-pagehero__inner { margin-inline: 0; text-align: left; }
.gv-pagehero.is-left .gv-pagehero__kicker { justify-content: flex-start; }
.gv-pagehero.is-left .gv-pagehero__lede { margin-inline: 0; }

/* ── Plan cards ────────────────────────────────────────────────────────── */

.gv-plans { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; align-items: stretch; }

/* The second card sat 24px lower than the first.
 *
 * The group carries WordPress's is-layout-flow, whose rule puts a
 * margin-block-start on every child after the first. That is harmless in a
 * flow layout and wrong in a grid, where it simply pushes the second item
 * down — the gap is already doing that job. */
.gv-plans > * { margin-block-start: 0; }

@media (max-width: 860px) { .gv-plans { grid-template-columns: minmax(0, 1fr); } }

/* A flex column, not a packed grid.
 *
 * It was display:grid with align-content:start, which packs every row at the
 * top — and in that arrangement margin-top:auto on the button has no free
 * space to push into, so the shorter card ended with its button stranded
 * mid-card above a block of nothing. As a column, auto margin does what it
 * is for and both buttons sit on the same line at the foot of both cards. */
.gv-plan { position: relative; padding: 30px; display: flex; flex-direction: column; gap: 6px; }
.gv-plan.is-featured { border-color: var(--gvl-primary-dark); }
.gv-plan__label { margin: 0; }
.gv-plan__name { margin: 2px 0 0; font-size: 26px; }
.gv-plan__price { margin: 10px 0 0; font-family: var(--gvl-font-display); font-weight: 800; font-size: 38px; letter-spacing: -.035em; }
.gv-plan__suffix { margin: 0; }
.gv-plan__sub { margin: 12px 0 0; color: var(--gvl-ink-2); }
.gv-plan__body { margin-top: 14px; }
/* Room under the price bands before the tick list starts, so the two read as
   two things rather than one long column. */
.gv-plan .gv-bands { margin-bottom: 22px; }
/* Room under the list, so the button is clearly what the list leads to
   rather than the last item in it. On the body rather than on the button,
   because margin-top:auto is what pins the button to the foot of the card
   and a second margin-top there would be ignored. */
.gv-plan__body { margin-bottom: 26px; }
.gv-plan__note { margin: 10px 0 0; }
/* .gv-plan__cta IS the button, so padding here is padding INSIDE it — which
   is how 30px of intended gap became 30px above the label and left the text
   sitting on the floor of the button. The gap belongs to the thing above it;
   see .gv-plan__body below. */
/* Directly under the list, not pinned to the foot of the card.
 *
 * It was margin-top:auto, which put both buttons on one line at the bottom —
 * tidy, but it left the shorter card with a gap between its last tick and
 * its button, and the button stopped reading as the end of that list. The
 * cards are still equal height; only the button moves up. */
.gv-plan__cta { align-self: start; }
.gv-plan { min-height: 100%; }

/* Forward on hover.
 *
 * Both cards, not only the featured one: a plan that lifts and a plan that
 * does not reads as one being clickable and the other not. The card moves up
 * and left by exactly the distance the shadow sits down and right, so the
 * shadow appears to deepen rather than the card appearing to drift. */
.gv-plan { transition: transform .15s ease, box-shadow .15s ease; }
.gv-plan:hover { transform: translate(-3px, -3px); }
.gv-plan.gv-shadow:hover { box-shadow: 8px 8px 0 var(--gvl-ink); }
.gv-plan.gv-shadow-vine:hover { box-shadow: 7px 7px 0 var(--gvl-vine); }

@media (prefers-reduced-motion: reduce) {
    .gv-plan { transition: none; }
    .gv-plan:hover { transform: none; }
}
.gv-plan__stamp { position: absolute; top: 16px; right: 14px; font-size: .85rem; }

/* The tick list on a plan. */
.is-style-gv-ticks { list-style: none; padding: 0; margin: 0; display: grid; gap: 8px; }
.is-style-gv-ticks li { padding-inline-start: 1.6em; position: relative; color: var(--gvl-ink-2); }
.is-style-gv-ticks li::before {
    content: "✓"; position: absolute; left: 0;
    color: var(--gvl-success); font-weight: 700;
}
/* What a plan does NOT include. A tick against "Memberships not included"
 * reads as though it does. */
.is-style-gv-ticks li.is-excluded::before { content: "–"; color: var(--gvl-ink-2); }

/* ── Plan comparison ───────────────────────────────────────────────────── */

.gv-cmp { margin-top: 72px; }
.gv-cmp__head { max-width: 46ch; margin-bottom: 28px; }
.gv-cmp__head .gv-h2 { margin: 0; text-wrap: balance; }
.gv-cmp__lede { margin: 12px 0 0; color: var(--gvl-ink-2); }

/* Its own card, so the sticky header has a surface to sit on rather than
   inheriting whatever section it was dropped into.
   
   NO overflow here, and that is the load-bearing part. An `overflow-x: auto`
   wrapper becomes the sticky containing block, so `top: 67px` stopped meaning
   "67px below the viewport top" and started meaning "67px below this box's
   own top" — which pinned the header DOWN over the first two rows, where it
   hid them from the moment the page loaded. A header that follows the page
   has to have no scrolling ancestor at all.
   
   So the table shrinks to fit instead of sliding sideways. */
.gv-cmp__scroll {
    background: var(--gvl-card);
    border: var(--gvl-border);
    border-radius: var(--gvl-radius-lg);
    padding: 0 22px;
}

.gv-cmp__table {
    width: 100%;
    border-collapse: separate; border-spacing: 0;
    table-layout: auto;
    font-size: 15.5px;
}

/* The column names stay put under the site header.
 *
 * A comparison whose headings have scrolled away is a column of ticks against
 * no question. 67px is the header's own height — it is sticky at top:0, so
 * this has to clear it rather than slide under it. */
.gv-cmp__table thead th {
    /* 72px is the site header's measured height — it is sticky at top:0, so
       this has to clear it exactly. 67 was a guess and left the column names
       sliding 5px under it. */
    position: sticky; top: 72px; z-index: 2;
    background: var(--gvl-card);
    text-align: center;
    font-family: var(--gvl-font-display); font-weight: 800;
    font-size: 17px; letter-spacing: -.02em;
    padding: 14px 16px;
    border-bottom: var(--gvl-border);
}
.gv-cmp__table thead th:first-child { text-align: left; background: var(--gvl-card); }
.gv-cmp__table thead th.is-featured { color: var(--gvl-primary-dark); }

/* A group heading inside the body.
   
   NOT sticky. Pinning it under the column names needs the thead's exact
   height as a magic number, and that height changes the moment the plan
   names wrap to two lines — which they do below 860px. One reliable sticky
   row beats two that disagree with each other. */
.gv-cmp__group th {
    text-align: left;
    background: var(--gvl-paper-2);
    font-family: var(--gvl-font-mono); font-size: 11.5px;
    letter-spacing: .13em; text-transform: uppercase; color: var(--gvl-ink-2);
    padding: 9px 16px;
    border-top: 1.5px solid var(--gvl-line-2);
    border-bottom: 1.5px solid var(--gvl-line);
}

.gv-cmp__table tbody th[scope="row"] {
    text-align: left; font-weight: 400;
    padding: 12px 16px 12px 0;
    border-bottom: 1px solid var(--gvl-line);
}
.gv-cmp__table tbody td {
    text-align: center; width: 190px;
    padding: 12px 16px;
    border-bottom: 1px solid var(--gvl-line);
}
/* The featured column is tinted the whole way down, so the eye can follow it
   without counting across. */
.gv-cmp__table td.is-featured { background: var(--gvl-primary-light); }

.gv-cmp__yes { color: var(--gvl-success); font-size: 19px; font-weight: 700; }
.gv-cmp__no  { color: var(--gvl-ink-2); font-size: 19px; }
.gv-cmp__value { font-family: var(--gvl-font-mono); font-size: 14px; font-weight: 600; }

.gv-cmp__table tbody tr:last-child th,
.gv-cmp__table tbody tr:last-child td { border-bottom: 0; }

/* Narrow: the feature column takes what it needs and the two plan columns
   give up width, rather than the table scrolling sideways. */
@media (max-width: 860px) {
    .gv-cmp__scroll { padding: 0 14px; }
    .gv-cmp__table { font-size: 14px; }
    .gv-cmp__table tbody td { width: 84px; padding: 11px 6px; }
    .gv-cmp__table tbody th[scope="row"] { padding-right: 10px; }
    .gv-cmp__table thead th { font-size: 13px; padding: 11px 6px; }
}
@media (max-width: 480px) {
    .gv-cmp__table { font-size: 13px; }
    .gv-cmp__table tbody td { width: 62px; }
    .gv-cmp__table thead th { font-size: 11.5px; }
}

/* Sticky headers and a scrolling page do not mix for everyone; somebody who
   asked for less movement gets a plain table. */
@media (prefers-reduced-motion: reduce) {
    .gv-cmp__table thead th,
    .gv-cmp__group th { position: static; }
}

/* ── Membership bands ──────────────────────────────────────────────────── */

.gv-bands { list-style: none; margin: 0; padding: 0; display: grid; gap: 7px; }
.gv-bands__row {
    display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
    border: 1.5px solid var(--gvl-line); border-radius: var(--gvl-radius-sm);
    padding: 10px 12px; background: var(--gvl-card);
}
/* Gold: the band this site is on. */
.gv-bands__row.is-current { background: var(--gvl-gold-wash); border-color: var(--gvl-gold); }
.gv-bands__price b { font-family: var(--gvl-font-display); font-size: 19px; }

/* ── Callout ───────────────────────────────────────────────────────────── */

.gv-callout { display: flex; gap: 20px; align-items: flex-start; padding: 28px; max-width: 920px; margin-inline: auto; }
.gv-callout__icon { width: 48px; height: 48px; flex-shrink: 0; }
.gv-callout__heading { margin: 0 0 8px; font-size: 24px; }
.gv-callout__text { margin: 0; color: var(--gvl-ink-2); }
.gv-callout__link { margin: 14px 0 0; font-weight: 600; }

@media (max-width: 620px) { .gv-callout { flex-direction: column; gap: 14px; } }

/* ── FAQ ───────────────────────────────────────────────────────────────── */

.gv-faq { padding-block: var(--gvl-section-y); }
.gv-faq__heading { margin-bottom: 28px; }
.gv-faq__list { display: grid; gap: 10px; max-width: 920px; }
.gv-faq__item { border: var(--gvl-border); border-radius: var(--gvl-radius); background: var(--gvl-card); }
.gv-faq__q {
    cursor: pointer; list-style: none;
    padding: 16px 20px;
    font-family: var(--gvl-font-display); font-weight: 800; font-size: 18px; letter-spacing: -.02em;
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.gv-faq__q::-webkit-details-marker { display: none; }
.gv-faq__q::after { content: "+"; font-size: 22px; line-height: 1; color: var(--gvl-primary-dark); flex-shrink: 0; }
.gv-faq__item[open] .gv-faq__q::after { content: "–"; }
.gv-faq__q:focus-visible { outline: 3px solid var(--gvl-vine); outline-offset: -3px; border-radius: var(--gvl-radius); }
.gv-faq__a { padding: 0 20px 18px; }
.gv-faq__a p { margin: 0; color: var(--gvl-ink-2); max-width: 60em; }

/* ── Footer ────────────────────────────────────────────────────────────── */

.gv-footer { background: var(--gvl-night); color: var(--gvl-ink-on-night); padding-block: 56px 32px; }
.gv-footer__inner { display: grid; gap: 40px; }
.gv-footer__brand img { height: 36px; width: auto; }
.gv-footer__tagline { margin: 14px 0 0; max-width: 34em; color: var(--gvl-ink-on-night); }
.gv-footer__cols { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; max-width: 640px; }
.gv-footer__coltitle {
    margin: 0 0 10px; color: var(--gvl-paper);
    font-family: var(--gvl-font-mono); font-size: 11px;
    letter-spacing: .14em; text-transform: uppercase; font-weight: 700;
}
.gv-footer__cols ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 7px; }
.gv-footer__cols a { color: var(--gvl-ink-on-night); text-decoration: none; }
.gv-footer__cols a:hover { color: var(--gvl-paper); text-decoration: underline; }
.gv-footer__base {
    display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap;
    border-top: 1px solid rgba(255, 255, 255, .14); padding-top: 20px;
    font-family: var(--gvl-font-mono); font-size: 12px;
}

@media (max-width: 620px) { .gv-footer__cols { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* ── Contact hero ──────────────────────────────────────────────────────── */

.gv-contact-hero { position: relative; overflow: hidden; }
.gv-contact-hero__field {
    position: absolute; inset: 0 auto 0 0;
    width: 52%; opacity: .75; pointer-events: none;
    /* Faded out rather than cut off. The home hero's field runs to the edge
       of the viewport, where the crop reads as the page continuing; this one
       ends in the middle of the page, and a hard vertical line there reads as
       a box somebody forgot to finish. */
    -webkit-mask-image: linear-gradient(to right, #000 55%, transparent 100%);
            mask-image: linear-gradient(to right, #000 55%, transparent 100%);
}
.gv-contact-hero__inner {
    position: relative;
    padding-block: 72px 84px;
    display: flex; flex-wrap: wrap; gap: 56px; align-items: start;
}
.gv-contact-hero__text { flex: 1 1 460px; min-width: 0; }
.gv-contact-hero__form { flex: 1 1 440px; min-width: 0; }
.gv-contact-hero .gv-h1 { text-wrap: balance; font-size: clamp(44px, 5.4vw, 72px); }
.gv-contact-hero__lede {
    margin: 26px 0 0; font-size: 19px; color: var(--gvl-ink-2); max-width: 32em;
}

@media (max-width: 860px) {
    .gv-contact-hero__inner { padding-block: 48px 52px; gap: 36px; }
    /* The form first on a phone. Somebody who opened the contact page came to
       write, and three steps about what happens next are not worth a scroll
       before they can start. */
    .gv-contact-hero__form { order: -1; flex-basis: 100%; }
}

/* What happens next.
 *
 * Numbered because it is a sequence: each one happens after the one above.
 * That is the test the house style applies to a numeral — if the order
 * carries no information, the number is decoration.
 */
.gv-next { list-style: none; margin: 38px 0 0; padding: 0; display: grid; gap: 0; }
.gv-next__item {
    display: flex; gap: 18px; align-items: baseline;
    padding: 18px 0;
    border-top: 1.5px dashed var(--gvl-line-2);
}
.gv-next__item:last-child { border-bottom: 1.5px dashed var(--gvl-line-2); }
.gv-next__no {
    flex: none;
    font-family: var(--gvl-font-mono); font-size: 13px; font-weight: 700;
    letter-spacing: .06em; color: var(--gvl-primary-dark);
}
.gv-next__body { display: grid; gap: 3px; min-width: 0; }
.gv-next__body strong { font-size: 17px; }
.gv-next__body small { font-size: 15px; color: var(--gvl-ink-2); line-height: 1.5; }

/* ── The form ──────────────────────────────────────────────────────────── */

.gv-form { padding: 28px 28px 30px; max-width: 560px; }
.gv-form__head {
    display: flex; flex-wrap: wrap; gap: 12px;
    align-items: center; justify-content: space-between;
    margin-bottom: 20px;
}
.gv-form__heading {
    margin: 0; font-family: var(--gvl-font-display);
    font-size: 28px; font-weight: 800; letter-spacing: -.03em;
}
.gv-form__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.gv-form__field { display: grid; gap: 6px; margin: 0; min-width: 0; }
.gv-form__field--wide { grid-column: 1 / -1; }

@media (max-width: 520px) { .gv-form__grid { grid-template-columns: 1fr; } }

.gv-form__field label {
    font-family: var(--gvl-font-mono); font-size: 11px;
    letter-spacing: .1em; text-transform: uppercase; color: var(--gvl-ink-2);
}
.gv-form__opt { text-transform: none; letter-spacing: 0; opacity: .75; }

/* Both forms wear the same controls. Scoped to the two wrappers rather than
   set on bare input/select/textarea, so nothing here reaches a field in post
   content or in a plugin's widget. */
.gv-form input,
.gv-form select,
.gv-form textarea,
.gv-signup input,
.gv-signup select,
.gv-signup textarea {
    width: 100%;
    font-family: inherit; font-size: 16px; color: var(--gvl-ink);
    background: #fff;
    border: 1.5px solid var(--gvl-line-2);
    border-radius: var(--gvl-radius-sm);
    padding: 11px 13px;
}
.gv-form textarea { resize: vertical; min-height: 128px; line-height: 1.55; }
/* Shorter in the signup: it is the one optional field, and a tall box there
   pushes the button that finishes the form off a laptop screen. */
.gv-signup textarea { resize: vertical; min-height: 76px; line-height: 1.55; }

/* The focus ring is the grape, two pixels, outside the box — so it reads at a
   glance on a page where every control already has an ink border. */
.gv-form input:focus-visible,
.gv-form select:focus-visible,
.gv-form textarea:focus-visible,
.gv-signup input:focus-visible,
.gv-signup select:focus-visible,
.gv-signup textarea:focus-visible {
    outline: 2px solid var(--gvl-primary);
    outline-offset: 2px;
    border-color: var(--gvl-primary);
}
.gv-form input::placeholder,
.gv-form textarea::placeholder,
.gv-signup input::placeholder,
.gv-signup textarea::placeholder { color: color-mix(in srgb, var(--gvl-ink-2) 55%, transparent); }

.gv-form__submit { margin-top: 22px; width: 100%; justify-content: center; }
.gv-form__note { margin: 14px 0 0; font-size: 13.5px; color: var(--gvl-ink-2); }

/* The reCAPTCHA attribution. Quiet, because it is a legal requirement rather
   than something anybody came here to read — but legible, not 9px grey. */
.gv-form__legal { margin: 8px 0 0; font-size: 12px; line-height: 1.5; color: var(--gvl-ink-2); }
.gv-form__legal a { color: var(--gvl-ink-2); text-decoration: underline; }
.gv-form__legal a:hover { color: var(--gvl-primary-dark); }

/* v3's floating badge, hidden — the attribution above is what Google asks for
   in exchange. It would otherwise float over the modal. */
.grecaptcha-badge { visibility: hidden; }

/* Something was wrong.
 *
 * Red is not in the palette and is not being added for this: the page already
 * says "attention" with the gold, and an error here is a correction rather
 * than an alarm. The wash plus the ink rule carries it.
 */
.gv-form__alert {
    margin: 0 0 18px; padding: 12px 14px;
    background: var(--gvl-gold-wash);
    border: 1.5px solid var(--gvl-gold);
    border-radius: var(--gvl-radius-sm);
    font-size: 15px;
}
.gv-form__err { font-size: 13.5px; color: var(--gvl-primary-dark); }
.gv-form [aria-invalid="true"],
.gv-signup [aria-invalid="true"] { border-color: var(--gvl-primary-dark); }

/* The honeypot. Taken out of the layout entirely rather than hidden with
   display:none, which some fillers check for. */
.gv-form__trap {
    position: absolute; width: 1px; height: 1px;
    margin: -1px; padding: 0; overflow: hidden;
    clip-path: inset(50%); white-space: nowrap;
}

.gv-form__done { display: grid; gap: 14px; justify-items: start; padding: 10px 0 6px; }
.gv-form__done p { margin: 0; font-size: 16.5px; color: var(--gvl-ink-2); line-height: 1.6; }
.gv-form__stamp { position: static; transform: rotate(-3deg); }

/* ── The other desks ───────────────────────────────────────────────────── */

.gv-desks__head { max-width: 42ch; margin-bottom: 44px; }
.gv-desks__head .gv-h2 { margin: 14px 0 0; text-wrap: balance; }
.gv-desks__grid {
    display: grid; gap: 20px;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}

.gv-desk {
    display: grid; gap: 10px; align-content: start;
    padding: 24px 22px 22px;
    color: inherit; text-decoration: none;
}
.gv-desk--link { position: relative; padding-bottom: 46px; }
.gv-desk--link:hover { box-shadow: var(--gvl-shadow-vine); transform: translate(-1px, -1px); }
.gv-desk--link:focus-visible { outline: 2px solid var(--gvl-primary); outline-offset: 3px; }
.gv-desk__mark {
    display: inline-flex; align-items: center; justify-content: center;
    width: 44px; height: 44px; border-radius: 12px;
    border: 1.5px solid var(--gvl-line-2);
    color: var(--gvl-primary-dark);
}
/* Four marks in the two inks and plain ink. No gold: gold means "where you
   are now" everywhere else in this design, and spending it as a fourth
   decorative colour here is exactly what the token's rule forbids. */
.gv-desk__mark--1 { color: var(--gvl-vine); }
.gv-desk__mark--2 { color: var(--gvl-ink); }
.gv-desk__mark--3 { color: var(--gvl-ink-2); }
.gv-desk__title { font-size: 18px; }
.gv-desk__text { font-size: 14.5px; color: var(--gvl-ink-2); line-height: 1.55; }
.gv-desk__go {
    position: absolute; left: 22px; bottom: 20px;
    font-size: 18px; color: var(--gvl-primary-dark);
}

@media (prefers-reduced-motion: reduce) { .gv-desk--link:hover { transform: none; } }

/* ── Launching a site ──────────────────────────────────────────────────── */

.gv-signup__heading {
    margin: 0; font-family: var(--gvl-font-display);
    font-size: 32px; font-weight: 800; letter-spacing: -.035em; line-height: 1.05;
}
.gv-signup__lede {
    margin: 10px 0 0; font-size: 15.5px; color: var(--gvl-ink-2); line-height: 1.6;
    max-width: 46ch;
}

/* Two groups, two questions. The rule under the legend is the device the rest
   of the page uses to separate a section from its heading. */
.gv-signup__group { border: 0; padding: 0; margin: 20px 0 0; min-width: 0; }
.gv-signup__legend {
    width: 100%; padding: 0 0 8px; margin: 0 0 13px;
    border-bottom: 1.5px dashed var(--gvl-line-2);
    font-family: var(--gvl-font-mono); font-size: 11px;
    letter-spacing: .14em; text-transform: uppercase; color: var(--gvl-primary-dark);
}

.gv-signup__actions { margin-top: 20px; }
.gv-signup__submit { width: 100%; justify-content: center; }

/* In the modal the actions ride along the bottom of the scrolling panel, so
   the thing that finishes the form is never something you scroll to find.
   The side padding is cancelled and re-applied so the band spans the full
   width rather than floating in a gutter. */
.gv-modal .gv-signup__actions {
    position: sticky; bottom: 0; z-index: 1;
    margin: 20px -30px 0; padding: 16px 30px 20px;
    background: var(--gvl-card);
    border-top: 1.5px solid var(--gvl-line);
}
.gv-modal .gv-form__note { margin-bottom: 0; }
.gv-signup__done { display: grid; gap: 14px; justify-items: start; }
/* The confirmation carries no action band, so it puts back the bottom padding
   the panel gave up for one. */
.gv-modal__panel:has(.gv-signup__done) { padding-bottom: 30px; }
.gv-signup__done p { margin: 0; font-size: 16.5px; color: var(--gvl-ink-2); line-height: 1.6; }
.gv-signup__stamp { position: static; transform: rotate(-3deg); }
.gv-form__help { font-size: 13px; color: var(--gvl-ink-2); }
.gv-form__help strong { color: var(--gvl-ink); font-weight: 600; }

/* The address field.
 *
 * The domain is inside the box with the input rather than beside it, because
 * what somebody is choosing is one part of one address — seeing the whole
 * thing assembled as they type is what stops them pasting a whole URL in.
 * The border lives on the wrapper so the group focuses as one object.
 */
.gv-affix {
    display: flex; align-items: stretch; min-width: 0;
    background: #fff;
    border: 1.5px solid var(--gvl-line-2);
    border-radius: var(--gvl-radius-sm);
    overflow: hidden;
}
.gv-affix:focus-within { outline: 2px solid var(--gvl-primary); outline-offset: 2px; border-color: var(--gvl-primary); }
.gv-affix__fix {
    display: flex; align-items: center; flex: none;
    padding: 11px 2px;
    font-family: var(--gvl-font-mono); font-size: 14px;
    color: var(--gvl-ink-2); background: var(--gvl-paper-2);
    white-space: nowrap;
}
.gv-affix__fix--before { padding-left: 12px; }
.gv-affix__fix--after  { padding-right: 12px; }

/* The input inside has no chrome of its own — the wrapper is the field now,
   and a second border here would draw a box inside a box. */
.gv-signup .gv-affix input {
    flex: 1 1 auto; min-width: 0;
    border: 0; border-radius: 0; background: transparent;
    padding-inline: 10px;
}
.gv-signup .gv-affix input:focus-visible { outline: 0; }

/* The subdomain reads as one word with the domain, so the typed part gets the
   weight and the fixed part stays quiet. */
.gv-affix input { font-family: var(--gvl-font-mono); font-size: 15px; font-weight: 600; }

@media (max-width: 420px) {
    .gv-affix { flex-wrap: wrap; }
    .gv-affix__fix { font-size: 12.5px; }
}

/* ── The launch modal ──────────────────────────────────────────────────── */

.gv-modal {
    border: 0; padding: 0; background: transparent;
    max-width: min(620px, calc(100vw - 32px));
    max-height: calc(100vh - 48px);
    margin: auto;
    overflow: visible;
}
.gv-modal::backdrop {
    /* The night ink rather than plain black: the page behind goes quiet
       without turning grey, and the grape in the panel still reads warm. */
    background: rgba(23, 21, 27, .62);
}
.gv-modal__panel {
    position: relative;
    /* No bottom padding: the sticky action band supplies it, and padding
       below a sticky element is a strip the content scrolls through. */
    padding: 28px 30px 0;
    max-height: calc(100vh - 48px);
    overflow-y: auto;
    box-shadow: var(--gvl-shadow);
}
.gv-modal__close {
    position: absolute; top: 12px; right: 12px;
    width: 36px; height: 36px; display: grid; place-items: center;
    font-size: 24px; line-height: 1;
    color: var(--gvl-ink-2); background: transparent;
    border: 1.5px solid transparent; border-radius: 50%;
    cursor: pointer;
}
.gv-modal__close:hover { background: var(--gvl-paper-2); color: var(--gvl-ink); }
.gv-modal__close:focus-visible { outline: 2px solid var(--gvl-primary); outline-offset: 2px; }

/* The panel arrives rather than appears — a dialog that is simply there has a
   way of looking like a mistake. Short, and skipped entirely for anyone who
   asked for less movement. */
@media (prefers-reduced-motion: no-preference) {
    .gv-modal[open] .gv-modal__panel { animation: gv-modal-in .18s ease-out; }
    @keyframes gv-modal-in {
        from { opacity: 0; transform: translateY(8px) scale(.985); }
        to   { opacity: 1; transform: none; }
    }
}

@media (max-width: 560px) {
    .gv-modal { max-width: calc(100vw - 16px); }
    .gv-modal__panel { padding: 26px 20px 0; }
    .gv-modal .gv-signup__actions { margin: 18px -20px 0; padding: 14px 20px 18px; }
    .gv-signup__heading { font-size: 27px; }
}

/* The start page: the same form, given a page to sit on. Narrow, because a
   form stretched to a 1240px container is a form whose labels are a long way
   from the boxes they name. */
.gv-start { padding-top: 0; }
.gv-start__card { max-width: 620px; margin-inline: auto; padding: 34px 32px 36px; }

@media (max-width: 560px) { .gv-start__card { padding: 26px 20px 24px; } }

/* ── Sign in ───────────────────────────────────────────────────────────── */

.gv-auth { min-height: 100vh; display: flex; flex-direction: column; background: var(--gvl-paper); }
.gv-auth__bar { padding-block: 22px; text-align: left; }
.gv-auth__brand { display: inline-flex; }
.gv-auth__brand img { display: block; height: 32px; width: auto; }

.gv-auth__split {
    flex: 1 1 auto;
    display: grid; gap: 40px; align-items: center;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    padding-block: 24px 64px;
}
.gv-auth__form { display: flex; justify-content: center; }
.gv-auth__card { width: 100%; max-width: 440px; padding: 34px 32px 36px; }
.gv-auth__heading {
    margin: 14px 0 20px; font-family: var(--gvl-font-display);
    font-size: 38px; font-weight: 800; letter-spacing: -.035em; line-height: 1.05;
}
.gv-auth__submit { margin-top: 20px; width: 100%; justify-content: center; }
.gv-auth__aside { margin: 18px 0 0; font-size: 14.5px; color: var(--gvl-ink-2); }
.gv-auth__aside a { color: var(--gvl-primary-dark); }

/* The plugin's script writes into this and toggles `hidden` on it, so the
   rule has to lose to [hidden] — which it does, because that is a one-class
   attribute selector of equal weight declared later in the base. */
.gv-auth__message {
    margin: 0 0 16px; padding: 12px 14px;
    border: 1.5px solid var(--gvl-line-2); border-radius: var(--gvl-radius-sm);
    background: #fff; font-size: 15px;
}
.gv-auth__message[hidden] { display: none; }
.gv-auth__message.is-error { border-color: var(--gvl-gold); background: var(--gvl-gold-wash); }

/* The half that is only a picture. Grape, because this is the one page where
   the brand colour can own the whole field without competing with content. */
.gv-auth__art {
    align-self: stretch;
    display: flex; align-items: center; justify-content: center;
    background: var(--gvl-primary);
    border: var(--gvl-border); border-radius: var(--gvl-radius-lg);
    box-shadow: var(--gvl-shadow);
    position: relative; overflow: hidden;
    min-height: 420px;
}
.gv-auth__art::before {
    content: ""; position: absolute; inset: 0;
    background-image: radial-gradient(rgba(255, 255, 255, .22) 1.2px, transparent 1.4px);
    background-size: var(--gvl-dots-size);
}
.gv-auth__art-inner { position: relative; text-align: center; padding: 40px; }
.gv-auth__mark { width: 120px; height: auto; }
.gv-auth__tagline {
    margin: 26px auto 0; max-width: 16ch;
    font-family: var(--gvl-font-display); font-weight: 800;
    font-size: 30px; line-height: 1.1; letter-spacing: -.03em;
    color: #fff; text-wrap: balance;
}

/* One column, and the picture goes. At this width it would be a band of
   colour above a form, costing a screen of scrolling to say nothing. */
@media (max-width: 860px) {
    .gv-auth__split { grid-template-columns: 1fr; padding-bottom: 40px; }
    .gv-auth__art { display: none; }
    .gv-auth__heading { font-size: 32px; }
}
@media (max-width: 520px) { .gv-auth__card { padding: 26px 20px 28px; } }

/* ── A confirmation link that did not work ─────────────────────────────── */

.gv-notice { background: var(--gvl-gold-wash); border-bottom: 1.5px solid var(--gvl-gold); }
.gv-notice__inner { display: flex; align-items: center; gap: 13px; padding-block: 13px; }
.gv-notice__mark {
    flex: none; width: 24px; height: 24px;
    display: grid; place-items: center;
    font-family: var(--gvl-font-mono); font-weight: 700; font-size: 14px;
    color: var(--gvl-ink); background: var(--gvl-gold);
    border-radius: 50%;
}
.gv-notice p { margin: 0; font-size: 15px; max-width: 72ch; }

/* ── Feature chapters ──────────────────────────────────────────────────── */

.gv-chapter__inner {
    display: grid; gap: 48px;
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    align-items: center;
}
/* The art changes sides down the page. Four chapters with the picture always
   on the right read as four of the same thing, and the eye stops arriving at
   the heading. */
.gv-chapter.is-flipped .gv-chapter__text { order: 2; }
.gv-chapter.is-flipped .gv-chapter__art  { order: 1; }

.gv-chapter__text { min-width: 0; }
.gv-chapter__art  { min-width: 0; display: flex; justify-content: center; }
.gv-chapter__art > * { width: 100%; }

/* The stencil numeral: outlined, oversized, and decorative. It marks position
   in a sequence that is genuinely ordered — a reader meets these in order —
   which is the only thing that earns a number. */
.gv-chapter__no {
    display: block;
    font-family: var(--gvl-font-display);
    font-size: 72px; font-weight: 800; line-height: .8;
    letter-spacing: -.04em;
    color: transparent;
    -webkit-text-stroke: 2px var(--gvl-line-2);
    margin-bottom: 14px;
}
.gv-chapter .gv-h2 { margin: 12px 0 0; text-wrap: balance; }
.gv-chapter__lede {
    margin: 18px 0 0; font-size: 18px; color: var(--gvl-ink-2); max-width: 40em;
}

.gv-ticks { list-style: none; margin: 24px 0 0; padding: 0; display: grid; gap: 11px; }
.gv-ticks li { display: grid; grid-template-columns: 22px minmax(0, 1fr); gap: 12px; font-size: 16px; }
/* The tick is drawn with a border rather than a glyph, so it lines up with
   the text's cap height at any size and needs no icon font. */
.gv-ticks li::before {
    content: ""; margin-top: 7px;
    width: 11px; height: 6px;
    border-left: 2.5px solid var(--gvl-vine);
    border-bottom: 2.5px solid var(--gvl-vine);
    transform: rotate(-45deg);
}
.gv-chapter__link { margin: 24px 0 0; font-size: 16px; }
.gv-chapter__link a { color: var(--gvl-primary-dark); font-weight: 600; }

@media (max-width: 900px) {
    .gv-chapter__inner { grid-template-columns: 1fr; gap: 32px; }
    /* Heading first on every chapter, whatever the desktop order says: a
       picture above the thing it illustrates explains nothing. */
    .gv-chapter.is-flipped .gv-chapter__text,
    .gv-chapter.is-flipped .gv-chapter__art { order: 0; }
    .gv-chapter__no { font-size: 56px; }
}

/* ── The features index ────────────────────────────────────────────────── */

.gv-findex { display: grid; gap: 20px; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
.gv-findex__item {
    display: grid; gap: 10px; align-content: start;
    padding: 24px 22px 22px;
    color: inherit; text-decoration: none;
    position: relative;
}
.gv-findex__item:hover { box-shadow: var(--gvl-shadow-vine); transform: translate(-1px, -1px); }
.gv-findex__item:focus-visible { outline: 2px solid var(--gvl-primary); outline-offset: 3px; }
.gv-findex__mark {
    display: inline-flex; align-items: center; justify-content: center;
    width: 44px; height: 44px; border-radius: 12px;
    border: 1.5px solid var(--gvl-line-2); color: var(--gvl-primary-dark);
}
.gv-findex__title { font-size: 18px; }
.gv-findex__blurb { font-size: 14.5px; color: var(--gvl-ink-2); line-height: 1.55; }
.gv-findex__go { color: var(--gvl-primary-dark); font-size: 18px; }

@media (prefers-reduced-motion: reduce) { .gv-findex__item:hover { transform: none; } }

/* ── News archive ──────────────────────────────────────────────────────── */

.gv-news__list { display: grid; gap: 0; }
.gv-news__row {
    display: grid; gap: 7px;
    padding: 30px 0;
    border-top: 1.5px dashed var(--gvl-line-2);
}
.gv-news__row:last-child { border-bottom: 1.5px dashed var(--gvl-line-2); }

.gv-news__meta {
    margin: 0; font-size: 11.5px; letter-spacing: .1em; text-transform: uppercase;
    color: var(--gvl-ink-2);
    display: flex; gap: 12px; align-items: center; flex-wrap: wrap;
}
.gv-news__cat {
    color: var(--gvl-primary-dark);
    border: 1.5px solid var(--gvl-primary-dark); border-radius: var(--gvl-pill);
    padding: 2px 9px;
}
.gv-news__title {
    margin: 0; font-family: var(--gvl-font-display); font-weight: 800;
    font-size: clamp(25px, 3vw, 33px); letter-spacing: -.035em; line-height: 1.08;
    text-wrap: balance;
}
.gv-news__title a { color: inherit; text-decoration: none; }
.gv-news__title a:hover { color: var(--gvl-primary-dark); }
.gv-news__excerpt { margin: 4px 0 0; color: var(--gvl-ink-2); font-size: 17px; max-width: 62ch; }
.gv-news__more { margin: 6px 0 0; font-size: 15.5px; }
.gv-news__more a { color: var(--gvl-primary-dark); font-weight: 600; }
.gv-news__empty { margin: 0; color: var(--gvl-ink-2); font-size: 18px; }

.gv-news__paging {
    margin-top: 40px; padding-top: 24px;
    border-top: var(--gvl-border);
    display: flex; gap: 8px; flex-wrap: wrap; align-items: center;
}
.gv-news__paging a,
.gv-news__paging span {
    min-width: 40px; height: 40px;
    display: inline-flex; align-items: center; justify-content: center;
    padding-inline: 12px;
    border: 1.5px solid var(--gvl-line-2); border-radius: var(--gvl-radius-sm);
    text-decoration: none; color: var(--gvl-ink); font-size: 15px;
}
.gv-news__paging a:hover { background: var(--gvl-paper-2); }
.gv-news__paging .current {
    background: var(--gvl-primary); border-color: var(--gvl-ink); color: #fff; font-weight: 700;
}
.gv-news__paging .dots { border: 0; }

/* ── A single entry ────────────────────────────────────────────────────── */

.gv-post__head { padding-block: 64px 0; }
.gv-post__date { margin: 0 0 14px; font-size: 12px; letter-spacing: .12em; text-transform: uppercase; color: var(--gvl-ink-2); }
.gv-post__title {
    margin: 0; font-family: var(--gvl-font-display); font-weight: 800;
    font-size: clamp(38px, 5.2vw, 62px); letter-spacing: -.04em; line-height: 1.02;
    max-width: 20ch; text-wrap: balance;
}
/* The reading column is narrower than the page.
   Running text at 1240px is a line nobody finishes. */
.gv-post__body { padding-block: 32px 8px; }
.gv-post__body > * { max-width: 68ch; margin-inline: 0; }
.gv-post__body p { font-size: 18px; line-height: 1.68; color: var(--gvl-ink-2); }
.gv-post__body h2 {
    font-family: var(--gvl-font-display); font-weight: 800;
    font-size: 28px; letter-spacing: -.03em; margin: 40px 0 10px; color: var(--gvl-ink);
}
.gv-post__body h3 { font-size: 21px; margin: 30px 0 8px; color: var(--gvl-ink); }
.gv-post__body ul, .gv-post__body ol { color: var(--gvl-ink-2); font-size: 18px; line-height: 1.6; }
.gv-post__body li { margin-bottom: 8px; }
.gv-post__body a { color: var(--gvl-primary-dark); }
.gv-post__body img { border: var(--gvl-border); border-radius: var(--gvl-radius); }
.gv-post__body blockquote {
    margin: 28px 0; padding: 4px 0 4px 22px;
    border-left: 4px solid var(--gvl-primary);
    font-size: 19px; color: var(--gvl-ink);
}

.gv-post__foot { padding-block: 24px 80px; }
.gv-post__back { margin: 0; }
.gv-post__back a { color: var(--gvl-primary-dark); font-weight: 600; text-decoration: none; }
.gv-post__back a:hover { text-decoration: underline; }

/* ── The editor ────────────────────────────────────────────────────────
 *
 * The canvas shows labelled fields rather than a rendered preview: these
 * blocks draw fixed decorative markup around a handful of editable strings,
 * and a preview would be mostly furniture with the editable parts hidden
 * inside it. A writer wants to see the words.
 */

.gv-edit {
    border: 1.5px dashed var(--gvl-line-2, #51495988);
    border-radius: 10px; padding: 12px 14px; background: #fff;
}
.gv-edit__head { margin-bottom: 8px; }
.gv-edit__name {
    font-family: var(--gvl-font-mono, monospace); font-size: 10.5px;
    letter-spacing: .1em; text-transform: uppercase; color: var(--gvl-primary-dark, #7b1e86);
}
.gv-edit__field { display: grid; gap: 2px; margin-bottom: 10px; }
.gv-edit__label {
    font-family: var(--gvl-font-mono, monospace); font-size: 10px;
    letter-spacing: .08em; text-transform: uppercase; color: var(--gvl-ink-2, #514a59);
}
.gv-edit__value { font-size: 15px; }
.gv-edit__inner { margin-top: 12px; border-top: 1px dashed var(--gvl-line, #1f1b2422); padding-top: 12px; }
