/* ============================================================================
   MTI: Measured Tones Institute
   ----------------------------------------------------------------------------
   Ported from the "Institute" static concept. Architecture, not palette, is what
   defines it:

     · An announcement bar carries live campaigns above everything else.
     · The homepage hero is a typographic statement with no image and no card.
     · Immediately below it, a TWO-PATH FORK: study with us, or bring us to you.
     · Content sits on full-bleed photographic bands and hairline-divided lists.
       There are no card grids anywhere, on purpose.
     · Display type is Cormorant Garamond at weight 300, set very large.

   Contents
     0. Tokens          5. Buttons              10. Footer & motion
     1. Reset           6. Bands & photography  11. WordPress additions
     2. Base            7. Rule lists & editorial
     3. Layout          8. Forms
     4. Typography      9. Header, announcement, mega-menu
   ========================================================================== */

/* ---------------------------------------------------------------------------
   0. TOKENS

   These are DEFAULTS, not the live values. theme.json is the source of truth:
   inc/tokens.php reads it with wp_get_global_settings(), merges anything set in
   Appearance → Theme Options, and prints a second :root block into <head> after
   this stylesheet. What you see below is what renders if that never runs.

   Deliberately NOT written as var(--wp--preset--color--*): on a classic theme
   with on-demand asset loading switched on, core defers its global-styles
   stylesheet to wp_footer, so those presets are not guaranteed to exist at first
   paint. Literals here, live values from PHP, no timing dependency either way.

   The contrast ratio noted against each colour is the reason that value exists.
   inc/admin/colors.php re-checks every documented pair server-side on save.
   --------------------------------------------------------------------------- */

