/* ==========================================================================
   24 PRECISION GOLF — Departure Board
   Design system. Tokens here map 1:1 to theme.json for the WordPress build.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */

:root {
  /* Ground — the board is unlit until the flaps land */
  --ink:            #0A0A0A;
  --ink-raised:     #141414;
  --ink-flap:       #1C1C1C;
  --hairline:       rgba(255, 255, 255, 0.09);
  --hairline-firm:  rgba(255, 255, 255, 0.16);

  /* Brand. #90B040 is confirmed. Never white text on it. */
  --green:          #90B040;
  --green-lift:     #A4C455;
  --green-deep:     #5F7729;
  --green-veil:     rgba(144, 176, 64, 0.12);

  --white:          #FFFFFF;
  /* Secondary text is tinted from the brand hue, never neutral gray */
  --dim:            #9BA48C;
  /* Long-form reading color: brighter than --dim, softer than pure white. */
  --read:           #D7DACF;
  /* Lightened from #6E765F, which measured 4.17:1 on ink and 3.59:1 on the flap
     face — under the 4.5 AA floor for the micro-caps it carries. */
  --dimmer:         #7E876D;

  /* Light-surface lockup (Memberships uses this) */
  --paper:          #F2F2F2;
  --paper-rule:     rgba(17, 17, 17, 0.12);

  /* The one documented extra accent. Error cannot be signalled in brand green,
     so a single alert hue is introduced here and nowhere else. */
  --alert:          #C6604A;
  --alert-text:     #E08A72;

  /* Type */
  --face-display: 'Michroma', 'Arial Narrow', sans-serif;
  --face-board:   'Saira Condensed', 'Arial Narrow', sans-serif;
  --face-text:    'Barlow', system-ui, -apple-system, sans-serif;

  --step--1: clamp(0.80rem, 0.77rem + 0.14vw, 0.88rem);
  --step-0:  clamp(1.00rem, 0.96rem + 0.20vw, 1.13rem);
  --step-1:  clamp(1.25rem, 1.16rem + 0.44vw, 1.52rem);
  --step-2:  clamp(1.56rem, 1.39rem + 0.85vw, 2.05rem);
  --step-3:  clamp(1.95rem, 1.65rem + 1.49vw, 2.77rem);
  --step-5:  clamp(3.05rem, 2.24rem + 4.03vw, 5.03rem);

  /* Rhythm */
  --gap-xs:  0.5rem;
  --gap-sm:  0.75rem;
  --gap-md:  1.25rem;
  --gap-lg:  2rem;
  --gap-xl:  3.25rem;
  --gap-2xl: 5rem;
  --gap-3xl: 7.5rem;

  --shell: 1240px;
  --rail:  clamp(1.15rem, 4vw, 3rem);

  --flip-ease: cubic-bezier(0.16, 1, 0.3, 1);
}

/* --------------------------------------------------------------------------
   2. Reset & base
   -------------------------------------------------------------------------- */

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--ink);
  color: var(--white);
  font-family: var(--face-text);
  font-size: var(--step-0);
  line-height: 1.65;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img { max-width: 100%; height: auto; display: block; }

h1, h2, h3, h4 {
  margin: 0;
  font-weight: 600;
  line-height: 1.06;
  letter-spacing: -0.02em;
  text-wrap: balance;
  /* White by default, but as a PLAIN ELEMENT selector so a single class can
     beat it. This deliberately does not live in theme.json any more.
     theme.json's elements.heading.color compiles to a rule that sets color on
     the heading itself, and an explicitly set color is never overridden by an
     inherited one — so .section--paper setting a dark color on the section had
     no effect on the headings inside it. Every heading in a light panel rendered
     white on #F2F2F2: contrast 1.12, which is invisible. Five of them on the
     coaching page alone.

     The light-panel override lives with the section rules, in section 7. */
  color: var(--white);
}

p { margin: 0; max-width: 68ch; }

a { color: inherit; }

:focus-visible {
  outline: 3px solid var(--green);
  outline-offset: 3px;
  border-radius: 2px;
}

.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;
}

.skip {
  position: absolute; left: var(--rail); top: -100px;
  z-index: 200; padding: 0.85rem 1.4rem;
  background: var(--green); color: #111111;
  font-family: var(--face-board); font-weight: 700;
  letter-spacing: 0.1em; text-transform: uppercase;
  text-decoration: none; transition: top 0.18s ease;
}
.skip:focus { top: var(--rail); }

.shell {
  width: 100%; max-width: var(--shell);
  margin-inline: auto; padding-inline: var(--rail);
}

/* --------------------------------------------------------------------------
   3. Board primitives — the world's grammar
   -------------------------------------------------------------------------- */

/* Placard: the small engraved caps that label every module on a real board */
.placard {
  font-family: var(--face-board);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--dim);
  font-variant-numeric: tabular-nums;
}

/* Flap cell: a single character carrier, split across its middle */
.flap {
  display: inline-block;
  position: relative;
  background: var(--ink-flap);
  color: var(--white);
  font-family: var(--face-board);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-align: center;
  min-width: 0.86em;
  padding: 0.1em 0.04em;
  border-radius: 2px;
  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.6);
}
.flap::after {
  content: "";
  position: absolute; inset-inline: 0; top: 50%;
  height: 1px; background: rgba(0, 0, 0, 0.55);
}
.flap--space { background: transparent; box-shadow: none; }
.flap--space::after { display: none; }
.flap--green { color: var(--green); }

/* Flip-in: the board's one authored motion moment. */
@media (prefers-reduced-motion: no-preference) {
  .is-flipping .flap {
    animation: flap-drop 0.44s var(--flip-ease) both;
    animation-delay: var(--flap-delay, 0ms);
  }
}
@keyframes flap-drop {
  0%   { transform: rotateX(-88deg); filter: brightness(0.35); }
  60%  { transform: rotateX(6deg);   filter: brightness(1.06); }
  100% { transform: rotateX(0);      filter: brightness(1); }
}

/* Status lamp */
.lamp {
  display: inline-flex; align-items: center; gap: 0.5rem;
  font-family: var(--face-board); font-size: var(--step--1);
  font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--green);
}
.lamp::before {
  content: ""; width: 8px; height: 8px; border-radius: 50%;
  background: var(--green);
  box-shadow: 0 0 0 3px rgba(144, 176, 64, 0.18), 0 0 12px 2px rgba(144, 176, 64, 0.5);
}
@media (prefers-reduced-motion: no-preference) {
  .lamp::before { animation: lamp-breathe 3.2s ease-in-out infinite; }
}
@keyframes lamp-breathe {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.55; }
}

/* --------------------------------------------------------------------------
   4. Wordmark — approved recolor, rebuilt as live text
   24 green · PRECISION white · GOLF green · rule green
   -------------------------------------------------------------------------- */

/* Mark-only in the sticky masthead; the full wordmark lives in the rail. */
.wordmark--markonly { gap: 0; }

.wordmark {
  display: inline-flex; align-items: center; gap: 0.72rem;
  min-height: 44px;
  text-decoration: none; line-height: 1;
}

/* Square ball asset with the white fill baked in. The supplied raster had a
   transparent interior — drawn to sit on white paper — which read as a dark
   ball on this ground. Regenerated at assets/images/logo-ball.png. */
.wordmark__mark {
  flex: none;
  width: 40px; height: 40px;
  background-image: url("../images/logo-ball.png");
  background-repeat: no-repeat;
  background-size: contain;
  background-position: center;
}

.wordmark__text { display: grid; gap: 0.18rem; }

.wordmark__line {
  font-family: var(--face-display);
  font-size: 0.95rem;
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.wordmark__24   { color: var(--green); }
.wordmark__rest { color: var(--white); }
.wordmark__golf { color: var(--green); }

.wordmark__rule { height: 2px; background: var(--green); width: 100%; }

/* Light-surface lockup: PRECISION goes ink, GOLF stays green */
.on-paper .wordmark__rest { color: #111111; }

/* --------------------------------------------------------------------------
   5. Actions
   -------------------------------------------------------------------------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 0.6rem;
  padding: 1rem 1.9rem;
  font-family: var(--face-board);
  font-size: var(--step-0);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-decoration: none;
  border: 1px solid transparent;
  border-radius: 3px;
  cursor: pointer;
  transition: transform 0.16s var(--flip-ease), background-color 0.16s ease,
              border-color 0.16s ease, color 0.16s ease;
}

/* Green surface always takes ink text. Non-negotiable. */
.btn--go {
  background: var(--green);
  color: #111111;
  box-shadow: 0 1px 0 var(--green-deep), 0 10px 26px -14px rgba(144, 176, 64, 0.9);
}
.btn--go:hover { background: var(--green-lift); transform: translateY(-2px); }
.btn--go:active { transform: translateY(0); }

.btn--quiet {
  background: transparent;
  color: var(--white);
  border-color: var(--hairline-firm);
}
.btn--quiet:hover { border-color: var(--green); color: var(--green); }

.btn[aria-disabled="true"] {
  opacity: 0.42; pointer-events: none;
}

.btn--block { width: 100%; }

/* --------------------------------------------------------------------------
   6. Terminal rail + masthead
   -------------------------------------------------------------------------- */

.rail {
  border-bottom: 1px solid var(--hairline);
  background: #060606;
}
.rail__inner {
  display: flex; flex-wrap: wrap; align-items: center;
  /* Column gap is 26px rather than --gap-lg (32px). With the social icons added
     the rail needed 1150px inside a 1144px shell — six pixels over, which wrapped
     the address and phone onto a second row and doubled the rail's height. Four
     gaps at 6px less reclaims 24px and puts it back on one line at desktop width.
     Measured, not guessed. Below roughly 1240px the rail still wraps, which is
     what it was built to do. */
  gap: var(--gap-sm) 26px;
  padding-block: 0.6rem;
}
.rail__item {
  font-family: var(--face-board); font-size: var(--step--1);
  font-weight: 500; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--dim); font-variant-numeric: tabular-nums;
}
.rail__item a { color: var(--dim); text-decoration: none; }
.rail__item a:hover { color: var(--green); }
.rail__spacer { margin-inline-start: auto; }
/* The right-hand pair (address + phone) is one flex item so the auto margin
   above pushes both together. As two separate siblings the auto margin ate the
   whole line's slack for the first of them and bumped the second onto a new
   row — see the note in header.php. */
.rail__group {
  display: inline-flex;
  align-items: center;
  gap: var(--gap-lg);
  flex-wrap: wrap;
}
/* Brand lockup in the rail. The rail scrolls away, so the masthead keeps the
   ball mark as the persistent way home. */
.rail__brand { padding-block: 0.1rem; }
.rail__brand .wordmark__line {
  font-family: var(--face-display); font-size: 0.85rem;
  letter-spacing: 0.02em; text-transform: none; line-height: 1; white-space: nowrap;
}
.rail__brand .wordmark__rule { height: 2px; background: var(--green); width: 100%; }


.masthead {
  position: sticky; top: 0; z-index: 100;
  background: rgba(10, 10, 10, 0.92);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--hairline);
}
.masthead__inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--gap-md); padding-block: var(--gap-sm);
}

