/* Methodical site styles.
   Design tokens (color, type, spacing, radius, elevation) are the single
   source of truth and live in the design system at design/tokens.css — this
   file imports them and consumes everything via var(--token). Never hard-code
   a brand colour here; add/adjust it in design/tokens.css instead. */
@import url('design/fonts.css');
@import url('design/tokens.css');

:root{
  --line: var(--color-border);
  --focus: 2px solid var(--color-amber);

  /* Fluid spacing scale — one source of truth for vertical rhythm.
     Section spacing is applied as a single gap between siblings (never
     doubled padding), so pages stay uniform regardless of content. */
  --space-section: clamp(2.75rem, 2rem + 3vw, 4.5rem);  /* ~44–72px */
  --space-lg:      clamp(2rem, 1.5rem + 2vw, 3.5rem);   /* hero/grid gaps */
  --space-md:      clamp(1.25rem, 1rem + 1vw, 2rem);
  --measure:       62ch;                                /* shared reading width */
  --wrap-pad:      clamp(1.25rem, 1rem + 1vw, 2rem);    /* fluid horizontal gutter */
}

*{box-sizing:border-box;}
/* scrollbar-gutter:stable reserves the vertical scrollbar's space at all times
   so the content width never changes when a scrollbar appears/disappears. This
   kills the horizontal "jutter" on the events page, where the empty-state → taller
   event-cards swap grows the page, toggles the scrollbar, and shifts everything
   left→right for ~1s. Applied site-wide so page width is consistent between pages
   too. (No effect where the OS uses overlay scrollbars, e.g. most mobile.) */
html{scroll-behavior:smooth; scrollbar-gutter:stable;}
body{
  margin:0;
  background:var(--color-paper);
  color:var(--color-text-body);
  font-family:var(--font-sans);
  line-height:var(--type-body-lh);
  display:flex; flex-direction:column;
  min-height:100vh; min-height:100svh;
}
main{flex:1; display:flex; flex-direction:column; gap:var(--space-section);}
h1,h2,h3{
  font-family:var(--font-display);
  color:var(--color-ink);
  margin:0 0 0.4em 0;
  font-weight:600;
  letter-spacing:0;
  line-height:var(--type-h2-lh);
  text-wrap:balance;
}
h1{font-size:clamp(2.5rem,5.2vw,var(--type-hero-size)); line-height:var(--type-h1-lh);}
h2{font-size:var(--type-h2-size);}
h3{font-size:var(--type-h3-size); line-height:var(--type-h3-lh);}
p{margin:0 0 1em 0;}
a{color:var(--color-amber-ink);}
a:hover{color:var(--color-amber-hover);}

/* Layout */
/* width:100% is required because sections are flex items of <main>; without an
   explicit width a flex item shrink-wraps to its content (and margin:0 auto then
   centers it), which would make intro sections narrower and centered. Claiming
   full width up to max-width keeps every section the same width, left-aligned. */
.wrap{width:100%; max-width:var(--container-max); margin:0 auto; padding-left:var(--wrap-pad); padding-right:var(--wrap-pad);}
/* Sections have no own vertical padding — the gap on <main> provides a single,
   uniform rhythm between them so adjacent sections never double up. The first
   section gets top spacing to clear the sticky header, on every page. */
section{padding:0;}
main > section:first-child{padding-top:var(--space-section);}

/* Header / nav — ink bar, amber active underline, amber CTA */
header{
  border-bottom:1px solid rgba(183,110,92,0.3);
  background:var(--color-ink);
  position:sticky; top:0; z-index:50;
}
.nav{
  display:flex; align-items:center; justify-content:space-between;
  /* Horizontal padding matches body content's gutter (--wrap-pad, same token
     .wrap uses) so the logo/hamburger sit on the same edge as every heading
     and lead below the header — see docs/CONVENTIONS.md breakpoints. */
  padding:16px var(--wrap-pad); max-width:var(--container-max); margin:0 auto;
}

/* Brand lockup. The header brand is a text wordmark for now; when an icon
   mark exists it is injected by scripts/build.mjs (buildHeaderMark) so all
   pages get it from one source. Keep any future mark's colours token-driven
   (currentColor / var(--token)), which requires inlining rather than <img>. */
.brand{
  display:inline-flex; align-items:center; gap:12px;
  text-decoration:none;
}
/* Sized by the S: the injected viewBox is the S-only box (height 540 = the S
   cap height), so height:24px renders the S at 24px and the lockup centres on
   the S — matching the previous mark exactly. The ² sits above the S cap-line
   and is allowed to overflow the box (overflow:visible), the same way the old
   ² overflowed its 30×24 wrapper. */