:root {
  /* Neutrals and grounds */
  --bone:         #f4f0e8;   /* page */
  --paper:        #fbf9f4;   /* raised */
  --sand:         #eae3d6;   /* inset band */
  --line:         #ded6c6;
  --line-strong:  #c6bca6;

  /* Ink */
  --ink:          #1c3a2e;   /* deep forest, 10.9:1 on bone */
  --ink-soft:     #2e5546;
  --muted:        #4a5a52;   /*  6.4:1 on bone */
  --faint:        #58685f;   /*  5.2:1 on bone, 4.6:1 on the sand band */

  /* Brass. Three values for three grounds: they are not interchangeable. */
  --brass:        #a8802c;   /* fill and large type only, 3.2:1 */
  --brass-deep:   #6e5216;   /* brass TEXT on bone, 6.4:1 */
  --brass-light:  #d0a445;   /* brass on the DARK ground, 5.4:1 on ink */
  --brass-wash:   #f0e7d2;
  --brass-hover:  #c2963a;
  --on-brass:     #241a05;

  /* On dark forest grounds */
  --on-ink:       #f4f0e8;   /* 10.9:1 on ink */
  --on-ink-muted: #b9c6bf;   /*  6.4:1 on ink */
  --on-ink-dim:   #cfdad4;

  /* Grounds that must NEVER appear in the dark-ground remap below.
     --ground-dark is deliberately a separate token from --ink: on .ink-bg and
     friends --ink has already been remapped to the light colour, so
     `background: var(--ink)` would paint the section cream and invert it. */
  --ground-dark:    #1c3a2e;
  --ground-photo:   #0f1d18;
  --accent-on-dark: #e5c882;

  /* Bare RGB triplets, for rgb(... / alpha) compositing. Without these the
     eleven scrim gradient stops and seven hairline alphas stay hardcoded, and
     "change the dark ground" would only be half true. PHP keeps them in step
     with the hex values above. */
  --ink-rgb:            28 58 46;
  --on-ink-rgb:         244 240 232;
  --accent-on-dark-rgb: 229 200 130;
  --scrim-rgb:          12 24 19;

  /* Type */
  --display: 'Cormorant Garamond', ui-serif, Georgia, serif;
  --sans:    'Inter', ui-sans-serif, system-ui, sans-serif;
  --arabic:  'Amiri', ui-serif, serif;

  /* Cormorant at 300 needs to be set BIG to read as intentional rather than
     thin. Nothing below --t-title uses it. */
  --t-mega:    clamp(3.25rem, 8vw, 7.5rem);
  --t-hero:    clamp(2.75rem, 6vw, 5.5rem);
  --t-display: clamp(2.25rem, 4.4vw, 3.75rem);
  --t-title:   clamp(1.625rem, 2.6vw, 2.25rem);
  --t-lead:    clamp(1.125rem, 1.5vw, 1.375rem);
  --t-eyebrow: 0.6875rem;

  /* Space */
  --shell:   78rem;
  --measure: 42rem;
  --gutter:  1.5rem;
  --bay:     clamp(4.5rem, 9vw, 8.5rem);   /* vertical rhythm between bands */

  --radius: 2px;                           /* institutional = almost no rounding */
  --radius-pill: 999px;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

@media (min-width: 48em) { :root { --gutter: 2.5rem; } }

/* ---------------------------------------------------------------------------
   1. RESET
   Structure only. Section 11 re-establishes list markers, paragraph margins
   and link underlines inside .entry-content: this reset is written for
   hand-authored markup where every gap is an explicit .mt-* utility, and
   block-editor prose needs those defaults back.
   --------------------------------------------------------------------------- */

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

* {
  margin: 0;
}

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

body {
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

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

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

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

h1,
h2,
h3,
h4 {
  font-weight: inherit;
  text-wrap: balance;
}

p,
li {
  text-wrap: pretty;
}

ul,
ol {
  list-style: none;
  padding: 0;
}

a {
  color: inherit;
  text-decoration: none;
}

table {
  border-collapse: collapse;
  width: 100%;
}

/* Visually hidden, still announced. `.visually-hidden--focusable` reveals
   itself on focus, which is how the skip-link works. */
.visually-hidden,
.visually-hidden--focusable:not(:focus):not(:focus-within) {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* A 6rem sticky masthead swallows any #anchor the smooth scroll lands on. */
html { scroll-padding-top: 7rem; }
figure { margin: 0; }


/* ---------------------------------------------------------------------------
   2. BASE
   --------------------------------------------------------------------------- */

body {
  background: var(--bone);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 1.0625rem;
  line-height: 1.65;
}

h1, h2, h3 {
  font-family: var(--display);
  font-weight: 300;
  line-height: 1.04;
  letter-spacing: -0.015em;
}

strong { font-weight: 600; }

:focus-visible {
  outline: 2px solid var(--brass-deep);
  outline-offset: 3px;
}

[lang='ar'] { font-family: var(--arabic); line-height: 2; font-weight: 400; }

::selection { background: var(--brass-wash); color: var(--ink); }

/* ---------------------------------------------------------------------------
   3. LAYOUT
   --------------------------------------------------------------------------- */

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

.shell--tight { max-width: 58rem; }
.shell--read { max-width: var(--measure); }

.bay { padding-block: var(--bay); }
.bay--half { padding-block: calc(var(--bay) * 0.55); }

.sand { background: var(--sand); }

/* Remap the tokens on every dark ground rather than listing the classes that
   use them. Overriding `.ink-bg .muted` only catches elements that literally
   carry `.muted`; it misses `.stats dd`, `.facts dd`, `blockquote cite` and
   anything added later. Remapping the variable catches all of them. */
.ink-bg,
.page-head,
.band-photo,
.fork__door,
.site-footer {
  --muted: var(--on-ink-muted);
  --faint: var(--on-ink-muted);
  --brass-deep: var(--brass-light);
  --ink: var(--on-ink);          /* so text defaulting to --ink stays legible */
}

.ink-bg { background-color: var(--ground-dark); color: var(--on-ink); }
.site-footer { background-color: var(--ground-dark); }
.page-head { background-color: var(--ground-dark); }

.ink-bg .eyebrow,
.page-head .eyebrow,
.band-photo .eyebrow,
.fork__door .eyebrow { color: var(--brass-light); }   /* plain brass is only 3.4:1 here */

.ink-bg .stats dt,
.page-head .stats dt { color: var(--brass-light); }

.cluster { display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: center; }
.cluster--center { justify-content: center; }
.cluster--between { justify-content: space-between; }


/* Asymmetric editorial split. Never an even 50/50, which reads as a template. */
.split { display: grid; gap: clamp(2rem, 4vw, 4.5rem); }

@media (min-width: 60em) {
  .split { grid-template-columns: 5fr 7fr; align-items: start; }
  .split--flip { grid-template-columns: 7fr 5fr; }
  .split--even { grid-template-columns: 1fr 1fr; }
  .split--center { align-items: center; }
}

.stick { align-self: start; }
@media (min-width: 60em) { .stick { position: sticky; top: 7.5rem; } }

.mt-xs { margin-top: 0.5rem; }
.mt-sm { margin-top: 1rem; }
.mt-md { margin-top: 1.75rem; }
.mt-lg { margin-top: 2.75rem; }
.mt-xl { margin-top: 4rem; }

/* ---------------------------------------------------------------------------
   4. TYPOGRAPHY
   --------------------------------------------------------------------------- */

.t-mega    { font-size: var(--t-mega); }
.t-hero    { font-size: var(--t-hero); }
.t-display { font-size: var(--t-display); }
.t-title   { font-size: var(--t-title); line-height: 1.12; }

.eyebrow {
  font-family: var(--sans);
  font-size: var(--t-eyebrow);
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  line-height: 1;
  color: var(--brass-deep);
}

.lead { font-size: var(--t-lead); line-height: 1.6; color: var(--muted); }
.measure { max-width: var(--measure); }
.measure--center { margin-inline: auto; }

.muted { color: var(--muted); }
.faint { color: var(--faint); }
.small { font-size: 0.875rem; color: var(--muted); }
.center { text-align: center; }
.nums { font-variant-numeric: tabular-nums; }

/* Italic serif emphasis, the one flourish this concept allows itself. */
.em { font-style: italic; color: var(--brass-deep); }

hr.rule { border: 0; border-top: 1px solid var(--line); margin-block: 2.5rem; }
.dropcap::first-letter {
  font-family: var(--display);
  font-size: 4em;
  line-height: 0.78;
  font-weight: 300;
  float: left;
  padding-right: 0.08em;
  padding-top: 0.04em;
  color: var(--brass-deep);
}

blockquote.pull {
  border-left: 1px solid var(--brass);
  padding-left: 1.5rem;
}

blockquote.pull p { font-family: var(--display); font-size: 1.5rem; line-height: 1.3; }
blockquote.pull cite { display: block; margin-top: 0.75rem; font-size: 0.8125rem; font-style: normal; color: var(--faint); letter-spacing: 0.08em; text-transform: uppercase; }

/* Standalone testimonial. Deliberately NOT --t-display: that scale is for
   section headings of six or eight words. A forty word quote set at 3.75rem
   runs to six lines and reads as a headline rather than as someone speaking. */
blockquote.quote { text-align: center; }

blockquote.quote::before {
  content: '\201C';
  display: block;
  font-family: var(--display);
  font-size: 4.5rem;
  line-height: 0.55;
  color: var(--brass-deep);
  margin-bottom: 1.5rem;
}

.quote-lead {
  font-family: var(--display);
  font-weight: 300;
  font-size: clamp(1.375rem, 2.1vw, 1.875rem);
  line-height: 1.45;
  letter-spacing: -0.004em;
  text-wrap: pretty;
  max-width: 34ch;
  margin-inline: auto;
}

.quote-cite {
  display: block;
  margin-top: 2rem;
  font-family: var(--sans);
  font-size: 0.75rem;
  font-style: normal;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}

.quote-cite::before {
  content: '';
  display: block;
  width: 2.5rem;
  height: 1px;
  background: var(--brass);
  margin: 0 auto 1.25rem;
}

.quote-cite strong { color: var(--ink); font-weight: 600; }

/* ---------------------------------------------------------------------------
   5. BUTTONS
   --------------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.625rem;
  padding: 0.9375rem 1.75rem;
  border-radius: var(--radius);
  font-size: 0.875rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  line-height: 1.2;
  transition: background-color 0.25s var(--ease), color 0.25s var(--ease), box-shadow 0.25s var(--ease);
}

.btn--primary { background: var(--ink); color: var(--on-ink); }
.btn--primary:hover { background: var(--ink-soft); }

.btn--brass { background: var(--brass); color: var(--on-brass); }   /* 8.0:1 */
.btn--brass:hover { background: var(--brass-hover); }

.btn--ghost { color: var(--ink); box-shadow: inset 0 0 0 1px var(--line-strong); }
.btn--ghost:hover { box-shadow: inset 0 0 0 1px var(--ink); }

/* Every dark ground needs the light ghost button, not just .ink-bg. The
   photographic headers and bands are dark too. */
.ink-bg .btn--ghost,
.page-head .btn--ghost,
.band-photo .btn--ghost,
.fork .btn--ghost {
  color: var(--on-ink);
  box-shadow: inset 0 0 0 1px rgb(var(--on-ink-rgb) / 0.4);
}

.ink-bg .btn--ghost:hover,
.page-head .btn--ghost:hover,
.band-photo .btn--ghost:hover,
.fork .btn--ghost:hover {
  background: rgb(var(--on-ink-rgb) / 0.1);
  box-shadow: inset 0 0 0 1px var(--on-ink);
}

.btn--sm { padding: 0.625rem 1.125rem; }
.btn--full { width: 100%; }

/* Underlined text link, the workhorse of this concept. */
.link {
  display: inline-block;
  font-weight: 600;
  font-size: 0.9375rem;
  color: var(--ink);
  border-bottom: 1px solid var(--brass);
  padding-bottom: 2px;
  transition: border-color 0.2s var(--ease), color 0.2s var(--ease);
}

.link:hover { color: var(--brass-deep); border-bottom-color: var(--brass-deep); }
.ink-bg .link { color: var(--on-ink); }

.skip-link { position: absolute; top: 1rem; left: 1rem; z-index: 90; }

/* ---------------------------------------------------------------------------
   6. BANDS & PHOTOGRAPHY
   The structural signature of this concept. Full-bleed imagery with text sat
   on it, alternating which side the text takes.
   --------------------------------------------------------------------------- */

/* Every photographic container carries an opaque dark base. Without it, a photo
   that fails to load leaves light text sitting on the page's own light ground. */
.band-photo {
  position: relative;
  isolation: isolate;
  background-color: var(--ground-photo);
  min-height: clamp(26rem, 60vh, 40rem);
  display: grid;
  align-items: end;
  color: var(--on-ink);
  overflow: hidden;
}

.band-photo img {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Scrim: without it, text over photography fails contrast at some crops. */
.band-photo::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(to top, rgb(var(--scrim-rgb) / 0.88) 0%, rgb(var(--scrim-rgb) / 0.55) 45%, rgb(var(--scrim-rgb) / 0.15) 100%);
}

.band-photo__body { padding-block: clamp(2.5rem, 5vw, 4rem); max-width: 40rem; }
.band-photo--right .band-photo__body { margin-left: auto; }
.band-photo--center { align-items: center; text-align: center; }
.band-photo--center .band-photo__body { margin-inline: auto; }
.band-photo .eyebrow { color: var(--accent-on-dark); }

/* Page header for inner pages: shorter photographic strip. */
.page-head {
  position: relative;
  isolation: isolate;
  color: var(--on-ink);
  overflow: hidden;
  padding-block: clamp(4rem, 9vw, 7rem);
}

.page-head img { position: absolute; inset: 0; z-index: -2; width: 100%; height: 100%; object-fit: cover; }
.page-head::after { content: ''; position: absolute; inset: 0; z-index: -1; background: linear-gradient(to top, rgb(var(--scrim-rgb) / 0.9), rgb(var(--scrim-rgb) / 0.7)); }
.page-head .eyebrow { color: var(--accent-on-dark); }
.page-head--plain { background-color: var(--ground-dark); }

/* A standalone figure, used inline in editorial flow. */
figure.plate { margin: 0; }
figure.plate img { width: 100%; height: auto; border-radius: var(--radius); }
figure.plate figcaption { margin-top: 0.75rem; font-size: 0.8125rem; color: var(--faint); }

figure.plate--tall img { aspect-ratio: 4 / 5; object-fit: cover; }
figure.plate--wide img { aspect-ratio: 16 / 9; object-fit: cover; }

/* --- TESTIMONIALS ---------------------------------------------------------
   The design carried one centred quote. The institute has a dozen, short and
   long, so there are two shapes: a grid of the short ones on the home page, and
   a stacked column of the long ones on their own page. Both reuse .quote-lead
   and .quote-cite, at a smaller step in the grid because four 60-word quotes at
   display size is a wall rather than a page. */
.quotes { display: grid; gap: 2.5rem 3rem; text-align: left; }

@media (min-width: 46em) {
  .quotes { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 72em) {
  .quotes { grid-template-columns: repeat(3, 1fr); }
}

.quotes .quote { text-align: left; }
.quotes .quote::before { content: none; }
.quotes .quote-lead {
  font-family: var(--display);
  font-size: 1.125rem;
  line-height: 1.55;
  max-width: none;
  margin-inline: 0;
  padding-left: 1.25rem;
  border-left: 1px solid var(--brass);
}
.quotes .quote-lead + .quote-lead { margin-top: 0.875rem; }
.quotes .quote-cite { margin-top: 1rem; text-align: left; }
.quotes .quote-cite::before { margin-inline: 0; }

/* --- THE LETTERS -----------------------------------------------------------
   The Testimonials page: every testimonial in full, one after another.

   Written first as .quotes--stack -- a column of long quotations with the name
   underneath, which is how the short ones are set. That works for a paragraph
   and fails for six: by the time you reach the name you have read the whole
   piece without knowing whose voice you were in. So the name leads here, and
   the brass hairline the short quotes carry down their left edge becomes a
   short rule under the name instead.

   No filled cells, for the same reason the roster has none: this design
   separates things with rules.
   -------------------------------------------------------------------------- */

.letters { display: block; }

.letter {
  border-top: 1px solid var(--line-strong);
  padding-block: 2.5rem 0.5rem;
  margin: 0;
}

.letter:first-child { border-top: 0; padding-top: 0; }

.letter__by { display: block; }

.letter__name {
  display: block;
  font-family: var(--display);
  font-size: 1.5rem;
  line-height: 1.25;
  color: var(--ink);
  text-wrap: balance;
}

.letter__note {
  display: block;
  margin-top: 0.375rem;
  font-size: 0.75rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--faint);
}

/* The accent, kept short: a full-width rule here would fight the hairline that
   separates one letter from the next. */
.letter__by::after {
  content: "";
  display: block;
  width: 2.5rem;
  margin-top: 1.125rem;
  border-top: 2px solid var(--brass);
}

.letter__body {
  margin: 1.25rem 0 0;
  padding: 0;
  border: 0;
}

.letter__body p {
  margin: 0;
  font-family: var(--sans);
  font-size: 1.0625rem;
  line-height: 1.75;
  color: var(--ink);
  text-wrap: pretty;
}

.letter__body p + p { margin-top: 1.125rem; }

@media (min-width: 54em) {
  .letter { padding-block: 3rem 1rem; }
  .letter__name { font-size: 1.75rem; }
}

/* --- THE ROSTER ------------------------------------------------------------
   Names and roles, several across.

   Written first as a grid of filled cells, which was wrong twice over. This
   design has no boxed cells anywhere: .rules, .facts and .checks are all
   hairline-separated text on the page's own ground. And on the sand band the
   filled cells were the same colour as the band, with --line dividers at 1.13:1
   against it, so the whole grid read as text scattered with unexplained gaps.

   So: no background at all, which means it sits correctly on the sand band and
   on the page alike, and --line-strong for the rule, which at 1.48:1 is actually
   a visible hairline rather than a rumour of one. */
.roster {
  display: grid;
  column-gap: 3rem;
}

@media (min-width: 34em) {
  .roster { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 54em) {
  .roster { grid-template-columns: repeat(3, 1fr); }
}

@media (min-width: 76em) {
  .roster { grid-template-columns: repeat(4, 1fr); }
}

.roster__item {
  border-top: 1px solid var(--line-strong);
  padding-block: 0.9375rem 1.125rem;
}

.roster__name {
  display: block;
  font-family: var(--display);
  font-size: 1.1875rem;
  line-height: 1.3;
  color: var(--ink);
  text-wrap: balance;
}

.roster__role {
  display: block;
  margin-top: 0.25rem;
  font-size: 0.8125rem;
  line-height: 1.45;
  color: var(--faint);
  text-wrap: pretty;
}

/* --- THE SESSION TIMETABLE ------------------------------------------------
   A weekly timetable is a table, so it is one. The hairlines and type come from
   the design's own .facts and .rules, so it sits with them rather than looking
   like a spreadsheet dropped onto the page. */
.schedule { width: 100%; border-collapse: collapse; }

.schedule thead th {
  font-family: var(--sans);
  font-size: var(--t-eyebrow);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--faint);
  font-weight: 600;
  text-align: left;
  padding: 0 0.75rem 0.75rem;
  border-bottom: 1px solid var(--line-strong);
}

.schedule tbody tr { border-bottom: 1px solid var(--line); }
.schedule tbody td,
.schedule tbody th { padding: 1.25rem 0.75rem; text-align: left; vertical-align: middle; }

.schedule__day {
  font-family: var(--display);
  font-size: 1.25rem;
  font-weight: 400;
  white-space: nowrap;
}
.schedule__time { font-weight: 600; white-space: nowrap; }
.schedule__note { display: block; font-size: 0.8125rem; color: var(--faint); margin-top: 0.125rem; }

/* The code sits on white whatever the ground behind it: a scanner needs the
   quiet zone to stay quiet. */
.schedule__qr {
  display: inline-block;
  padding: 0.375rem;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  line-height: 0;
}
.schedule__qr img { width: 5.5rem; height: auto; }
.schedule__join { white-space: nowrap; }
.schedule__join .link { display: block; margin-top: 0.5rem; font-size: 0.8125rem; }

/* On a phone a four-column table cannot be read across, so each row becomes a
   block and the column headings come back in front of each value. */
@media (max-width: 44em) {
  .schedule thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
  .schedule tbody tr { display: block; padding-block: 1.25rem; }
  .schedule tbody th,
  .schedule tbody td { display: block; padding: 0; }
  .schedule__day { font-size: 1.375rem; }

  .schedule tbody td[data-label] { margin-top: 0.5rem; }
  .schedule tbody td[data-label]::before {
    content: attr(data-label);
    display: block;
    font-size: var(--t-eyebrow);
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--faint);
    margin-bottom: 0.25rem;
  }
  .schedule__qr img { width: 7rem; }
}

/* --- JOIN LINKS -----------------------------------------------------------
   WhatsApp and Telegram on the Schedule page. Not in the static design, which
   has no free-sessions page at all. Built from .cluster and .btn--ghost so it
   sits in the same family as every other pair of buttons. */
.join-links__link {
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0.75rem 1.25rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  font-weight: 600;
  font-size: 0.9375rem;
  transition: border-color 0.2s var(--ease), color 0.2s var(--ease);
}
.join-links__link:hover { border-color: var(--brass); color: var(--brass-deep); }
.join-links__mark { width: 1.25rem; height: 1.25rem; flex: 0 0 auto; }

/* --- THE EPISODE PLAYER ----------------------------------------------------
   Not in the static design, which links out and lets the visitor leave. A
   podcast has to be playable on its own page, so an episode carries a frame
   here whether or not a recording exists yet. It borrows .plate's radius and
   16:9 crop so it sits in the same family as every other picture. */
.player { position: relative; border-radius: var(--radius); overflow: hidden; }

/* --- THE EPISODE WATCH PAGE -----------------------------------------------
   Player left, the rest of the series right. One column until there is room
   for both, because a 22rem sidebar beside a 16:9 video needs about 68em. */
.episode { display: grid; gap: 2.5rem; align-items: start; }

@media (min-width: 68em) {
  .episode { grid-template-columns: minmax(0, 1fr) 22rem; gap: 2.5rem 3rem; }
}

.episode__meta { margin-top: 1.25rem; }
.episode__body { margin-top: 2rem; max-width: 42rem; }

.episode-list__head { margin-bottom: 1rem; }
.episode-list__items { display: grid; gap: 0.25rem; }

/* Above the breakpoint the list scrolls on its own, so a long series does not
   push the page down past the player it belongs to. */
@media (min-width: 68em) {
  .episode-list__items { max-height: 30rem; overflow-y: auto; padding-right: 0.5rem; }
}

.episode-list__item a {
  display: grid;
  grid-template-columns: 7.5rem 1fr;
  gap: 0.875rem;
  padding: 0.5rem;
  border-radius: var(--radius);
  transition: background 0.2s var(--ease);
}
.episode-list__item a:hover { background: var(--sand); }
.episode-list__item.is-current a { background: var(--sand); }

.episode-list__art { position: relative; display: block; aspect-ratio: 16 / 9; overflow: hidden; border-radius: var(--radius); background: var(--ground-photo); }
.episode-list__art img { width: 100%; height: 100%; object-fit: cover; }

/* The same play mark as the main player, at list size. */
.episode-list__mark {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  background: rgb(var(--ink-rgb) / 0.55);
  border: 1px solid rgb(var(--on-ink-rgb) / 0.65);
  display: grid;
  place-items: center;
}
.episode-list__mark::before {
  content: '';
  border-style: solid;
  border-width: 0.25rem 0 0.25rem 0.4rem;
  border-color: transparent transparent transparent var(--on-ink);
  transform: translateX(18%);
}

.episode-list__text { min-width: 0; align-self: center; }
.episode-list__title {
  display: block;
  font-family: var(--display);
  font-size: 1rem;
  line-height: 1.3;
  color: var(--ink);
  overflow-wrap: anywhere;
}
.episode-list__meta { display: block; margin-top: 0.25rem; font-size: 0.75rem; color: var(--faint); }
.episode-list__item.is-current .episode-list__title { color: var(--brass-deep); }

/* --- THE POSTER CAPTION ---------------------------------------------------
   The episode's name is set over its artwork rather than baked into the image,
   so every episode carries the same type whoever adds it, the text stays sharp
   at any width, and it can be read aloud and translated. */
.player__caption {
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  padding: clamp(1rem, 3vw, 2rem);
  background: linear-gradient(to top, rgb(var(--scrim-rgb) / 0.85), rgb(var(--scrim-rgb) / 0));
  color: var(--on-ink);
  pointer-events: none;
}
.player__caption-meta {
  display: block;
  font-size: var(--t-eyebrow);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--brass-light);
  margin-bottom: 0.5rem;
}
.player__caption-title {
  display: block;
  font-family: var(--display);
  font-size: clamp(1.125rem, 2.6vw, 1.75rem);
  line-height: 1.2;
  text-wrap: balance;
}

/* The facade: our artwork, our button, and no YouTube until it is pressed. */
.player__frame { position: relative; display: block; aspect-ratio: 16 / 9; background: var(--ground-photo); }
.player__frame img,
.player__frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; border: 0; }
.player__frame img { filter: saturate(0.8) brightness(0.82); transition: filter 0.3s var(--ease); }
.player__frame:hover img { filter: saturate(0.95) brightness(0.95); }

