/* ============================================================
   EdQuest - site styles
   Colors: #f84 (flame), #666 (slate), #000 (ink), #fff (paper)
   Font: Noticia Text (self-hosted woff2 in /static/fonts/)
   Mobile-first, no framework. HTMX-friendly.
   ============================================================ */

:root {
  --flame: #ff8844;
  --flame-deep: #e66a1a;
  --slate: #666666;
  --slate-soft: #8a8a8a;
  --slate-faint: #e6e6e6;
  --ink: #000000;
  --paper: #ffffff;
  --paper-warm: #fafafa;
  --canvas: #faf7f1;   /* warm page-surface - core brand color */

  /* Brand rounding: a squared bottom-right corner mirrors the Q-mark logo.
     Baking it into the radius tokens means every control that already uses them
     (buttons, inputs, cards, the search box, the subscribe field, ...) gets the
     motif from one place - no per-control edits. Order: TL TR BR BL. */
  --radius-sm: 4px 4px 0 4px;
  --radius: 8px 8px 0 8px;
  --radius-lg: 14px 14px 0 14px;
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.06);
  --shadow: 0 4px 14px rgba(0, 0, 0, 0.08);
  --shadow-lg: 0 12px 40px rgba(0, 0, 0, 0.12);

  --font-body: "Noticia Text", Georgia, "Times New Roman", serif;
  --gap: 1rem;
  --container: 72rem;

  --focus: 0 0 0 3px rgba(255, 136, 68, 0.4);
}

/* ---------- Self-hosted Noticia Text ---------- */
@font-face {
  font-family: "Noticia Text";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: local("Noticia Text"),
       url("/static/fonts/noticia-text-400.94e4b31c31cb.woff2") format("woff2");
}
@font-face {
  font-family: "Noticia Text";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: local("Noticia Text Italic"),
       url("/static/fonts/noticia-text-400-italic.da14259e743a.woff2") format("woff2");
}
@font-face {
  font-family: "Noticia Text";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: local("Noticia Text Bold"),
       url("/static/fonts/noticia-text-700.a64945645224.woff2") format("woff2");
}

/* ---------- Reset-ish ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.6;
  color: var(--ink);
  background: var(--canvas);
  -webkit-font-smoothing: antialiased;
  /* Sticky footer: fill the viewport so a short page's footer still reaches the
     bottom instead of leaving a canvas-coloured strip below it. */
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
/* The content grows to absorb spare height, pushing the footer to the bottom. */
main { flex: 1 0 auto; }
img, svg { max-width: 100%; height: auto; display: block; }
a { color: var(--flame-deep); text-decoration: underline; text-underline-offset: 3px; }
a:hover { color: var(--ink); }
a:focus-visible, button:focus-visible, input:focus-visible,
textarea:focus-visible, select:focus-visible {
  outline: none; box-shadow: var(--focus); border-radius: 4px;
}

h1, h2, h3, h4 {
  font-family: var(--font-body);
  line-height: 1.2;
  margin: 0 0 0.5em;
  font-weight: 700;
}
h1 { font-size: clamp(1.85rem, 4vw + 0.5rem, 2.75rem); }
h2 { font-size: clamp(1.45rem, 2.5vw + 0.5rem, 2rem); }
h3 { font-size: 1.25rem; }

p { margin: 0 0 1rem; }

/* ---------- Layout ---------- */
.container {
  width: 100%;
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 1.25rem;
}

.skip-link {
  position: absolute; left: -9999px; top: 0;
  background: var(--ink); color: var(--paper);
  padding: 0.5rem 0.75rem; z-index: 100;
}
.skip-link:focus { left: 0.5rem; top: 0.5rem; }

/* ---------- Header / nav ---------- */
.site-header {
  position: sticky; top: 0; z-index: 50;
  background: var(--paper);
  border-bottom: 1px solid var(--slate-faint);
  box-shadow: var(--shadow-sm);
}
.site-header__inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; padding: 0.75rem 0;
}
.brand {
  display: inline-flex; align-items: center; gap: 0.55rem;
  text-decoration: none; color: inherit;
}
.brand__mark {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.4rem; height: 2.4rem;
}
.brand__mark > svg { width: 100%; height: 100%; display: block; }
.brand__wordmark {
  font-family: var(--font-body);
  font-weight: 500; font-size: 1.55rem; line-height: 1;
  letter-spacing: -0.01em; color: var(--ink);
}
.brand__wordmark em {
  font-style: italic; color: var(--flame-deep);
}
/* Legacy <img class="brand__logo"> still works if any template uses it. */
.brand__logo { height: 44px; width: auto; }

.nav-toggle {
  appearance: none; background: transparent; border: 0;
  padding: 0.5rem; cursor: pointer; color: var(--ink);
}
.nav-toggle__bar {
  display: block; width: 24px; height: 2px; background: var(--ink);
  margin: 5px 0; transition: transform 0.2s ease, opacity 0.2s ease;
}
.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}
.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(2) {
  opacity: 0;
}
.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}

.site-nav {
  display: none;
  flex-direction: column;
  position: absolute; left: 0; right: 0; top: 100%;
  background: var(--paper);
  border-bottom: 1px solid var(--slate-faint);
  box-shadow: var(--shadow);
  padding: 0.5rem 1.25rem 1.25rem;
}
.site-nav[data-open="true"] { display: flex; }
.site-nav a {
  display: block; padding: 0.75rem 0;
  color: var(--ink); text-decoration: none;
  font-weight: 700;
  border-bottom: 1px solid var(--slate-faint);
}
.site-nav a:last-child { border-bottom: 0; }
.site-nav a:hover, .site-nav a[aria-current="page"] { color: var(--flame-deep); }
.site-nav__signin { font-weight: 500; }
.site-nav__signup {
  border: 1px solid var(--flame);
  padding: 0.4rem 0.9rem;
  border-radius: var(--radius);
  font-weight: 500;
}
.site-nav__signup:hover {
  background: var(--flame); color: var(--paper);
}
.site-nav__logout { margin: 0; display: inline; }
.site-nav__logout-btn {
  background: transparent; border: 0; padding: 0;
  font: inherit; color: var(--slate); cursor: pointer;
}
.site-nav__logout-btn:hover { color: var(--flame-deep); }
.site-nav__inbox { position: relative; display: inline-flex; align-items: center; gap: 0.35rem; }
.site-nav__inbox-count {
  background: var(--flame); color: var(--paper);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.7rem; font-weight: 500;
  border-radius: 999px;
  padding: 1px 7px;
  min-width: 1.4em;
  text-align: center;
  line-height: 1.4;
}

/* ---------- Account control (header) ----------
   A top-bar button that opens a dropdown of account actions, à la GardenCAD's
   account/sync button. Mobile-first: the trigger is hidden and the menu items
   render inline within the collapsed nav; the desktop block below turns it
   into a pill button + floating popover. */
