/* ==========================================================================
   Trail Pass design system.

   The platform serves two farms, so it deliberately belongs to neither.

   The two brand sites were the reference:

     Van Gaalen   navy #13243F, brass #C49A47, parchment, Fraunces + Karla
     Vergenoeg    forest #0B2719, orange #FF4D00, gold #C9922A, cream,
                  Playfair Display + Source Serif 4

   What they already share is a warm off white page, a very large serif
   headline, a small uppercase widely letterspaced eyebrow above it, pill
   buttons, and a gold accent. Van Gaalen's brass #C49A47 and Vergenoeg's gold
   #C9922A are practically the same colour, so gold is the honest bridge.

   Where they differ is the dark: navy against forest green. This takes the
   midpoint, a deep slate green, so a member arriving from either farm's site
   feels a relative rather than a stranger.

   The typefaces are a third pair on purpose. Newsreader is a sibling to
   Fraunces and Playfair without copying either, and Instrument Sans keeps the
   member list and the admin legible, which a serif would not be at small
   sizes in bright sunlight.

   Both are self hosted in /assets/fonts. Nothing here calls out to Google or
   any other third party at runtime.
   ========================================================================== */

@import url("/assets/fonts.css?v=10");

:root {
    /* Page */
    --cream:        #FBF7EF;   /* between Van Gaalen parchment and Vergenoeg cream */
    --card:         #FFFDF8;
    --line:         #E5DBC8;
    --line-soft:    #F0E9DC;

    /* The dark, sitting between navy and forest green */
    --slate:        #16302A;
    --slate-deep:   #0E211D;
    --slate-line:   #2C4A42;

    /* The shared accent */
    --gold:         #C4952F;   /* on dark backgrounds */
    --gold-deep:    #8A6A1F;   /* on light, dark enough for small text */
    --gold-pale:    #EFE3C6;

    /* Text */
    --ink:          #1A2420;
    --ink-soft:     #55605B;
    --ink-faint:    #7C857F;

    /* Status, used on the members sheet and the member card */
    --ok:           #1B7A4B;
    --ok-bg:        #E6F4EC;
    --bad-bg:       #FBEAE9;
    --warn-bg:      #FDF1DC;
    --dead-bg:      #ECEDEB;

    --radius:       14px;
    --radius-lg:    22px;
    --shadow:       0 18px 40px -22px rgba(14, 33, 29, .38);
    --shadow-soft:  0 2px 10px -4px rgba(14, 33, 29, .18);

    --display: "Newsreader", Georgia, "Times New Roman", serif;
    --body:    "Instrument Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;

    --wrap:    1080px;
    --ease:    cubic-bezier(.22, 1, .36, 1);
}

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

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

body {
    margin: 0;
    background: var(--cream);
    color: var(--ink);
    font-family: var(--body);
    /* 17px, matching both brand sites. Smaller is hard work outdoors. */
    font-size: 17px;
    line-height: 1.65;
    -webkit-font-smoothing: antialiased;
    /* Stops any child ever pushing the page sideways, a recurring bug on
       this client's other sites. */
    overflow-x: hidden;
}

h1, h2, h3, h4 {
    font-family: var(--display);
    font-weight: 500;
    line-height: 1.12;
    letter-spacing: -0.01em;
    color: var(--slate);
    margin: 0 0 .5em;
}

h1 { font-size: clamp(38px, 6.4vw, 68px); }
h2 { font-size: clamp(27px, 3.6vw, 40px); }
h3 { font-size: clamp(20px, 2.2vw, 25px); }

p { margin: 0 0 1.1em; }
a { color: var(--gold-deep); }
img { max-width: 100%; height: auto; display: block; }

/* Everything focusable shows where it is. Needed by anyone using a keyboard,
   and it costs nothing. */
:focus-visible {
    outline: 3px solid var(--gold);
    outline-offset: 3px;
    border-radius: 4px;
}

.wrap {
    width: 100%;
    max-width: var(--wrap);
    margin: 0 auto;
    padding: 0 24px;
}

.section { padding: clamp(52px, 7vw, 92px) 0; }
.section--tight { padding: clamp(34px, 4.5vw, 56px) 0; }
.section--card  { background: var(--card); border-block: 1px solid var(--line-soft); }

/* --------------------------------------------------------------------------
   Eyebrow. Both brand sites open with one of these above the headline.
   -------------------------------------------------------------------------- */

.eyebrow {
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .2em;
    text-transform: uppercase;
    color: var(--gold-deep);
    margin: 0 0 16px;
    display: block;
}
.eyebrow--on-dark { color: var(--gold); }