.nav { display: flex; align-items: center; gap: clamp(0.9rem, 2vw, 1.9rem); }
.nav a {
  display: inline-flex; align-items: center;
  min-height: 44px;
  font-family: var(--face-board); font-size: var(--step--1);
  font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--white); text-decoration: none;
  border-bottom: 2px solid transparent;
  /* Multi-word items were breaking mid-label, so "Book a bay" stacked into
     three lines and the whole masthead read as cramped. Never wrap a nav item:
     if the row runs out of room the fix is fewer items, not broken words. */
  white-space: nowrap;
  transition: color 0.16s ease, border-color 0.16s ease;
}
.nav a:hover { color: var(--green); border-bottom-color: var(--green); }
.nav a[aria-current="page"] { color: var(--green); border-bottom-color: var(--green); }

.masthead__actions { display: flex; align-items: center; gap: var(--gap-sm); }
.masthead .btn { padding: 0.7rem 1.25rem; font-size: var(--step--1); }

@media (max-width: 900px) {
  .nav--main { display: none; }
}


/* Masthead search -------------------------------------------------------- */
/* 13rem is the widest the field can be and still leave the wordmark, seven nav
   items and the CTA on one line inside the 1240px shell. */
.msearch { position: relative; flex: 1 1 11rem; max-width: 20rem; min-width: 0; }
.msearch__icon {
  position: absolute; left: 0.7rem; top: 50%; transform: translateY(-50%);
  width: 1em; height: 1em; color: var(--dim); pointer-events: none;
  fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
.msearch__input {
  width: 100%; padding: 0.62rem 0.7rem 0.62rem 2.15rem;
  background: var(--ink-raised); color: #fff;
  border: 1px solid var(--hairline-firm); border-radius: 3px;
  font-family: var(--face-text); font-size: 16px; line-height: 1.2;
  transition: border-color 0.16s ease;
}
.msearch__input::placeholder { color: var(--dim); opacity: 1; }
.msearch__input:hover { border-color: rgba(255, 255, 255, 0.26); }
.msearch__input:focus { border-color: var(--green); }
.msearch:focus-within .msearch__icon { color: var(--green); }

.msearch__panel {
  /* anchored to the field's right edge so it can be wider than the field
     without ever running off the viewport */
  position: absolute; top: calc(100% + 0.5rem); right: 0; left: auto;
  min-width: 21rem; max-width: min(26rem, calc(100vw - 2rem));
  background: #0A0A0A; border: 1px solid var(--hairline-firm); border-radius: 3px;
  box-shadow: 0 24px 60px -34px rgba(0, 0, 0, 1);
  max-height: 60vh; overflow-y: auto; z-index: 110;
}
/* Between 900 and 1200 the wordmark, seven nav items, the field and the CTA cannot
   share one line. Rather than let it wrap raggedly, give the field its own row. */
@media (max-width: 900px) {
  .msearch__panel { left: 0; right: 0; min-width: 0; max-width: none; }
}
.msearch__list { list-style: none; margin: 0; padding: 0; }
.msearch__list li + li { border-top: 1px solid var(--hairline); }
.msearch__hit { display: block; padding: 0.7rem 0.9rem; text-decoration: none; }
.msearch__hit:hover, .msearch__hit:focus-visible { background: rgba(144, 176, 64, 0.08); }
.msearch__hitkey {
  display: block; font-family: var(--face-board); font-size: 0.72rem; font-weight: 600;
  letter-spacing: 0.18em; text-transform: uppercase; color: var(--green);
}
.msearch__hitname {
  display: block; margin-top: 0.1rem;
  font-family: var(--face-board); font-size: 1rem; font-weight: 600; color: #fff;
}
.msearch__count, .msearch__none {
  margin: 0; padding: 0.6rem 0.9rem; border-top: 1px solid var(--hairline);
  font-family: var(--face-board); font-size: 0.72rem; font-weight: 600;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--dimmer);
  font-variant-numeric: tabular-nums;
}
.msearch__none { letter-spacing: 0; text-transform: none; font-family: var(--face-text); color: var(--dim); }
.msearch__none a { color: var(--green); }

/* Above 1200 everything shares one line and the nav is allowed to shrink into it;
   wrapping is only enabled below, where the field takes its own row. */
.masthead__inner { flex-wrap: nowrap; }
/* The CTA never shrinks or wraps its label — the field absorbs the slack instead. */
.masthead__actions { flex: 0 0 auto; }
.masthead .btn { white-space: nowrap; }
@media (max-width: 1200px) {
  /* the nav tightens first; with the wordmark gone the row still holds */
  .nav--main { gap: 0.9rem; }
}
@media (max-width: 900px) {
  .masthead__inner { flex-wrap: wrap; }
  /* nav and CTA are both gone down here, so the 40px mark and the field share
     one row rather than stacking */
  .msearch { flex: 1 1 auto; max-width: none; }
}
@media (max-width: 900px) {
  /* the fixed book bar already carries this call to action down here, and the
     duplicate was forcing the masthead to a third row */
  .masthead__actions { display: none; }
}

/* --------------------------------------------------------------------------
   7. Sections
   -------------------------------------------------------------------------- */

.section { padding-block: var(--gap-3xl); }
.section--tight { padding-block: var(--gap-2xl); }
.section--paper {
  background: var(--paper); color: #111111;
}
/* Headings need an EXPLICIT rule here, not inheritance from the line above.
   h1-h6 carry their own color declaration (see section 2), and an inherited
   value never beats an explicit one no matter how specific the ancestor is.
   Without this, every heading in a light panel is white on #F2F2F2. */