.acct { display: block; }
.acct__btn { display: none; }                 /* no trigger on mobile */
.acct__menu, .acct__menu[hidden] { display: block; }  /* always inline on mobile */
.acct__who {
  padding: 0.75rem 0 0.5rem; margin: 0;
  color: var(--slate); font-size: 0.85rem; line-height: 1.4;
}
.acct__who strong { color: var(--ink); }
.acct__menu .acct__item {
  display: flex; align-items: center; justify-content: space-between; gap: 0.75rem;
  width: 100%; padding: 0.75rem 0;
  font: inherit; font-weight: 700; text-align: left;
  color: var(--ink); text-decoration: none;
  background: transparent; border: 0; border-bottom: 1px solid var(--slate-faint);
  cursor: pointer;
}
.acct__menu .acct__item:last-child { border-bottom: 0; }
.acct__menu .acct__item:hover { color: var(--flame-deep); }
.acct__signout { color: var(--flame-deep); }
.acct__signout-form { margin: 0; display: block; }
.acct__sep { display: none; }                 /* mobile: item borders separate */
.acct__badge {
  background: var(--flame); color: var(--paper);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.7rem; font-weight: 500;
  border-radius: 999px; padding: 1px 7px;
  min-width: 1.4em; text-align: center; line-height: 1.4;
}

/* ---------- Inbox ---------- */
.inbox-tabs {
  display: flex;
  gap: 0;
  border-bottom: 1px solid var(--slate-faint);
  margin: 1rem 0 1.5rem;
}
.inbox-tab {
  padding: 0.7rem 1.1rem;
  color: var(--slate);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}
.inbox-tab:hover { color: var(--ink); }
.inbox-tab.is-active {
  color: var(--ink);
  border-bottom-color: var(--flame);
}
.inbox-tab__count {
  background: var(--flame); color: var(--paper);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.7rem; padding: 1px 6px; border-radius: 999px;
}

/* Triage filters over the shared inbox. */
.inbox-filters { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0 0 1.25rem; }
.chip {
  display: inline-block;
  padding: 0.3rem 0.75rem;
  border: 1px solid var(--slate-faint);
  /* Same rounding as .btn - a filter chip is a control, and at ~34px tall the
     standard radius reads as a rectangle rather than the capsule it was. */
  border-radius: var(--radius);
  color: var(--slate);
  text-decoration: none;
  font-size: 0.88rem;
}
.chip:hover { color: var(--ink); border-color: var(--slate-soft); }
.chip.is-active { color: var(--paper); background: var(--ink); border-color: var(--ink); }

/* ---------- Pagination (partials/pagination.html) ---------- */
.pager {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
  margin: 1.5rem 0 0; padding-top: 1rem;
  border-top: 1px solid var(--slate-faint);
}
.pager__link { text-decoration: none; font-weight: 500; }
.pager__link.is-disabled { color: var(--slate-faint); cursor: default; }
.pager__status { color: var(--slate); font-size: 0.9rem; }

.inbox-list {
  list-style: none;
  padding: 0;
  margin: 0;
}
.inbox-row {
  border-top: 1px solid var(--slate-faint);
}
.inbox-row:last-child { border-bottom: 1px solid var(--slate-faint); }
.inbox-row--unread { background: rgba(255, 136, 68, 0.05); }
.inbox-row__link {
  display: grid;
  grid-template-columns: minmax(140px, 1fr) minmax(200px, 2fr) minmax(0, 3fr) 60px;
  gap: 1rem;
  padding: 0.75rem 0.5rem;
  text-decoration: none;
  color: var(--ink);
  align-items: baseline;
}
/* Shared inbox (triage): one extra column for claim state. A fixed width keeps
   the badges aligned down the list so the unclaimed ones are scannable in a
   single vertical sweep - this used to be a paragraph under each row, which
   read fine but doubled the height of the list. */