.player__play { position: absolute; inset: 0; display: grid; place-items: center; cursor: pointer; }
.player__play-mark {
  width: clamp(3.5rem, 7vw, 5rem);
  aspect-ratio: 1;
  border-radius: 50%;
  background: rgb(var(--on-ink-rgb) / 0.16);
  border: 1px solid rgb(var(--on-ink-rgb) / 0.7);
  display: grid;
  place-items: center;
  transition: background 0.2s var(--ease), transform 0.2s var(--ease), border-color 0.2s var(--ease);
}
.player__play:hover .player__play-mark { background: var(--brass); border-color: var(--brass); transform: scale(1.06); }
.player__play:focus-visible .player__play-mark { outline: 2px solid var(--on-ink); outline-offset: 4px; }
.player__play-mark::before {
  content: '';
  border-style: solid;
  border-width: 0.6rem 0 0.6rem 1rem;
  border-color: transparent transparent transparent var(--on-ink);
  transform: translateX(15%);
}

/* Video, from any provider: oEmbed hands back an iframe with fixed width and
   height attributes, so the ratio has to be imposed here rather than trusted. */
.player > iframe,
.player > video,
.player .wp-video,
.player .wp-video-shortcode {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  border: 0;
}

/* Audio is a strip, not a picture: no crop, and room to breathe. */
.player--audio { background: var(--sand); border: 1px solid var(--line); padding: 1rem; }
.player--audio > iframe { aspect-ratio: auto; height: 152px; }
.player--audio .wp-audio-shortcode,
.player--audio audio { display: block; width: 100%; }