.section--paper :is(h1, h2, h3, h4, h5, h6) { color: #111111; }
.section--paper p { color: #2A2A2A; }
.section--raised { background: var(--ink-raised); }

.section__head { margin-bottom: var(--gap-xl); max-width: 56ch; }
.section__title {
  font-family: var(--face-display);
  font-size: var(--step-3);
  letter-spacing: -0.01em;
  line-height: 1.14;
}
.section__lede {
  margin-top: var(--gap-md);
  font-size: var(--step-1);
  color: var(--dim);
  line-height: 1.55;
}
.section--paper .section__lede { color: #3A3A3A; }

/* Panel inset and title clearance — two bugs that read as one.

   1. A .section is a panel with its own background, but had no horizontal
      padding, so every title sat flush against the panel's left edge. Measured
      at 0px inset on all four sections of /coaching/.

   2. .section__title carries no bottom margin. Spacing was living on
      .section__head, which the converted pages do not use — their titles are
      bare .section__title elements. Where the next block brought its own margin
      (.section__lede, .hero__actions) it looked fine; where it did not
      (.manifest, .specs, both of which open with a border-top) the gap measured
      0px and the rule cut straight through the title's descenders.

   The :not() exclusions keep the blocks that already space themselves correctly
   from being double-spaced. */

/* Only the sections that actually paint a panel. A plain .section has no
   background, so padding it just pushes its content out of line with the
   page title above — measured 968px against the title's 920px on /contact/.
   The panels are the ones whose edge the text was touching. */
.section--raised,
.section--paper { padding-inline: var(--rail); }

.section__title + *:not(.section__lede),
.page__title + *:not(.page__standfirst) {
  margin-top: var(--gap-lg);
}

/* Centered section head. The default is left-aligned, which is right for a
   section that argues a point. It is wrong for a section that introduces a row
   of equal items — a centered title above a left-aligned lede reads as a
   mistake, which is exactly how "Our Tech" and "Why Visit" looked. */
.section--center .section__head,
.section--center .section__title,
.section--center .section__lede { text-align: center; }
.section--center .section__head { margin-inline: auto; }
.section--center .section__lede { margin-inline: auto; }

/* --------------------------------------------------------------------------
   7b. Page header — the standing head on every non-home page

   page.php has always emitted .page__head / .page__title / .page__standfirst /
   .page__body, and none of the four were ever styled. The title therefore sat
   directly beneath the masthead with no separation on every interior page,
   which read as the header and the content colliding. This is that missing
   block, not a change of design.
   -------------------------------------------------------------------------- */

.page__head {
  padding-block: var(--gap-2xl) var(--gap-lg);
}

.page__title {
  font-family: var(--face-display);
  font-size: var(--step-3);
  letter-spacing: -0.01em;
  line-height: 1.14;
  max-width: 20ch;
}

.page__standfirst {
  margin-top: var(--gap-md);
  max-width: 58ch;
  font-size: var(--step-1);
  line-height: 1.55;
  color: var(--dim);
}

.page__body {
  padding-bottom: var(--gap-2xl);
}

/* The gap that separates a title from the content under it belongs to the
   header, so a page whose first block is a full-bleed section does not end up
   with double spacing. */
.page__body > :first-child { margin-top: 0; }

/* A page header followed immediately by a full-bleed section double-spaces.
   The header contributes its own bottom padding and the section contributes a
   full padding-block on top of it, so the title floats away from the content
   it introduces — measured 132px on /book/ (32 header + 80 section + leading),
   which reads as two unrelated blocks rather than a heading and its body.

   The header already provides the separation, so the section's leading padding
   is redundant in this one position only. Scoped to :first-child so a section
   anywhere else on the page keeps its full rhythm.

   Four pages are affected today — book, contact, meet-pga-pro, membership —
   which are the four rebuilt into this theme's own section markup. The Spectra
   pages start with a uagb container and are untouched by this. */
.page__body > .section:first-child { padding-top: var(--gap-lg); }

@media (max-width: 700px) {
  .page__head { padding-block: var(--gap-xl) var(--gap-md); }
  .page__title { max-width: none; }
}

/* Course list — a directory page, so the title behaves as a masthead over the
   list rather than as the opening line of an argument. Scoped to the one page
   via the slug body class, NOT applied to .page__title globally, because every
   other page's title is left-aligned by design and centering them all is a much
   larger change than was asked for.

   The rule underneath is a border on an inline-block, so it sizes to the words
   instead of spanning the whole container the way text-decoration on a centered
   block would. */
/* Two selectors on purpose.

   .page--course-list is the theme's own slug class and is the one to keep: it
   survives the page being recreated with a new ID, and it says what it means.

   .page-id-4446 is WordPress core's, and it is here because the slug class only
   appears in HTML generated AFTER the theme change went live. LiteSpeed holds
   page HTML and did not release this URL on either a full purge or a targeted
   one — both reported success and both left X-LiteSpeed-Cache: hit serving the
   old markup. The core class is already in that cached copy, so styling against
   it works immediately instead of waiting on a cache that will not let go.

   When the cached copy finally expires, the slug class carries it. Remove the
   ID selector then. */
.page--course-list .page__head,
.page-id-4446 .page__head { text-align: center; }

/* /membership/ prints no page header — the content opens with its own <h1>
   ("Memberships that match your game"), so the template's "Membership" title
   above it was the same sentence twice. See pg24_show_page_header().

   With the header gone the body would otherwise start hard against the
   masthead, so this restores the breathing room the header used to provide.
   The section keeps its own rhythm below. */
.page--membership .page__body > .section:first-child {
  padding-top: var(--gap-2xl);
}
/* The promoted heading is an h1 now, but it should read at section scale, not
   at the larger .page__title size — it sits inside the section, not above it. */
.page--membership .section__title {
  max-width: 24ch;
}
.page--course-list .page__title,
.page-id-4446 .page__title {
  display: inline-block;
  max-width: none;
  font-size: clamp(2.4rem, 1.9rem + 2.2vw, 3.6rem);
  padding-bottom: var(--gap-sm);
  border-bottom: 3px solid var(--green);
}

/* --------------------------------------------------------------------------
   8. Hero board
   -------------------------------------------------------------------------- */

.hero {
  position: relative;
  padding-block: var(--gap-2xl) var(--gap-3xl);
  overflow: hidden;
  isolation: isolate;
}

/* The room is dark and the screen is the light source.
   Footage sits behind the board the way a bay glows behind a terminal display. */
.hero__media {
  position: absolute; inset: 0;
  z-index: 0;
  background: var(--ink);
  pointer-events: none;
}
.hero__media video {
  width: 100%; height: 100%;
  object-fit: cover;
  opacity: 0.42;
  filter: saturate(0.75) contrast(1.05);
}

/* Scrim guarantees text contrast regardless of which frame is on screen.
   Worst case (a pure-white frame) still composites to roughly #272727. */
.hero__scrim {
  position: absolute; inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(
      to bottom,
      rgba(10, 10, 10, 0.55) 0%,
      rgba(10, 10, 10, 0.74) 38%,
      rgba(10, 10, 10, 0.92) 78%,
      var(--ink) 100%
    ),
    linear-gradient(to right, rgba(10, 10, 10, 0.72) 0%, rgba(10, 10, 10, 0.15) 62%);
}

.hero::before {
  content: "";
  position: absolute; inset: 0;
  z-index: 2;
  background:
    radial-gradient(120% 80% at 50% -10%, rgba(144, 176, 64, 0.10), transparent 60%),
    repeating-linear-gradient(
      to bottom,
      transparent 0 38px,
      rgba(255, 255, 255, 0.014) 38px 39px
    );
  pointer-events: none;
}
.hero > .shell { position: relative; z-index: 3; }

/* Motion is opt-out. Reduced motion holds a still frame instead of looping. */
@media (prefers-reduced-motion: reduce) {
  .hero__media video { display: none; }
}

/* Terminal identification plate. A real board names its airport at scale before it
   lists a single departure — this is that, not an eyebrow over the heading. */
.hero__lockup {
  display: flex;
  align-items: center;
  gap: clamp(0.85rem, 2vw, 1.5rem);
  margin-bottom: clamp(1.5rem, 3.5vw, 2.75rem);
}

.hero__lockup-mark {
  flex: none;
  width: clamp(62px, 8.5vw, 104px);
  aspect-ratio: 1;
  background-image: url("../images/logo-ball.png");
  background-repeat: no-repeat;
  background-size: contain;
  background-position: center;
}

/* One line, the way the lockup is actually drawn: 24 beside PRECISION GOLF,
   with the rule spanning both. Michroma is very wide, so both sizes are fluid
   and tuned to clear a 375px viewport rather than stacking. */
.hero__lockup-text {
  display: grid;
  grid-template-columns: auto auto;
  align-items: baseline;
  justify-content: start;
  column-gap: clamp(0.35rem, 1vw, 0.7rem);
  row-gap: clamp(0.2rem, 0.6vw, 0.45rem);
}

.hero__lockup-name {
  font-family: var(--face-display);
  font-size: var(--step-3);
  line-height: 1;
  letter-spacing: 0.02em;
  color: var(--green);
}

.hero__lockup-sub {
  font-family: var(--face-display);
  font-size: var(--step-0);
  line-height: 1.1;
  letter-spacing: 0.16em;
  white-space: nowrap;
}
.hero__lockup-sub .nsep  { color: var(--white); }
.hero__lockup-sub .ngolf { color: var(--green); }

.hero__lockup-rule {
  grid-column: 1 / -1;
  height: clamp(2px, 0.35vw, 4px);
  background: var(--green);
  width: 100%;
}

/* Measured: the full-size lockup clears the gutter down to 375px with 18px to
   spare, and overflows below that. Under 375 only, pull in the mark, the
   tracking and the sub size enough to hold one line rather than stacking. */
@media (max-width: 374px) {
  .hero__lockup { gap: 0.7rem; }
  .hero__lockup-mark { width: 48px; }
  .hero__lockup-sub { font-size: 0.88rem; letter-spacing: 0.115em; }
}

.hero__title {
  font-family: var(--face-display);
  font-size: var(--step-5);
  line-height: 1.02;
  letter-spacing: -0.03em;
  max-width: 16ch;
}
.hero__title em {
  font-style: normal;
  color: var(--green);
}
.hero__sub {
  margin-top: var(--gap-md);
  font-size: var(--step-1);
  color: var(--dim);
  max-width: 46ch;
  line-height: 1.5;
}
.hero__actions {
  margin-top: var(--gap-lg);
  display: flex; flex-wrap: wrap; gap: var(--gap-sm);
}

/* The board itself */
.board {
  margin-top: var(--gap-2xl);
  border: 1px solid var(--hairline-firm);
  border-radius: 5px;
  background: linear-gradient(180deg, #101010, #0B0B0B);
  box-shadow: 0 34px 80px -50px rgba(0, 0, 0, 1), inset 0 1px 0 rgba(255,255,255,0.05);
  overflow: hidden;
}

.board__head {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: var(--gap-sm);
  padding: var(--gap-md) var(--gap-lg);
  border-bottom: 1px solid var(--hairline);
  background: #070707;
}

/* The course list button, at the top of the board.

   Its own bar rather than a third item inside .board__head: that head is a
   space-between row holding the placard and the lamp, and adding a third child
   would push the lamp into the middle, moving a status indicator that has read
   at the right edge since the design was set. Same #070707 ground and the same
   padding, so it reads as an extension of the head block rather than a strip
   floating above the table.

   It replaces a quiet footer link that pointed at /technology/ instead of the
   course list. See template-parts/board.php. */
.board__cta {
  padding: var(--gap-md) var(--gap-lg);
  border-bottom: 1px solid var(--hairline);
  background: #070707;
}

/* Sized down from the page-level CTA. This sits inside a component, beside a
   status lamp, and at full .btn scale it competes with the board itself. */
.board__cta .btn {
  padding: 0.7rem 1.4rem;
  font-size: var(--step--1);
}

/* The board is wider than a phone. It scrolls inside its own rail rather than
   being clipped by the panel's rounded corners. */
.board__scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  scrollbar-color: var(--dimmer) transparent;
}
.board__scroll::-webkit-scrollbar { height: 6px; }
.board__scroll::-webkit-scrollbar-thumb {
  background: var(--dimmer); border-radius: 3px;
}
.board__scroll::-webkit-scrollbar-track { background: transparent; }

.board__table { width: 100%; min-width: 30rem; border-collapse: collapse; }

.board__table th {
  text-align: left;
  padding: var(--gap-sm) var(--gap-lg);
  border-bottom: 1px solid var(--hairline);
  font-family: var(--face-board);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--dimmer);
  white-space: nowrap;
}
.board__table td {
  /* Gives the flap its hinge. Without a perspective ancestor the rotateX below
     renders as a flat vertical squash instead of a card falling forward. */
  perspective: 620px;
  padding: var(--gap-sm) var(--gap-lg);
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
  font-family: var(--face-board);
  font-size: clamp(1rem, 0.85rem + 0.7vw, 1.45rem);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
  white-space: nowrap;
}
.board__table tr:last-child td { border-bottom: 0; }
.board__table tbody tr { transition: background-color 0.16s ease; }
.board__table tbody tr:hover { background: rgba(144, 176, 64, 0.05); }

.board__time { color: var(--white); }
.board__dest { color: var(--white); }
.board__region { color: var(--dimmer); font-size: 0.72em; letter-spacing: 0.14em; }
.board__status { color: var(--green); letter-spacing: 0.16em; font-weight: 700; }
.board__status--hold { color: var(--dim); }

.board__foot {
  padding: var(--gap-md) var(--gap-lg);
  border-top: 1px solid var(--hairline);
  background: #070707;
  display: flex; flex-wrap: wrap; gap: var(--gap-sm) var(--gap-lg);
  align-items: center; justify-content: space-between;
}

@media (max-width: 720px) {
  .board__col-region { display: none; }
  .board__table th, .board__table td { padding-inline: var(--gap-md); }
}

/* --------------------------------------------------------------------------
   9. Split panels & lists (no card grids)
   -------------------------------------------------------------------------- */

.split {
  display: grid;
  gap: var(--gap-xl);
  grid-template-columns: 1fr;
  align-items: start;
}
@media (min-width: 900px) {
  .split { grid-template-columns: 1.05fr 0.95fr; gap: var(--gap-2xl); }
  .split--wide-left { grid-template-columns: 1.35fr 0.65fr; }
}

/* Manifest: a ruled list, the board's other native structure */
.manifest { border-top: 1px solid var(--hairline); }
.manifest__row {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--gap-md) var(--gap-lg);
  padding-block: var(--gap-lg);
  border-bottom: 1px solid var(--hairline);
}
@media (min-width: 700px) {
  .manifest__row { grid-template-columns: 8.5rem 1fr; }
}
.manifest__key {
  font-family: var(--face-board);
  font-size: var(--step--1);
  font-weight: 600; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--green);
  padding-top: 0.35rem;
  font-variant-numeric: tabular-nums;
}
.manifest__title {
  font-family: var(--face-board);
  font-size: var(--step-2);
  font-weight: 600;
  letter-spacing: 0.01em;
  line-height: 1.15;
}
.manifest__body { margin-top: var(--gap-xs); color: var(--dim); }
.manifest__body a { color: var(--green); text-underline-offset: 3px; }
.section--paper .manifest { border-color: var(--paper-rule); }
.section--paper .manifest__row { border-color: var(--paper-rule); }
.section--paper .manifest__key { color: var(--green-deep); }
.section--paper .manifest__body { color: #3A3A3A; }

/* Spec strip — data the product actually outputs */
.specs {
  display: grid; gap: 1px;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  background: var(--hairline);
  border: 1px solid var(--hairline);
  border-radius: 4px;
  overflow: hidden;
}

/* THE DEFECT: the price grid sat centered under a left-aligned section title.

   Not a rule in this stylesheet — WordPress's "constrained" group layout caps
   any child that is not explicitly aligned at the theme's content-size and
   centers it with auto margins. Measured on /coaching/ before this rule: the
   section title spanned 1144px from x=61, while .specs was squeezed to 729px
   starting at x=268. Two elements in the same section, on two different left
   edges, which reads as a misplaced box rather than a deliberate inset.

   The grid is a full-width comparison table; it is not body copy, so the
   content-size cap is the wrong constraint for it. Overriding here rather than
   changing the group's layout means the surrounding prose keeps its measure.

   Affects /coaching/ and /corporate/, the only two pages using .specs. */
.section .specs {
  max-width: none;
  margin-inline: 0;
}

/* The "See packages" button targets this grid. Without a scroll margin the
   jump lands the grid flush against the masthead and pushes its own
   "Lesson packages" heading off the top of the viewport, so the reader arrives
   at a wall of prices with no title. */
.specs[id] { scroll-margin-top: 8rem; }
.specs__cell { background: var(--ink-raised); padding: var(--gap-lg) var(--gap-md); }
.specs__value {
  font-family: var(--face-board);
  font-size: var(--step-3);
  font-weight: 600;
  color: var(--green);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.specs__label {
  margin-top: var(--gap-xs);
  font-family: var(--face-board);
  font-size: var(--step--1);
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--dim);
}

/* --------------------------------------------------------------------------
   10. Placeholder + empty states (honesty guards)
   -------------------------------------------------------------------------- */

.tbc {
  display: inline-block;
  padding: 0.15em 0.5em;
  background: var(--green-veil);
  border: 1px dashed var(--green);
  border-radius: 3px;
  font-family: var(--face-board);
  font-size: 0.82em;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--green);
}
.section--paper .tbc { color: var(--green-deep); border-color: var(--green-deep); }