.inbox-list--triage .inbox-row__link {
  grid-template-columns: minmax(140px, 1fr) minmax(200px, 2fr) minmax(0, 3fr) 9rem 60px;
}
.inbox-row__owner { min-width: 0; }
.inbox-row__owner .badge {
  margin-left: 0;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.inbox-row__link:hover { background: var(--canvas); }
.inbox-row__from {
  font-weight: 600;
  display: inline-flex; align-items: center; gap: 0.4rem;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.inbox-row__dot {
  display: inline-block;
  width: 8px; height: 8px;
  background: var(--flame);
  border-radius: 50%;
  flex: 0 0 auto;
}
.inbox-row__subject {
  font-weight: 500;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.inbox-row__preview {
  color: var(--slate);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 0.92rem;
}
.inbox-row--unread .inbox-row__preview,
.inbox-row--unread .inbox-row__subject { color: var(--ink); }
.inbox-row__when {
  color: var(--slate);
  font-size: 0.85rem;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
@media (max-width: 720px) {
  /* Named areas here, so the claim badge can share the preview's line instead
     of claiming one of its own - the stacked row stays three lines tall
     whether or not this is a shared inbox. */
  .inbox-row__link,
  .inbox-list--triage .inbox-row__link {
    grid-template-columns: 1fr auto;
    grid-template-areas: "from when" "subject subject" "preview owner";
  }
  .inbox-row__from { grid-area: from; }
  .inbox-row__when { grid-area: when; }
  .inbox-row__subject { grid-area: subject; }
  .inbox-row__preview { grid-area: preview; }
  .inbox-row__owner { grid-area: owner; justify-self: end; }
  /* Cap it at the desktop column width so a long name ellipsises instead of
     squeezing the preview down to a couple of words. */
  .inbox-row__owner .badge { max-width: 9rem; }
}
.empty-state {
  padding: 2rem;
  text-align: center;
  border: 1px dashed var(--slate-faint);
  border-radius: var(--radius);
}

.message-detail {
  background: var(--canvas);
  border: 1px solid var(--slate-faint);
  border-radius: var(--radius);
  padding: 1.4rem 1.6rem;
}
.message-detail__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 1.2rem 2rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--slate-faint);
  margin-bottom: 1rem;
  font-size: 0.95rem;
}
.message-detail__meta > div { display: flex; flex-direction: column; gap: 0.2rem; }
/* From's value is compound (name + <email>); keep it on one value line under
   the label, wrapping a long address rather than splitting name off the bracket. */
.message-detail__fromval { overflow-wrap: anywhere; }
.message-detail__body {
  font-family: var(--font-body);
  font-size: 1.05rem;
  line-height: 1.6;
}
.message-detail__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-top: 1.4rem;
  padding-top: 1rem;
  border-top: 1px solid var(--slate-faint);
}

/* Replies already sent, shown under the message so the thread reads in order.
   Indented and flipped to the paper tone so an answer is never mistaken for
   part of what the sender wrote. */
.reply-sent {
  margin-top: 1.2rem;
  padding: 0.9rem 1.1rem;
  background: var(--paper);
  border-left: 3px solid var(--flame);
  border-radius: 0 var(--radius) var(--radius) 0;
}
.reply-sent--failed { border-left-color: #d23b3b; }
.reply-sent__meta {
  margin: 0 0 0.5rem;
  font-size: 0.9rem;
  color: var(--slate);
}
.reply-sent__body { font-size: 1rem; line-height: 1.55; }
.reply-sent__body p:last-child { margin-bottom: 0; }

/* The composer is a <details> so it opens with no JavaScript; the summary is
   styled as the button that replaced "Reply via email". */
.reply-composer { margin-top: 1.4rem; }
.reply-composer__toggle {
  display: inline-block;
  cursor: pointer;
  list-style: none;
}
/* Safari still needs the vendor pseudo-element to drop the disclosure marker,
   which would otherwise sit inside the button next to the label. */
.reply-composer__toggle::-webkit-details-marker { display: none; }
/* Flex column rather than margins on each row: the hidden CSRF input and the
   <datalist> are display:none, so they never become gapped flex items. */
.reply-composer__form {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  margin-top: 1rem;
  padding: 1.1rem 1.2rem;
  background: var(--paper);
  border: 1px solid var(--slate-faint);
  border-radius: var(--radius);
}
.reply-composer__to {
  margin: 0;
  font-size: 0.95rem;
  overflow-wrap: anywhere;
}
.reply-composer__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem 1rem;
}
.reply-composer__actions .muted { font-size: 0.85rem; }

@media (min-width: 800px) {
  .nav-toggle { display: none; }
  .site-nav {
    display: flex; flex-direction: row; position: static;
    align-items: center;
    padding: 0; border: 0; box-shadow: none; gap: 1.1rem;
  }
  .site-nav a {
    padding: 0.25rem 0; border-bottom: 2px solid transparent;
  }
  .site-nav a[aria-current="page"] {
    border-bottom-color: var(--flame);
  }
  /* Auth actions are buttons, not plain links. The `.site-nav a.<class>`
     specificity (0,2,1) beats `.site-nav a` (0,1,1), so the link padding /
     hover-underline above don't leak in and break the pills. */
  .site-nav a.site-nav__signin,
  .site-nav a.site-nav__signup {
    padding: 0.45rem 1rem;
    border: 1px solid transparent;
    border-radius: var(--radius);
    font-weight: 600;
    line-height: 1;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
  }
  .site-nav a.site-nav__signin {
    border-color: var(--flame);
    color: var(--flame-deep);
  }
  .site-nav a.site-nav__signin:hover {
    background: var(--flame); border-color: var(--flame); color: var(--paper);
  }
  .site-nav a.site-nav__signup {
    background: var(--flame); border-color: var(--flame); color: var(--paper);
  }
  .site-nav a.site-nav__signup:hover {
    background: var(--flame-deep); border-color: var(--flame-deep); color: var(--paper);
  }

  /* Account control on desktop: pill trigger + floating popover. */
  .acct { position: relative; }
  .acct__btn {
    display: inline-flex; align-items: center; gap: 0.45rem;
    padding: 0.3rem 0.55rem 0.3rem 0.35rem;
    border: 1px solid var(--slate-faint); border-radius: var(--radius);
    background: var(--paper); color: var(--ink); cursor: pointer;
    font: inherit; font-weight: 600; line-height: 1;
    transition: background 0.15s ease, border-color 0.15s ease;
  }
  .acct__btn:hover,
  .acct__btn[aria-expanded="true"] {
    border-color: var(--flame); background: var(--paper-warm);
  }
  .acct__avatar {
    display: inline-flex; align-items: center; justify-content: center;
    width: 1.7rem; height: 1.7rem; flex: none;
    /* A circle with a squared lower-right corner - mirrors the Q-mark logo. */
    border-radius: 50% 50% 0 50%; background: var(--flame); color: var(--paper);
    font-size: 0.8rem; font-weight: 700;
  }
  .acct__name { max-width: 13ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .acct__caret { color: var(--slate); transition: transform 0.15s ease; }
  .acct__btn[aria-expanded="true"] .acct__caret { transform: rotate(180deg); }

  .acct__menu {
    position: absolute; right: 0; top: calc(100% + 10px);
    min-width: 240px; padding: 0.4rem; z-index: 60;
    background: var(--paper);
    border: 1px solid var(--slate-faint); border-radius: 10px;
    box-shadow: 0 12px 30px rgba(0, 0, 0, 0.14);
  }
  .acct__menu[hidden] { display: none; }
  .acct__menu:not([hidden]) { display: block; }
  .acct__who {
    padding: 0.4rem 0.6rem 0.5rem; margin-bottom: 0.3rem;
    border-bottom: 1px solid var(--slate-faint);
  }
  .acct__menu .acct__item {
    padding: 0.5rem 0.6rem; border-bottom: 0; border-radius: 7px;
    font-weight: 500; font-size: 0.92rem;
  }
  .acct__menu .acct__item:hover { background: var(--paper-warm); color: var(--flame-deep); }
  .acct__sep { display: block; height: 1px; background: var(--slate-faint); margin: 0.3rem 0.25rem; }
}

/* ---------- Hero ---------- */
.hero {
  padding: 3rem 0 2.5rem;
  border-bottom: 1px solid var(--slate-faint);
}
.hero__eyebrow {
  text-transform: uppercase; letter-spacing: 0.1em;
  font-size: 0.78rem; color: var(--flame-deep); font-weight: 700;
  margin-bottom: 0.5rem;
}
.hero__lede { font-size: 1.15rem; color: var(--slate); max-width: 40rem; }
.hero__actions { margin-top: 1.5rem; display: flex; flex-wrap: wrap; gap: 0.75rem; }

/* ---------- Buttons ---------- */
.btn {
  --bg: var(--flame); --fg: var(--ink); --bd: var(--flame);
  display: inline-flex; align-items: center; justify-content: center;
  gap: 0.4rem;
  padding: 0.7rem 1.15rem;
  background: var(--bg); color: var(--fg);
  border: 2px solid var(--bd); border-radius: var(--radius);
  font: inherit; font-weight: 700; text-decoration: none;
  cursor: pointer; min-height: 44px; /* touch target */
  transition: transform 0.05s ease, background 0.2s ease, color 0.2s ease;
}
.btn:hover { background: var(--flame-deep); border-color: var(--flame-deep); color: var(--paper); }
.btn:active { transform: translateY(1px); }
/* A disabled button has to LOOK disabled. There was no rule for it, so the
   course page's "Rebuild all videos" sat there in full contrast with its hover
   intact while refusing every press - the worst of the three possible states,
   because the only feedback was nothing happening. Greyed, flat, and the hover
   and press animations off, so the reason in the title attribute is the second
   thing you look for rather than the first. */
.btn:disabled,
.btn[aria-disabled="true"] {
  --bg: var(--slate-faint); --fg: var(--slate); --bd: var(--slate-faint);
  cursor: not-allowed;
  box-shadow: none;
}
.btn:disabled:hover,
.btn[aria-disabled="true"]:hover {
  background: var(--slate-faint); border-color: var(--slate-faint); color: var(--slate);
}
.btn:disabled:active { transform: none; }
.btn--ghost {
  --bg: transparent; --fg: var(--ink); --bd: var(--ink);
}
.btn--ghost:hover { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.btn--block { width: 100%; }
.btn--sm { padding: 0.45rem 0.8rem; min-height: 36px; font-size: 0.95rem; }
/* The size and running time ride inside a download button rather than beside
   it: they are what you decide on before clicking - 412 MB over a hotel wifi
   is a different proposition from 41 MB - and beside it they were a caption
   nobody read. Lighter than the label so the button still reads as a verb. */
.btn__meta { font-weight: 400; font-size: 0.85em; opacity: 0.75; white-space: nowrap; }
/* Never let the glyph shrink when the label wraps. */
.icon-dl { flex: none; }

/* ---------- Sections ---------- */
section { padding: 1.5rem 0; }
.section-title { font-size: 1.4rem; margin-bottom: 1rem; }
.section-title small {
  display: block; text-transform: uppercase; letter-spacing: 0.1em;
  font-size: 0.78rem; color: var(--flame-deep); font-weight: 700;
  margin-bottom: 0.25rem;
}

/* ---------- Card grid ---------- */
.cards {
  display: grid; gap: 1.25rem;
  grid-template-columns: 1fr;
}
@media (min-width: 640px) {
  .cards { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 960px) {
  .cards--3 { grid-template-columns: repeat(3, 1fr); }
  .cards--2 { grid-template-columns: repeat(2, 1fr); }
}
.card {
  background: var(--paper);
  border: 1px solid var(--slate-faint);
  border-radius: var(--radius-lg);
  padding: 1.5rem;
  box-shadow: var(--shadow-sm);
  display: flex; flex-direction: column; gap: 0.75rem;
}
.card__title { margin: 0; font-size: 1.15rem; }
.card__meta { color: var(--slate); font-size: 0.92rem; }
.card a.btn { margin-top: auto; }

/* ---------- Project showcase cards ---------- */
.project-card {
  /* Per-project accent; the modifiers below recolor the tile, bullets + CTA. */
  --proj-accent: #4a8a3e;             /* GardenCAD green (default) */
  --proj-accent-deep: #3c7233;        /* hover/active */
  --proj-tile-bg: #eef4ea;
  --proj-tile-border: #d8e6d0;
  --proj-btn-fg: #fff;                /* CTA label color */
}
.project-card--fire {
  --proj-accent: var(--flame);        /* FirePrevented orange */
  --proj-accent-deep: var(--flame-deep);
  --proj-tile-bg: #fff1e6;
  --proj-tile-border: #ffd9bd;
  --proj-btn-fg: var(--ink);          /* dark label reads better on light orange */
}
.project-card--whfd {
  --proj-accent: #c8102e;             /* Woodbury Heights red */
  --proj-accent-deep: #a50d26;
  --proj-tile-bg: #fcebed;
  --proj-tile-border: #f3c1bb;
}
.project-card--resqr {
  --proj-accent: #6b7280;             /* ResQ-R grey (green is GardenCAD's) */
  --proj-accent-deep: #565c66;
  --proj-tile-bg: #f1f2f4;
  --proj-tile-border: #dcdfe3;
}
.project-card .hero__actions { margin-top: auto; }  /* line CTAs up across cards */

/* Each project's CTA button wears that project's accent color. */
.project-card .btn {
  --bg: var(--proj-accent);
  --bd: var(--proj-accent);
  --fg: var(--proj-btn-fg);
}
.project-card .btn:hover,
.project-card .btn:focus-visible {
  background: var(--proj-accent-deep);
  border-color: var(--proj-accent-deep);
  color: #fff;
}
.project-card__head {
  display: flex; align-items: center; gap: 1rem;
}
.project-card__logo {
  flex: 0 0 auto;
  display: grid; place-items: center;
  width: 72px; height: 72px;
  background: var(--proj-tile-bg);     /* soft tile carrying the mark */
  border: 1px solid var(--proj-tile-border);
  border-radius: var(--radius);        /* squared bottom-right, brand corner */
}
.project-card__logo img { width: 40px; height: auto; display: block; }
.project-card__heading {
  display: flex; flex-direction: column; gap: 0.1rem; min-width: 0;
}
.project-card__tagline { margin: 0; color: var(--slate); font-size: 0.98rem; }
.project-card__by {
  margin: 0.15rem 0 0; font-size: 0.72rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.09em; color: var(--slate-soft);
}
.project-card__features {
  list-style: none; margin: 0.1rem 0 0; padding: 0;
  display: grid; gap: 0.45rem;
}
.project-card__features li {
  position: relative; padding-left: 1.6rem; color: var(--slate);
}
.project-card__features li::before {
  content: ""; position: absolute; left: 0.15rem; top: 0.4em;
  width: 0.7rem; height: 0.7rem;
  background: var(--proj-accent);      /* per-project accent */
  border-radius: 50% 50% 0 50%;        /* mirrors the avatar / logo corner */
}

/* ---------- Forms ---------- */
.form {
  display: grid; gap: 1rem;
  max-width: 32rem;
}
.field { display: flex; flex-direction: column; gap: 0.35rem; }
.field label { font-weight: 700; font-size: 0.95rem; }
.field .help { color: var(--slate); font-size: 0.85rem; }
.field input,
.field select,
.field textarea {
  font: inherit; line-height: 1.4;
  color: var(--ink); background: var(--paper);
  border: 2px solid var(--slate-faint); border-radius: var(--radius);
  padding: 0.65rem 0.8rem; min-height: 44px; width: 100%;
}
/* Native <select> ships with its own chrome and line-height, which
   makes it taller than a paired <input> at the same padding. Strip
   that and supply a custom arrow so it matches input height pixel-
   for-pixel. */
.field select {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%23666' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5l5 5 5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.8rem center;
  background-size: 12px 8px;
  padding-right: 2.4rem;
}
.field textarea { min-height: 8rem; }
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--flame); }
.field--error input, .field--error select, .field--error textarea { border-color: #d23b3b; }

/* ---------- Auth pages (allauth: login, signup, password reset, …) ----------
   These pages render through templates/allauth/layouts/base.html into the
   .auth card. allauth's form fields are <p><label><input></p> and its buttons
   are class-less <button>, so we style those element shapes here (plus the
   custom login.html, which uses the same shapes). */
.auth { padding: 3rem 0; background: var(--canvas); }
.auth__card {
  max-width: 26rem; margin: 0 auto;
  background: var(--paper);
  border: 1px solid var(--slate-faint);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: 2rem;
}
.auth__card h1 { font-size: 1.6rem; line-height: 1.15; margin: 0 0 1.25rem; }
.auth__card > p,
.auth__card form p { margin: 0 0 1rem; }
.auth__card label { display: block; font-weight: 700; font-size: 0.95rem; margin-bottom: 0.3rem; }
.auth__card input[type="text"],
.auth__card input[type="email"],
.auth__card input[type="password"],
.auth__card input[type="url"],
.auth__card input[type="number"],
.auth__card input:not([type]) {
  width: 100%;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--slate-faint);
  border-radius: var(--radius);
  background: var(--paper);
  font: inherit; color: var(--ink);
}
.auth__card input:focus { border-color: var(--flame); outline: none; }
.auth__card input[type="checkbox"],
.auth__card input[type="radio"] { margin-right: 0.45rem; }
.auth__card input[type="checkbox"] + label,
.auth__card input[type="radio"] + label { display: inline; font-weight: 500; margin-bottom: 0; }
/* allauth renders class-less <button>s; make them the primary action. The
   custom login.html uses explicit .btn classes, so exclude classed buttons. */
.auth__card button:not([class]) {
  display: inline-flex; align-items: center; justify-content: center;
  width: 100%; margin-top: 0.25rem;
  padding: 0.65rem 1rem;
  background: var(--flame); color: var(--paper);
  border: 1px solid var(--flame); border-radius: var(--radius);
  font: inherit; font-weight: 700; cursor: pointer;
}
.auth__card button:not([class]):hover { background: var(--flame-deep); border-color: var(--flame-deep); }
.auth__card a { color: var(--flame-deep); }
.auth__card hr { border: 0; border-top: 1px solid var(--slate-faint); margin: 1.25rem 0; }
/* Consent checkboxes on the signup + consent pages. Tighter than a normal form
   row so the age box and the terms box read as one group, and hanging-indented
   so a wrapped label lines up under itself rather than under the box. */
/* Specificity, not !important: .auth__card form p sets the 1rem row gap above. */
.auth__card form p.auth__check {
  display: grid; grid-template-columns: auto 1fr;
  gap: 0 0.15rem; align-items: start;
  margin-bottom: 0.6rem;
}
.auth__check input[type="checkbox"] { margin-top: 0.35rem; }
.auth__check .auth__field-error { grid-column: 2; }

.auth__divider {
  display: flex; align-items: center; gap: 0.75rem;
  margin: 1rem 0; color: var(--slate); font-size: 0.85rem;
}
.auth__divider::before, .auth__divider::after {
  content: ""; flex: 1; height: 1px; background: var(--slate-faint);
}
.auth__errors {
  list-style: none; margin: 0 0 1rem; padding: 0.6rem 0.8rem;
  background: #fdecec; border: 1px solid #f5c2c2; border-radius: var(--radius);
  color: #a12b2b; font-size: 0.9rem;
}
.auth__field-error { display: block; margin-top: 0.3rem; color: #d23b3b; font-size: 0.85rem; }
.auth__help { display: block; margin-top: 0.3rem; color: var(--slate); font-size: 0.85rem; }
.auth__alt { margin: 1.25rem 0 0; font-size: 0.9rem; color: var(--slate); text-align: center; }
.auth__alt span { margin: 0 0.4rem; color: var(--slate-faint); }
.field__error { color: #d23b3b; font-size: 0.85rem; }

/* ---------- Messages ---------- */
.messages { list-style: none; margin: 1.25rem 0; padding: 0; display: grid; gap: 0.5rem; }
.message {
  padding: 0.75rem 1rem; border-radius: var(--radius);
  background: var(--paper-warm); border-left: 4px solid var(--slate);
}
.message--success { border-left-color: #2c8a2c; }
.message--warning { border-left-color: var(--flame); }
.message--error { border-left-color: #d23b3b; }

/* ---------- Footer ---------- */
.site-footer {
  background: var(--ink); color: var(--paper);
  padding: 2.5rem 0 1.5rem;
  margin-top: 3rem;
}
.site-footer a {
  color: var(--flame);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: color 120ms, border-color 120ms;
}
.site-footer a:hover,
.site-footer a:focus-visible {
  color: var(--paper);
  border-bottom-color: var(--flame);
}
.site-footer__grid {
  display: grid; gap: 2rem;
  grid-template-columns: 1fr;
}
@media (min-width: 720px) {
  .site-footer__grid { grid-template-columns: 1.5fr 1fr 1fr; }
}
.site-footer__col h3 { color: var(--paper); font-size: 1rem; margin-bottom: 0.75rem; }
.site-footer__col ul { list-style: none; padding: 0; margin: 0; }
.site-footer__col li { margin-bottom: 0.35rem; }
.site-footer__fine {
  margin-top: 2rem; padding-top: 1rem; border-top: 1px solid #333;
  color: #aaa; font-size: 0.85rem; display: flex; flex-wrap: wrap;
  gap: 1rem; justify-content: space-between;
}
.site-footer__version {
  color: #888;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 0.78rem;
}
.site-footer__version a { color: #aaa; }
.site-footer__legal { display: flex; gap: 1rem; }
.site-footer__legal a { color: #aaa; }

/* ---------- Newsletter (footer) ---------- */
.newsletter-form { display: grid; gap: 0.5rem; }
.newsletter-form input[type="email"] {
  background: var(--paper); color: var(--ink); border: 0;
  border-radius: var(--radius); padding: 0.65rem 0.8rem; min-height: 44px;
}

/* ---------- Utility ---------- */
.muted { color: var(--slate); }
.mt-0 { margin-top: 0; }
.mt-1 { margin-top: 0.5rem; }
.mt-2 { margin-top: 1rem; }
.mt-3 { margin-top: 1.5rem; }
.mt-4 { margin-top: 2rem; }
.text-center { text-align: center; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* ---------- Classes catalog + detail ---------- */
.catalog-filters {
  display: grid; gap: 1rem;
  grid-template-columns: 1fr;
}
@media (min-width: 640px) {
  .catalog-filters { grid-template-columns: 2fr 1fr 1fr; align-items: end; }
}

.session-grid {
  display: grid; gap: 2rem;
  grid-template-columns: 1fr;
}
@media (min-width: 880px) {
  .session-grid { grid-template-columns: 2fr 1fr; align-items: start; }
  .session-grid__side { position: sticky; top: 90px; }
}

/* ---------- HTMX hooks ---------- */
.htmx-indicator { display: none; }
.htmx-request .htmx-indicator { display: inline-block; }
.htmx-request.htmx-indicator { display: inline-block; }

/* ---------- Materials + progress + prereqs ---------- */
.material-list { list-style: none; padding: 0; margin: 0.5rem 0 0 0; }
.material-list li {
  padding: 0.5rem 0;
  border-top: 1px solid var(--slate-faint);
  display: flex; flex-wrap: wrap; gap: 0.4rem 0.6rem; align-items: baseline;
}
.material-list li:first-child { border-top: none; }
.material-list li > p { flex-basis: 100%; margin: 0; font-size: 0.9rem; }

.card__materials { margin: 0.5rem 0; }
.card__materials summary {
  cursor: pointer; color: var(--flame-deep);
  padding: 0.25rem 0; min-height: 36px; display: inline-flex; align-items: center;
}
.card__materials summary:focus-visible {
  outline: none; box-shadow: var(--focus); border-radius: 4px;
}

.progress {
  background: var(--slate-faint);
  border-radius: 999px;
  height: 8px;
  overflow: hidden;
  margin: 0.5rem 0;
}
.progress__bar {
  background: var(--flame);
  height: 100%;
  transition: width 220ms ease-out;
  min-width: 0;
}
.card--progress .card__meta { margin-top: 0.25rem; }

.badge {
  display: inline-block;
  font-size: 0.75rem;
  font-weight: 700;
  padding: 0.15rem 0.55rem;
  border-radius: var(--radius-sm);
  background: var(--slate-faint);
  color: var(--slate);
  vertical-align: middle;
  margin-left: 0.4rem;
  line-height: 1.4;
}
.badge--complete { background: var(--flame); color: var(--paper); }

.prereqs { padding: 0; list-style: none; margin: 0.5rem 0; }
.prereqs li { padding: 0.3rem 0; line-height: 1.45; }
.prereqs .check {
  color: #2a8a3e; font-weight: 700; margin-right: 0.35rem;
  display: inline-block; width: 1.1em; text-align: center;
}
.prereqs .cross {
  color: #c0392b; font-weight: 700; margin-right: 0.35rem;
  display: inline-block; width: 1.1em; text-align: center;
}

/* Certificate verification */
.card--verify { max-width: 540px; margin: 0 auto; }
.cert-detail {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.15rem 1rem;
  margin: 1rem 0;
}
.cert-detail dt {
  font-weight: 700; color: var(--slate);
  font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.05em;
  margin-top: 0.5rem;
}
.cert-detail dt:first-child { margin-top: 0; }
.cert-detail dd { margin: 0; word-break: break-word; }
@media (min-width: 520px) {
  .cert-detail { grid-template-columns: max-content 1fr; align-items: baseline; }
  .cert-detail dt { margin-top: 0; }
}

/* ---------- Instructor roster ---------- */
/* Mobile-first: horizontal scroll wrapper for the table so 4 columns
   never break the page width. On wide screens the scroll never kicks in. */
.roster-wrap {
  width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  margin: 0 -1.25rem; /* extend to the container edge for thumb-scrolling */
  padding: 0 1.25rem;
}
.roster {
  width: 100%; border-collapse: collapse;
  min-width: 36rem; /* keeps columns from collapsing into illegibility */
}
.roster th, .roster td {
  padding: 0.75rem 0.6rem; text-align: left;
  border-bottom: 1px solid var(--slate-faint);
  vertical-align: top;
}
.roster th {
  background: var(--paper-warm); font-weight: 700;
  font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--slate);
}
.roster td small { display: block; color: var(--slate); }
.roster select {
  font: inherit; padding: 0.4rem 0.5rem; min-height: 36px;
  border: 2px solid var(--slate-faint); border-radius: var(--radius);
  background: var(--paper);
}
.roster__actions { display: flex; gap: 0.5rem; flex-wrap: wrap; }

/* ---------- Inline video/audio player ---------- */
.player {
  background: var(--ink); border-radius: var(--radius-lg);
  overflow: hidden; max-width: 920px; margin: 0 auto;
}
.player video {
  width: 100%; height: auto; display: block;
  max-height: 70vh; background: var(--ink);
}
.player audio { width: 100%; display: block; padding: 1rem; background: var(--paper-warm); }

/* ---------- Cancel-session disclosure ---------- */
.hero__danger { margin-top: 1rem; }
.hero__danger > summary {
  display: inline-flex; align-items: center; gap: 0.4rem;
  cursor: pointer; color: #c0392b; font-weight: 700;
  padding: 0.4rem 0.6rem; min-height: 36px;
  border: 1px solid currentColor; border-radius: var(--radius);
  list-style: none;
}
.hero__danger > summary::-webkit-details-marker { display: none; }
.hero__danger[open] > summary { background: #fdf3f1; }

/* ---------- Generic narrow form ---------- */
.form-grid { display: grid; gap: 1rem; max-width: 36rem; }
.form-grid label {
  display: flex; flex-direction: column; gap: 0.35rem;
  font-weight: 700; font-size: 0.95rem;
}
.form-grid input[type="text"],
.form-grid input[type="email"],
.form-grid input[type="url"],
.form-grid input[type="number"],
.form-grid input[type="file"],
.form-grid textarea,
.form-grid select {
  font: inherit; color: var(--ink); background: var(--paper);
  padding: 0.65rem 0.8rem; min-height: 44px;
  border: 2px solid var(--slate-faint); border-radius: var(--radius);
}
.form-grid textarea { min-height: 6rem; resize: vertical; }
.form-grid input:focus, .form-grid select:focus, .form-grid textarea:focus {
  border-color: var(--flame); outline: none;
}
.form-grid input[type="file"] { padding: 0.45rem 0.5rem; }
.form-grid .check-row {
  flex-direction: row; align-items: center; gap: 0.6rem;
  min-height: 44px; font-weight: 400;
}
.form-grid .check-row input { margin: 0; width: 20px; height: 20px; flex: 0 0 auto; }
.form-grid > div { display: flex; flex-wrap: wrap; gap: 0.5rem; }

/* ---------- Staff tables ---------- */
.staff-table {
  width: 100%;
  border-collapse: collapse;
  margin: 1rem 0 2rem;
  font-size: 0.95rem;
}
.staff-table th, .staff-table td {
  text-align: left;
  padding: 0.55rem 0.7rem;
  border-bottom: 1px solid var(--slate-faint);
  vertical-align: middle;
}
.staff-table th {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.7rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--slate);
  border-bottom: 2px solid var(--ink);
}
.staff-table tr:hover { background: var(--canvas); }
.staff-table code {
  background: var(--canvas);
  padding: 1px 6px;
  border-radius: 3px;
  font-size: 0.85rem;
}

/* ---------- StreamField blocks ---------- */

.block-heading { margin: 2rem 0 1rem; }
.block-heading__eyebrow {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--flame-deep);
  margin: 0 0 0.4rem;
}
.block-heading__text { margin: 0; line-height: 1.15; }
.block-heading--h2 .block-heading__text { font-size: 1.8rem; }
.block-heading--h3 .block-heading__text { font-size: 1.3rem; }

.block-callout {
  padding: 1rem 1.2rem;
  border-radius: var(--radius);
  border-left: 4px solid var(--slate);
  background: var(--canvas);
  margin: 1.4rem 0;
}
.block-callout__title { margin: 0 0 0.4rem; font-size: 1.05rem; }
.block-callout__body p:last-child { margin-bottom: 0; }
.block-callout--info    { border-left-color: var(--slate); }
.block-callout--flame   { border-left-color: var(--flame); background: rgba(255, 136, 68, 0.08); }
.block-callout--warning { border-left-color: #d23b3b; background: #fdecea; }
.block-callout--success { border-left-color: #2e7d32; background: #ebf6ec; }

.block-cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin: 1rem 0 1.6rem;
}

.block-async-course { max-width: 28rem; }

.block-event-list {
  list-style: none;
  padding: 0;
  margin: 1rem 0 1.6rem;
}
.block-event-list li {
  display: grid;
  grid-template-columns: 60px 1fr;
  gap: 1rem;
  padding: 0.85rem 0;
  border-bottom: 1px solid var(--slate-faint);
  align-items: start;
}
.block-event-list__date {
  text-align: center;
  border: 1px solid var(--slate-faint);
  padding: 0.3rem;
  border-radius: var(--radius);
  font-family: var(--font-body);
}
.block-event-list__date .month {
  display: block;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.65rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--flame-deep);
}
.block-event-list__date .day {
  font-size: 1.3rem;
  font-weight: 700;
}
.block-event-list__body p { margin: 0.3rem 0; }
.block-event-list__body p:last-child { margin: 0.3rem 0 0; }

.block-instructor {
  background: var(--canvas);
  border: 1px solid var(--slate-faint);
  border-radius: var(--radius);
  padding: 1.4rem 1.6rem;
  margin: 1.4rem 0;
}
.block-instructor__eyebrow {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--slate);
  margin: 0 0 0.4rem;
}
.block-instructor__name { margin: 0 0 0.3rem; }

.block-impact {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(220px, 1fr);
  gap: 1.6rem;
  align-items: center;
  background: var(--canvas);
  border: 1px solid var(--slate-faint);
  border-left: 4px solid var(--flame);
  border-radius: var(--radius);
  padding: 1.4rem 1.6rem;
  margin: 1.4rem 0;
}
@media (max-width: 720px) {
  .block-impact { grid-template-columns: 1fr; }
}
.block-impact__quote { margin: 0; }
.block-impact__quote p {
  font-family: var(--font-body);
  font-size: 1.15rem;
  font-style: italic;
  line-height: 1.4;
  margin: 0 0 0.5rem;
}
.block-impact__quote cite { color: var(--slate); font-style: normal; }
.block-impact__ask { text-align: center; }
.block-impact__cost { margin: 0 0 0.6rem; }
.block-impact__cost strong { font-size: 1.6rem; color: var(--flame-deep); display: block; }
.block-impact__campaign { font-size: 0.8rem; margin-top: 0.5rem; }

/* ---------- Donation campaigns ---------- */
.campaign-progress {
  padding: 16px 18px;
  background: var(--canvas);
  border: 1px solid var(--slate-faint);
  border-radius: var(--radius);
  margin: 12px 0;
}
.campaign-progress--compact { padding: 10px 12px; margin: 8px 0; }
.campaign-progress__name { font-weight: 700; margin: 0 0 4px; font-size: 1.05rem; }
.campaign-progress__summary { font-size: 0.9rem; margin: 0 0 8px; }
.campaign-progress__bar {
  width: 100%;
  height: 14px;
  background: #fff;
  border: 1px solid var(--slate-faint);
  border-radius: 999px;
  overflow: hidden;
  margin: 8px 0;
}
.campaign-progress__fill {
  height: 100%;
  background: linear-gradient(90deg, var(--flame), var(--flame-deep));
  transition: width 200ms;
}
.campaign-progress__stats {
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: 1.05rem;
}
.campaign-progress__pct {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  color: var(--flame-deep);
  font-weight: 600;
}
.campaign-progress__meta { font-size: 0.85rem; margin-top: 4px; }
.campaign-progress__cta { margin-top: 12px; }

.campaign-detail__cols {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(280px, 1fr);
  gap: 2rem;
  align-items: start;
}
@media (max-width: 800px) {
  .campaign-detail__cols { grid-template-columns: 1fr; }
}
.campaign-detail__cover {
  width: 100%; max-height: 320px; object-fit: cover;
  border-radius: var(--radius); margin-bottom: 1rem;
}
.supporter-list { list-style: none; padding: 0; margin: 0; }
.supporter-list li {
  border-bottom: 1px solid var(--slate-faint);
  padding: 0.6rem 0;
}
.supporter-list li p { margin: 0.3rem 0 0; font-style: italic; }

/* ---------- Status badges ---------- */
/* Rounded rectangle, not a pill: at ~17px tall the standard --radius (8px)
   would round a badge almost to a full capsule, so badges get their own
   smaller token. Same squared bottom-right brand corner as everything else. */
.badge {
  display: inline-block;
  vertical-align: middle;
  padding: 2px 8px;
  border-radius: var(--radius-sm);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.65rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin-left: 0.4rem;
}
.badge--draft     { background: #f0ebe0; color: #87807a; }
.badge--published { background: var(--flame); color: var(--ink); }

/* Shared-inbox claim state (contact/inbox.html). Unclaimed is the actionable
   one, so it's outlined in flame to catch the eye without turning a busy list
   into a wall of solid orange; a message someone else already owns recedes
   into the default grey. All three carry a border so the outlined one doesn't
   sit a pixel taller than its neighbours. */
.badge--mine      { background: var(--flame); color: var(--ink); border: 1px solid transparent; }
.badge--claimed   { background: var(--slate-faint); color: var(--slate); border: 1px solid transparent; }
.badge--unclaimed { background: transparent; color: var(--ink); border: 1px solid var(--flame); }

/* ---------- Message read / unread status ---------- */
/* The badge and the "read by ... ago" note share one row under the Status
   label, so the note never wraps onto its own line. */
.message-detail__status { display: flex; align-items: center; flex-wrap: wrap; gap: 0.5rem; }
.message-detail__status .badge { margin-left: 0; }
/* Both use the standard site font (not the mono badge face). Read is a plain
   black outline; unread stays a solid flame fill, so the two states are still
   easy to tell apart at a glance. Shape comes from the shared badge radius, so
   the status on a message detail page matches the badges in the inbox list. */
.badge--read,
.badge--unread {
  font-family: inherit;
  font-size: 0.78rem;
  letter-spacing: 0.03em;
  border: 1px solid transparent;
}
.badge--read   { background: transparent; color: var(--ink); border-color: var(--ink); }
.badge--unread { background: var(--flame); color: var(--ink); font-weight: 700; }

.card__actions { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0.6rem 0; }
.lesson-mini-list {
  list-style: none; padding: 0; margin: 0.6rem 0 0;
  border-top: 1px solid var(--slate-faint);
}
.lesson-mini-list li {
  padding: 0.4rem 0;
  border-bottom: 1px solid var(--slate-faint);
  display: flex; flex-wrap: wrap; gap: 0.6rem; align-items: baseline;
}
.lesson-mini-list li a { text-decoration: none; color: var(--ink); font-weight: 500; }
.lesson-mini-list li a:hover { color: var(--flame-deep); }

/* A course-level content action: what it does on the left, the button that
   does it on the right. Two of them stack, and each explains itself, because
   these replace commands somebody used to run on the server and the person
   pressing one should not have to guess what it touches. */
.content-action {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  align-items: flex-start;
  justify-content: space-between;
  padding: 0.9rem 0;
  border-top: 1px solid var(--slate-faint);
}
.content-action > div { flex: 1 1 22rem; min-width: 0; }
.content-action p { margin: 0.25rem 0 0; }
.content-action form { flex: 0 0 auto; }
.content-action code { font-size: 0.85em; word-break: break-all; }
.content-action__log { margin-top: 0.5rem; font-size: 0.85rem; }
.content-action__log summary { cursor: pointer; color: var(--flame-deep); }
.content-action__log pre {
  margin: 0.4rem 0 0;
  padding: 0.6rem 0.8rem;
  max-height: 14rem;
  overflow: auto;
  background: var(--paper-2, #f4f1ea);
  border: 1px solid var(--slate-faint);
  white-space: pre-wrap;
  word-break: break-word;
  font-size: 0.8rem;
}

/* ---------- Contact form ---------- */
.contact-form { max-width: 36rem; }
.contact-form__honeypot {
  position: absolute; left: -9999px; width: 1px; height: 1px;
  overflow: hidden;
}

/* ---------- Brand mark (Q) ----------
   Two complementary use patterns:

   1. `<img src="{% static 'img/q-mark.svg' %}" class="brand-mark">` - wraps the
       baked-color file at a controlled size. Use brand-mark--dark or
       --light to pull in the single-color variants instead.

   2. `{% include "brand/q_mark.svg" %}` - inlines the SVG so its
       currentColor picks up the surrounding text color. The parent
       sets `color:` (or `class="brand-mark"`), the mark inherits it.
       Same `.brand-mark--<size>` classes work for sizing here too.
*/
.brand-mark {
  display: inline-block;
  vertical-align: middle;
  width: 1.5em; height: 1.5em;
  flex: 0 0 auto;
  color: var(--flame);
}
.brand-mark--sm { width: 1em; height: 1em; }
.brand-mark--md { width: 2em; height: 2em; }
.brand-mark--lg { width: 3em; height: 3em; }
.brand-mark--xl { width: 5em; height: 5em; }
.brand-mark--block { display: block; }
.brand-mark > svg, .brand-mark > img {
  width: 100%; height: 100%; display: block;
}
.brand-mark--ink { color: var(--ink); }
.brand-mark--paper { color: var(--paper); }
.brand-mark--slate { color: var(--slate); }
.brand-mark--flame { color: var(--flame); }
.brand-mark--canvas { color: var(--canvas); }

/* Duotone Q-mark - independent CSS variables driven by data-q-fill /
   data-q-stroke attributes. Each named value maps to a brand token.
   For raw colors, set --q-fill / --q-stroke on a wrapping element. */
.q-mark-duo[data-q-fill="flame"]       { --q-fill: var(--flame); }
.q-mark-duo[data-q-fill="flame-deep"]  { --q-fill: var(--flame-deep); }
.q-mark-duo[data-q-fill="slate"]       { --q-fill: var(--slate); }
.q-mark-duo[data-q-fill="ink"]         { --q-fill: var(--ink); }
.q-mark-duo[data-q-fill="paper"]       { --q-fill: var(--paper); }
.q-mark-duo[data-q-fill="canvas"]      { --q-fill: var(--canvas); }
.q-mark-duo[data-q-fill="transparent"] { --q-fill: transparent; }

.q-mark-duo[data-q-stroke="flame"]       { --q-stroke: var(--flame); }
.q-mark-duo[data-q-stroke="flame-deep"]  { --q-stroke: var(--flame-deep); }
.q-mark-duo[data-q-stroke="slate"]       { --q-stroke: var(--slate); }
.q-mark-duo[data-q-stroke="ink"]         { --q-stroke: var(--ink); }
.q-mark-duo[data-q-stroke="paper"]       { --q-stroke: var(--paper); }
.q-mark-duo[data-q-stroke="canvas"]      { --q-stroke: var(--canvas); }
.q-mark-duo[data-q-stroke="transparent"] { --q-stroke: transparent; }

/* Footer lockup - Q-mark + wordmark, on the dark footer background. */
.site-footer__lockup {
  display: inline-flex; align-items: center; gap: 0.75rem;
  margin-bottom: 0.75rem;
}
.site-footer__lockup .brand-mark { width: 3rem; height: 3rem; }
.site-footer__wordmark {
  font-family: var(--font-body);
  font-size: 1.75rem; font-weight: 500; line-height: 1;
  margin: 0; color: var(--paper);
  letter-spacing: -0.01em;
}
.site-footer__motto {
  color: var(--flame); font-style: italic;
  font-size: 1.05rem; margin: 0 0 0.75rem;
}
.site-footer__credit {
  display: inline-flex; align-items: center; gap: 0.5rem;
}

/* ---------- Async-course viewer ---------- */
.hero--compact { padding: 2rem 0 1.5rem; }


.lesson-nav {
  display: flex; gap: 0.5rem; flex-wrap: wrap;
  justify-content: space-between; align-items: center;
}

/* Slide player */
.player {
  background: var(--paper);
  border: 1px solid var(--slate-faint);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}
.player__progress { margin: 0; border-radius: 0; }
.player__viewport {
  position: relative;
  min-height: 22rem;
  padding: 2rem 1.25rem;
  background: var(--paper-warm);
}
.player__slide { display: none; }
.player__slide--active { display: block; }
.player__main { max-width: 48rem; margin: 0 auto; }
.player__image {
  display: block; max-width: 100%; height: auto;
  margin: 0 auto 1.5rem; border-radius: var(--radius);
}
.player__title {
  font-size: clamp(1.5rem, 2.5vw + 0.5rem, 2.1rem);
  margin: 0 0 1rem;
}
.player__body { font-size: 1.05rem; }
.player__body ul, .player__body ol { padding-left: 1.25rem; }
.player__audio {
  display: block; width: 100%; max-width: 48rem;
  margin: 1.5rem auto 0;
}
.player__script {
  max-width: 48rem; margin: 1.5rem auto 0;
  font-size: 0.95rem; color: var(--slate);
}
.player__script summary { cursor: pointer; color: var(--flame-deep); }
.player__controls {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem;
  padding: 1rem 1.25rem;
  border-top: 1px solid var(--slate-faint);
  background: var(--paper);
}
.player__counter { font-variant-numeric: tabular-nums; }

@media (max-width: 600px) {
  .player__viewport { padding: 1.5rem 1rem; min-height: 18rem; }
  .player__controls { padding: 0.75rem 1rem; }
}

/* ---------- Volunteer log ---------- */
.vol-grid {
  display: grid; gap: 2rem;
  grid-template-columns: 1fr;
}
@media (min-width: 880px) {
  .vol-grid { grid-template-columns: 1.5fr 1fr; align-items: start; }
}
.vol-grid__form > .form-grid { max-width: none; }

/* ---------- Policy pages (privacy, terms) ---------- */
/* Long-form legal copy: one narrow measure so it stays readable, and rules
   between top-level sections so somebody scanning for "how long do you keep X"
   can find the boundary. */
/* Cap each block rather than the container itself: .policy sits on the
   .container div, and narrowing that would centre the copy while the hero
   heading above it stays left-aligned. Constraining the children instead gives
   a left-aligned measure, the same way .hero__lede does. */
.policy > * { max-width: 44rem; }
.policy h2 {
  font-size: 1.3rem; margin: 2.5rem 0 0.75rem;
  padding-top: 1.5rem; border-top: 1px solid var(--slate-faint);
}
.policy > :first-child { margin-top: 0; }
.policy > h2:first-child { padding-top: 0; border-top: none; }
.policy h3 { font-size: 1.02rem; margin: 1.5rem 0 0.4rem; }
.policy p { margin: 0 0 1rem; }
.policy ul { margin: 0 0 1rem; padding-left: 1.25rem; }
.policy li { margin-bottom: 0.4rem; }
.policy .roster-wrap { margin-bottom: 1.5rem; }
.policy .roster td small { margin-top: 0.25rem; }

.policy__version {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 0.78rem;
}
.policy__summary {
  background: var(--paper-warm);
  border: 1px solid var(--slate-faint);
  border-left: 4px solid var(--flame);
  border-radius: var(--radius);
  padding: 1.25rem 1.5rem;
  margin-bottom: 2rem;
}
.policy__summary > :last-child { margin-bottom: 0; }
.policy__notice {
  background: var(--canvas);
  border-left: 4px solid var(--flame-deep);
  border-radius: var(--radius-sm);
  padding: 1rem 1.25rem;
}

/* ---------- Prefers reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
  html { scroll-behavior: auto; }
}