/* The frame before a recording exists. The artwork is dimmed under the ink
   wash so the caption stays legible over any photograph. */
figure.player--poster { margin: 0; }
figure.player--poster img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  filter: saturate(0.55);
}
.player--poster::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, rgb(var(--ink-rgb) / 0.25), rgb(var(--ink-rgb) / 0.78));
  pointer-events: none;
}
.player__note {
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 1.25rem;
  color: var(--on-ink);
  font-size: 0.9375rem;
  text-wrap: pretty;
}

/* A play mark, drawn rather than shipped as an asset: one triangle inside one
   circle, so it inherits the palette and needs no image request. */
.player__mark {
  flex: 0 0 auto;
  width: 2.5rem;
  height: 2.5rem;
  border: 1px solid rgb(var(--on-ink-rgb) / 0.55);
  border-radius: 50%;
  position: relative;
}
.player__mark::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-40%, -50%);
  border-style: solid;
  border-width: 0.4375rem 0 0.4375rem 0.75rem;
  border-color: transparent transparent transparent var(--on-ink);
}

@media (max-width: 34em) {
  .player__note { padding: 1rem; font-size: 0.875rem; }
  .player__mark { width: 2rem; height: 2rem; }
  .player__mark::before { border-width: 0.35rem 0 0.35rem 0.6rem; }
}

/* --- THE FORK -------------------------------------------------------------
   The homepage's defining element. Two doors, side by side, full width. */
.fork { display: grid; }

@media (min-width: 52em) { .fork { grid-template-columns: 1fr 1fr; } }

.fork__door {
  position: relative;
  isolation: isolate;
  background-color: var(--ground-photo);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: clamp(22rem, 46vh, 32rem);
  padding: clamp(2rem, 4vw, 3.5rem);
  color: var(--on-ink);
  transition: color 0.3s var(--ease);
}

.fork__door img {
  position: absolute; inset: 0; z-index: -2;
  width: 100%; height: 100%; object-fit: cover;
  transition: transform 0.9s var(--ease);
}

.fork__door::after {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(to top, rgb(var(--scrim-rgb) / 0.92) 10%, rgb(var(--scrim-rgb) / 0.5) 60%, rgb(var(--scrim-rgb) / 0.25) 100%);
  transition: background 0.4s var(--ease);
}

.fork__door:hover img { transform: scale(1.04); }
.fork__door:hover::after { background: linear-gradient(to top, rgb(var(--scrim-rgb) / 0.94) 10%, rgb(var(--scrim-rgb) / 0.62) 65%, rgb(var(--scrim-rgb) / 0.3) 100%); }

.fork__door .eyebrow { color: var(--accent-on-dark); }
.fork__door h2 { margin-top: 0.75rem; font-size: var(--t-display); }
.fork__door p { margin-top: 0.875rem; color: var(--on-ink-dim); max-width: 30rem; }
.fork__arrow { margin-top: 1.5rem; display: inline-flex; align-items: center; gap: 0.5rem; font-weight: 600; font-size: 0.9375rem; }
.fork__door:hover .fork__arrow { color: var(--accent-on-dark); }