.empty {
  border: 1px dashed var(--hairline-firm);
  border-radius: 4px;
  padding: var(--gap-xl) var(--gap-lg);
  text-align: center;
  background: rgba(255, 255, 255, 0.015);
}
.empty__title {
  font-family: var(--face-board);
  font-size: var(--step-1);
  font-weight: 600; letter-spacing: 0.06em;
}
.empty__body { margin: var(--gap-sm) auto 0; color: var(--dim); max-width: 52ch; }


/* Reviews ---------------------------------------------------------------- */
.revs {
  display: grid;
  gap: var(--gap-md);
  margin-top: var(--gap-lg);
  grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
  align-items: start;
}
.rev {
  margin: 0;
  padding: var(--gap-md);
  border: 1px solid var(--hairline);
  border-top: 2px solid var(--green);
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.015);
}
.rev__stars { color: var(--green); letter-spacing: 0.14em; font-size: var(--step--1); }
.rev__text {
  margin: var(--gap-sm) 0 0;
  color: var(--read);
  quotes: none;
}
.rev__by {
  display: flex; flex-direction: column; gap: 2px;
  margin-top: var(--gap-md);
  padding-top: var(--gap-sm);
  border-top: 1px solid var(--hairline);
}
.rev__name {
  font-family: var(--face-board);
  font-weight: 600; letter-spacing: 0.06em;
  font-size: var(--step--1);
}
.rev__meta { color: var(--dim); font-size: var(--step--1); }
.revs__src { margin-top: var(--gap-lg); max-width: 68ch; color: var(--dim); font-size: var(--step--1); }
.revs__src a { color: var(--green); text-underline-offset: 3px; }


/* Directory / site search ------------------------------------------------ */
.dir__field { position: relative; margin-top: var(--gap-lg); max-width: 44rem; }
.dir__icon {
  position: absolute; left: 1.05rem; top: 50%; transform: translateY(-50%);
  width: 1.15em; height: 1.15em; color: var(--dim); pointer-events: none;
  fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
.dir__input {
  width: 100%; padding: 1rem 1.15rem 1rem 3.1rem;
  background: var(--ink-raised); color: #fff;
  border: 1px solid var(--hairline-firm); border-radius: 3px;
  font-family: var(--face-text); font-size: var(--step-0); line-height: 1.4;
  transition: border-color 0.16s ease;
}
.dir__input::placeholder { color: var(--dim); opacity: 1; }
.dir__input:hover { border-color: rgba(255, 255, 255, 0.26); }
.dir__input:focus { border-color: var(--green); }
.dir__input::-webkit-search-cancel-button { filter: grayscale(1) opacity(0.6); }
.dir__field:focus-within .dir__icon { color: var(--green); }

.dir__count {
  margin-top: var(--gap-sm);
  font-family: var(--face-board); font-size: var(--step--1); font-weight: 600;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--dimmer);
  font-variant-numeric: tabular-nums;
}

.dir__list {
  list-style: none; margin: var(--gap-md) 0 0; padding: 0;
  border-top: 1px solid var(--hairline);
}
.dir__row { border-bottom: 1px solid var(--hairline); }
.dir__row[hidden] { display: none; }
.dir--idle .dir__list, .dir--idle .dir__none { display: none; }

.dir__link {
  display: grid; gap: 0.15rem 1.5rem; padding: 1.05rem 0;
  text-decoration: none; align-items: baseline;
}
.dir__link:hover .dir__name { color: var(--green); }
.dir__key {
  font-family: var(--face-board); font-size: var(--step--1); font-weight: 600;
  letter-spacing: 0.18em; text-transform: uppercase; color: var(--green);
}
.dir__name {
  font-family: var(--face-board); font-size: var(--step-1); font-weight: 600;
  color: #fff; transition: color 0.16s ease;
}
.dir__blurb { color: var(--dim); grid-column: 1 / -1; }
.dir__none { margin-top: var(--gap-md); color: var(--dim); }
.dir__none a { color: var(--green); text-underline-offset: 3px; }

@media (min-width: 700px) {
  .dir__link { grid-template-columns: 8.5rem 1fr; }
  .dir__blurb { grid-column: 2; }
}

/* --------------------------------------------------------------------------
   11. Footer
   -------------------------------------------------------------------------- */

.footer { border-top: 1px solid var(--hairline); background: #060606; }
.footer__grid {
  display: grid; gap: var(--gap-xl);
  grid-template-columns: 1fr;
  padding-block: var(--gap-2xl) var(--gap-lg);
}
@media (min-width: 800px) {
  .footer__grid { grid-template-columns: 1.4fr 1fr 1fr 1fr; }
}
.footer__title {
  font-family: var(--face-board);
  font-size: var(--step--1);
  font-weight: 700; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--dimmer);
  margin-bottom: var(--gap-md);
}
.footer__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.15rem; }
.footer__list a {
  display: inline-flex; align-items: center;
  min-height: 44px;
  color: var(--white); text-decoration: none;
}
.footer__list a:hover { color: var(--green); }
.footer__legal {
  border-top: 1px solid var(--hairline);
  padding-block: var(--gap-md);
  display: flex; flex-wrap: wrap; gap: var(--gap-sm) var(--gap-lg);
  justify-content: space-between;
  color: var(--dimmer);
  font-size: var(--step--1);
}

/* --------------------------------------------------------------------------
   12. Icons — authored SVG, one stroke weight
   -------------------------------------------------------------------------- */

.icon {
  width: 1.1em; height: 1.1em;
  flex: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  fill: none;
  vertical-align: -0.16em;
}
.icon--yes { color: var(--green); }
.icon--no  { color: var(--dimmer); }

/* --------------------------------------------------------------------------
   13. Tier board — memberships as access levels
   -------------------------------------------------------------------------- */

.tiers {
  border: 1px solid var(--hairline-firm);
  border-radius: 5px;
  overflow: hidden;
  background: linear-gradient(180deg, #101010, #0B0B0B);
  box-shadow: 0 34px 80px -50px rgba(0, 0, 0, 1);
}

.tier {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--gap-sm) var(--gap-lg);
  padding: var(--gap-lg);
  border-bottom: 1px solid var(--hairline);
  position: relative;
}
.tier:last-child { border-bottom: 0; }
@media (min-width: 820px) {
  .tier { grid-template-columns: 10rem 1fr 12rem; align-items: center; }
}

.tier__name {
  font-family: var(--face-board);
  font-size: var(--step-2);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  line-height: 1;
}
.tier__price {
  font-family: var(--face-board);
  font-size: var(--step-1);
  font-weight: 500;
  color: var(--green);
  font-variant-numeric: tabular-nums;
  margin-top: 0.35rem;
}
.tier__price small {
  font-size: 0.6em; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--dim);
}
.tier__list {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: 0.5rem;
  font-size: var(--step--1);
  color: var(--dim);
}
.tier__list li { display: flex; align-items: flex-start; gap: 0.55rem; }
.tier__list li span { flex: 1; }

.tier--flagged { background: var(--green-veil); }
.tier--flagged .tier__name { color: var(--green); }

.tier__flag {
  display: inline-flex; align-items: center;
  align-self: start;
  padding: 0.3rem 0.7rem;
  margin-bottom: 0.5rem;
  background: var(--green);
  color: #111111;
  font-family: var(--face-board);
  font-size: var(--step--1); font-weight: 700;
  letter-spacing: 0.16em; text-transform: uppercase;
  border-radius: 2px;
}

/* --------------------------------------------------------------------------
   14. Course library — filterable destinations
   -------------------------------------------------------------------------- */

.filters {
  display: flex; flex-wrap: wrap; gap: var(--gap-xs);
  margin-bottom: var(--gap-lg);
}
.filter {
  padding: 0.5rem 1rem;
  background: transparent;
  border: 1px solid var(--hairline-firm);
  border-radius: 3px;
  color: var(--dim);
  font-family: var(--face-board);
  font-size: var(--step--1);
  font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase;
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease, background-color 0.15s ease;
}
.filter:hover { color: var(--white); border-color: var(--hairline-firm); }
.filter[aria-pressed="true"] {
  background: var(--green); color: #111111; border-color: var(--green);
}

.courses {
  border-top: 1px solid var(--hairline);
  display: grid; grid-template-columns: 1fr;
}
@media (min-width: 760px) { .courses { grid-template-columns: 1fr 1fr; column-gap: var(--gap-2xl); } }

.course {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--gap-md);
  padding-block: var(--gap-sm);
  border-bottom: 1px solid var(--hairline);
  font-family: var(--face-board);
  letter-spacing: 0.04em;
}
.course__name { font-size: var(--step-0); font-weight: 500; }
.course__region {
  font-size: var(--step--1); color: var(--dimmer);
  letter-spacing: 0.16em; text-transform: uppercase; white-space: nowrap;
}
.course[hidden] { display: none; }

.courses__count {
  margin-top: var(--gap-md);
  font-family: var(--face-board);
  font-size: var(--step--1);
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--dim);
}