.brand .mark{
  height:24px; width:auto; display:block;
  overflow:visible; flex-shrink:0;
  color:var(--color-on-dark);
}
.brand .divider{
  width:1px; height:29px; flex-shrink:0;
  background:rgba(244,245,247,0.28);
}
.brand .word{
  font-family:var(--font-display); font-weight:600;
  font-size:clamp(1.35rem, 1rem + 1vw, 26px); line-height:1; color:var(--color-on-dark);
  letter-spacing:0.01em; white-space:nowrap;
  position:relative; top:-1px;
}

ul.links{display:flex; gap:26px; list-style:none; margin:0; padding:0;}
ul.links a{
  text-decoration:none; color:var(--color-on-dark); opacity:0.8;
  font-size:0.9rem; font-weight:var(--fw-semibold);
  border-bottom:2px solid transparent; padding-bottom:4px;
  transition:border-color .15s ease, opacity .15s ease;
}
ul.links a:hover, ul.links a.active{border-bottom-color:var(--color-amber); opacity:1;}
.nav-inner{display:flex; align-items:center; gap:32px; min-width:0;}

.nav-toggle{
  display:none; flex-direction:column; justify-content:center; gap:5px;
  width:36px; height:36px; padding:0; background:none; border:none; cursor:pointer;
}
.nav-toggle span{
  display:block; width:22px; height:2px; border-radius:2px; background:var(--color-on-dark);
  transition:transform .2s ease, opacity .2s ease;
}
.nav-toggle[aria-expanded="true"] span:nth-child(1){transform:translateY(7px) rotate(45deg);}
.nav-toggle[aria-expanded="true"] span:nth-child(2){opacity:0;}
.nav-toggle[aria-expanded="true"] span:nth-child(3){transform:translateY(-7px) rotate(-45deg);}