/* ---------------------------------------------------------------------------
   7. RULE LISTS & EDITORIAL
   This concept has no cards. Structure comes from hairlines and numbering.
   --------------------------------------------------------------------------- */

/* The numbers are generated, not typed. In the static concept every row carried
   a literal "01"/"02", which is why the "Beyond the cohorts" list on courses.html
   starts at 03: it was copied from the homepage and never renumbered. A counter
   makes that class of bug impossible, and lets a Query Loop number its own rows.
   Templates emit <span class="rules__num"></span> with no content. */
.rules { border-top: 1px solid var(--line); counter-reset: mti-rule; }
.rules > * { border-bottom: 1px solid var(--line); counter-increment: mti-rule; }
.rules__num::before { content: counter(mti-rule, decimal-leading-zero); }

.rules__row {
  display: grid;
  gap: 0.5rem 2.5rem;
  padding-block: clamp(1.5rem, 3vw, 2.25rem);
  align-items: baseline;
}

@media (min-width: 46em) {
  .rules__row { grid-template-columns: 4rem 1fr; }
  .rules__row--wide { grid-template-columns: 4rem 18rem 1fr; }
}

.rules__num {
  font-family: var(--display);
  font-size: 1.75rem;
  color: var(--brass-deep);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.rules__term { font-family: var(--display); font-size: var(--t-title); transition: color 0.2s var(--ease); }
a.rules__row:hover .rules__term { color: var(--brass-deep); }
.rules__body { color: var(--muted); }

/* Definition table for facts, the alternative to a stats card. */
.facts { border-top: 1px solid var(--line); }
.facts > * {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 1.5rem; padding-block: 0.875rem; border-bottom: 1px solid var(--line);
}
.facts dt { color: var(--faint); font-size: 0.875rem; letter-spacing: 0.04em; }
/* Long values (email addresses) must break rather than push the row wide. */
.facts dd { font-weight: 600; text-align: right; min-width: 0; overflow-wrap: anywhere; }
.ink-bg .facts, .ink-bg .facts > * { border-color: rgb(var(--on-ink-rgb) / 0.18); }
.ink-bg .facts dt { color: var(--on-ink-muted); }

/* Oversized statistic set. */
.stats { display: grid; gap: 2.5rem 2rem; }
@media (min-width: 40em) { .stats { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 64em) { .stats--4 { grid-template-columns: repeat(4, 1fr); } }

.stats dt { font-family: var(--display); font-size: clamp(3rem, 6vw, 4.5rem); font-weight: 300; line-height: 0.9; color: var(--brass-deep); font-variant-numeric: tabular-nums; }
.stats dd { margin-top: 0.625rem; font-size: 0.9375rem; color: var(--muted); max-width: 22ch; }
.ink-bg .stats dt { color: var(--brass); }

/* Checklist. */
.checks { display: grid; gap: 0.75rem 2rem; }
@media (min-width: 46em) { .checks { grid-template-columns: repeat(2, 1fr); } }
.checks li { display: flex; gap: 0.75rem; align-items: baseline; }
.checks li::before { content: '·'; color: var(--brass); font-size: 1.5rem; line-height: 1; flex-shrink: 0; }

/* Pricing, set as a rule list rather than three cards. */
.plans { border-top: 1px solid var(--line); }
.plans > li { border-bottom: 1px solid var(--line); }
.plan {
  display: grid; gap: 0.375rem 2rem; align-items: center;
  padding-block: 1.75rem;
}
@media (min-width: 46em) { .plan { grid-template-columns: 1fr auto auto; } }
.plan__amount { font-family: var(--display); font-size: clamp(2.25rem, 4vw, 3rem); line-height: 1; font-variant-numeric: tabular-nums; }
.plan__amount small { font-family: var(--sans); font-size: 1rem; color: var(--faint); }
.plan__label { font-family: var(--display); font-size: var(--t-title); }
.plan--featured .plan__amount { color: var(--brass-deep); }

.tag {
  display: inline-block; padding: 0.1875rem 0.625rem;
  border-radius: var(--radius-pill);
  background: var(--brass-wash); color: var(--brass-deep);
  font-size: 0.6875rem; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
}
.ink-bg .tag { background: rgb(var(--accent-on-dark-rgb) / 0.16); color: var(--accent-on-dark); }

/* FAQ on <details> so it works without JavaScript. */
.faq { border-top: 1px solid var(--line); }
.faq > details { border-bottom: 1px solid var(--line); }
.faq summary {
  display: flex; align-items: baseline; justify-content: space-between; gap: 1.5rem;
  padding-block: 1.375rem; cursor: pointer; list-style: none;
  font-family: var(--display); font-size: var(--t-title);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::marker { content: ''; }
.faq summary::after { content: '+'; font-family: var(--sans); font-size: 1.125rem; color: var(--brass-deep); transition: transform 0.25s var(--ease); }
.faq details[open] summary::after { transform: rotate(45deg); }
.faq p { padding-bottom: 1.5rem; color: var(--muted); max-width: var(--measure); }

/* Placeholder marker. */

/* --- THE PARTNER RAIL ------------------------------------------------------
   One row, scrolling, with each mark half again as large as it used to be.

   It wrapped onto as many lines as it needed, which was right for the six the
   design was drawn with. At eleven, keeping them on the page had shrunk every
   mark to 44px tall -- and a wordmark set inside a seal is a smudge at 44px.
   The institute asked to be able to see them.

   The scrolling is the browser's own: a flex row that overflows. A swipe works
   on a phone, shift-scroll on a desktop, and the arrow keys work because the
   row is focusable. site.js adds the arrows and the slow auto-advance on top of
   that; with no JavaScript this is still a row you can scroll, and nothing is
   hidden behind a control that does not work.
   -------------------------------------------------------------------------- */

/* The arrows live in this padding rather than over the row: sitting on top of
   it they clipped whichever logo happened to be at the edge. */
.logo-rail { position: relative; padding-inline: 3.25rem; }

@media (max-width: 46em) {
  /* No room to give up on a phone, and no arrows there either -- a swipe is
     the control. */
  .logo-rail { padding-inline: 0; }
  .logo-rail__nav { display: none; }
}

.logos {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 3.5rem;
  overflow-x: auto;
  padding-block: 0.5rem;
  scrollbar-width: none;          /* the arrows and the fades say it scrolls */
}

.logos::-webkit-scrollbar { display: none; }
.logos > li { flex: 0 0 auto; }

.logos img {
  height: 4.5rem;
  width: auto;
  opacity: 0.55;
  transition: opacity 0.2s var(--ease);
}

.logos img:hover { opacity: 1; }

/* Focus lands on the row itself, since that is what the arrow keys drive. */
.logos:focus-visible { outline: 2px solid var(--brass); outline-offset: 0.5rem; }

/* Only while there is somewhere to scroll: site.js sets these. */
.logo-rail[data-overflow] .logos { mask-image: linear-gradient(90deg, transparent, #000 3rem, #000 calc(100% - 3rem), transparent); }
.logo-rail[data-at-start] .logos { mask-image: linear-gradient(90deg, #000 calc(100% - 3rem), transparent); }
.logo-rail[data-at-end] .logos { mask-image: linear-gradient(90deg, transparent, #000 3rem); }

.logo-rail__nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 1;
  width: 2.5rem;
  height: 2.5rem;
  padding: 0;
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  background: var(--bone);
  color: var(--ink);
  cursor: pointer;
  transition: border-color 0.2s var(--ease), background-color 0.2s var(--ease);
}

.logo-rail__nav:hover { border-color: var(--brass); background: var(--sand); }
.logo-rail__nav:focus-visible { outline: 2px solid var(--brass); outline-offset: 2px; }
.logo-rail__nav[hidden] { display: none; }
.logo-rail__nav--prev { left: 0; }
.logo-rail__nav--next { right: 0; }

/* The chevron, drawn rather than fetched: two borders and a rotation. */
.logo-rail__nav::before {
  content: "";
  display: block;
  width: 0.5rem;
  height: 0.5rem;
  margin-inline: auto;
  border-top: 1.5px solid currentColor;
  border-right: 1.5px solid currentColor;
}

.logo-rail__nav--prev::before { transform: translateX(0.15rem) rotate(-135deg); }
.logo-rail__nav--next::before { transform: translateX(-0.15rem) rotate(45deg); }

/* On the sand band the button has to sit on sand, not on the page. */
.sand .logo-rail__nav { background: var(--sand); }
.sand .logo-rail[data-overflow] .logos,
.sand .logo-rail[data-at-start] .logos,
.sand .logo-rail[data-at-end] .logos { mask-image: none; }

/* No scroll snapping here on purpose: a logo strip has no slides to snap to,
   and it fought the arrows. scroll-behavior is left alone too -- site.js asks
   for a smooth scroll and then makes sure it actually happened, because some
   browsers ignore the request and a page that is not visible runs no animation
   frames at all. */

/* Ayah, set as a quiet full-width band. */
.ayah { text-align: center; }
.ayah__ar { font-size: clamp(2rem, 5.5vw, 3.75rem); line-height: 1.9; }
.ayah__tr { font-family: var(--display); font-style: italic; font-size: 1.25rem; }
.ayah__ref { font-size: var(--t-eyebrow); letter-spacing: 0.18em; text-transform: uppercase; color: var(--faint); }
/* The client asked for MEASURED and TONES to stand out: the translation is
   where the institute's name comes from. --ink is the forest already carrying
   body text and the announcement bar, so this introduces no new colour. */
.ayah__en strong { color: var(--ink); font-weight: 600; }

/* ---------------------------------------------------------------------------
   8. FORMS
   --------------------------------------------------------------------------- */

.field-group { display: grid; gap: 1.25rem; }
@media (min-width: 40em) { .field-group--2 { grid-template-columns: 1fr 1fr; } }
.field-group .full { grid-column: 1 / -1; }

.label { display: block; font-size: 0.8125rem; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--faint); }
.label .req { color: var(--brass-deep); }

.field {
  width: 100%; margin-top: 0.5rem; padding: 0.8125rem 0;
  border: 0; border-bottom: 1px solid var(--line-strong);
  background: transparent; color: var(--ink);
  border-radius: 0;
  transition: border-color 0.2s var(--ease);
}
.field:focus { outline: none; border-bottom-color: var(--ink); border-bottom-width: 2px; }
.field::placeholder { color: var(--faint); }
textarea.field { min-height: 8rem; resize: vertical; }
select.field { appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--faint) 50%), linear-gradient(135deg, var(--faint) 50%, transparent 50%); background-position: calc(100% - 12px) 1.35rem, calc(100% - 7px) 1.35rem; background-size: 5px 5px; background-repeat: no-repeat; }

.field-inline { display: flex; gap: 0.75rem; align-items: flex-end; }
.field-inline .field { flex: 1; }

/* Donation amounts, as a segmented row rather than three cards. */
.amounts { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; border: 1px solid var(--line-strong); }
/* The picker is radio inputs and labels, not buttons: the design's aria-pressed
   buttons held their state only in JavaScript and discarded it on submit. These
   selectors must follow the markup, or the tiles lose their padding, their
   dividers and any sign of which one is chosen. */
.amounts label { padding: 1.125rem 0.75rem; text-align: center; border-right: 1px solid var(--line-strong); transition: background 0.2s var(--ease); display: block; }
.amounts label:last-of-type { border-right: 0; }
.amounts input:checked + label { background: var(--ink); color: var(--on-ink); }
.amounts .amt { display: block; font-family: var(--display); font-size: 1.75rem; line-height: 1; }
.amounts .amt-label { display: block; margin-top: 0.375rem; font-size: 0.75rem; color: var(--faint); }
.amounts input:checked + label .amt-label { color: var(--on-ink-muted); }

.toggle { display: inline-flex; border: 1px solid var(--line-strong); }
.toggle label { padding: 0.5rem 1.25rem; font-size: 0.8125rem; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--faint); }
.toggle input:checked + label { background: var(--ink); color: var(--on-ink); }

.meter { height: 2px; background: var(--line); overflow: hidden; }
.meter__fill { height: 100%; background: var(--brass); }

/* ---------------------------------------------------------------------------
   9. HEADER, ANNOUNCEMENT BAR, MEGA-MENU
   --------------------------------------------------------------------------- */

.announce {
  background: var(--ink);
  color: var(--on-ink);
  font-size: 0.8125rem;
  text-align: center;
  padding-block: 0.625rem;
}
.announce a { border-bottom: 1px solid rgb(var(--accent-on-dark-rgb) / 0.6); color: var(--accent-on-dark); font-weight: 600; margin-left: 0.5rem; }
.announce a:hover { border-bottom-color: var(--accent-on-dark); }

.site-header {
  position: sticky; top: 0; z-index: 60;
  background: color-mix(in srgb, var(--bone) 94%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}

.masthead { display: flex; align-items: center; justify-content: space-between; gap: 2rem; height: 6rem; }

/* Wordmark sits BENEATH the mark, not beside it. */
.brand {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.375rem;
  flex-shrink: 0;
  color: var(--ink);
  line-height: 1;
}
.brand__mark {
  height: 30px;
  width: auto;
  flex-shrink: 0;
  color: var(--ink);     /* inline svg fills with currentColor */
}

/* The full lockup carries its own wordmark, so it only appears where there is
   room for that wordmark to be legible: the footer, not the header. */
.brand--full { display: inline-flex; }

.brand__logo {
  height: 46px;
  width: auto;            /* 416:87, so size by height only */
  flex-shrink: 0;
  color: var(--on-ink);
}
.brand__name { font-family: var(--display); font-size: 0.9375rem; font-weight: 400; line-height: 1; letter-spacing: 0.01em; }
.brand__sub { display: block; margin-top: 0.25rem; font-family: var(--sans); font-size: 0.5625rem; font-weight: 600; letter-spacing: 0.2em; text-transform: uppercase; color: var(--faint); }

.site-nav { display: none; }
.masthead__actions { display: none; }

@media (min-width: 68em) {
  .site-nav { display: flex; align-items: center; gap: 2rem; }
  .masthead__actions { display: flex; align-items: center; gap: 1.25rem; }
  .nav-toggle { display: none; }
}

.nav-link {
  font-size: 0.9375rem; font-weight: 500; color: var(--muted);
  padding-block: 0.25rem;
  border-bottom: 1px solid transparent;
  transition: color 0.2s var(--ease), border-color 0.2s var(--ease);
}
.nav-link:hover, .nav-link[aria-current='page'] { color: var(--ink); border-bottom-color: var(--brass); }

/* Mega-menu: opens on hover and on focus-within, so keyboard users get it too. */
.has-mega { position: relative; }
.mega {
  position: absolute; top: calc(100% + 1px); left: 50%; transform: translateX(-50%) translateY(-6px);
  width: min(46rem, 90vw);
  background: var(--paper);
  border: 1px solid var(--line);
  padding: 2rem;
  display: grid; gap: 1.5rem 2.5rem;
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity 0.22s var(--ease), transform 0.22s var(--ease), visibility 0.22s;
  box-shadow: 0 24px 60px -30px rgb(var(--ink-rgb) / 0.35);
}
@media (min-width: 48em) { .mega { grid-template-columns: repeat(2, 1fr); } }
.has-mega:hover .mega, .has-mega:focus-within .mega { opacity: 1; visibility: visible; pointer-events: auto; transform: translateX(-50%) translateY(0); }
.mega__item { display: block; padding: 0.5rem; }
.mega__item strong { display: block; font-family: var(--display); font-size: 1.25rem; font-weight: 400; }
.mega__item span { display: block; margin-top: 0.125rem; font-size: 0.8125rem; color: var(--faint); }
.mega__item:hover strong { color: var(--brass-deep); }

.nav-toggle { padding: 0.5rem 0.875rem; }

.nav-panel { border-top: 1px solid var(--line); background: var(--bone); max-height: 75vh; overflow-y: auto; }
.nav-panel__group { padding-block: 1.25rem; border-bottom: 1px solid var(--line); }
.nav-panel__group > .eyebrow { display: block; margin-bottom: 0.75rem; }
.nav-panel a { display: block; padding-block: 0.5rem; font-family: var(--display); font-size: 1.375rem; }
.nav-panel .cluster { padding-block: 1.5rem; }
.nav-panel .btn { flex: 1; }

.crumbs { display: flex; flex-wrap: wrap; gap: 0.5rem; font-size: 0.8125rem; color: var(--on-ink-muted); }
.crumbs a:hover { color: var(--on-ink); }

/* ---------------------------------------------------------------------------
   10. FOOTER & MOTION
   --------------------------------------------------------------------------- */

.site-footer { color: var(--on-ink); padding-block: clamp(3.5rem, 7vw, 5.5rem) 3rem; }
.site-footer a { color: var(--on-ink); }
.site-footer__grid { display: grid; gap: 3rem; }
@media (min-width: 60em) { .site-footer__grid { grid-template-columns: 2fr 1fr 1fr 1.2fr; } }
.site-footer h2 { font-family: var(--sans); font-size: var(--t-eyebrow); font-weight: 600; letter-spacing: 0.2em; text-transform: uppercase; color: var(--on-ink-muted); }
.site-footer ul { margin-top: 1.25rem; display: grid; gap: 0.75rem; font-size: 0.9375rem; }
.site-footer ul a:hover { color: var(--accent-on-dark); }
.site-footer .brand { color: var(--on-ink); }
/* `.site-footer a` outranks `.btn--brass`, which silently repainted the footer
   CTA light-on-brass at 3.2:1. Restore the button's own colour. */
.site-footer .btn--brass { color: var(--on-brass); }
/* Under the button, deliberately quieter than it: a second full-weight call
   would read as two asks rather than one ask with a gentler option beside it. */
.site-footer .foot-monthly { margin-top: 0.875rem; font-size: 0.8125rem; }
.site-footer .foot-monthly a { color: var(--on-ink-muted); text-decoration: underline; text-underline-offset: 0.2em; }
.site-footer .foot-monthly a:hover { color: var(--accent-on-dark); }

.site-footer .brand img { color: var(--on-ink); }
.site-footer .brand__sub { color: var(--on-ink-muted); }
.site-footer .field { border-bottom-color: rgb(var(--on-ink-rgb) / 0.35); color: var(--on-ink); }
.site-footer .field:focus { border-bottom-color: var(--accent-on-dark); }
.site-footer .field::placeholder { color: rgb(var(--on-ink-rgb) / 0.5); }
.site-footer .label { color: var(--on-ink-muted); }
.colophon { margin-top: 3.5rem; padding-top: 1.75rem; border-top: 1px solid rgb(var(--on-ink-rgb) / 0.18); display: flex; flex-wrap: wrap; gap: 1rem; justify-content: space-between; font-size: 0.8125rem; color: var(--on-ink-muted); }

.reveal { opacity: 0; transform: translateY(14px); transition: opacity 0.7s var(--ease), transform 0.7s var(--ease); }
.reveal.is-visible { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
  .fork__door img, .fork__door::after { transition: none; }
}

/* ---------------------------------------------------------------------------
   11. WORDPRESS ADDITIONS

   None of this existed in the static concept. It covers the three things a CMS
   introduces that hand-authored pages never had: prose a client types, markup
   core emits, and states a form can be in.
   --------------------------------------------------------------------------- */

/* --- Utilities replacing the concept's inline style attributes ------------- */
.u-w-18ch  { max-width: 18ch; margin-inline: auto; }
.u-w-22rem { max-width: 22rem; }
.u-w-26rem { max-width: 26rem; }
.u-one-col { grid-template-columns: 1fr; }
.u-stack-sm { display: grid; gap: 0.5rem; }
.u-center-screen { min-height: 60vh; display: grid; place-items: center; }

/* --- The mobile nav panel -------------------------------------------------
   The concept relied entirely on the user agent's [hidden]{display:none}: there
   was no author rule for it at all. Any plugin or block stylesheet that sets
   `display` on .nav-panel beats the UA sheet and pins the panel permanently
   open, with no visible cause. State the contract explicitly. The !important is
   a correctness guard, not a style preference, and it is the only one here. */
.nav-panel[hidden] { display: none !important; }

/* Scroll lock while the panel is open. Set as a class on <html> rather than by
   writing body.style.overflow, so we never stomp a value someone else set. */
html.nav-open, html.nav-open body { overflow: hidden; }

/* --- Prose scope ----------------------------------------------------------
   The reset zeroes margins, strips list markers and removes link underlines,
   right for hand-authored markup where every gap is an explicit .mt-* utility,
   wrong for anything written in the block editor. Restore normal typographic
   defaults wherever a client's own words are rendered. */
/* Prose spacing, but not between the design's own bands. A page assembled from
   patterns has <section> children that already carry their own vertical rhythm
   through .bay; adding a paragraph gap on top of that opens a seam between every
   band that the design does not have. */
.entry-content > * + *:not(section):not(.wp-block-group) { margin-top: 1.25rem; }

/* :not([class*='mt-']) is load-bearing. `.entry-content p` is specificity (0,1,1)
   and `.mt-md` is (0,1,0), so without it this rule silently overrides every
   spacing utility the design puts on a paragraph, which is the whole vertical
   rhythm, on every page. Form and notice markup is excluded for the same reason. */
.entry-content p:not([class*='mt-']):not(.small):not(.field-error),
.entry-content ul:not([class*='mt-']):not(.rules):not(.checks):not(.logos):not(.plans),
.entry-content ol:not([class*='mt-']),
.entry-content dl:not([class*='mt-']):not(.facts):not(.stats),
.entry-content table,
.entry-content figure:not([class*='mt-']):not(.plate),
.entry-content pre { margin-block: 1.25rem; }

/* Nothing inside a form belongs to the prose scope. */
.entry-content form p,
.entry-content form ul,
.entry-content .form-notice ul { margin-block: 0; }
.entry-content .form-notice ul { padding-left: 0; list-style: none; }
.entry-content .form-notice li { margin-block: 0.25rem; }

.entry-content > :first-child { margin-top: 0; }
.entry-content > :last-child  { margin-bottom: 0; }

.entry-content h2 { font-size: var(--t-title); margin-top: 2.5rem; }
.entry-content h3 { font-size: 1.375rem; margin-top: 2rem; }
.entry-content h4 { font-family: var(--sans); font-size: 1.0625rem; font-weight: 600; margin-top: 1.75rem; }

.entry-content ul:not(.rules):not(.checks):not(.logos):not(.plans),
.entry-content ol { padding-left: 1.5rem; }
.entry-content ul:not(.rules):not(.checks):not(.logos):not(.plans) { list-style: disc; }
.entry-content ol { list-style: decimal; }
.entry-content li { margin-block: 0.375rem; }
.entry-content li::marker { color: var(--brass-deep); }
.entry-content .rules li,
.entry-content .checks li,
.entry-content .plans li { margin-block: 0; }

/* An inline link inside prose has to look like a link. Buttons and the concept's
   own .link component opt out: they carry their own affordance. */
.entry-content a:not(.btn):not(.link):not(.rules__row):not(.mega__item) {
  color: var(--brass-deep);
  text-decoration: underline;
  text-underline-offset: 0.18em;
  text-decoration-thickness: 1px;
}
.entry-content a:not(.btn):not(.link):not(.rules__row):not(.mega__item):hover { color: var(--ink); }

.entry-content strong { font-weight: 600; }
.entry-content em { font-style: italic; }

.entry-content code,
.entry-content kbd,
.entry-content samp {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.875em;
  background: var(--brass-wash);
  padding: 0.125em 0.375em;
  border-radius: var(--radius);
}
.entry-content pre {
  background: var(--sand);
  padding: 1.25rem;
  border-radius: var(--radius);
  overflow-x: auto;
}
.entry-content pre code { background: none; padding: 0; }

.entry-content blockquote:not(.pull):not(.quote):not(.letter__body) {
  border-left: 1px solid var(--brass);
  padding-left: 1.5rem;
  font-family: var(--display);
  font-size: 1.375rem;
  line-height: 1.35;
}

.entry-content table { border-collapse: collapse; width: 100%; font-size: 0.9375rem; }
.entry-content th,
.entry-content td { border-bottom: 1px solid var(--line); padding: 0.75rem 0.5rem; text-align: left; }
.entry-content th { font-family: var(--sans); font-weight: 600; }

.entry-content hr:not(.rule) {
  border: 0;
  border-top: 1px solid var(--line);
  margin-block: 2.5rem;
}

/* --- Core block and classic markup ---------------------------------------- */
.alignleft  { float: left;  margin: 0.375rem 1.5rem 1.25rem 0; }
.alignright { float: right; margin: 0.375rem 0 1.25rem 1.5rem; }
.aligncenter { display: block; margin-inline: auto; }

.entry-content .alignwide {
  max-width: min(var(--shell), 100%);
  margin-inline: auto;
  width: 100%;
}
.entry-content .alignfull {
  max-width: 100vw;
  margin-inline: calc(50% - 50vw);
  width: 100vw;
}

.wp-caption { max-width: 100%; }
.wp-caption-text,
.wp-element-caption { font-size: 0.8125rem; color: var(--faint); margin-top: 0.625rem; letter-spacing: 0.02em; }

.wp-block-image img { height: auto; }
.wp-block-button__link { border-radius: var(--radius); }
.wp-block-separator { border: 0; border-top: 1px solid var(--line); opacity: 1; }

.screen-reader-text {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap; border: 0;
}
.screen-reader-text:focus { clip: auto; clip-path: none; width: auto; height: auto; }

/* --- Pagination ------------------------------------------------------------ */
.pagination {
  display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center;
  margin-top: 3rem; padding-top: 2rem; border-top: 1px solid var(--line);
}
.pagination .page-numbers {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 2.5rem; height: 2.5rem; padding-inline: 0.75rem;
  border: 1px solid var(--line); border-radius: var(--radius);
  font-size: 0.875rem; font-variant-numeric: tabular-nums;
  transition: border-color 0.2s var(--ease), color 0.2s var(--ease);
}
.pagination .page-numbers:hover { border-color: var(--brass); color: var(--brass-deep); }
.pagination .page-numbers.current { background: var(--ink); border-color: var(--ink); color: var(--on-ink); }
.pagination .page-numbers.dots { border-color: transparent; }

/* --- Form states -----------------------------------------------------------
   The static concept had no error or success state, because none of its forms
   could be submitted. */
.form-notice {
  padding: 1rem 1.25rem;
  border-left: 3px solid var(--brass);
  background: var(--brass-wash);
  margin-bottom: 1.75rem;
}
.form-notice--ok    { border-left-color: var(--ink); }
.form-notice--error { border-left-color: #a4342a; background: #f7e9e7; color: #6d221b; }
.form-notice ul { margin-top: 0.5rem; display: grid; gap: 0.25rem; }
.form-notice a { text-decoration: underline; }
.form-notice:focus-visible { outline: 2px solid var(--brass-deep); outline-offset: 3px; }

.field[aria-invalid='true'] { border-bottom-color: #a4342a; border-bottom-width: 2px; }
.field-error { display: block; margin-top: 0.375rem; font-size: 0.8125rem; color: #8c2b22; }
.ink-bg .field-error,
.site-footer .field-error { color: var(--accent-on-dark); }

/* The honeypot. Positioned off-canvas rather than display:none, because a
   number of bots skip fields that are display:none, which defeats the point. */
.hp-field {
  position: absolute !important;
  left: -9999px; top: auto;
  width: 1px; height: 1px; overflow: hidden;
}

/* --- Donation picker as radio inputs ---------------------------------------
   The concept used <button aria-pressed>, whose state lives only in JS and is
   discarded on submit. These are real radios, visually hidden behind their
   labels, so the control works with a keyboard and with JS switched off. */
.amounts input[type='radio'],
.toggle input[type='radio'] { position: absolute; opacity: 0; width: 1px; height: 1px; }

.amounts input[type='radio']:focus-visible + label,
.toggle  input[type='radio']:focus-visible + label { outline: 2px solid var(--brass-deep); outline-offset: 3px; }

.amounts label,
.toggle  label { cursor: pointer; }

/* --- Admin bar ------------------------------------------------------------- */
.admin-bar .site-header { top: 32px; }
@media (max-width: 782px) { .admin-bar .site-header { top: 46px; } }

/* --- BLOOMERANG ------------------------------------------------------------
   The donation form is Bloomerang's markup, not ours, so this only gives it a
   width to sit in and keeps its own inputs from spilling out of the column.
   Deliberately no restyling of their fields: their form has to keep working
   when they change it, and a payment form is the wrong place to be clever. */
/* Bloomerang draws whatever their account is configured to draw, and the theme
   has no say in it. What it can do is stop the result overflowing its column,
   and put it where the page expects a control to be. */

/* Seen only by someone who can fix what it describes, so it is allowed to look
   like what it is: an editor's note, not part of the design. */
.admin-note {
  border: 1px dashed var(--line-strong);
  padding: 1rem 1.125rem;
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--faint);
}
.admin-note a { color: var(--brass-deep); text-decoration: underline; text-underline-offset: 0.2em; }

/* The hosted donation page, framed. Bloomerang draws it; this only gives it the
   width of the column and a rule so it reads as a panel rather than as a hole
   in the page. No border-radius and no shadow: nothing else in this design has
   either, and dressing a payment form to look like something it is not would be
   the wrong instinct anyway. */

.donate-frame { width: 100%; border: 1px solid var(--line-strong); background: #fff; }
.donate-frame iframe { display: block; width: 100%; height: var(--frame-h, 2400px); border: 0; }

/* Stacked, on a phone or a narrow tablet, the frame is given the whole form's
   height and does not scroll inside itself. A nested scroll region on a touch
   screen fights the page for every swipe, and the form is the last thing that
   should be fought with.

   The extra 320px is where the form's fields stop sitting two to a row. It is a
   measurement of this form, not a rule: change the fields in Bloomerang and the
   number moves, which is why the base is a setting and not a constant. */
@media (max-width: 46em) {
  .donate-frame iframe { height: calc(var(--frame-h, 2400px) + 20rem); }
}

/* Beside the campaign, on a desktop, it is a panel instead: as tall as the
   screen allows, scrolling inside itself, and held in place by .stick while the
   reader goes through the case for giving next to it. The whole ask is then one
   screen -- what the money does on the left, the way to send it on the right --
   rather than a meter with an empty column beside it and the form a band below.

   Sized from the viewport rather than from the setting, because what matters
   here is that it fits the screen, not that it fits the form. */
@media (min-width: 60em) {
  .donate-frame iframe {
    height: calc(100vh - 11rem);
    min-height: 34rem;
    max-height: 52rem;
  }
}

.bloomerang-form { max-width: 100%; }
.bloomerang-form img,
.bloomerang-form iframe,
.bloomerang-form table { max-width: 100%; }
.bloomerang-form input,
.bloomerang-form select,
.bloomerang-form textarea { max-width: 100%; box-sizing: border-box; }

/* Their button widget arrives left-aligned inside a flex row of its own, which
   on a centred band reads as a mistake. Centre the row, and dress the button in
   this site's own type -- the inline styles Bloomerang writes are why these
   need !important, and only the appearance is touched: the link, its
   destination and their "Powered by" mark are left exactly as they arrive. */

.bloomerang-form > div { justify-content: center; }

.bloomerang-form .secure-btn {
  width: auto !important;
  height: auto !important;
  padding: 0.8125rem 1.75rem !important;
  background-color: var(--ink) !important;
  color: var(--on-ink, #f4f0e8) !important;
  border-radius: 0 !important;
  font-family: var(--sans) !important;
  font-size: 0.875rem !important;
  font-weight: 500 !important;
  letter-spacing: 0.04em !important;
  cursor: pointer;
}

.bloomerang-form .secure-btn:hover { background-color: var(--brass-deep) !important; }