/* --------------------------------------------------------------------------
   15. FAQ — golfer-facing, question format for answer engines
   -------------------------------------------------------------------------- */

.faq { border-top: 1px solid var(--hairline); }
.faq__item { border-bottom: 1px solid var(--hairline); padding-block: var(--gap-lg); }
.faq__q {
  font-family: var(--face-board);
  font-size: var(--step-1);
  font-weight: 600;
  letter-spacing: 0.02em;
  line-height: 1.25;
}
.faq__a { margin-top: var(--gap-sm); color: var(--dim); }
.section--paper .faq { border-color: var(--paper-rule); }
.section--paper .faq__item { border-color: var(--paper-rule); }
.section--paper .faq__a { color: #3A3A3A; }

/* --------------------------------------------------------------------------
   16. Form — labels visible, errors near the field, helper text persistent
   -------------------------------------------------------------------------- */

.form { max-width: 34rem; display: grid; gap: var(--gap-md); }

.field { display: grid; gap: 0.4rem; }

.field__label {
  font-family: var(--face-board);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--dim);
}

.field__input {
  width: 100%;
  min-height: 48px;
  padding: 0.75rem 0.9rem;
  background: var(--ink-raised);
  border: 1px solid var(--hairline-firm);
  border-radius: 3px;
  color: var(--white);
  font-family: var(--face-text);
  font-size: var(--step-0);
  line-height: 1.5;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}
.field__input::placeholder { color: var(--dimmer); }
.field__input:hover { border-color: var(--dim); }
.field__input:focus-visible { border-color: var(--green); background: #171717; }

textarea.field__input { resize: vertical; min-height: 8rem; }

select.field__input {
  appearance: none;
  /* Chevron drawn in the world's own stroke weight, not a system glyph. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239BA48C' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.85rem center;
  background-size: 1.1rem;
  padding-right: 2.6rem;
}

.field__help {
  font-size: var(--step--1);
  color: var(--dim);
  max-width: 46ch;
}

.field__input:user-invalid { border-color: var(--alert); }
.field__input:user-invalid + .field__help { color: var(--alert-text); }

/* --------------------------------------------------------------------------
   17. Article — long-form reading. Mode is Read: comprehension first.
   -------------------------------------------------------------------------- */

.article { max-width: 44rem; margin-inline: auto; }

.article__meta {
  display: flex; flex-wrap: wrap; gap: var(--gap-sm) var(--gap-lg);
  padding-block: var(--gap-md);
  border-top: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
  margin-bottom: var(--gap-xl);
  font-family: var(--face-board);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--dim);
}

.prose { font-size: var(--step-0); line-height: 1.75; }
.prose > * + * { margin-top: var(--gap-md); }

.prose p { max-width: 68ch; color: var(--read); }

.prose h2 {
  margin-top: var(--gap-xl);
  font-family: var(--face-board);
  font-size: var(--step-2);
  font-weight: 600;
  letter-spacing: 0.01em;
  line-height: 1.2;
  color: var(--white);
}
.prose h3 {
  margin-top: var(--gap-lg);
  font-family: var(--face-board);
  font-size: var(--step-1);
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--white);
}

.prose ul, .prose ol { max-width: 66ch; padding-left: 1.25rem; color: var(--read); }
.prose li + li { margin-top: 0.5rem; }
.prose li::marker { color: var(--green); }

.prose a { color: var(--green); text-underline-offset: 3px; }
.prose a:hover { color: var(--green-lift); }

.prose strong { color: var(--white); font-weight: 600; }

/* Pull-quote: the one place an article raises its voice. */
.prose blockquote {
  margin-block: var(--gap-xl);
  padding-left: clamp(1rem, 3vw, 2rem);
  border-left: 1px solid var(--green);
  font-family: var(--face-board);
  font-size: var(--step-2);
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: 0.01em;
  color: var(--white);
}
.prose blockquote p { max-width: 34ch; color: inherit; }

/* Inline data table inside an article */
.prose table {
  width: 100%; border-collapse: collapse;
  font-family: var(--face-board);
  font-variant-numeric: tabular-nums;
}
.prose th, .prose td {
  text-align: left;
  padding: var(--gap-sm) var(--gap-md);
  border-bottom: 1px solid var(--hairline);
}
.prose th {
  font-size: var(--step--1); font-weight: 600;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--dimmer);
}
.prose td { color: var(--read); }
.prose tbody tr:last-child td { border-bottom: 0; }

/* Article index rows */
.posts { border-top: 1px solid var(--hairline); }
.post {
  display: grid; gap: var(--gap-xs);
  padding-block: var(--gap-lg);
  border-bottom: 1px solid var(--hairline);
}
.post__title {
  font-family: var(--face-board);
  font-size: var(--step-2);
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: 0.01em;
}
.post__title a { text-decoration: none; }
.post__title a:hover { color: var(--green); }
.post__dek { color: var(--dim); max-width: 66ch; }
.post__tag {
  font-family: var(--face-board);
  font-size: var(--step--1);
  font-weight: 600; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--green);
}

/* Sticky mobile book bar */
.bookbar {
  position: fixed; inset-inline: 0; bottom: 0; z-index: 120;
  padding: 0.7rem var(--rail) calc(0.7rem + env(safe-area-inset-bottom, 0px));
  background: rgba(6, 6, 6, 0.95);
  backdrop-filter: blur(12px);
  border-top: 1px solid var(--hairline-firm);
  display: none;
}
@media (max-width: 900px) {
  .bookbar { display: block; }
  /* Scoped to .has-bookbar: the bar is suppressed on /book/ and on the
     protected slugs, and reserving space for a bar that is not there is what
     left 5.2rem of dead air at the foot of every phone page while the markup
     was missing entirely. */
  body.has-bookbar { padding-bottom: 5.2rem; }
}


/* Photography ------------------------------------------------------------ */
/* Supplied at 1179px native, so no rendition is ever larger than the source
   and no plate is asked to fill a full-bleed band. */
.plates {
  display: grid;
  gap: var(--gap-md);
  margin-top: var(--gap-lg);
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
}
.plate { margin: 0; min-width: 0; }
.plate__frame {
  display: block;
  border: 1px solid var(--hairline);
  border-radius: 3px;
  background: var(--ink-flap);
  overflow: hidden;
}
.plate img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 2;
  object-fit: cover;
}
.plate__cap {
  margin-top: 0.6rem;
  font-family: var(--face-board);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--dimmer);
}
/* One photograph carrying a point on its own. */
.plates--solo { grid-template-columns: 1fr; max-width: 60rem; }
.plates--solo .plate img { aspect-ratio: 16 / 9; }
/* Two side by side, and they stay side by side until the screen is genuinely narrow. */
.plates--pair { grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr)); }

.section--paper .plate__frame { border-color: var(--paper-rule); background: #E4E4E4; }
.section--paper .plate__cap { color: #4A4A4A; }

@media (max-width: 30rem) {
  .plates { gap: var(--gap-sm); }
  .plate__cap { letter-spacing: 0.14em; }
}


/* Touch targets ---------------------------------------------------------- */
/* .wordmark, .nav a and .footer__list a already carry the 44px floor. The
   course filters were missed and measured 39px on a 375px viewport. Height
   only, so the visual weight of the control is unchanged. */
@media (pointer: coarse) {
  .filter { min-height: 44px; }
}


/* Mobile navigation ------------------------------------------------------ */
/* Below 900px .nav--main is display:none. This is what replaces it: a
   disclosure panel, not a drawer - the board does not slide. */
.navtoggle { display: none; }
.navpanel[hidden] { display: none; }

@media (min-width: 901px) {
  .navpanel { display: none; }
}

@media (max-width: 900px) {
  .navtoggle {
    display: inline-flex; align-items: center; gap: 0.55rem;
    flex: 0 0 auto;
    min-height: 44px; padding: 0 0.85rem;
    background: transparent;
    border: 1px solid var(--hairline-firm);
    border-radius: 3px;
    color: var(--dim);
    font-family: var(--face-board);
    font-size: var(--step--1); font-weight: 600;
    letter-spacing: 0.14em; text-transform: uppercase;
    cursor: pointer;
    transition: color 0.15s ease, border-color 0.15s ease;
  }
  .navtoggle:hover,
  .navtoggle[aria-expanded="true"] { color: var(--white); border-color: var(--hairline-firm); }
  .navtoggle:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; }

  .navtoggle__bars { position: relative; display: block; width: 15px; height: 2px; background: currentColor; }
  .navtoggle__bars::before,
  .navtoggle__bars::after { content: ''; position: absolute; left: 0; width: 15px; height: 2px; background: currentColor; }
  .navtoggle__bars::before { top: -5px; }
  .navtoggle__bars::after  { top: 5px; }

  .navpanel {
    border-top: 1px solid var(--hairline);
    background: var(--ink-raised);
  }
  .navpanel__nav { display: grid; }
  .navpanel__nav a {
    display: flex; align-items: center;
    min-height: 48px;
    border-bottom: 1px solid var(--hairline);
    color: var(--read); text-decoration: none;
    font-family: var(--face-board);
    font-size: var(--step-0); font-weight: 600;
    letter-spacing: 0.12em; text-transform: uppercase;
  }
  .navpanel__nav a:hover { color: var(--white); }
  .navpanel__nav a[aria-current="page"] { color: var(--green); }
  .navpanel .btn { margin: var(--gap-md) 0 var(--gap-lg); }
}

/* --------------------------------------------------------------------------
   18. Journal index — the posts archive

   template-parts/card-post.php has existed since the theme was written and had
   no styling, because there was no posts archive to render it in. Adding
   home.php gave it one.

   Deliberately NOT a card grid. Section 9 is titled "no card grids" and means
   it: this is a board of departures, so the index is a list with hairlines and
   a tabular date column, not tiles. It also degrades honestly — 55 entries in a
   grid is a wall; 55 entries in a list is an index.
   -------------------------------------------------------------------------- */

.cards {
  margin-top: var(--gap-lg);
  border-top: 1px solid var(--hairline);
}

.card { margin: 0; }

.card__link {
  display: grid;
  gap: 0.35rem var(--gap-lg);
  grid-template-columns: 1fr;
  padding-block: var(--gap-lg);
  border-bottom: 1px solid var(--hairline);
  text-decoration: none;
  color: inherit;
  transition: background-color 0.16s ease;
}
@media (min-width: 760px) {
  .card__link {
    grid-template-columns: 1fr 12ch;
    align-items: baseline;
  }
  .card__date { text-align: right; }
}

.card__link:hover,
.card__link:focus-visible {
  background: var(--green-veil);
}

.card__title {
  grid-column: 1;
  font-family: var(--face-board);
  font-size: var(--step-1);
  font-weight: 600;
  line-height: 1.2;
  color: var(--white);
}
.card__link:hover .card__title { color: var(--green); }

.card__blurb {
  grid-column: 1;
  margin: 0;
  max-width: 64ch;
  color: var(--dim);
  font-size: var(--step-0);
  line-height: 1.55;
}

.card__date {
  font-family: var(--face-board);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dimmer);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
@media (min-width: 760px) {
  .card__date { grid-column: 2; grid-row: 1 / span 2; }
}

/* Any featured image stays out of the way of the list rhythm. */
.card__media { grid-column: 1; margin-bottom: var(--gap-xs); }
.card__media img { border-radius: 3px; }

/* Pagination ------------------------------------------------------------- */

.navigation.pagination { margin-top: var(--gap-xl); }
.navigation.pagination .nav-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap-xs);
  align-items: center;
}
.navigation.pagination .page-numbers {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  padding-inline: 0.6rem;
  border: 1px solid var(--hairline-firm);
  border-radius: 2px;
  font-family: var(--face-board);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--read);
}
.navigation.pagination .page-numbers:hover { border-color: var(--green); color: var(--green); }
.navigation.pagination .page-numbers.current {
  background: var(--green);
  border-color: var(--green);
  color: #111111;
}
.navigation.pagination .page-numbers.dots { border-color: transparent; color: var(--dimmer); }