.lede {
    font-size: clamp(18px, 2vw, 21px);
    color: var(--ink-soft);
    max-width: 60ch;
}

/* The italic gold second line, the move both brand sites use in headlines. */
.accent { font-style: italic; color: var(--gold-deep); }
.accent--on-dark { color: var(--gold); }

/* --------------------------------------------------------------------------
   Buttons, pills as on both sites
   -------------------------------------------------------------------------- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    font-family: var(--body);
    font-size: 16px;
    font-weight: 600;
    line-height: 1.2;
    /* 52px tall, comfortably past the 44px minimum for a cold thumb. */
    padding: 16px 30px;
    border-radius: 999px;
    border: 2px solid transparent;
    text-decoration: none;
    cursor: pointer;
    transition: transform .18s var(--ease), box-shadow .18s var(--ease),
                background .18s var(--ease), color .18s var(--ease),
                border-color .18s var(--ease);
}
.btn:hover  { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }

.btn--primary { background: var(--slate); color: #fff; box-shadow: var(--shadow-soft); }
.btn--primary:hover { background: var(--slate-deep); }

.btn--gold { background: var(--gold); color: var(--slate-deep); font-weight: 700; }
.btn--gold:hover { background: #D3A643; }

.btn--ghost { background: transparent; color: var(--slate); border-color: var(--line); }
.btn--ghost:hover { border-color: var(--slate); }

.btn--ghost-on-dark { background: transparent; color: #fff; border-color: rgba(255,255,255,.45); }
.btn--ghost-on-dark:hover { border-color: #fff; background: rgba(255,255,255,.08); }

.btn--block { width: 100%; }
.btn[disabled] { opacity: .55; cursor: not-allowed; transform: none; }

/* --------------------------------------------------------------------------
   Header and footer
   -------------------------------------------------------------------------- */

.site-head { position: relative; z-index: 5; padding: 20px 0; }
.site-head__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    flex-wrap: wrap;
}

.brand {
    display: inline-flex;
    align-items: baseline;
    gap: 9px;
    text-decoration: none;
    font-family: var(--display);
    font-size: 25px;
    font-weight: 600;
    color: var(--slate);
    letter-spacing: -0.01em;
}
.brand__mark { color: var(--gold-deep); font-style: italic; }
.site-head--on-dark .brand { color: #fff; }
.site-head--on-dark .brand__mark { color: var(--gold); }

.site-foot {
    background: var(--slate-deep);
    color: rgba(255,255,255,.72);
    padding: 46px 0 40px;
    font-size: 15px;
    margin-top: auto;
}
.site-foot a { color: var(--gold); text-decoration: none; }
.site-foot a:hover { text-decoration: underline; }
.site-foot__grid {
    display: flex;
    flex-wrap: wrap;
    gap: 18px 40px;
    justify-content: space-between;
    align-items: baseline;
}

/* --------------------------------------------------------------------------
   Hero, a full bleed photograph with a dark wash, as both brand sites open
   -------------------------------------------------------------------------- */

.hero {
    position: relative;
    background: var(--slate-deep);
    color: #fff;
    overflow: hidden;
}

.hero__bg {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: center 40%;
    opacity: .45;
}

/* The wash. Without it the headline is unreadable over a bright sky, a
   mistake already made once on the Van Gaalen home page. */
.hero::after {
    content: "";
    position: absolute;
    inset: 0;
    background:
        linear-gradient(100deg, rgba(14,33,29,.93) 0%, rgba(14,33,29,.74) 45%, rgba(14,33,29,.44) 100%),
        linear-gradient(to bottom, rgba(14,33,29,.5) 0%, transparent 32%, rgba(14,33,29,.62) 100%);
}

.hero__inner {
    position: relative;
    z-index: 2;
    padding: clamp(56px, 9vw, 116px) 0 clamp(60px, 9vw, 112px);
    max-width: 720px;
}
.hero h1 { color: #fff; margin-bottom: .35em; }
.hero__lede { font-size: clamp(18px, 2vw, 21px); color: rgba(255,255,255,.88); max-width: 52ch; }
.hero__actions { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 32px; }

/* A compact hero for the inner pages, no photograph. */
.hero--slim .hero__inner { padding: clamp(38px, 5vw, 60px) 0 clamp(34px, 4.5vw, 52px); }

/* --------------------------------------------------------------------------
   Cards
   -------------------------------------------------------------------------- */

.grid {
    display: grid;
    gap: 22px;
    grid-template-columns: repeat(auto-fit, minmax(258px, 1fr));
}

.card {
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    padding: 28px;
    display: flex;
    flex-direction: column;
    /* Without this a long word can widen the whole grid track. */
    min-width: 0;
}

.card__price {
    font-family: var(--display);
    font-size: clamp(34px, 4vw, 46px);
    font-weight: 600;
    color: var(--slate);
    line-height: 1;
    margin: 6px 0 4px;
}
.card__price small {
    display: block;
    font-family: var(--body);
    font-size: 14px;
    font-weight: 500;
    color: var(--ink-faint);
    margin-top: 8px;
}

.card__list { list-style: none; margin: 16px 0 24px; padding: 0; }
.card__list li {
    position: relative;
    padding-left: 26px;
    margin-bottom: 9px;
    color: var(--ink-soft);
    font-size: 16px;
}
.card__list li::before {
    content: "";
    position: absolute;
    left: 4px;
    top: .62em;
    width: 9px; height: 9px;
    border-radius: 50%;
    background: var(--gold);
}
.card > .btn { margin-top: auto; }

/* Selectable membership card on the signup form.

   .pick__box is a <span> holding block level content, so it MUST be given a
   display of its own. Left as the default inline, padding and height are
   ignored, the block children escape the border box, and the three cards
   collapse into each other. That is exactly what happened the first time. */
.pick {
    position: relative;
    cursor: pointer;
    display: block;
    height: 100%;
}
.pick input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.pick__box {
    display: flex;
    flex-direction: column;
    border: 2px solid var(--line);
    border-radius: var(--radius-lg);
    background: var(--card);
    padding: 22px 24px;
    height: 100%;
    transition: border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.pick__box strong {
    display: block;
    font-family: var(--display);
    font-size: 20px;
    font-weight: 600;
    color: var(--slate);
    line-height: 1.25;
}
.pick__box .card__price { margin-top: auto; padding-top: 10px; }

/* On a form, three stacked rows read as "pick one" far more clearly than a
   grid that wraps two across and leaves the third stranded on its own line. */
.grid--pick { grid-template-columns: 1fr; gap: 14px; }
.grid--pick .pick__box {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    padding: 20px 24px;
}
.grid--pick .pick__box .card__price {
    margin: 0;
    padding: 0;
    text-align: right;
    font-size: 30px;
    white-space: nowrap;
}
.grid--pick .pick__box .card__price small { margin-top: 2px; }

@media (max-width: 460px) {
    /* Too narrow for name and price side by side without the name wrapping
       awkwardly, so go back to one above the other. */
    .grid--pick .pick__box { flex-direction: column; align-items: flex-start; gap: 6px; }
    .grid--pick .pick__box .card__price { text-align: left; }
}
.pick input:checked + .pick__box {
    border-color: var(--gold);
    box-shadow: 0 0 0 4px var(--gold-pale);
}
.pick input:focus-visible + .pick__box { outline: 3px solid var(--gold); outline-offset: 3px; }

/* --------------------------------------------------------------------------
   Numbered steps
   -------------------------------------------------------------------------- */

.steps { counter-reset: step; }
.step__n {
    counter-increment: step;
    font-family: var(--display);
    font-size: 40px;
    font-weight: 500;
    color: var(--gold);
    line-height: 1;
    display: block;
    margin-bottom: 10px;
}
.step__n::before { content: counter(step); }

/* --------------------------------------------------------------------------
   Forms
   -------------------------------------------------------------------------- */

.field { margin-bottom: 20px; min-width: 0; }

.label {
    display: block;
    font-size: 14px;
    font-weight: 600;
    color: var(--slate);
    margin-bottom: 7px;
}

.input, .select, .textarea {
    width: 100%;
    /* Must stay at 16px or more. Anything smaller makes iOS Safari zoom in
       when the field is tapped, which throws the layout around. */
    font-size: 16px;
    font-family: var(--body);
    color: var(--ink);
    background: #fff;
    border: 2px solid var(--line);
    border-radius: 12px;
    padding: 14px 16px;
    min-height: 52px;
    transition: border-color .16s var(--ease), box-shadow .16s var(--ease);
}
.input:focus, .select:focus, .textarea:focus {
    outline: none;
    border-color: var(--gold);
    box-shadow: 0 0 0 4px var(--gold-pale);
}

.hint { font-size: 14.5px; color: var(--ink-soft); margin: 6px 0 0; }

.check {
    display: flex;
    align-items: flex-start;
    gap: 13px;
    padding: 16px 18px;
    background: var(--card);
    border: 2px solid var(--line);
    border-radius: var(--radius);
    cursor: pointer;
    font-size: 16px;
}
.check input {
    width: 24px; height: 24px;
    margin: 1px 0 0;
    flex: 0 0 auto;
    accent-color: var(--gold-deep);
}
.check:hover { border-color: var(--gold); }

/* The legal text. Scrollable so the page does not become endless, but the
   wording itself is never shortened, because its fingerprint is stored
   against every signature. */
.legal {
    max-height: 320px;
    overflow-y: auto;
    background: #fff;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 22px 24px;
    font-size: 15px;
    line-height: 1.7;
    color: var(--ink-soft);
    white-space: pre-wrap;
    -webkit-overflow-scrolling: touch;
}

/* On privacy.php the notice is the point of the page, not a box to scroll
   past on the way to a payment button. */
.legal--page {
    max-height: none;
    overflow-y: visible;
}

/* --------------------------------------------------------------------------
   Notices and status pills
   -------------------------------------------------------------------------- */

.note {
    border-radius: var(--radius);
    padding: 16px 20px;
    margin-bottom: 22px;
    font-size: 16px;
    border: 1px solid;
}
.note--info { background: var(--card);    border-color: var(--line); color: var(--ink-soft); }
.note--ok   { background: var(--ok-bg);   border-color: #BEDFCD;     color: #10502F; }
.note--bad  { background: var(--bad-bg);  border-color: #F0C4C1;     color: #8C1B15; }
.note--warn { background: var(--warn-bg); border-color: #EFD9A8;     color: #6E4700; }

.pill {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 12.5px;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    padding: 7px 15px;
    border-radius: 999px;
    white-space: nowrap;
}
.pill--ok   { background: var(--ok-bg);   color: #10502F; }
.pill--bad  { background: var(--bad-bg);  color: #8C1B15; }
.pill--warn { background: var(--warn-bg); color: #6E4700; }
.pill--dead { background: var(--dead-bg); color: #414945; }
.pill__dot  { width: 8px; height: 8px; border-radius: 50%; background: currentColor; }

/* --------------------------------------------------------------------------
   The membership card, held up at a gate
   -------------------------------------------------------------------------- */

.member-card {
    background: var(--slate);
    color: #fff;
    border-radius: var(--radius-lg);
    padding: clamp(28px, 5vw, 44px);
    box-shadow: var(--shadow);
    text-align: center;
    position: relative;
    overflow: hidden;
}
.member-card::before {
    content: "";
    position: absolute;
    inset: 0;
    background: radial-gradient(120% 80% at 50% 0%, rgba(196,149,47,.22), transparent 60%);
}
.member-card > * { position: relative; }
.member-card__label {
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .2em;
    text-transform: uppercase;
    color: var(--gold);
    margin-bottom: 10px;
}
.member-card__number {
    font-family: var(--display);
    /* Deliberately enormous. Staff read this out and type it into the sheet,
       often at arm's length in full sun. */
    font-size: clamp(64px, 16vw, 112px);
    font-weight: 600;
    line-height: 1;
    letter-spacing: -0.02em;
    color: #fff;
}
.member-card__name {
    font-family: var(--display);
    font-size: clamp(22px, 3.4vw, 30px);
    margin-top: 14px;
    color: #fff;
}
.member-card__meta { color: rgba(255,255,255,.78); font-size: 15.5px; margin-top: 6px; }
.member-card__rule { height: 1px; background: var(--slate-line); margin: 22px 0; border: 0; }

/* --------------------------------------------------------------------------
   Utilities
   -------------------------------------------------------------------------- */

.stack > * + * { margin-top: 18px; }

/* The numbered steps on the signup form are major breaks, not list items.
   18px between them left each STEP heading sitting almost on top of the
   field above it. */
.stack--steps > * + * { margin-top: 52px; }
.center { text-align: center; }
.mx-auto { margin-inline: auto; }
.narrow { max-width: 620px; }
.muted { color: var(--ink-soft); }
.nowrap { white-space: nowrap; }

.sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

.page { min-height: 100vh; display: flex; flex-direction: column; }
.page__body { flex: 1; }

/* --------------------------------------------------------------------------
   Small screens
   -------------------------------------------------------------------------- */

@media (max-width: 620px) {
    .wrap { padding: 0 18px; }
    .card { padding: 22px; }
    .hero__actions .btn { width: 100%; }
    .site-foot__grid { flex-direction: column; }
}

/* Respect a reduced motion preference rather than animating regardless. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .001ms !important;
        transition-duration: .001ms !important;
    }
    .btn:hover { transform: none; }
}

/* Printing a membership page should give a clean card, not a dark slab that
   drains an inkjet. */
@media print {
    .site-head, .site-foot, .btn { display: none !important; }
    body { background: #fff; }
    .member-card { background: #fff; color: #000; box-shadow: none; border: 2px solid #000; }
    .member-card__number, .member-card__name, .member-card__label { color: #000; }
}

/* --------------------------------------------------------------------------
   The mark
   -------------------------------------------------------------------------- */

.brand__logo {
    flex: 0 0 auto;
    /* Drawn in currentColor, so it takes the gold from the rules below rather
       than carrying its own. One drawing serves the dark header and the cream
       one. */
    color: var(--gold-deep);
}
.site-head--on-dark .brand__logo { color: var(--gold); }
.brand { gap: 12px; align-items: center; }

@media (max-width: 420px) {
    /* The name alone is enough on a narrow phone, and it buys back the room
       the Log in button needs. */
    .brand__logo { width: 28px; height: 28px; }
    .brand { font-size: 21px; gap: 9px; }
}

/* The office login is a single centred card, so the mark sits above the
   heading rather than in a header bar. */
.login-brand {
    display: inline-flex;
    align-items: center;
    gap: 11px;
    margin-bottom: 18px;
    font-size: 22px;
}

/* --------------------------------------------------------------------------
   Motion
   -------------------------------------------------------------------------- */

/* IMPORTANT: nothing is hidden here by default.
   .reveal-off is added by assets/motion.js, and ONLY to elements that are
   below the fold when the page loads. If that script never runs, every one of
   these elements is simply visible, which is the whole point. Do not be
   tempted to "tidy" this by giving the base state opacity 0. */
.reveal-off {
    opacity: 0;
    transform: translateY(18px);
}

.section h2,
.section .lede,
.card,
.steps > div,
.pick,
.note {
    transition: opacity .6s var(--ease), transform .6s var(--ease);
}

/* Applied for a single frame alongside .reveal-off so the browser does not
   animate the element out before animating it in. */
.reveal-instant { transition: none !important; }

/* Stagger the cards in a row so they arrive one after another rather than all
   at once, which reads as deliberate rather than as a glitch. */
.grid > .card:nth-child(2),
.grid > .pick:nth-child(2) { transition-delay: .08s; }
.grid > .card:nth-child(3),
.grid > .pick:nth-child(3) { transition-delay: .16s; }
.grid > .card:nth-child(4),
.grid > .pick:nth-child(4) { transition-delay: .24s; }

/* Buttons ------------------------------------------------------------------ */

.btn {
    position: relative;
    overflow: hidden;
}

/* A slow sheen across the gold button on hover. Gold catches light, so this
   is the one place a shine is honest rather than decorative. */
.btn--gold::after {
    content: "";
    position: absolute;
    top: 0;
    left: -60%;
    width: 40%;
    height: 100%;
    background: linear-gradient(100deg, transparent, rgba(255,255,255,.42), transparent);
    transform: skewX(-18deg);
    transition: left .55s var(--ease);
    pointer-events: none;
}
.btn--gold:hover::after { left: 120%; }

/* A real press. Lifting on hover then dropping on click is what makes a
   button feel like a button rather than a coloured rectangle. */
.btn:active { transform: translateY(1px) scale(.985); }

.btn--primary,
.btn--gold { box-shadow: 0 2px 10px -4px rgba(14,33,29,.3); }
.btn--primary:hover,
.btn--gold:hover { box-shadow: 0 10px 22px -10px rgba(14,33,29,.45); }

/* Cards lift very slightly under the cursor, enough to say "this is a thing"
   without turning the page into a bouncy castle. */
.card { transition: opacity .6s var(--ease), transform .6s var(--ease), box-shadow .3s var(--ease); }
.card:hover { box-shadow: 0 14px 30px -20px rgba(14,33,29,.35); }

.pick__box:hover { border-color: var(--gold); }

/* The mark draws its ridgeline once, on first load. A quiet nod to the
   self drawing ridgeline that is the signature of the Van Gaalen site. */
@keyframes ridge-draw {
    from { stroke-dashoffset: 120; }
    to   { stroke-dashoffset: 0; }
}
.site-head--on-dark .brand__logo path {
    stroke-dasharray: 120;
    animation: ridge-draw 1.5s var(--ease) .25s both;
}

/* Everything above is switched off for anyone who has asked for less motion.
   The existing reduced motion block already zeroes transitions and animations,
   and .reveal-off is never applied because motion.js returns early. */
@media (prefers-reduced-motion: reduce) {
    .btn--gold::after { display: none; }
    .site-head--on-dark .brand__logo path { animation: none; stroke-dashoffset: 0; }
}