/* Buttons — primary = ink fill / paper text; secondary = ink outline;
   header CTA = amber fill / ink text (on-dark). */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  background:var(--color-ink); color:var(--color-on-dark); text-decoration:none; text-align:center;
  padding:13px 24px; border-radius:var(--radius-sm); font-weight:var(--fw-bold); font-size:0.9rem;
  border:1px solid var(--color-ink); cursor:pointer; transition:transform .12s ease, background .15s ease;
}
.btn:hover{background:#3C5C48; transform:translateY(-1px);}
.btn.secondary{background:transparent; color:var(--color-ink);}
.btn.secondary:hover{background:rgba(27,33,48,0.06);}
header .btn{
  background:var(--color-amber); color:var(--color-ink); border-color:var(--color-amber);
  /* Fluid so the CTA scales with the viewport instead of holding a fixed
     desktop size and crowding the brand on phones; nowrap keeps it on one
     line. See design principle: mobile-first, fluid before fixed. */
  padding:clamp(8px, 1.4vw, 11px) clamp(13px, 3vw, 20px);
  font-size:clamp(0.8rem, 0.7rem + 0.4vw, 0.9rem);
  white-space:nowrap;
}
header .btn:hover{background:#C9826F;}
.btn:focus-visible, a:focus-visible, button:focus-visible, input:focus-visible, textarea:focus-visible, select:focus-visible{outline:var(--focus); outline-offset:2px;}
header .btn:focus-visible{outline-color:var(--color-on-dark);}

/* Hero — home landing, two-column, fills the viewport fold */
.hero{
  display:grid; grid-template-columns:1.1fr 0.9fr; gap:var(--space-lg); align-items:center;
  flex:1; align-content:center;
}

/* Standard intro on content pages: left-editorial, heading + lead, real
   content follows immediately (no forced fold). */
/* Widened from the 62ch reading measure so the heading/lead visibly span the
   content area above full-width card grids, rather than orphaning at ~two
   cards on wide screens. Left-aligned (inline with the header brand). */
.intro h1{max-width:30ch;}
.intro p{max-width:82ch;}
.intro p:last-child{margin-bottom:0;}

/* About-page supporting paragraphs: the intro there carries two extra prose
   paragraphs no other page's intro has (~600px of unbroken text on a phone).
   A rule + tighter rhythm splits the pitch (h1+lead) from supporting detail
   so it reads as two beats instead of one solid block — text is unchanged. */
.intro-detail{
  border-top:1px solid var(--color-border);
  padding-top:var(--space-md);
  margin-top:var(--space-md);
}
.intro-detail p{line-height:1.5; margin-bottom:0.8em;}

/* Fold modifier: fills the initial viewport and vertically centers its copy. */
.intro-fold{flex:1; display:flex; flex-direction:column; justify-content:center;}
.eyebrow{
  font-family:var(--font-sans); text-transform:uppercase; letter-spacing:var(--type-eyebrow-ls);
  font-size:var(--type-eyebrow-size); font-weight:var(--fw-bold); color:var(--color-amber-ink);
  margin-bottom:14px; display:block;
}
.lead{font-size:1.1rem; line-height:1.6; max-width:var(--measure); color:var(--color-text-body);}
.hero-copy p.lead{max-width:46ch;}
.hero-actions{display:flex; gap:14px; margin-top:22px; flex-wrap:wrap;}
.pull-quote{
  font-family:var(--font-display); font-size:1.5rem; line-height:1.4; color:var(--color-ink);
  border-left:3px solid var(--color-amber); padding:2px 0 2px 22px; margin:var(--space-md) 0 0; max-width:60ch;
}
.pull-quote cite{display:block; font-family:var(--font-sans); font-style:normal; font-size:0.85rem; font-weight:var(--fw-semibold); color:var(--color-text-muted); margin-top:12px;}

/* Shop window panel (signature visual) — ink surface, amber frame */
.shopwindow{
  background:var(--color-ink);
  border:6px solid var(--color-amber);
  border-radius:var(--radius-lg);
  padding:0;
  position:relative;
  box-shadow: 0 18px 40px rgba(27,33,48,0.25);
  overflow:hidden;
}
.shopwindow-bar{
  display:flex; align-items:center; justify-content:space-between;
  padding:10px 16px; background:rgba(0,0,0,0.18);
  border-bottom:1px solid rgba(183,110,92,0.35);
}
.shopwindow-bar .sign{
  font-family:var(--font-sans); font-size:0.7rem; font-weight:var(--fw-bold); color:#E8C66A;
  letter-spacing:0.08em; display:flex; align-items:center; gap:8px;
}
.shopwindow-bar .dot{width:8px; height:8px; border-radius:50%; background:var(--color-success); box-shadow:0 0 0 3px rgba(95,191,138,0.2);}
.shopwindow-body{padding:20px; min-height:230px; display:flex; flex-direction:column; gap:12px;}
.demo-msg{
  font-family:var(--font-sans); font-size:0.85rem; padding:10px 14px; border-radius:var(--radius-sm);
  max-width:85%; line-height:1.5;
}
.demo-msg.them{background:rgba(244,245,247,0.08); color:#E4E8F0; align-self:flex-start; border:1px solid rgba(244,245,247,0.12);}
.demo-msg.us{background:var(--color-amber-ink); color:var(--color-on-dark); align-self:flex-end; font-weight:var(--fw-semibold);}

/* Feature grid */
.grid3{display:grid; grid-template-columns:repeat(3,1fr); gap:var(--space-md);}
.card{
  background:var(--color-surface); border:1px solid var(--color-border-card); border-radius:var(--radius-md);
  padding:24px; position:relative; box-shadow:var(--shadow-card);
}
.card .eyebrow{margin-bottom:10px; font-size:11px; letter-spacing:0.08em;}
.card h3{font-size:1rem; margin-bottom:8px;}
.card p{color:var(--color-text-body); font-size:0.9rem; margin:0; line-height:1.55;}

/* Process timeline (real sequence, numbering justified) — set on a sand panel.
   Padding is fluid (not the old fixed 40px 44px): at 320px the fixed value
   left only ~157px for step copy, wrapping "We learn your business…" to 6
   lines. clamp() reaches the original 40px/44px again around ~1200px, so
   nothing changes at desktop widths — see docs/DECISIONS.md 2026-07-11 for
   the precedent (header CTA fluid-before-fixed). */
.timeline-panel{
  background:var(--color-sand); border:1px solid var(--color-sand-border);
  border-radius:var(--radius-lg);
  padding:clamp(1.5rem, 1rem + 2vw, 2.5rem) clamp(1.25rem, 0.75rem + 3vw, 2.75rem);
}
.timeline{display:flex; flex-direction:column; gap:0; border-left:2px solid var(--color-border); margin-left:14px;}
.timeline .step{position:relative; padding:0 0 32px 32px;}
.timeline .step:last-child{padding-bottom:0;}
.timeline .step::before{
  content:attr(data-n); position:absolute; left:-15px; top:0;
  width:28px; height:28px; border-radius:50%; background:var(--color-ink); color:var(--color-on-dark);
  font-family:var(--font-sans); font-weight:var(--fw-bold); font-size:0.8rem;
  display:flex; align-items:center; justify-content:center;
}
.timeline h3{font-size:0.95rem; margin-bottom:6px;}
.timeline p{color:var(--color-text-body); margin:0; font-size:0.9rem;}

/* Pricing */
/* Four tiers -> four across on wide (steps to 2 then 1 via the media queries).
   align-items:stretch equalises card heights; the CTA is pushed to the bottom
   so every card's button lines up regardless of feature count. */
.pricing-grid{display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:var(--space-md); align-items:stretch;}
.price-card > .btn{margin-top:auto;}
/* Website Audit dimensions - compact two-column checklist on the Book-a-call page. */
.audit-dims{list-style:none; padding:0; margin:14px 0 26px; display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:9px 28px; max-width:640px;}
.audit-dims li{position:relative; padding-left:22px; font-size:0.95rem; color:var(--color-text-body);}
.audit-dims li::before{content:"\2713"; position:absolute; left:0; color:var(--color-amber-ink); font-weight:var(--fw-bold);}
@media (max-width:560px){.audit-dims{grid-template-columns:1fr;}}
.price-card{
  background:var(--color-surface); border:1px solid var(--color-border-card); border-radius:var(--radius-md); padding:28px;
  display:flex; flex-direction:column; gap:14px; box-shadow:var(--shadow-card);
}
.price-card.featured{border:2px solid var(--color-amber); box-shadow:var(--shadow-amber);}
.price-card .amount{font-family:var(--font-sans); font-size:2rem; font-weight:var(--fw-heavy); color:var(--color-ink);}
.price-card .amount span{font-family:var(--font-sans); font-size:0.875rem; font-weight:var(--fw-medium); color:var(--color-text-muted);}
.price-card ul{list-style:none; padding:0; margin:0; display:flex; flex-direction:column; gap:9px; font-size:0.9rem; color:var(--color-text-body);}
.price-card li::before{content:"- "; color:var(--color-amber-ink);}

/* Contact form */
.form-grid{display:grid; gap:18px; max-width:520px;}
label{font-size:13px; font-weight:var(--fw-bold); color:var(--color-ink); display:block; margin-bottom:6px;}
input, textarea, select{
  width:100%; padding:12px 14px; border:1px solid var(--color-border); border-radius:var(--radius-sm);
  font-family:var(--font-sans); font-size:0.9rem; background:var(--color-surface); color:var(--color-ink);
}
input:focus, textarea:focus, select:focus{border-color:var(--color-amber); outline:2px solid rgba(183,110,92,0.25); outline-offset:0;}
textarea{resize:vertical; min-height:120px;}

footer{
  border-top:1px solid rgba(183,110,92,0.3); padding:28px 0; margin-top:var(--space-section);
  background:var(--color-ink);
}
.footer-inner{display:flex; justify-content:space-between; align-items:center; flex-wrap:wrap; gap:12px;}
.footer-inner p{margin:0; font-size:0.8rem; color:var(--color-on-dark); opacity:0.75;}
/* Cloudflare Turnstile attribution — its own muted line below the footer row. */
.footer-inner .turnstile-notice{flex-basis:100%; font-size:0.72rem; opacity:0.55;}
.footer-inner .turnstile-notice a{color:inherit; text-decoration:underline;}
/* The site's own legal pages. Links on the forest footer keep cream on hover
   (docs/CONVENTIONS.md: dark-surface links must SET their hover colour). */
.footer-inner .legal-links a{color:inherit; text-decoration:underline;}
.footer-inner .legal-links a:hover{color:inherit; opacity:1;}

/* Course-card actions: Book + interest side by side, wrapping on narrow cards. */
.course-actions{display:flex; gap:10px; flex-wrap:wrap; align-items:center;}

/* Legal pages (terms, privacy): plain prose sections, spacing only — type
   and colour come from the page-wide styles. */
.legal h2{margin:2.25rem 0 0.5rem; font-size:1.15rem;}
.legal p, .legal ul{margin:0.5rem 0 1rem;}
.legal ul{padding-left:1.25rem;}
.legal li{margin:0.3rem 0;}

/* ============ Chat Widget ============ */
/* Launcher pill + panel styling only — behaviour lives in script.js and the
   backend in api/chat.js; those are intentionally left untouched. */
#fd-chat-launcher{
  position:fixed; bottom:22px; right:22px; z-index:100;
  background:var(--color-ink); color:var(--color-on-dark);
  border:2px solid var(--color-amber); border-radius:var(--radius-pill);
  padding:12px 18px; font-family:var(--font-sans); font-size:0.8rem; font-weight:var(--fw-bold);
  display:flex; align-items:center; gap:9px; cursor:pointer;
  box-shadow:0 10px 30px rgba(27,33,48,0.3);
  transition:transform .15s ease, bottom .15s ease;
}
#fd-chat-launcher:hover{transform:translateY(-2px);}
#fd-chat-launcher .dot{width:8px; height:8px; border-radius:50%; background:var(--color-success); box-shadow:0 0 0 3px rgba(95,191,138,0.25);}

#fd-chat-panel{
  position:fixed; bottom:22px; right:22px; z-index:101;
  width:340px; max-width:calc(100vw - 32px); height:460px; max-height:calc(100vh - 100px);
  background:var(--color-ink); border:2px solid var(--color-amber); border-radius:var(--radius-lg);
  display:none; flex-direction:column; overflow:hidden;
  box-shadow:0 20px 50px rgba(27,33,48,0.35);
  transition:bottom .15s ease;
}
#fd-chat-panel.open{display:flex;}
.fd-chat-head{
  display:flex; align-items:center; justify-content:space-between;
  padding:12px 14px; background:rgba(0,0,0,0.18); border-bottom:1px solid rgba(183,110,92,0.3);
}
.fd-chat-head .title{font-family:var(--font-sans); color:var(--color-on-dark); font-size:0.8rem; font-weight:var(--fw-bold); letter-spacing:0.06em; display:flex; align-items:center; gap:8px;}
.fd-chat-head .title .dot{width:7px; height:7px; border-radius:50%; background:var(--color-success);}
.fd-chat-close{background:none; border:none; color:var(--color-on-dark); font-size:1.1rem; cursor:pointer; line-height:1; padding:4px;}
.fd-chat-body{flex:1; overflow-y:auto; padding:14px; display:flex; flex-direction:column; gap:10px;}
.fd-msg{font-family:var(--font-sans); font-size:0.82rem; padding:9px 12px; border-radius:var(--radius-sm); max-width:85%; line-height:1.45;}
.fd-msg.bot{background:rgba(244,245,247,0.08); color:#E4E8F0; align-self:flex-start; border:1px solid rgba(244,245,247,0.12);}
.fd-msg.user{background:var(--color-amber-ink); color:var(--color-on-dark); align-self:flex-end; font-weight:var(--fw-semibold);}
.fd-msg.typing{color:var(--color-neutral); font-style:italic;}
/* Persistent hand-off to the human path. The assistant CAN capture a lead
   in-chat (api/chat.js FOLLOW-UP section, owner-approved 2026-09-04); this
   link is the alternative it offers and the fallback when capture fails,
   and the widget appends ?topic=… to it when the assistant names one. */
.fd-chat-contact-link{
  display:block; text-align:center; padding:8px 12px;
  font-family:var(--font-sans); font-size:0.78rem; font-weight:var(--fw-semibold);
  color:var(--color-on-dark); text-decoration:underline;
  border-top:1px solid rgba(183,110,92,0.25);
}
/* Hover must SET color: the global a:hover (amber on cream) outranks the
   base rule here and painted accent-on-forest at 1.19:1 (owner UAT,
   2026-09-26 — measured, not eyeballed). On forest, hover stays cream and
   affordance comes from the panel's own tint idiom. */
.fd-chat-contact-link:hover{
  color:var(--color-on-dark); background:rgba(244,245,247,0.08);
  text-decoration:underline;
}
.fd-chat-input-row{display:flex; gap:8px; padding:12px; border-top:1px solid rgba(183,110,92,0.25);}
.fd-chat-input-row input{
  flex:1; background:rgba(244,245,247,0.06); border:1px solid rgba(244,245,247,0.18);
  color:#E4E8F0; border-radius:var(--radius-sm); padding:10px 12px; font-family:var(--font-sans); font-size:0.85rem;
}
.fd-chat-input-row input::placeholder{color:var(--color-neutral);}
.fd-chat-input-row button{
  background:var(--color-amber-ink); border:none; color:var(--color-on-dark); border-radius:var(--radius-sm); padding:0 16px;
  font-weight:var(--fw-bold); cursor:pointer; font-size:0.85rem;
}

/* Events & Ticketing */
/* Plain small label above the slots grid — replaces what used to be a full
   second eyebrow+h2+lead intro block repeating the page's own intro. Keeps
   the "no obligation" reassurance without gating real content behind a
   second stacked intro (see events.html). */
.section-label{
  font-size:0.85rem; font-weight:var(--fw-semibold); color:var(--color-text-muted);
  margin:0 0 var(--space-md) 0;
}
.events-grid{display:grid; grid-template-columns:repeat(2,1fr); gap:var(--space-md);}
.event-card{display:flex; flex-direction:column; gap:10px;}
.event-card .eyebrow{margin-bottom:0;}
.event-location{color:var(--color-text-body); font-size:0.9rem; margin:0;}
.event-meta{display:flex; justify-content:space-between; align-items:center; margin:6px 0;}
.event-price{font-family:var(--font-sans); font-weight:var(--fw-heavy); color:var(--color-ink); font-size:1.05rem;}
.event-spots{font-family:var(--font-sans); font-size:0.8rem; font-weight:var(--fw-semibold); color:var(--color-amber-ink);}
.load-more-btn{grid-column:1/-1; justify-self:center; margin-top:var(--space-md);}

/* Checkout summary — the event-summary markup is injected by checkout.js
   (h2 + date <p> + <p class="event-price">); the container is styled as an
   ink card so those injected elements read as the design's summary panel. */
.checkout-summary{
  background:var(--color-ink); border-radius:var(--radius-lg);
  padding:22px 24px; margin-bottom:28px;
}
.checkout-summary h2{color:var(--color-on-dark); font-size:var(--type-h3-size); margin:0 0 6px;}
.checkout-summary p{color:var(--color-neutral); font-size:0.85rem; margin:0 0 4px;}
.checkout-summary p:last-child{margin-bottom:0;}
.checkout-summary .event-price{color:var(--color-on-dark); font-weight:var(--fw-heavy); font-size:1.15rem; margin-top:8px;}
fieldset.attendee-fields{
  border:1px solid var(--color-border); border-radius:var(--radius-md); padding:18px 20px 8px;
  margin:0 0 16px 0; display:grid; gap:14px;
}
fieldset.attendee-fields legend{
  font-family:var(--font-sans); font-size:0.7rem; font-weight:var(--fw-bold); text-transform:uppercase;
  letter-spacing:0.08em; color:var(--color-amber-ink); padding:0 6px;
}
.form-error{color:var(--color-amber-ink); font-size:0.9rem; margin:12px 0 0 0;}
.form-success{
  background:var(--color-surface); border:1px solid var(--color-border-card); border-radius:var(--radius-md);
  padding:24px; margin-top:16px; box-shadow:var(--shadow-card);
}
.rating-group{display:flex; gap:10px; margin-bottom:16px;}
.rating-group label{
  display:flex; align-items:center; justify-content:center; width:44px; height:44px;
  border:1px solid var(--color-border); border-radius:50%; cursor:pointer; font-weight:var(--fw-bold);
  margin-bottom:0; color:var(--color-ink); background:var(--color-surface);
}
.rating-group input{position:absolute; opacity:0; width:0; height:0;}
.rating-group input:checked + label{background:var(--color-amber-ink); border-color:var(--color-amber-ink); color:var(--color-on-dark);}

/* Tablet: step 3-col grids down to 2-col before collapsing to 1 on phones */
@media (max-width:1000px){
  .grid3, .pricing-grid{grid-template-columns:repeat(2,1fr);}
}

@media (max-width:820px){
  .events-grid{grid-template-columns:1fr;}
  .hero{grid-template-columns:1fr;}
  .grid3, .pricing-grid{grid-template-columns:1fr;}
  .nav{padding:14px var(--wrap-pad);}
  .nav-inner{gap:14px;}
  .nav-toggle{display:flex;}
  ul.links{
    display:none; position:absolute; top:100%; left:0; right:0;
    flex-direction:column; gap:0; background:var(--color-ink);
    border-bottom:1px solid rgba(183,110,92,0.3); padding:4px 24px 12px; z-index:60;
  }
  ul.links.open{display:flex;}
  ul.links li{width:100%;}
  ul.links a{
    display:block; padding:14px 0; font-size:1rem;
    border-bottom:1px solid rgba(244,245,247,0.1);
  }
  ul.links li:last-child a{border-bottom:none;}
}

/* Large phones (370–389px): the full lockup (mark + divider + wordmark) would
   crowd the amber CTA + hamburger here, but mark + wordmark still fits with
   clean breathing room (measured ≥12px gap to the CTA, growing to ~30px by
   389px) once the divider is dropped. This is the "drop the divider first"
   step: it buys back the business name on large phones (e.g. Galaxy S20
   Ultra) without touching the CTA or hamburger. The divider returns at
   390px, where the full three-part lockup fits with its own clean gap. */
@media (max-width:389px){
  .brand .divider{display:none;}
}

/* Small/medium phones: below 370px the measured gap to the CTA shrinks past
   a clean margin (2–3px at 360px — reads as touching, not deliberate), so
   the wordmark is hidden down here (it returns at 370px, the divider at
   390px). KNOWN GAP: with a text-only brand this leaves the header brand
   visually empty at ≤369px (the link keeps its aria-label) — see
   docs/ROADMAP.md; the collapse wants re-working for a text-only brand. */
@media (max-width:369px){
  .brand .word{display:none;}
  .brand{gap:0;}
}

/* Phones: stack the hero CTAs full-width. Side by side, "Start a project" and
   "See packages" have different intrinsic widths, so they read as a ragged,
   unequal two-up row (and wrap unevenly around 320px). Stacking gives both one
   shared left/right edge and equal width — the primary stays on top (DOM order). */
@media (max-width:480px){
  .hero-actions{flex-direction:column; align-items:stretch;}
}

@media (prefers-reduced-motion: reduce){
  *{transition:none !important; scroll-behavior:auto !important;}
}


/* Hero figure — teaching photo in a clean rounded frame (the design-system
   "hero image frame" radius). A crisp rounded rectangle reads as intentional
   and modern; the earlier all-edge feather + vignette read as dated. */
.hero-figure{margin:0;}
.hero-figure img{
  display:block; width:100%; height:100%; min-height:440px; max-height:580px;
  object-fit:cover; object-position:center 42%;
  border-radius:var(--radius-lg);
}
@media (max-width:820px){ .hero-figure img{max-height:420px;} }

/* Next-course band */
.next-course{background:var(--color-ink); color:var(--color-on-dark); border-radius:var(--radius-lg);
  padding:clamp(1.75rem, 1.25rem + 2vw, 2.75rem); display:grid; grid-template-columns:1.6fr 1fr; gap:var(--space-lg); align-items:stretch;}
.next-course-text{display:flex; flex-direction:column; gap:var(--space-3);}
.next-course h2{color:var(--color-on-dark); margin:0;}
.next-course p{color:var(--color-neutral); margin:0;}
.next-course .eyebrow{color:#E8C66A;}
.next-course-meta{display:flex; flex-direction:column; gap:var(--space-4);
  border-left:1px solid rgba(247,241,232,0.2); padding-left:var(--space-lg);}
.next-course .nc-line{font-size:0.95rem; color:var(--color-on-dark); margin:0;}
.next-course .nc-line strong{display:block; font-size:0.7rem; text-transform:uppercase; letter-spacing:0.08em; color:#E8C66A; font-weight:var(--fw-bold); margin-bottom:2px;}
.next-course .btn{background:var(--color-amber-ink); border-color:var(--color-amber-ink); color:var(--color-on-dark); align-self:start; margin-top:var(--space-2);}
.next-course .btn:hover{background:#C9826F;}
@media (max-width:820px){ .next-course{grid-template-columns:1fr;} .next-course-meta{border-left:none; padding-left:0; border-top:1px solid rgba(247,241,232,0.2); padding-top:var(--space-md);} }

/* Partner logo strip.
   Source logos are a mix of transparent PNGs and JPEGs with baked-in white
   backgrounds. `mix-blend-mode:multiply` drops those white fields into the
   cream page so every mark floats without a box; grayscale + reduced opacity
   give the muted, editorial "trusted by" wall (full colour on hover). The one
   reversed lockup (UCL, white-on-dark) is pre-baked to a mono-on-transparent
   PNG upstream since no blend mode can lift a dark field off a light page. */
.logo-strip{display:flex; flex-wrap:wrap; align-items:center; gap:26px 44px; margin:var(--space-md) 0;}
.logo-strip img{
  height:40px; width:auto; max-width:150px; object-fit:contain;
  filter:grayscale(1); opacity:0.68; mix-blend-mode:multiply;
  transition:opacity .15s ease, filter .15s ease;
}
.logo-strip img:hover{filter:grayscale(0); opacity:1;}
/* Optical balancing — normalise perceived size, not bounding-box height, so no
   one mark dominates. Order: UCL, FCDO, SRA, NIHR-Oxford, LISS-DTP, SGSSS,
   NIHR-North-Thames. Heavy wordmarks shrink; circular/dense marks nudge up. */
.logo-strip img:nth-child(1){height:29px;}   /* UCL — heavy solid wordmark */
.logo-strip img:nth-child(3){height:37px;}   /* SRA — bold lettermark */
.logo-strip img:nth-child(5){height:44px;}   /* LISS DTP — circular, reads small */
@media (max-width:600px){
  .logo-strip{gap:18px 30px;}
  .logo-strip img{height:32px;}
  .logo-strip img:nth-child(1){height:24px;}
  .logo-strip img:nth-child(3){height:30px;}
  .logo-strip img:nth-child(5){height:36px;}
}

/* Two-column course grid + course cards */
.grid2{display:grid; grid-template-columns:1fr 1fr; gap:var(--space-md);}
.course-card{display:flex; flex-direction:column; gap:10px;}
.course-card .btn{margin-top:auto; align-self:flex-start;}
@media (max-width:820px){ .grid2{grid-template-columns:1fr;} }

/* Lecturer profiles */
.lecturers{display:grid; grid-template-columns:1fr 1fr; gap:var(--space-lg);}
.lecturer{display:flex; gap:20px; align-items:flex-start;}
.lecturer img{width:118px; height:118px; border-radius:50%; object-fit:cover; object-position:center top; flex-shrink:0; border:3px solid var(--color-sand);}
.lecturer h3{margin-bottom:6px;}
.lecturer p{font-size:0.92rem; color:var(--color-text-body); margin:0; line-height:1.55;}
@media (max-width:820px){ .lecturers{grid-template-columns:1fr;} }

/* ==========================================================================
   ACCENT SYSTEM.
   Terracotta is the single accent and it reaches every call to action, on
   cream and on forest alike, plus the chat frame. Space Grotesk is the
   display face (see design/tokens.css --font-display).

   THE DARK-SURFACE CONSTRAINT. On the forest header, no solid fill of any
   hue can both separate from the surface at 3:1 and carry cream text at
   4.5:1: the first needs fill luminance >= 0.2742, the second caps it at
   <= 0.1578 — an empty window. The way out is that it doesn't have to: a
   text-labelled filled button is identified by its LABEL, so under WCAG
   1.4.11 the fill owes no 3:1 of its own (that criterion bites for
   unlabelled icon controls, input boundaries and state indicators). So the
   primary CTA is the SAME component on every surface — real terracotta
   fill (--color-amber-ink), cream label at 5.30:1, no border, no shadow —
   and sits deliberately quiet against the forest bar (1.63:1). Hover
   darkens the fill (--color-amber-hover, cream label 7.30:1), same as on
   light surfaces. Keyboard focus gets its own indicator: an offset outline
   that must clear the surface on its own, hence cream on forest (8.65:1).

   Tone per surface, and why:
     any surface, filled CTA    -> --color-amber-ink  + cream text   5.30:1
     any surface, hover         -> --color-amber-hover + cream text  7.30:1
     light surface, outline CTA -> --color-amber-ink border + text   5.30:1
     forest surface, focus ring -> cream offset outline vs forest    8.65:1
     chat frame (forest on cream) -> --color-amber                   3.46:1
       against the cream page it sits on. Against the forest fill inside it is
       2.50:1, which is fine here: the frame is decoration, not the thing that
       identifies the control, the forest fill does that at 8.65:1 on cream.
   ========================================================================== */

/* Soft-but-square buttons. */
.btn{ border-radius:8px; }

/* ---- Every CTA is terracotta -------------------------------------------
   The accent is the DEFAULT for a primary button rather than an opt-in
   marker class, so no class needs sprinkling through nine pages of markup.
   Every `.btn` that is not `.secondary` is terracotta wherever it appears. */
.btn:not(.secondary){
  background:var(--color-amber-ink);
  border-color:var(--color-amber-ink);
  color:var(--color-on-dark);
}
.btn:not(.secondary):hover{
  background:var(--color-amber-hover);
  border-color:var(--color-amber-hover);
}
/* Outline CTA takes the accent as border + text, so the secondary action is
   part of the same accent system instead of a neutral ink outline. */
.btn.secondary{
  background:transparent;
  color:var(--color-amber-ink);
  border-color:var(--color-amber-ink);
}
.btn.secondary:hover{ background:rgba(154,78,59,0.08); }

/* ---- Forest surfaces: header bar ---------------------------------------
   The primary CTA needs NO colour overrides here: the generic
   `.btn:not(.secondary)` recipe above (terracotta fill, cream label) is the
   component on every surface, and at (0,2,0) it already beats the legacy
   `header .btn` layer at (0,1,1). Only two things differ on the header:
   the rounded-square corner (--radius-sm against the button's ~35px height
   reads as a square with the corners taken off) and the focus ring colour —
   the offset outline is the focus indicator, so it must clear the FOREST
   surface on its own: cream at 8.65:1, where the default accent outline
   would sit at 2.50:1. */
header .btn:not(.secondary){
  border-radius:var(--radius-sm);
}
header .btn:focus-visible{
  outline-color:var(--color-on-dark);
}
/* On forest the underline goes cream — no line at accent luminance can
   clear 3:1 against this green (see the dark-surface constraint above). */
ul.links a:hover, ul.links a.active{ border-bottom-color:var(--color-on-dark); }

/* ---- Forest surfaces: next-course panel --------------------------------
   Same primary CTA component via the generic recipe; only the focus ring
   needs the forest override. */
.next-course .btn:focus-visible{
  outline-color:var(--color-on-dark);
}
.next-course .eyebrow, .next-course .nc-line strong{ color:var(--color-on-dark); }

/* ---- Forest surfaces: the Ask Methodical chat -------------------------- */
/* The chat frame carries the accent too, so it reads as part of one system. */
#fd-chat-launcher{ border-color:var(--color-amber); }
#fd-chat-panel{ border-color:var(--color-amber); }
/* Head chrome stays cream: it is labelling, not accent, and cream is 8.65:1
   on forest where the tint would be 4.76:1. */
.fd-chat-head .title, .fd-chat-close{ color:var(--color-on-dark); }
/* Send is a call to action, so it is the SAME primary CTA component as the
   header button: terracotta fill, cream label, hover darkens; the focus
   ring goes cream because it must clear the forest panel on its own. */
.fd-chat-input-row button{
  background:var(--color-amber-ink);
  color:var(--color-on-dark);
}
.fd-chat-input-row button:hover{
  background:var(--color-amber-hover);
}
.fd-chat-input-row button:focus-visible{
  outline-color:var(--color-on-dark);
}
/* User bubbles are not interactive — terracotta + cream at 5.30:1. */
.fd-msg.user{ background:var(--color-amber-ink); color:var(--color-on-dark); }