/* The closing copy from the posts page, printed under the list. */
.page__outro { margin-top: var(--gap-2xl); }


/* --------------------------------------------------------------------------
   19. Contact routes, and rescuing the contact form

   THE FORM WAS INVISIBLE ON THE LIVE SITE.
   Measured 2026-08-17: the SureForms fields rendered with color #FFFFFF and
   border #FFFFFF, transparent background, inside a container SureForms paints
   #FFFFFF. White text, white borders, white ground. Five real fields and a
   submit button, none of them possible to see.

   Cause: no SureForms stylesheet was loaded on the page at all —
   document.styleSheets contained none. page-contact.php renders the form by
   calling do_shortcode() during template output, which is long after
   wp_enqueue_scripts has run, so the plugin never got the chance to enqueue its
   CSS. The fields then inherited the theme's white body color onto the
   plugin's inline white container.

   Rather than fight the plugin's enqueue timing, the theme styles the form
   itself. That holds whether or not SureForms' CSS ever loads, and it makes the
   form match the board instead of being a white slab in the middle of it.

   Worth recording why this survived a check: this form was "verified" earlier by
   counting inputs. Nine inputs were present, so it passed. Counting elements
   proves markup exists. It does not prove a person can see them.
   -------------------------------------------------------------------------- */

/* Ryan asked for the contact values 10% larger than body copy. */
.contact__value {
  font-size: 1.1em;
  line-height: 1.6;
  color: var(--read);
}
.contact__value a { color: var(--green); text-underline-offset: 3px; }
.contact__value a:hover { color: var(--green-lift); }

/* The icons sit inside .manifest__key, which is green, and .icon strokes with
   currentColor — so they are visible without being colored separately. The old
   Spectra icons were filled black on a black ground. */
.manifest__key .icon { margin-right: 0.45rem; }

/* --- SureForms, restyled to the board ----------------------------------- */

.srfm-form-container,
.srfm-form-container.srfm-bg-color {
  background: var(--ink-raised) !important;
  color: var(--read) !important;
  border: 1px solid var(--hairline);
  border-radius: 3px;
  padding: var(--gap-xl) var(--gap-lg);
  margin-top: var(--gap-2xl);
}

.srfm-form-container input[type="text"],
.srfm-form-container input[type="email"],
.srfm-form-container input[type="tel"],
.srfm-form-container input[type="number"],
.srfm-form-container input[type="url"],
.srfm-form-container select,
.srfm-form-container textarea {
  width: 100%;
  background: var(--ink) !important;
  color: var(--white) !important;
  border: 1px solid var(--hairline-firm) !important;
  border-radius: 2px;
  padding: 0.7rem 0.85rem;
  font-family: var(--face-text);
  font-size: var(--step-0);
  min-height: 44px;
}

/* The fields are placeholder-only — there are no labels in the markup — so the
   placeholder is the entire label. It has to be readable, not decorative. */
.srfm-form-container ::placeholder {
  color: var(--dim) !important;
  opacity: 1;
}

.srfm-form-container input:focus,
.srfm-form-container textarea:focus,
.srfm-form-container select:focus {
  outline: 3px solid var(--green);
  outline-offset: 2px;
  border-color: var(--green) !important;
}

.srfm-form-container textarea { min-height: 8rem; resize: vertical; }

.srfm-form-container button,
.srfm-form-container [type="submit"] {
  background: var(--green) !important;
  /* Never white text on the brand green — DESIGN.md, and it measures ~2.5:1. */
  color: #111111 !important;
  border: 0;
  border-radius: 2px;
  padding: 0.85rem 1.6rem;
  min-height: 44px;
  font-family: var(--face-board);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
}
.srfm-form-container button:hover,
.srfm-form-container [type="submit"]:hover { background: var(--green-lift) !important; }

/* Errors need the one documented alert hue, not brand green. */
.srfm-form-container .srfm-error,
.srfm-form-container .srfm-error-message { color: var(--alert-text) !important; }


/* --------------------------------------------------------------------------
   20. Coaches, and the lesson-package catalog

   The two coach portraits were 296x300 and 225x300 sources squashed into the
   same box, so they read as different sizes and different crops. They are now
   1:1 renditions cut from the 1179px facility masters, both 760x760, both real
   photographs of instruction in a bay rather than headshots.

   AMELIA IS THE REVENUE LAYER. Everything below touches color only — no
   layout, no positioning, no display, nothing interactive. Amelia's own markup,
   classes, scripts and behavior are untouched. The catalog rendered as a
   white slab on a black page; this puts it on the board without altering how it
   works. Re-verify the purchase flow after any change here.
   -------------------------------------------------------------------------- */

.pros {
  display: grid;
  gap: var(--gap-xl);
  grid-template-columns: 1fr;
  margin-top: var(--gap-lg);
}
@media (min-width: 60rem) {
  .pros { grid-template-columns: 1fr 1fr; gap: var(--gap-2xl); }
}

.pro__frame {
  border: 1px solid var(--hairline);
  border-radius: 3px;
  overflow: hidden;
  background: var(--ink-flap);
  max-width: 22rem;
}
.pro__frame img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;   /* both portraits identical, whatever the source */
  object-fit: cover;
}

.pro__name {
  margin-top: var(--gap-md);
  font-family: var(--face-board);
  font-size: var(--step-2);
  line-height: 1.15;
}
.pro__role {
  margin-top: var(--gap-xs);
  font-family: var(--face-board);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--green);
}
.pro__bio { margin-top: var(--gap-md); }
.pro__bio p { color: var(--read); line-height: 1.7; }

/* Ryan asked for this heading 30% larger. It was a Spectra h3 at 21px; as a
   standard .section__title it is already ~44px, more than double, and in scale
   with every other section heading on the site. Multiplying that by a further
   1.3 made it 57.6px — the largest type anywhere on 24PG, including the home
   hero, which is the wrong kind of bigger. Standard section size, with the
   clearance he asked for above the catalog. */
.packages__title { margin-bottom: var(--gap-xl); }

/* --------------------------------------------------------------------------
   Member portal — findability and the passwordless explanation

   THE SUPPORT CALL THIS ANSWERS
   Members rang Eric asking how to get into their membership portal. Two causes,
   both measured rather than guessed:

   1. On the old site "My Profile" was item 7 in the primary nav, a plain link
      next to Home and Memberships. The rebuild dropped it from the menu and
      left only the theme's own header button. On a phone with the menu closed
      that button measured 0x0 — it does not render at all — so the sole
      reachable link was in the footer, 8,052px down the page.

   2. There is no password anywhere in this system. 381 Amelia customers exist
      and NOT ONE is attached to a WordPress login, so the only way in is the
      emailed access link. A member hunting for a password field finds a lone
      email box and reasonably concludes the login is broken.

   "My Profile" is now back in the primary nav menu, which puts it in the mobile
   panel alongside every other destination. The standalone account button is
   therefore redundant, and two identical "My profile" links 200px apart in one
   header reads as a bug — so it is hidden here rather than removed from
   template-helpers.php, which keeps pg24_account_link() intact for the
   'account' menu location it was designed around. */
.btn--account { display: none; }

/* The explanation above the sign-in box. Measure kept short: it is instructions
   to act on, not prose to settle into. */
.portal__intro {
  max-width: 60ch;
  margin-bottom: var(--gap-xl);
  padding: var(--gap-md) var(--gap-lg);
  border-left: 3px solid var(--green);
  background: var(--ink-raised);
  color: var(--read);
}
.portal__intro strong { color: var(--white); }

/* The members' signpost on /book/. The catalog there is the pay-per-use
   menu; a member's included time is booked from the Customer Panel instead,
   and until this line existed nothing on the page said so — which is what
   sent members to Eric asking why they were being charged $50. */
.member-note {
  max-width: 60ch;
  margin-bottom: var(--gap-xl);
  padding: var(--gap-md) var(--gap-lg);
  border-left: 3px solid var(--green);
  background: var(--ink-raised);
  color: var(--read);
}
.member-note strong { color: var(--white); }
.member-note a { color: var(--green-lift); }

/* The four-step how-to on the member portal.

   Members could not find the booking path even once it existed, because it
   lives three levels inside Amelia's panel. Rather than keep redesigning
   someone else's UI, the page now just tells them the route in plain steps,
   using the exact words that appear on the controls — Memberships, Account,
   Book a Bay, Book Now — so the instruction and the screen agree. */
.portal__steps {
  max-width: 60ch;
  margin-bottom: var(--gap-xl);
  padding: var(--gap-md) var(--gap-lg);
  border: 1px solid var(--hairline);
  border-left: 3px solid var(--green);
  border-radius: 3px;
  background: var(--ink-raised);
}
.portal__steps-title {
  margin: 0 0 var(--gap-sm);
  font-family: var(--face-board);
  font-size: var(--step-0);
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--white);
}
.portal__steps-list {
  margin: 0;
  padding-left: 1.35rem;
  color: var(--read);
}
.portal__steps-list li { margin-bottom: 0.45rem; line-height: 1.55; }
.portal__steps-list li:last-child { margin-bottom: 0; }
.portal__steps-list strong { color: var(--white); }
.portal__steps-foot {
  margin: var(--gap-sm) 0 0;
  color: var(--dim);
  font-size: var(--step--1);
}

/* --- Amelia catalog: color only ----------------------------------------

   THE DEFECT THIS FIXES, AND HOW IT SURVIVED A PREVIOUS PASS

   Amelia ships its own palette and applies it inline-ish through its own
   classes: #1a2c37 for text on what it assumes is a light page. This site is
   near-black (#0A0A0A), so the booking catalog rendered dark-on-dark.
   Measured on /book/ 2026-08-17, before this block:

       .am-fcil__item-name   #1a2c37 on #0a0a0a   1.38:1
       .am-fcil__heading     #33434c on #0a0a0a   1.93:1
       .am-fcil__item-price  #1d7f25 on #0a0a0a   3.88:1

   WCAG asks 4.5:1 for body text. 1.38:1 is not "hard to read", it is invisible
   — the four bookable services were black text on a black panel.

   The previous version of this block already claimed to fix it, and did
   nothing, because it was written against GUESSED class names:

       .am-cat__wrapper :is(h1, h2, h3, h4, h5, .am-fcil__item-title)

   Amelia emits no .am-fcil__item-title and no headings at all here. The
   selector matched zero elements. CSS fails silently — no error, no warning,
   the stylesheet loads fine — so the fix looked shipped and the page stayed
   unreadable. The class names below were read off the live DOM, not guessed.

   Color only. No layout, no spacing, no behavior: Amelia is the revenue path
   and the door, and its markup is not ours to restructure. */

.am-cat__wrapper,
.am-cat__wrapper.am-fcil,
.am-fcil__item-inner {
  background: transparent !important;
  box-shadow: none !important;
}
.am-fcil__item-inner {
  border: 1px solid var(--hairline) !important;
  border-radius: 3px;
}

/* Catch-all first: anything Amelia renders in its dark ink gets the reading
   color. Specific rules below lift the parts that carry more weight. This
   ordering means a class we have not seen yet still comes out legible rather
   than invisible. */
.am-cat__wrapper,
.am-cat__wrapper :is(p, span, div, li) { color: var(--read) !important; }

/* The section heading and the service names — the two things a customer scans
   to decide what to book. */
.am-cat__wrapper :is(h1, h2, h3, h4, h5),
.am-fcil__heading,
.am-cat__wrapper .am-fcil__item-name {
  color: var(--white) !important;
}

/* Price. Amelia's own green (#1d7f25) is a different green from the brand and
   measures 3.88:1 here. --green-lift is the brand green raised for dark
   ground. The pill behind it is Amelia's, tinted from its own variable, so it
   is neutralised rather than re-tinted. */
.am-cat__wrapper .am-fcil__item-price {
  color: var(--green-lift) !important;
  background: var(--green-veil) !important;
}

/* Duration and the small print under it, set at 80% opacity by Amelia. */
.am-cat__wrapper :is(.am-fcil__item-info, .am-fcil__item-info__inner, .am-micro),
.am-cat__wrapper :is(.am-fcil__item-info, .am-fcil__item-info__inner) * {
  color: var(--read) !important;
  opacity: 1 !important;
}

/* Icons inherit Amelia's ink too. */
.am-cat__wrapper [class^="am-icon-"],
.am-cat__wrapper [class*=" am-icon-"] { color: var(--green-lift) !important; }

/* The filter control above the list. */
.am-cat__wrapper .am-button--secondary,
.am-cat__wrapper .am-button--plain {
  color: var(--read) !important;
  border-color: var(--hairline-firm) !important;
}

/* --- Amelia buttons: the catch-all must not reach their labels -------------

   THE DEFECT THIS FIXES, WHICH THIS STYLESHEET CAUSED

   The catch-all above sets every span inside .am-cat__wrapper to --read so that
   an unseen Amelia class cannot come out invisible on the near-black page. It
   was written to PREVENT unreadable text and it produced exactly that, because
   Amelia colors each button label against that button's own background, and
   several of those backgrounds are light. Measured on /book/ at 375px:

       "View More Photos"    #D7DACF on #FFFFFF   1.42:1   (white gallery bar)
       "Select Date & Time"  #D7DACF on #1D7F25   3.60:1   (the primary CTA)

   The second is the worse one: it is the button a customer presses to spend
   money, and nobody reported it — it was found by sweeping the flow after Ryan
   reported the first.

   The lesson is the rule's own shape: a defensive !important catch-all cannot
   know what background its target sits on. So button labels now inherit from
   the button, and the buttons are colored explicitly below. */
.am-cat__wrapper .am-button__inner { color: inherit !important; }

/* Primary and filled actions in brand green. Dark label, never white — see the
   palette note on --green. #111 on #90B040 measures 7.62:1. */
.am-cat__wrapper .am-button--primary,
.am-cat__wrapper .am-button--filled {
  background: var(--green) !important;
  border-color: var(--green) !important;
  color: #111111 !important;
}
.am-cat__wrapper .am-button--primary:hover,
.am-cat__wrapper .am-button--filled:hover {
  background: var(--green-lift) !important;
  border-color: var(--green-lift) !important;
}

/* The photo gallery disclosure.

   Ryan: "a white bar ... takes up almost the entire length of the screen on
   mobile and you can barely read the text". Measured 242x40, 65% of a 375px
   viewport, label at 1.42:1. It is a secondary affordance — look at more
   pictures if you feel like it — so it should read as one: a compact control
   with a chevron, not a full-width slab competing with the booking CTA.

   Color and size only. The click still opens Amelia's own gallery, and the
   button keeps its real label for screen readers rather than being replaced by
   a bare glyph. */
.am-cat__wrapper .am-fcis__gallery .am-fcis__gallery-btn {
  display: inline-flex !important;
  align-items: center;
  width: auto !important;
  min-width: 0 !important;
  max-width: 100% !important;
  padding: 0.4rem 0.75rem !important;
  /* 44px floor: the compact restyle brought it to 40px, which is under the
     touch-target minimum this project audits for. Height only — the control
     stays visually small. */
  min-height: 44px !important;
  background: transparent !important;
  border: 1px solid var(--hairline-firm) !important;
  border-radius: 3px !important;
  color: var(--read) !important;
  font-size: var(--step--1) !important;
}
.am-cat__wrapper .am-fcis__gallery .am-fcis__gallery-btn:hover {
  background: var(--ink-flap) !important;
  border-color: var(--green) !important;
  color: var(--white) !important;
}
/* The chevron Ryan asked for, appended to the existing label. */
.am-cat__wrapper .am-fcis__gallery .am-fcis__gallery-btn .am-button__inner::after {
  content: "\25BE";
  margin-inline-start: 0.4rem;
}

/* --- Member portal: the collapsed sidebar toggle --------------------------

   WHAT WAS REPORTED
   "On mobile the member portal doesn't show the appointments/memberships
   sidebar at all."

   WHAT IS ACTUALLY HAPPENING
   Nothing is missing. Amelia collapses its cabinet sidebar on narrow screens —
   the wrapper gains .am-collapsed — and moves the account navigation behind a
   hamburger in the panel header. Tapping it DOES open a menu carrying the
   customer name, Appointments, Memberships and Log out; all four were measured
   rendering at 375px once the control was triggered.

   The control is the defect, not the menu. Amelia ships it as a bare <div>:

       .am-caph__menu    24x42px, cursor:auto, no label, no border

   24px wide is well under the 44px touch minimum, cursor:auto tells a pointer
   user it is not interactive, and there is no text to read. So it reads as
   decoration, and the account navigation reads as absent.

   WHY NOT SIMPLY FORCE THE SIDEBAR OPEN
   The panel is 338px wide inside the page rail on a 375px phone. Amelia
   collapses precisely because a persistent sidebar plus content does not fit
   that width; overriding .am-collapsed would win the argument and lose the
   layout. Making Amelia's own affordance findable is smaller and more durable.

   Scoped to .am-collapsed, so the desktop panel — which shows the sidebar
   permanently and needs no toggle — is untouched. Size and color only; the
   click handler stays Amelia's. */
.am-cap__wrapper.am-collapsed .am-caph__menu {
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  min-width: 44px;
  min-height: 44px;
  padding-inline: 0.6rem;
  cursor: pointer;
  border: 1px solid var(--green);
  border-radius: 3px;
  color: var(--green) !important;
}
.am-cap__wrapper.am-collapsed .am-caph__menu:hover,
.am-cap__wrapper.am-collapsed .am-caph__menu:focus-visible {
  background: var(--green-veil);
}

/* A word, so the control says what it opens instead of relying on the glyph.
   Deliberately "Account" and not "Menu": the masthead already carries a control
   labeled Menu, and two Menus on one screen is its own defect. */
.am-cap__wrapper.am-collapsed .am-caph__menu::after {
  content: "Account";
  font-family: var(--face-board);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* --- Member portal: the control that reaches "Book Now" -------------------

   THE ACTUAL ANSWER TO "MEMBERS SEE THE $50 FEE"

   Amelia does let a member book their included sessions, but ONLY from the
   Customer Panel — never from the booking catalog. Its own documentation:
   "Clicking a package opens its details, where customers can see all
   associated appointments, book remaining sessions, and cancel the package."

   Verified on this site: /profile/ > Memberships > Bronze Membership > this
   control > "Tee Time - 1 Hour  0/100 Appointments booked" > Book Now. No
   payment step, and usage is tracked against the allowance.

   Nobody found it because Amelia ships the control as a bare 15x25px <div>
   containing only an arrow glyph — no label, no border, smaller than a
   fingertip and smaller even than the sidebar toggle. The function was there
   the whole time; the affordance was not. This is the third instance of that
   same pattern in this panel.

   COLOR NOTE, MEASURED RATHER THAN ASSUMED
   The cabinet renders on WHITE, not on the site's near-black. Brand --green
   (#90B040) measures 2.48:1 there and would fail outright, which is the exact
   mistake made earlier on the booking catalog. --green-deep (#5F7729) gives
   5.05:1 and is used instead. Same brand family, correct ground. */
.am-cap__wrapper .am-sc__btn {
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  min-width: 44px;
  min-height: 44px;
  /* !important throughout: Amelia's own rules for this control win on padding
     and flex-direction otherwise. Measured without it — padding computed to 0
     and the label clipped at scrollWidth 81 inside a 71px box. */
  padding-inline: 1rem !important;
  width: auto !important;
  flex-shrink: 0 !important;
  white-space: nowrap !important;
  /* A filled button, matching "Book a bay" in the masthead. It was an outlined
     control and before that a bare arrow; a member scanning the card should
     recognize it as the same action they already know from the header. Dark
     label on brand green measures 7.62:1 and is the documented pairing —
     never white on --green. */
  background: var(--green) !important;
  border: 1px solid var(--green);
  border-radius: 3px;
  color: #111111 !important;
  cursor: pointer;
}
.am-cap__wrapper .am-sc__btn:hover,
.am-cap__wrapper .am-sc__btn:focus-visible {
  background: var(--green-lift) !important;
  border-color: var(--green-lift);
}

/* THE COLLISION: Amelia lays the capacity readout and this control side by side
   in a flex row with no gap at all — measured 0px between them at 375px, so
   "1/200 Appointment booked" runs straight into the button. Widening the label
   to "Book a Bay" makes the row 279px inside a 240px container, so on a phone
   they stack instead of fighting for the same line. */
.am-cap__wrapper .am-sc__top-right {
  gap: var(--gap-sm);
}
@media (max-width: 700px) {
  .am-cap__wrapper .am-sc__top { flex-wrap: wrap !important; }
  .am-cap__wrapper .am-sc__top-right {
    flex-direction: column !important;
    align-items: flex-start !important;
    gap: var(--gap-sm) !important;
  }
  /* the capacity readout takes its own line, so the button is never squeezed */
  .am-cap__wrapper .am-sc__capacity { width: 100%; }
}

/* The label. "Book time" rather than "Open", because the whole problem is that
   members did not know this path led to booking at all. */
.am-cap__wrapper .am-sc__btn::before {
  content: "Book a Bay";
  font-family: var(--face-board);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  white-space: nowrap;
}


/* --------------------------------------------------------------------------
   21. Membership tiers as columns

   The existing .tier component (section 13) is a stack of full-width rows. That
   reads well for comparing a long feature list, but Ryan asked for all four
   tiers side by side, and the old page had Bronze/Silver/Gold in a row with
   Platinum stranded underneath on its own.

   This is a column variant, not a new design: it reuses .tier__name,
   .tier__price and .tier__list exactly, so the type scale and colors stay the
   house ones.

   WHAT WAS WRONG BEFORE
   Every tier name and price rendered #FFFFFF on the tier's own light card
   (cream, pale gray, pale yellow). Measured white-on-white, contrast 1.0. The
   tier art was the same generic shield-and-golfer clipart recolored three
   times. Both are replaced: real facility photographs, one per tier, and text
   on the board's own dark ground.
   -------------------------------------------------------------------------- */

.tiers--cols {
  border: 0;
  background: none;
  box-shadow: none;
  border-radius: 0;
  overflow: visible;
  display: grid;
  gap: var(--gap-md);
  grid-template-columns: 1fr;
  margin-top: var(--gap-lg);
}
@media (min-width: 40rem)  { .tiers--cols { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 68rem)  { .tiers--cols { grid-template-columns: repeat(4, 1fr); } }

.tier--card {
  display: flex;
  flex-direction: column;
  gap: var(--gap-xs);
  padding: 0 0 var(--gap-lg);
  border: 1px solid var(--hairline-firm);
  border-radius: 4px;
  background: linear-gradient(180deg, #121212, #0B0B0B);
  overflow: hidden;
}

.tier__media {
  margin: 0 0 var(--gap-md);
  border-bottom: 1px solid var(--hairline);
  background: var(--ink-flap);
}
.tier__media img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

/* The name and price need room of their own. On the old page the price sat on
   top of the tier badge and the two overlapped. */
.tier--card .tier__name,
.tier--card .tier__price,
.tier--card .tier__list,
.tier--card .tier__action { padding-inline: var(--gap-md); }

.tier--card .tier__name { color: var(--white); }

/* --------------------------------------------------------------------------
   Tier identity swatches

   Each tier name sits on its own metal, so a member can tell the columns apart
   at a glance rather than by reading.

   TEXT COLOR, DECIDED BY MEASUREMENT
   The ask was white type with a green outline, because silver and platinum are
   pale. Measured against each swatch, white fails on all four:

       bronze   #CD7F32   white 3.14   dark #111  6.00
       silver   #C0C0C0   white 1.82   dark #111 10.38
       gold     #D4AF37   white 2.10   dark #111  8.98
       platinum #E5E4E2   white 1.27   dark #111 14.86

   An outline would not rescue it: contrast is measured between the glyph and
   what sits behind it, so a stroke changes how the type looks without changing
   whether it is legible — and on letter-spaced uppercase at this size it reads
   as muddy. Dark ink clears 4.5:1 on every swatch with room to spare, it is how
   an actual metal badge reads, and it matches the house rule already applied to
   brand green: dark text on a light accent, never white.

   The negative inline margin pulls the swatch out by its own padding so the
   NAME still aligns with the price and feature list underneath. */
.tier--card .tier__name {
  display: inline-block;
  width: auto;
  /* All four swatches share one width so the row reads as a set rather than
     four ragged tabs. 15ch is sized to the longest label, "Platinum", which
     measured 173px against Bronze's 139px at 1280px — the asymmetry only shows
     on desktop, since the narrow card already stretches them equal on a phone.
     A ch unit rather than a pixel value so it tracks the font if the type scale
     ever moves. */
  min-width: 15ch;
  padding: 0.35rem 0.8rem !important;
  margin-inline: calc(var(--gap-md) - 0.8rem);
  border-radius: 3px;
  color: #111111 !important;
  text-align: center;
}
.tier--card.tier--bronze   .tier__name { background: #CD7F32; }
.tier--card.tier--silver   .tier__name { background: #C0C0C0; }
.tier--card.tier--gold     .tier__name { background: #D4AF37; }
.tier--card.tier--platinum .tier__name { background: #E5E4E2; }

/* THE FLAG: "Best value" sat in normal flow above the Platinum name, which
   pushed that one title down a line and left the four headings on two
   different baselines. Lifting it out of flow onto the photograph puts it
   above the column, as asked, and lets all four names line up. */
.tier--card { position: relative; }
.tier--card.tier--flagged .tier__flag {
  position: absolute;
  top: var(--gap-sm);
  right: var(--gap-sm);
  z-index: 2;
  margin-bottom: 0;
}
.tier--card .tier__price { margin-top: 0.15rem; margin-bottom: var(--gap-sm); }
.tier--card .tier__list { color: var(--read); margin-bottom: var(--gap-md); }
.tier--card .tier__list li::before {
  content: "";
  width: 6px; height: 6px; margin-top: 0.55em;
  border-radius: 50%;
  background: var(--green);
  flex: none;
}
.tier--card .tier__action { margin-top: auto; }

/* Amelia opens its dialog from a click on the element carrying the trigger
   class, so the class must stay on a wrapper around the button. Losing it makes
   the button inert and the membership unpurchasable. */
.tier__action .wp-block-button { display: block; }

.tier--card.tier--flagged {
  border-color: var(--green);
  background: linear-gradient(180deg, rgba(144,176,64,0.10), #0B0B0B);
}

/* THE MISSING BOTTOM EDGE ON PLATINUM

   Reported as "the green border at the bottom of the Platinum column is not
   showing up". It was genuinely absent, not covered — the computed value on
   that card read:

       border-bottom: 0px none rgb(144, 176, 64)

   Green color, no width, no style, so nothing to paint. The other three sides
   were 1px solid green.

   The cause is section 13, not this section. `.tier:last-child { border-bottom: 0 }`
   at line 1161 exists for the ROW-STACK variant, where .tier elements are
   stacked inside one bordered .tiers box and the final row must not double up
   on the container's own edge. This column variant reuses the same .tier base
   class, so that rule still fires — but here every card is its own four-sided
   box with nothing to cancel, so it simply deletes the bottom edge of whichever
   card is last. Platinum is last, and Platinum is the flagged card, which is
   why only the green outline looked broken.

   LONGHANDS, DELIBERATELY. This selector outranks .tier--card.tier--flagged
   above, so `border-bottom: 1px solid ...` would also seize the COLOR and
   repaint Platinum's bottom edge hairline gray — trading a missing border for
   a wrong-colored one. Setting only width and style lets each card keep the
   color it already has.

   Scoped to .tiers--cols so the row-stack variant, still used by the legacy
   memberships markup, keeps its original behavior.

   Pre-existing since the column variant shipped; confirmed against the
   committed baseline rather than assumed, and unrelated to the flag
   repositioning done the same day. Affects every breakpoint. */
.tiers--cols .tier:last-child {
  border-bottom-width: 1px;
  border-bottom-style: solid;
}

.tiers__note {
  margin-top: var(--gap-md);
  font-size: var(--step--1);
  color: var(--dimmer);
}

/* --------------------------------------------------------------------------
   Gift cards

   Gift cards are sold by Cardivo, an outside platform, so this page is a
   storefront rather than a checkout: it says what a card covers, shows the
   amounts on offer, and hands off. There is one destination and therefore one
   button. The amounts are chosen ON Cardivo, so they are set as read-only chips
   rather than links - four buttons all going to the same page would imply four
   products and there is only one.

   The earlier version of this section styled eight .tier--card columns for a
   Stripe integration that has been removed. Those rules went with it.
   -------------------------------------------------------------------------- */

.gift-amounts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap-sm);
  margin: var(--gap-md) 0;
  padding: 0;
  list-style: none;
}

.gift-amount {
  font-family: var(--face-board);
  font-size: var(--step-1);
  letter-spacing: 0.04em;
  padding: 0.55rem 1.1rem;
  border: 1px solid var(--hairline-firm);
  border-radius: 3px;
  background: var(--ink-flap);
  color: var(--white);
}

/* "or any amount" is a statement, not a denomination, so it does not wear the
   same box as the fixed figures. */
.gift-amount--any {
  border-style: dashed;
  background: none;
  color: var(--read);
  font-size: var(--step-0);
  display: inline-flex;
  align-items: center;
}

.gift-action {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--gap-sm);
  margin-top: var(--gap-md);
}

.gift-steps {
  margin: 0 0 var(--gap-md);
  padding-left: 1.2rem;
  color: var(--read);
  line-height: 1.6;
}
.gift-steps li { margin-bottom: var(--gap-xs); }

.gift-note {
  margin: 0;
  color: var(--read);
  font-size: 0.95rem;
}

/* --------------------------------------------------------------------------
   Social profiles

   Restored 2026-08-20. The old Astra site linked TikTok, Facebook and Instagram
   from every page; the cutover dropped them because they lived in the theme's
   footer social builder rather than in content. See pg24_social_links().

   Two placements, one component. The footer row is the primary one. The rail
   variant is smaller because the terminal rail is a data strip, not a nav bar,
   and an icon there competes with the "now boarding" lamp if it is the same
   weight as everything else.
   -------------------------------------------------------------------------- */

.social {
  display: flex;
  align-items: center;
  gap: var(--gap-xs);
  margin: var(--gap-md) 0 0;
  padding: 0;
  list-style: none;
}

.social__link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 44px is the tap-target floor. The glyph is 20px; the rest is padding, which
     is why the icon looks small and the hit area is not. */
  width: 44px;
  height: 44px;
  border-radius: 3px;
  color: var(--dim);
  transition: color 0.16s ease, background-color 0.16s ease;
}
.social__link:hover,
.social__link:focus-visible {
  color: var(--green);
  background: rgba(144, 176, 64, 0.10);
}

.social__icon {
  width: 20px;
  height: 20px;
  display: block;
}

/* Rail variant: tighter, and pulled flush to the rail's own edge so it lines up
   with the text items rather than floating in its own padding. */
.rail__social { display: inline-flex; }
.social--rail {
  margin: 0;
  gap: 0;
}
.social--rail .social__link {
  width: 30px;
  height: 30px;
}
.social--rail .social__icon {
  width: 15px;
  height: 15px;
}
