/* ==========================================================================
   The PTO App — in-browser demo shell
   Design tokens + frame chrome + router transitions + ui kit + home skeleton.
   Tokens are ported verbatim from theptoapp/lib/theme.ts and the website design
   spec (§7). Everything is driven by two data-attrs on <html>:
     [data-appearance="light"|"dark"]   -> neutral + ink surface
     [data-palette="midnightCoral"|...] -> brand + category tints
   The two axes compose (4 palettes x 2 appearances) via var indirection.
   ========================================================================== */

/* ---------- global constants (appearance/palette independent) ---------- */
:root {
  /* System font ONLY — never the site's Google fonts. */
  --font: -apple-system, "SF Pro Text", system-ui, "Segoe UI", Roboto, sans-serif;

  /* Radii ramp (theme.ts Radii). */
  --r8: 8px;  --r10: 10px; --r12: 12px; --r14: 14px; --r16: 16px;
  --r18: 18px; --r24: 24px; --r32: 32px; --r999: 999px;

  /* Semantic (hold across themes). */
  --ok: #34c759;
  --ok-deep: #1f8d3a;   /* theme.ts Semantic.successDeep — the fundraiser $ / % ink */
  --bad: #E55247;
  --warn: #FFB347;
  --info: #3DB4C5;
  --bronze: #A9673A;    /* Sponsors' Bronze tier chip — no palette-tinted category fits, so
                            it's a fixed hex like --ok/--bad/--warn/--info above */

  /* Chrome geometry. */
  --sb-h: 54px;   /* status-bar / top safe area */
  --tab-h: 83px;  /* tab bar incl. home-indicator */
  --edge-h: 34px; /* bottom clearance for the home indicator alone — pushed
                     screens hide the tab bar (see .no-tabbar) and reclaim
                     the rest of that height for content / a sticky CTA */

  /* Screen push/pop transition. */
  --slide: 260ms cubic-bezier(0.32, 0.72, 0, 1);
}

/* ---------- neutrals per appearance (theme.ts Neutral dyn pairs) ---------- */
:root[data-appearance="light"] {
  --n-bg: #FFFFFF;
  --n-bg-soft: #f5f6f8;
  --n-bg-softer: #fafbfc;
  --n-tile: #eef0f3;
  --n-line: #e2e5e9;
  --n-line-soft: #eceef1;
  --n-fg3: #bcc0c5;
  --n-fg2: #9aa0a6;
  --n-fg1: #6c727a;
  --n-fg1b: #5b6168;
  --n-fg-deep: #3a3f46;
  --app-ink: var(--pal-ink);   /* body ink = active palette ink in light */
  --backdrop: #e8ebf0;         /* letterbox behind the phone (standalone) */
  --glass-fill: rgba(255, 255, 255, 0.06);
  --glass-edge: rgba(255, 255, 255, 0.14);
}
:root[data-appearance="dark"] {
  --n-bg: #0F1115;
  --n-bg-soft: #171A20;
  --n-bg-softer: #13161B;
  --n-tile: #1E222A;
  --n-line: #2A2E37;
  --n-line-soft: #1F232B;
  --n-fg3: #5B6168;
  --n-fg2: #7A8088;
  --n-fg1: #A0A6AD;
  --n-fg1b: #B5BBC2;
  --n-fg-deep: #D4D8DE;
  --app-ink: #F2F4F7;          /* single near-white ink over any deep canvas */
  --backdrop: #05070c;
  --glass-fill: rgba(255, 255, 255, 0.05);
  --glass-edge: rgba(255, 255, 255, 0.12);
}

/* ---------- palettes (theme.ts `themes`) ---------- */
:root[data-palette="midnightCoral"] {
  --pri: #FF6A55; --pri-deep: #D94B38; --pri-soft: #FFD5CE;
  --pal-ink: #0A0F28; --cta-fg: #FFFFFF;
  --hero-a: #1B2B6E; --hero-b: #0B1437; --hero-c: #0A0F28;
  --c-events: #3FA6A5; --c-volunteer: #F2B441; --c-fundraising: #E74C8A;
  --c-resources: #7C83DB; --c-surveys: #58BA8E;
}
:root[data-palette="slateCitrus"] {
  --pri: #9ED431; --pri-deep: #6B9400; --pri-soft: #E9F9BA;
  --pal-ink: #0C0D11; --cta-fg: #0C0D11;
  --hero-a: #1F222A; --hero-b: #16181E; --hero-c: #0C0D11;
  --c-events: #3DB4C5; --c-volunteer: #FFB347; --c-fundraising: #FF5C8A;
  --c-resources: #8E84FF; --c-surveys: #7FE6A5;
}
:root[data-palette="forestApricot"] {
  --pri: #F39A63; --pri-deep: #D97A4A; --pri-soft: #FCE7D5;
  --pal-ink: #0F1F19; --cta-fg: #0F1F19;
  --hero-a: #2D6247; --hero-b: #1F4434; --hero-c: #0F1F19;
  --c-events: #5A8B7B; --c-volunteer: #D9A441; --c-fundraising: #CC5A47;
  --c-resources: #4E6A92; --c-surveys: #7FA375;
}
:root[data-palette="tealGold"] {
  --pri: #F2B441; --pri-deep: #C48E20; --pri-soft: #FBE7B8;
  --pal-ink: #0A2E38; --cta-fg: #0A2E38;
  --hero-a: #1F7A8F; --hero-b: #0F4C5C; --hero-c: #0A2E38;
  --c-events: #2A9D8F; --c-volunteer: #F2B441; --c-fundraising: #E76F51;
  --c-resources: #476C9B; --c-surveys: #7FA375;
}

/* ---------- type ramp (theme.ts Type) ---------- */
.t-display { font-size: 42px; font-weight: 800; line-height: 44px; letter-spacing: -1.68px; }
.t-h1 { font-size: 30px; font-weight: 800; line-height: 35px; letter-spacing: -0.75px; }
.t-h2 { font-size: 26px; font-weight: 800; line-height: 31px; letter-spacing: -0.52px; }
.t-h3 { font-size: 22px; font-weight: 700; line-height: 28px; letter-spacing: -0.33px; }
.t-h4 { font-size: 17px; font-weight: 700; line-height: 22px; letter-spacing: -0.17px; }
.t-h5 { font-size: 16px; font-weight: 600; line-height: 22px; }
.t-body { font-size: 15px; font-weight: 500; line-height: 22px; }
.t-body-sm { font-size: 14px; font-weight: 500; line-height: 21px; }
.t-meta { font-size: 13px; font-weight: 500; line-height: 18px; }
.t-meta-sm { font-size: 12px; font-weight: 600; line-height: 17px; }
.t-eyebrow { font-size: 11px; font-weight: 700; line-height: 15px; letter-spacing: 1.32px; text-transform: uppercase; }

/* ---------- reset + stage ---------- */
* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
body {
  font-family: var(--font);
  background: var(--backdrop);
  color: var(--app-ink);
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
button { font-family: inherit; }

/* Task 18 a11y fix: a single global focus-visible ring for every native
   interactive element in the demo. Most buttons never had `outline` reset
   so they already fell back to the UA default ring; a handful of text
   inputs (search bars, the donate custom-amount field, the chat composer)
   set `outline: none` and relied on a `:focus` border-color change instead
   — fine for a pointer, easy to miss for a keyboard user tabbing through a
   busy screen. Element-type selectors here (`input:focus-visible`, etc.)
   out-specificity those single-class `outline: none` resets, so this wins
   without having to touch each one individually. More specific existing
   rules (.tour-btn, .tour-pill__start/close) still take precedence where
   they intentionally pick a different outline color for contrast reasons. */
button:focus-visible,
a:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--pri);
  outline-offset: 2px;
}

/* The logical device. 393x852 (iPhone 16 Pro), scaled to fit its container
   via --demo-scale (computed in main.js on resize).
   Centered with position:fixed + top/left:50% + translate(-50%,-50%) rather
   than the parent `body{display:grid;place-items:center}` this replaced:
   a grid/flex item's automatic min-size doesn't shrink below its specified
   width/height (393x852) for `auto`-sized tracks, so the implicit column/row
   track was forced to the item's full unscaled 393x852 box regardless of
   the actual (often much smaller) container — `min-width:0;min-height:0`
   does NOT help here since `auto` track sizing keys off the item's
   max-content contribution, not its min-size floor. That left the track
   (and the item centered within it) overflowing the visible viewport, and
   `transform-origin:center center` then scaled around that miscentered
   point instead of the viewport's actual center — offsetting the rendered
   phone by ~13% at mobile hero widths. `position:fixed` sidesteps grid/flex
   sizing entirely: top/left:50% is resolved against the viewport (the
   containing block for fixed position — the iframe's own viewport when
   embedded), and translate(-50%,-50%) shifts back by exactly half of the
   element's own (pre-scale) box so its center lands on the viewport center
   before `scale()` ever runs — so scaling around that same center keeps it
   pinned, at any container size. Verified via getBoundingClientRect at
   200x434 / 320x694 / 393x852 / 500x1084 / 400x700: symmetric letterbox
   gaps (max delta sub-pixel), zero scrollable overflow. */
.demo-root {
  position: fixed;
  top: 50%;
  left: 50%;
  width: 393px;
  height: 852px;
  background: var(--n-bg);
  overflow: hidden;
  border-radius: var(--screen-radius, 44px);
  transform: translate(-50%, -50%) scale(var(--demo-scale, 1));
  transform-origin: center center;
  box-shadow: 0 40px 90px -30px rgba(0, 0, 0, 0.55);
}

/* ---------- status bar ---------- */
.statusbar {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: var(--sb-h);
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 30px 0 28px;
  color: var(--app-ink);      /* adaptive: dark glyphs on light, light on dark */
  pointer-events: none;
}
/* Poster-gated: both capture masters (light + dark) show near-black glyphs
   over the navy hero — the capture template bakes dark glyphs regardless of
   appearance — so '/' must match at boot. Non-hero screens stay adaptive
   (.statusbar above) since only this route is poster-gated. */
.statusbar--hero { color: #0A0A0A; }
.statusbar__time {
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.2px;
  font-variant-numeric: tabular-nums;
  padding-top: 4px;
}
.statusbar__glyphs {
  display: flex;
  align-items: center;
  gap: 7px;
  padding-top: 4px;
}
.statusbar__island {
  position: absolute;
  top: 11px;
  left: 50%;
  transform: translateX(-50%);
  width: 122px;
  height: 36px;
  background: #000;
  border-radius: 20px;
}
.sb-signal { height: 11px; width: auto; display: block; }
.sb-wifi { height: 12px; width: auto; display: block; }
.sb-battery { height: 12px; width: auto; display: block; }

/* ---------- screen stack ---------- */
#screen {
  position: absolute;
  top: 0; left: 0; right: 0;
  bottom: var(--tab-h);
  overflow: hidden;
}
.screen {
  position: absolute;
  inset: 0;
  overflow-y: auto;
  overflow-x: hidden;
  /* Keep wheel/trackpad scrolling INSIDE the phone: at the top/bottom of a
     screen the scroll must not chain out to the host marketing page (the
     embedded iframe case), which otherwise reads as "the app won't scroll". */
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  background: var(--n-bg);
  will-change: transform;
}
.screen::-webkit-scrollbar { width: 0; height: 0; }
.screen.is-animating { transition: transform var(--slide); }
.screen--under::after {            /* dim the screen sliding behind */
  content: "";
  position: absolute;
  inset: 0;
  background: #000;
  opacity: 0.16;
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  .screen.is-animating { transition: none; }
  .screen--under::after { display: none; }
}

/* ---------- tab bar ---------- */
.tabbar {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: var(--tab-h);
  display: flex;
  align-items: stretch;
  padding: 8px 6px 22px;
  background: color-mix(in srgb, var(--n-bg) 85%, transparent);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  border-top: 1px solid var(--n-line);
  z-index: 20;
}
.tab {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  gap: 3px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--n-fg2);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: color 140ms ease, transform 120ms ease;
}
.tab svg { width: 26px; height: 26px; display: block; }
.tab__label { font-size: 10px; font-weight: 600; letter-spacing: 0.1px; }
.tab.is-active { color: var(--pri); }
.tab:active { transform: scale(0.92); }

/* A11y/visual fix (task 18, deferred from task 5 review): real iOS renders
   this as a subtle, low-contrast neutral bar, not a branded ink pill.
   --app-ink is the active PALETTE's ink (near-navy in midnightCoral, near-
   black in the others), so on light palettes it read as a solid dark pill —
   correct-but-wrong-looking. --n-fg2 is appearance-aware (light/dark) but
   palette-INVARIANT (theme.ts Neutral, not Semantic/palette), so it gives
   every palette the same quiet, native-looking indicator instead of one
   that visibly shouts the current brand color. Decorative (aria-hidden),
   so this is a visual fix only — no contrast floor applies. */
.home-indicator {
  position: absolute;
  bottom: 8px;
  left: 50%;
  transform: translateX(-50%);
  width: 134px;
  height: 5px;
  border-radius: 3px;
  background: var(--n-fg2);
  opacity: 0.7;
  z-index: 21;
  pointer-events: none;
}

/* Pushed (non-tab-root) screens hide the tab bar entirely — router.js
   toggles this on #demo-root per route (see TAB_ROOTS). The home indicator
   is a separate sibling element, so it stays visible either way; #screen
   just reclaims the height the tab bar isn't using anymore, which is what
   lets a pushed screen's own sticky CTA dock (a `position: fixed` child of
   `.screen`) sit right above the indicator instead of above a hidden bar. */
.demo-root.no-tabbar .tabbar { display: none; }
.demo-root.no-tabbar #screen { bottom: var(--edge-h); }

/* ---------- overlay layer (toasts + sheets), scales with the phone ---------- */
#overlay {
  position: absolute;
  inset: 0;
  z-index: 40;
  pointer-events: none;
}
#overlay > * { pointer-events: auto; }

.toast-layer {
  position: absolute;
  left: 0; right: 0;
  bottom: calc(var(--tab-h) + 14px);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  pointer-events: none;
}
.toast {
  max-width: 80%;
  padding: 11px 18px;
  border-radius: var(--r999);
  background: color-mix(in srgb, var(--app-ink) 92%, transparent);
  color: var(--n-bg);
  text-align: center;
  box-shadow: 0 10px 30px -8px rgba(0, 0, 0, 0.5);
  opacity: 0;
  transform: translateY(12px) scale(0.98);
  transition: opacity 200ms ease, transform 200ms ease;
}
.toast.is-in { opacity: 1; transform: translateY(0) scale(1); }
@media (prefers-reduced-motion: reduce) {
  .toast { transition: opacity 120ms linear; transform: none; }
}

.sheet-wrap { position: absolute; inset: 0; }
.sheet-scrim {
  position: absolute;
  inset: 0;
  background: rgba(6, 8, 16, 0.42);
  opacity: 0;
  transition: opacity 260ms ease;
}
.sheet-panel {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  max-height: 86%;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 8px 20px calc(20px + env(safe-area-inset-bottom));
  background: var(--n-bg);
  border-radius: var(--r24) var(--r24) 0 0;
  box-shadow: 0 -18px 50px -20px rgba(0, 0, 0, 0.5);
  transform: translateY(100%);
  transition: transform var(--slide);
}
.sheet-grabber {
  width: 38px; height: 5px;
  border-radius: 3px;
  background: var(--n-line);
  margin: 0 auto 10px;
}
.sheet-wrap.is-open .sheet-scrim { opacity: 1; }
.sheet-wrap.is-open .sheet-panel { transform: translateY(0); }
@media (prefers-reduced-motion: reduce) {
  .sheet-panel, .sheet-scrim { transition: none; }
}

/* ==========================================================================
   SHARED — event card + cover + tag chips (Home / Events / Detail)
   ========================================================================== */
.event-card {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform 120ms ease;
}
.event-card:active { transform: scale(0.985); }

.cover {
  position: relative;
  width: 100%;
  height: 160px;
  border-radius: var(--r16);
  overflow: hidden;
  background: var(--n-tile);
}
.cover__img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cover__initials {
  width: 100%; height: 100%;
  display: grid; place-items: center;
  background: linear-gradient(140deg, var(--c-events), var(--hero-b));
}
.cover__initials span { font-size: 44px; font-weight: 800; color: #fff; letter-spacing: -1px; }
.cover__date {
  position: absolute;
  top: 12px; left: 12px;
  padding: 5px 10px;
  border-radius: var(--r999);
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
}
.event-card__title { margin: 12px 0 0; color: var(--app-ink); }
.event-card__meta {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-top: 6px;
  color: var(--n-fg1b);
  font-size: 14px;
  font-weight: 500;
}
.event-card__meta svg { width: 15px; height: 15px; flex: 0 0 auto; color: var(--n-fg2); }
.event-card__meta span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.event-card__tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 11px; }

.chip-tag {
  padding: 4px 9px;
  border-radius: var(--r999);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.4px;
  text-transform: uppercase;
}
.chip-tag--volunteer { background: color-mix(in srgb, var(--c-volunteer) 18%, var(--n-bg)); color: var(--c-volunteer); }
.chip-tag--fundraiser { background: color-mix(in srgb, var(--c-fundraising) 18%, var(--n-bg)); color: var(--c-fundraising); }
.chip-tag--event { background: var(--n-bg-soft); color: var(--n-fg1); }

/* ==========================================================================
   HOME — collapsing navy hero + white sheet
   ========================================================================== */
.home { background: var(--n-bg); }
.home__herofix { position: sticky; top: 0; height: 0; z-index: 5; }

.hero {
  position: relative;
  width: 100%;
  height: 334px;
  overflow: hidden;
  padding: calc(var(--sb-h) + 8px) 20px 22px;
  border-radius: 0 0 32px 32px;
  background: linear-gradient(140deg, var(--hero-a) 0%, var(--hero-b) 52%, var(--hero-c) 100%);
  color: #fff;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.hero__orb {
  position: absolute;
  top: -80px; right: -70px;
  width: 320px; height: 320px;
  border-radius: 50%;
  background: radial-gradient(circle,
    color-mix(in srgb, var(--pri) 32%, transparent) 0%,
    color-mix(in srgb, var(--pri) 8%, transparent) 55%,
    transparent 78%);
  pointer-events: none;
}
.hero__top { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.hero__eyebrow {
  display: flex;
  align-items: center;
  gap: 9px;
  min-width: 0;
  color: rgba(255, 255, 255, 0.7);
}
.hero__eyebrow::before {
  content: "";
  flex: 0 0 auto;
  width: 18px; height: 2px;
  border-radius: 1px;
  background: var(--pri);
}
.hero__bell {
  position: relative;
  flex: 0 0 auto;
  width: 44px; height: 44px;   /* invisible tap target — bare glyph, no disc */
  border-radius: var(--r999);
  border: 0;
  background: none;
  color: #fff;
  display: grid;
  place-items: center;
  cursor: pointer;
}
.hero__bell-badge {
  position: absolute;
  top: 6px; right: 6px;   /* offset for the larger 44px invisible tap target, same visual hug on the glyph */
  min-width: 16px; height: 16px;
  padding: 0 4px;
  border-radius: var(--r999);
  background: var(--pri);
  color: var(--pal-ink);
  font-size: 10px;
  font-weight: 800;
  display: grid;
  place-items: center;
}
.hero__expanded { display: flex; flex-direction: column; }
.hero__greeting { margin: 4px 0 0; color: #fff; }
.hero__sub { margin: 6px 0 0; color: rgba(255, 255, 255, 0.65); }
.stats { display: flex; gap: 10px; margin-top: 16px; }
.stat {
  flex: 1;
  padding: 12px;
  border-radius: var(--r16);
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--glass-edge);
}
.stat__num { font-size: 22px; font-weight: 800; line-height: 26px; letter-spacing: -0.4px; }
.stat--events .stat__num { color: var(--c-events); }
.stat--fav .stat__num { color: var(--c-fundraising); }
.stat--new .stat__num { color: var(--pri); }
.stat__label { margin-top: 6px; color: rgba(255, 255, 255, 0.6); }

.home__sheet {
  position: relative;
  background: var(--n-bg);
  padding: 334px 16px 44px;
}
.home__section { margin-bottom: 28px; }
.home__section:first-child { padding-top: 22px; }

.section-head { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.section-head--coral { --sh-tint: var(--pri); }
.section-head--teal { --sh-tint: var(--c-events); }
.section-head__chip {
  width: 40px; height: 40px;
  flex: 0 0 auto;
  border-radius: var(--r12);
  display: grid;
  place-items: center;
  background: color-mix(in srgb, var(--sh-tint) 15%, var(--n-bg));
  color: var(--sh-tint);
}
/* Task 18: promoted from a plain div to a real <h2> (see home.js) for valid
   heading order — margin:0 cancels the UA default h2 block margin so the
   flex-centered .section-head row's layout is unaffected. */
.section-head__title { margin: 0; color: var(--app-ink); }
.section-head__badge {
  flex: 0 0 auto;
  min-width: 22px; height: 22px;
  padding: 0 7px;
  border-radius: var(--r999);
  background: var(--sh-tint);
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.section-head__spacer { flex: 1; }
.section-head__more {
  flex: 0 0 auto;
  color: var(--pri);
  font-size: 15px;
  font-weight: 600;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

/* announcement carousel */
.carousel { display: flex; flex-direction: column; gap: 12px; margin-top: 12px; }
.carousel__track {
  display: flex;
  overflow-x: auto;
  overscroll-behavior: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.carousel__track::-webkit-scrollbar { display: none; }
.announce {
  flex: 0 0 100%;
  box-sizing: border-box;
  scroll-snap-align: start;
  min-height: 132px;
  padding: 14px;
  border-radius: var(--r16);
  background: color-mix(in srgb, var(--a-tint) 14%, var(--n-bg));
  display: flex;
  flex-direction: column;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.announce--0 { --a-tint: var(--pri); }
.announce--1 { --a-tint: var(--c-events); }
.announce--2 { --a-tint: var(--c-fundraising); }
.announce--3 { --a-tint: var(--c-volunteer); }
.announce--4 { --a-tint: var(--c-surveys); }
.announce__date {
  align-self: flex-start;
  padding: 4px 10px;
  border-radius: var(--r999);
  background: rgba(255, 255, 255, 0.85);
  border: 1px solid color-mix(in srgb, var(--a-tint) 32%, transparent);
  color: var(--a-tint);
  font-size: 11px;
  font-weight: 700;
}
.announce__grow { flex: 1; min-height: 8px; }
.announce__title { margin: 0 0 4px; color: var(--app-ink); font-size: 16px; font-weight: 700; letter-spacing: -0.2px; }
.announce__body {
  margin: 0;
  color: var(--n-fg1);
  font-size: 14px;
  font-weight: 500;
  line-height: 20px;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.carousel__dots { display: flex; justify-content: center; align-items: center; }
/* Task 18 (Lighthouse target-size): the dot itself is a deliberately tiny
   iOS-style pagination marker (6px, 18px pill when active) — real 6x6/18x6
   buttons packed 6px apart fail the 24x24 minimum tap target both on their
   own size and on spacing to their neighbor. The button/hit-area grows to a
   full 24x24 (so adjacent dots' hit areas just meet, no dead zone and no
   overlap); the small visible marker moves to an ::after so it keeps
   reading exactly as before. JS is untouched — it still just toggles
   .is-active on this same element. */
.carousel__dot {
  width: 24px; height: 24px;
  display: grid; place-items: center;
  border: 0;
  padding: 0;
  background: none;
  cursor: pointer;
}
.carousel__dot::after {
  content: "";
  width: 6px; height: 6px;
  border-radius: var(--r999);
  background: var(--n-line);
  transition: width 200ms ease, background 200ms ease;
}
.carousel__dot.is-active::after { width: 18px; background: var(--pri); }

.home__events { display: flex; flex-direction: column; gap: 20px; }

/* quick links — stacked label + coral arrow (matches 08-home-scrolled) */
.quick-links { margin-top: 4px; }
.quick-links__eyebrow { display: block; color: var(--n-fg1); margin-bottom: 6px; }
.quick-link {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--n-line-soft);
  padding: 14px 0;
  cursor: pointer;
}
.quick-link:last-child { border-bottom: 0; }
.quick-link__label { color: var(--app-ink); font-size: 20px; font-weight: 700; line-height: 26px; }
.quick-link__arrow { color: var(--pri); font-size: 20px; font-weight: 700; line-height: 1; }

/* ==========================================================================
   EVENTS — title bar + search + segmented + list
   ========================================================================== */
.events { background: var(--n-bg); min-height: 100%; }
.events__header {
  position: sticky;
  top: 0;
  z-index: 4;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: calc(var(--sb-h) + 8px) 20px 12px;
  background: color-mix(in srgb, var(--n-bg) 82%, transparent);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
}
.events__bar { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; }
.events__title { text-align: center; color: var(--app-ink); }
.events__actions { justify-self: end; display: flex; align-items: center; gap: 8px; }
.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px; height: 36px;
  border-radius: var(--r10);
  border: 0;
  background: none;
  color: var(--app-ink);
  cursor: pointer;
}
.events__bar > .icon-btn { justify-self: start; }
.events__new {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  border: 0;
  background: none;
  padding: 6px 2px;
  color: var(--pri);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.5px;
  cursor: pointer;
}
.events__new svg { width: 14px; height: 14px; }
.events__search {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 14px;
  border-radius: var(--r999);
  background: var(--n-bg-soft);
}
.events__search svg { width: 16px; height: 16px; flex: 0 0 auto; color: var(--n-fg2); }
.events__search-input { flex: 1; border: 0; background: none; color: var(--app-ink); padding: 0; outline: none; }
.events__search-input::placeholder { color: var(--n-fg2); }
.segmented { display: flex; gap: 3px; padding: 3px; border-radius: var(--r12); background: var(--n-bg-soft); }
.seg {
  flex: 1;
  padding: 9px 8px;
  text-align: center;
  border: 0;
  border-radius: var(--r10);
  background: none;
  color: var(--n-fg1);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}
.seg.is-active {
  background: var(--n-bg);
  color: var(--app-ink);
  font-weight: 700;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.10);
}
.events__list { display: flex; flex-direction: column; gap: 22px; padding: 16px 16px 44px; }

.empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 10px;
  padding: 64px 30px;
}
.empty__icon {
  width: 64px; height: 64px;
  border-radius: var(--r16);
  display: grid;
  place-items: center;
  background: var(--n-bg-soft);
  color: var(--c-events);
}
.empty__title { color: var(--app-ink); }
.empty__note { color: var(--n-fg2); max-width: 240px; }

/* ==========================================================================
   EVENT DETAIL — photo hero + meta + RSVP + volunteer + action rows
   ========================================================================== */
.detail { background: var(--n-bg); min-height: 100%; }
.detail__cover {
  position: relative;
  height: 280px;
  border-radius: 0 0 28px 28px;
  overflow: hidden;
  background: var(--n-tile);
}
.detail__cover--missing { background: linear-gradient(140deg, var(--c-events), var(--hero-b)); }
.cover__initials--hero { height: 100%; }
.cover__initials--hero span { font-size: 72px; }
.detail__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, transparent 55%, rgba(0, 0, 0, 0.45));
  pointer-events: none;
}
.detail__back {
  position: absolute;
  top: calc(var(--sb-h) - 6px);
  left: 14px;
  z-index: 2;
  width: 38px; height: 38px;
  border-radius: var(--r999);
  border: 0;
  background: rgba(0, 0, 0, 0.45);
  color: #fff;
  display: grid;
  place-items: center;
  cursor: pointer;
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
}
.detail__body { padding: 20px 20px 40px; display: flex; flex-direction: column; gap: 16px; }
.detail__tags { display: flex; flex-wrap: wrap; gap: 8px; }
.detail__title { margin: 0; color: var(--app-ink); }

.detail-meta {
  background: var(--n-bg-soft);
  border-radius: var(--r16);
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.detail-meta__row { display: flex; align-items: center; gap: 10px; color: var(--n-fg-deep); font-size: 15px; font-weight: 500; }
.detail-meta__row svg { width: 16px; height: 16px; flex: 0 0 auto; color: var(--n-fg1); }
.detail-meta__row--link { color: var(--pri); }
.detail-meta__row--link svg { color: var(--pri); }

.detail__about { display: flex; flex-direction: column; gap: 8px; }
.detail__eyebrow { color: var(--n-fg1); }
.detail__desc { margin: 0; color: var(--n-fg-deep); }

.rsvp-card, .vol-card {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 16px;
  border-radius: var(--r16);
  border: 1px solid var(--n-line);
}
.rsvp-card__title, .vol-card__title { color: var(--app-ink); }
.rsvp-seg { display: flex; gap: 8px; }
.rsvp-seg__btn {
  flex: 1;
  padding: 11px 8px;
  border-radius: var(--r12);
  border: 1px solid var(--n-line);
  background: var(--n-bg);
  color: var(--n-fg-deep);
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  transition: background 150ms ease, color 150ms ease, border-color 150ms ease;
}
.rsvp-seg__btn.is-active { background: var(--pri); border-color: var(--pri); color: var(--pal-ink); font-weight: 700; }

.vol-role { display: flex; flex-direction: column; gap: 9px; }
.vol-role__top { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.vol-role__name { color: var(--app-ink); }
.vol-role__count { flex: 0 0 auto; color: var(--n-fg1); }
.vol-role__bar { height: 8px; border-radius: var(--r999); background: var(--n-tile); overflow: hidden; }
.vol-role__fill { height: 100%; border-radius: var(--r999); background: var(--c-volunteer); transition: width 240ms ease; }
.vol-role__btn {
  align-self: flex-start;
  padding: 8px 18px;
  border-radius: var(--r999);
  border: 0;
  background: var(--pri);
  color: var(--pal-ink);
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
}
.vol-role__btn.is-full { background: var(--n-bg-soft); color: var(--n-fg2); cursor: default; }
.vol-role__done {
  align-self: flex-start;
  padding: 8px 18px;
  border-radius: var(--r999);
  background: color-mix(in srgb, var(--c-surveys) 18%, var(--n-bg));
  color: var(--c-surveys);
  font-size: 14px;
  font-weight: 700;
}

.detail-row {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  text-align: left;
  padding: 14px 4px;
  border: 0;
  border-top: 1px solid var(--n-line-soft);
  background: none;
  cursor: pointer;
}
.detail-row__icon {
  flex: 0 0 auto;
  width: 34px; height: 34px;
  border-radius: var(--r12);
  display: grid;
  place-items: center;
  background: var(--n-bg-soft);
  color: var(--pri);
}
.detail-row__label { flex: 1; color: var(--app-ink); }
.detail-row > svg { color: var(--n-fg2); flex: 0 0 auto; }

/* ==========================================================================
   ANNOUNCEMENTS — nav-style header + list + detail (pushed, not a tab root)
   ========================================================================== */
.nav-header {
  position: sticky;
  top: 0;
  z-index: 4;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: calc(var(--sb-h) + 8px) 12px 14px 8px;
  background: color-mix(in srgb, var(--n-bg) 82%, transparent);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
}
.nav-header__title { flex: 1; margin: 0; color: var(--app-ink); }
.nav-header__new {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  flex: 0 0 auto;
  border: 0;
  background: none;
  padding: 6px 8px;
  color: var(--pri);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.5px;
  cursor: pointer;
}
.nav-header__new svg { width: 14px; height: 14px; }

.date-chip {
  align-self: flex-start;
  padding: 4px 10px;
  border-radius: var(--r999);
  border: 1px solid var(--pri);
  color: var(--pri);
  font-size: 11px;
  font-weight: 700;
}

.announcements { background: var(--n-bg); min-height: 100%; }
.announcements__list { display: flex; flex-direction: column; gap: 14px; padding: 16px 16px 44px; }

.announcement-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 100%;
  text-align: left;
  padding: 16px;
  border-radius: var(--r16);
  border: 1px solid var(--n-line);
  background: var(--n-bg);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform 120ms ease;
}
.announcement-card:active { transform: scale(0.985); }
.announcement-card__title { margin: 0; color: var(--app-ink); }
.announcement-card__body {
  margin: 0;
  color: var(--n-fg1);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.announcement-detail { background: var(--n-bg); min-height: 100%; }
.announcement-detail__body { padding: 4px 20px 40px; display: flex; flex-direction: column; gap: 14px; }
.announcement-detail__title { margin: 0; color: var(--app-ink); }
.announcement-detail__desc { margin: 0; color: var(--n-fg-deep); }
.announcement-detail__meta { color: var(--n-fg2); }

/* ==========================================================================
   CREATE FORMS — Announcement + Event (shared field / switch / CTA)
   ========================================================================== */
.create { background: var(--n-bg); min-height: 100%; }
.create__body { padding: 12px 20px 40px; display: flex; flex-direction: column; gap: 18px; }

.field { display: flex; flex-direction: column; gap: 8px; }
.field__row { display: flex; gap: 12px; }
.field__row .field { flex: 1; min-width: 0; }
.field__label { color: var(--n-fg1); }
.field__input, .field__textarea {
  width: 100%;
  padding: 12px 14px;
  border-radius: var(--r12);
  border: 1.5px solid transparent;
  background: var(--n-bg-soft);
  color: var(--app-ink);
  font-family: inherit;
  font-size: 15px;
  font-weight: 500;
  line-height: 22px;
  outline: none;
  transition: border-color 150ms ease;
}
.field__input::placeholder, .field__textarea::placeholder { color: var(--n-fg2); }
.field__input:focus, .field__textarea:focus { border-color: var(--pri); }
.field__textarea { resize: none; min-height: 96px; }
/* Native date/time pickers render with the OS's own chrome — hint the
   picker's own color scheme so its icon/glyphs stay legible in dark mode. */
input.field__input[type="date"], input.field__input[type="time"] { color-scheme: light; }
:root[data-appearance="dark"] input.field__input[type="date"],
:root[data-appearance="dark"] input.field__input[type="time"] { color-scheme: dark; }

.switch-row { display: flex; align-items: center; justify-content: space-between; padding: 2px 0; }
.switch-row__label { color: var(--app-ink); }
.switch {
  position: relative;
  flex: 0 0 auto;
  width: 50px; height: 30px;
  border-radius: var(--r999);
  border: 0;
  padding: 0;
  background: var(--n-line);
  cursor: pointer;
  transition: background 150ms ease;
}
.switch.is-on { background: var(--pri); }
.switch__thumb {
  position: absolute;
  top: 2px; left: 2px;
  width: 26px; height: 26px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.25);
  transition: transform 150ms ease;
}
.switch.is-on .switch__thumb { transform: translateX(20px); }

.btn-primary {
  width: 100%;
  padding: 16px;
  border-radius: var(--r16);
  border: 0;
  background: var(--pri);
  color: var(--pal-ink);
  font-size: 16px;
  font-weight: 800;
  cursor: pointer;
  transition: opacity 150ms ease, transform 120ms ease;
}
.btn-primary:active:not(:disabled) { transform: scale(0.985); }
.btn-primary:disabled { opacity: 0.4; cursor: not-allowed; }

/* ==========================================================================
   SHARED — tinted icon chip (Board NavCards, Profile menu, Notifications,
   Archived list). Soft palette-tinted fill + solid glyph; recolors per theme.
   ========================================================================== */
.icon-chip {
  flex: 0 0 auto;
  width: 44px; height: 44px;
  border-radius: var(--r12);
  display: grid;
  place-items: center;
}
.icon-chip--sm { width: 32px; height: 32px; border-radius: var(--r10); }
.icon-chip--coral     { color: var(--pri);            background: color-mix(in srgb, var(--pri) 16%, var(--n-bg)); }
.icon-chip--coralDeep { color: var(--pri-deep);       background: color-mix(in srgb, var(--pri-deep) 16%, var(--n-bg)); }
.icon-chip--teal      { color: var(--c-events);       background: color-mix(in srgb, var(--c-events) 16%, var(--n-bg)); }
.icon-chip--amber     { color: var(--c-volunteer);    background: color-mix(in srgb, var(--c-volunteer) 18%, var(--n-bg)); }
.icon-chip--pink      { color: var(--c-fundraising);  background: color-mix(in srgb, var(--c-fundraising) 16%, var(--n-bg)); }
.icon-chip--green     { color: var(--c-surveys);      background: color-mix(in srgb, var(--c-surveys) 18%, var(--n-bg)); }
.icon-chip--indigo    { color: var(--c-resources);    background: color-mix(in srgb, var(--c-resources) 18%, var(--n-bg)); }
.icon-chip--muted     { color: var(--n-fg1);          background: var(--n-bg-soft); }
.icon-chip--danger    { color: var(--bad);            background: color-mix(in srgb, var(--bad) 14%, var(--n-bg)); }

/* ==========================================================================
   BOARD — hub (tab root) + pushed Manage sub-screens (pledges/archived/verify)
   ========================================================================== */
.board { background: var(--n-bg); min-height: 100%; }
.board__body {
  padding: calc(var(--sb-h) + 24px) 16px 40px;
  display: flex;
  flex-direction: column;
  gap: 22px;
}
.board__intro { display: flex; flex-direction: column; gap: 3px; }
.board__eyebrow { color: var(--n-fg2); }
.board__title { margin: 2px 0 0; color: var(--app-ink); }
.board__subtitle { color: var(--n-fg2); }
.board__section { display: flex; flex-direction: column; gap: 10px; }
.board__section-label { color: var(--n-fg1); }

.nav-card {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  text-align: left;
  padding: 16px;
  border-radius: var(--r14);
  border: 1px solid var(--n-line);
  background: var(--n-bg-soft);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform 120ms ease;
}
.nav-card:active { transform: scale(0.99); }
.nav-card__body { flex: 1; min-width: 0; }
.nav-card__title { color: var(--app-ink); }
.nav-card__sub { margin-top: 2px; color: var(--n-fg2); }
.nav-card__chev { flex: 0 0 auto; color: var(--n-fg3); font-size: 24px; line-height: 1; }

.board-sub { background: var(--n-bg); min-height: 100%; }
.board-sub__body { padding: 8px 16px 40px; }
.board-sub__intro { margin: 4px 4px 16px; color: var(--n-fg1); }

.pledge-list { display: flex; flex-direction: column; }
.pledge-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 4px;
  border-top: 1px solid var(--n-line-soft);
}
.pledge-row:first-child { border-top: 0; }
.pledge-row__body { flex: 1; min-width: 0; }
.pledge-row__name { color: var(--app-ink); }
.pledge-row__note { margin-top: 2px; color: var(--n-fg2); }
.pledge-row__amount { flex: 0 0 auto; color: var(--ok-deep); }
.pledge-row--total { margin-top: 6px; border-top: 2px solid var(--n-line); }
.pledge-row--total .pledge-row__amount { color: var(--app-ink); }

.archive-list { display: flex; flex-direction: column; gap: 10px; padding-top: 8px; }
.archive-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px;
  border-radius: var(--r14);
  border: 1px solid var(--n-line-soft);
  background: var(--n-bg-softer);
}
.archive-row__body { flex: 1; min-width: 0; }
.archive-row__title { color: var(--n-fg-deep); }
.archive-row__when { margin-top: 2px; color: var(--n-fg2); }

.verify-card {
  margin-top: 8px;
  padding: 24px 20px;
  border-radius: var(--r18);
  background: color-mix(in srgb, var(--c-surveys) 12%, var(--n-bg));
  border: 1px solid color-mix(in srgb, var(--c-surveys) 28%, transparent);
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 10px;
}
.verify-card__badge {
  width: 60px; height: 60px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--c-surveys) 22%, var(--n-bg));
  color: var(--c-surveys);
  display: grid;
  place-items: center;
}
.verify-card__title { margin: 0; color: var(--app-ink); }
.verify-card__note { margin: 0; color: var(--n-fg1); }

/* ==========================================================================
   PROFILE — navy hero + glass stats + email + continuous tinted-chip menu
   ========================================================================== */
.profile { background: var(--n-bg-softer); min-height: 100%; }
.profile__hero {
  position: relative;
  overflow: hidden;
  padding: calc(var(--sb-h) + 8px) 20px 22px;
  border-radius: 0 0 32px 32px;
  background: linear-gradient(140deg, var(--hero-a) 0%, var(--hero-b) 52%, var(--hero-c) 100%);
  color: #fff;
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.profile__orb {
  position: absolute;
  top: -80px; right: -60px;
  width: 240px; height: 240px;
  border-radius: 50%;
  background: radial-gradient(circle,
    color-mix(in srgb, var(--pri) 32%, transparent) 0%,
    color-mix(in srgb, var(--pri) 8%, transparent) 58%,
    transparent 82%);
  pointer-events: none;
}
.profile__id-row { display: flex; align-items: center; gap: 14px; }
.profile__avatar {
  flex: 0 0 auto;
  width: 64px; height: 64px;
  border-radius: 50%;
  background: var(--pri);
  color: var(--cta-fg);
  display: grid;
  place-items: center;
  font-size: 26px;
  font-weight: 800;
  border: 2px solid rgba(255, 255, 255, 0.6);
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.25);
}
.profile__id-text { min-width: 0; }
.profile__name { margin: 0; color: #fff; }
.profile__sub { margin-top: 2px; color: rgba(255, 255, 255, 0.65); }
.profile__stats { display: flex; gap: 10px; }
.profile-stat {
  flex: 1;
  min-width: 0;
  padding: 12px;
  border-radius: var(--r16);
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--glass-edge);
}
.profile-stat__value { font-size: 22px; font-weight: 800; letter-spacing: -0.4px; line-height: 26px; }
.profile-stat--school .profile-stat__value { color: var(--pri); }
.profile-stat--role .profile-stat__value { color: var(--c-fundraising); }
.profile-stat--status .profile-stat__value { color: var(--c-events); }
.profile-stat__label { margin-top: 6px; color: rgba(255, 255, 255, 0.65); }

.profile__email-wrap { padding: 16px 20px 0; }
.profile__email { color: var(--n-fg1); }

.profile__menu {
  margin-top: 18px;
  background: var(--n-bg);
  border-top: 1px solid var(--n-line-soft);
  border-bottom: 1px solid var(--n-line-soft);
}
.profile__signout {
  margin-top: 28px;
  background: var(--n-bg);
  border-top: 1px solid var(--n-line-soft);
  border-bottom: 1px solid var(--n-line-soft);
}
.menu-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  text-align: left;
  padding: 14px 16px;
  border: 0;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform 120ms ease;
}
.menu-row:active { transform: scale(0.99); }
/* Inset hairline between rows (after the 32px chip + 16 pad + 14 gap = 62px). */
.menu-row:not(:first-child)::before {
  content: "";
  position: absolute;
  left: 62px; right: 0; top: 0;
  height: 1px;
  background: var(--n-line-soft);
}
.menu-row__label { flex: 1; min-width: 0; color: var(--app-ink); font-size: 16px; font-weight: 500; }
.menu-row__chev { flex: 0 0 auto; color: var(--n-fg3); font-size: 22px; line-height: 1; }
.menu-row--danger .menu-row__label { color: var(--bad); font-weight: 600; }

/* ==========================================================================
   ACTIVITY — pushed, four segments (Events/RSVPs/Volunteering/Donations)
   ========================================================================== */
.activity { background: var(--n-bg); min-height: 100%; }
.activity__seg-wrap { padding: 8px 16px 4px; }
.segmented--activity .seg { font-size: 12px; padding: 9px 4px; }
.activity__list { display: flex; flex-direction: column; gap: 12px; padding: 12px 16px 40px; }
.activity-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px;
  border-radius: var(--r14);
  border: 1px solid var(--n-line);
  background: var(--n-bg);
}
.activity-row__body { flex: 1; min-width: 0; }
.activity-row__title { color: var(--app-ink); }
.activity-row__meta { margin-top: 2px; color: var(--n-fg1); }
.activity-row__amount { flex: 0 0 auto; color: var(--ok-deep); }
.activity-chip {
  flex: 0 0 auto;
  padding: 4px 10px;
  border-radius: var(--r999);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.3px;
  text-transform: uppercase;
}
.activity-chip--going { background: color-mix(in srgb, var(--ok) 18%, var(--n-bg)); color: var(--ok-deep); }
.activity-chip--maybe { background: color-mix(in srgb, var(--c-volunteer) 20%, var(--n-bg)); color: var(--c-volunteer); }
.activity-chip--no { background: var(--n-bg-soft); color: var(--n-fg1); }

/* ==========================================================================
   APPEARANCE — segmented Light/Dark/System + 2×2 palette grid (theming showpiece)
   ========================================================================== */
.appearance { background: var(--n-bg); min-height: 100%; }
.appearance__body { padding: 12px 20px 40px; display: flex; flex-direction: column; gap: 28px; }
.appearance__section { display: flex; flex-direction: column; gap: 12px; }
.appearance__label { color: var(--n-fg2); }
.appearance__lead { color: var(--n-fg1); line-height: 20px; }

.palette-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.palette-card {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 14px;
  border-radius: var(--r16);
  border: 1.5px solid var(--n-line);
  background: var(--n-bg-soft);
  text-align: left;
  cursor: pointer;
  transition: transform 120ms ease;
}
.palette-card:active { transform: scale(0.985); }
.palette-card.is-active { border-color: var(--pri); border-width: 2px; padding: 13.5px; }
.palette-swatches { display: flex; gap: 6px; }
.palette-swatch { flex: 1; height: 28px; border-radius: var(--r8); }
.palette-card__row { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 22px; }
.palette-card__name { color: var(--app-ink); }
.palette-card__active {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 8px;
  border-radius: var(--r999);
  background: var(--pri);
  color: var(--cta-fg);
}
.palette-card__active-text { font-size: 10px; font-weight: 800; letter-spacing: 0.8px; text-transform: uppercase; }

/* ==========================================================================
   NOTIFICATIONS — pushed list, read/unread rows, Mark all read header action
   ========================================================================== */
.nav-header__action {
  flex: 0 0 auto;
  border: 0;
  background: none;
  padding: 6px 4px;
  color: var(--pri);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}
.notifs { background: var(--n-bg); min-height: 100%; }
.notifs__list { display: flex; flex-direction: column; gap: 10px; padding: 12px 16px 40px; }
.notif-row {
  display: flex;
  gap: 12px;
  padding: 12px;
  border-radius: var(--r14);
  border: 1px solid var(--n-line);
  background: var(--n-bg);
}
.notif-row.is-read { background: var(--n-bg-softer); border-color: var(--n-line-soft); }
.notif-row__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.notif-row__top { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; }
.notif-row__text { flex: 1; color: var(--app-ink); }
.notif-row.is-read .notif-row__text { color: var(--n-fg1b); }
.notif-row__dot { flex: 0 0 auto; width: 8px; height: 8px; margin-top: 5px; border-radius: 50%; background: var(--pri); }
.notif-row__dot--teal { background: var(--c-events); }
.notif-row__dot--pink { background: var(--c-fundraising); }
.notif-row__dot--amber { background: var(--c-volunteer); }
.notif-row__dot--green { background: var(--c-surveys); }
.notif-row__time { color: var(--n-fg2); }

/* ==========================================================================
   NEWSLETTER — AI draft showpiece: shimmer → typewriter reveal → send
   ========================================================================== */
.newsletter { background: var(--n-bg); min-height: 100%; }
.newsletter__body { padding: 12px 20px 40px; display: flex; flex-direction: column; gap: 14px; }
.newsletter__intro { margin: 0; color: var(--n-fg2); }
.newsletter__foot { margin: 2px 0 0; color: var(--n-fg3); text-align: center; }

.btn-primary--icon { display: flex; align-items: center; justify-content: center; gap: 8px; }

.newsletter__shimmer {
  padding: 18px;
  border-radius: var(--r16);
  border: 1px solid var(--n-line);
  background: var(--n-bg-soft);
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.newsletter__shimmer-label { color: var(--n-fg1); }
.nl-skeleton { display: flex; flex-direction: column; gap: 10px; }
.nl-skeleton__line {
  height: 11px;
  border-radius: 6px;
  background: linear-gradient(90deg, var(--n-tile) 25%, var(--n-bg-softer) 50%, var(--n-tile) 75%);
  background-size: 300% 100%;
  animation: nl-shimmer 1.3s ease-in-out infinite;
}
@keyframes nl-shimmer { 0% { background-position: 150% 0; } 100% { background-position: -150% 0; } }
@media (prefers-reduced-motion: reduce) {
  .nl-skeleton__line { animation: none; }
}

.newsletter__paper {
  padding: 18px;
  border-radius: var(--r16);
  border: 1px solid var(--n-line);
  background: var(--n-bg-soft);
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-height: 120px;
}
.nl-greeting { color: var(--app-ink); font-size: 15px; font-weight: 700; }
.nl-heading { margin-top: 9px; color: var(--app-ink); font-size: 15px; font-weight: 700; }
.nl-para { color: var(--n-fg1); font-size: 14px; line-height: 21px; }
.nl-bullet { color: var(--n-fg1); font-size: 14px; line-height: 21px; }
.nl-signoff { margin-top: 9px; color: var(--app-ink); font-size: 14px; font-weight: 600; }
.nl-caret {
  display: inline-block;
  width: 2px; height: 1em;
  margin-left: 1px;
  vertical-align: -2px;
  background: var(--pri);
  animation: nl-blink 1s step-end infinite;
}
@keyframes nl-blink { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .nl-caret { display: none; } }

.newsletter__actions { display: flex; flex-direction: column; gap: 10px; }
.newsletter__regen {
  align-self: center;
  border: 0;
  background: none;
  padding: 6px 10px;
  color: var(--pri);
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
}
.newsletter__sent {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 15px;
  border-radius: var(--r16);
  background: color-mix(in srgb, var(--ok) 16%, var(--n-bg));
  color: var(--ok-deep);
  font-size: 16px;
  font-weight: 800;
}

/* ==========================================================================
   FUNDRAISERS — list, detail (gradient hero + progress card + board tools),
   the donate sheet (chips/custom/spinner/success), and confetti.
   ========================================================================== */

/* ---- list (nav-style header w/ back-circle, text tabs, stacked cards) ---- */
.fundraisers { background: var(--n-bg); min-height: 100%; }
.fund-header {
  position: sticky;
  top: 0;
  z-index: 4;
  padding: calc(var(--sb-h) + 8px) 20px 0;
  background: color-mix(in srgb, var(--n-bg) 82%, transparent);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid var(--n-line);
}
.fund-bar { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; padding-bottom: 14px; }
.fund-back {
  justify-self: start;
  width: 40px; height: 40px;
  border-radius: var(--r999);
  border: 0;
  background: var(--n-bg-soft);
  color: var(--app-ink);
  display: grid;
  place-items: center;
  cursor: pointer;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.08);
}
.fund-title { text-align: center; color: var(--app-ink); }
.fund-tabs { display: flex; gap: 22px; padding: 14px 20px; }
.fund-tab { background: none; border: 0; padding: 0; cursor: pointer; font-size: 16px; font-weight: 600; color: var(--n-fg2); }
.fund-tab.is-active { color: var(--app-ink); font-weight: 800; }

.fund-list { display: flex; flex-direction: column; gap: 30px; padding: 20px 20px 110px; }

.fund-card {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform 120ms ease;
}
.fund-card:active { transform: scale(0.985); }
.fund-card__thumb {
  position: relative;
  width: 80px; height: 80px;
  border-radius: var(--r16);
  overflow: hidden;
  display: grid;
  place-items: center;
}
.fund-card__thumb--fundraising { background: linear-gradient(140deg, var(--c-fundraising), var(--hero-b)); }
.fund-card__thumb--events { background: linear-gradient(140deg, var(--c-events), var(--hero-b)); }
.fund-card__thumb--volunteer { background: linear-gradient(140deg, var(--c-volunteer), var(--hero-b)); }
.fund-card__initials { font-size: 26px; font-weight: 800; color: #fff; letter-spacing: -0.5px; }
.fund-card__badge {
  position: absolute;
  top: 8px; left: 8px;
  padding: 4px 8px;
  border-radius: var(--r999);
  background: var(--pri);
  color: var(--cta-fg);
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.4px;
}
.fund-card__title { margin: 12px 0 0; color: var(--app-ink); }
.fund-card__bar { margin-top: 10px; height: 8px; border-radius: var(--r999); background: #e5e7eb; overflow: hidden; }
.fund-card__fill { height: 100%; border-radius: var(--r999); background: var(--pri); transition: width 500ms ease; }
.fund-card__meta { margin-top: 8px; color: var(--n-fg1b); }
.fund-card > svg { display: block; margin-top: 6px; color: var(--n-fg3); }

.fund-fab {
  position: fixed;
  right: 20px; bottom: 24px;
  z-index: 5;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 0;
  padding: 14px 20px;
  border-radius: var(--r999);
  background: var(--pri);
  color: var(--pal-ink);
  font-size: 15px;
  font-weight: 800;
  cursor: pointer;
  box-shadow: 0 14px 30px -8px color-mix(in srgb, var(--pri) 55%, transparent);
}
.fund-fab svg { width: 14px; height: 14px; }

/* ---- detail (gradient hero + progress card + board tools + sticky CTA) ---- */
.fund-detail { background: var(--n-bg); min-height: 100%; }
.fund-hero {
  position: relative;
  height: 280px;
  border-radius: 0 0 28px 28px;
  overflow: hidden;
  background: linear-gradient(135deg, var(--c-fundraising) 0%, var(--hero-b) 100%);
}
.fund-hero__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, transparent 45%, rgba(0, 0, 0, 0.45));
  pointer-events: none;
}
.fund-hero__pills {
  position: absolute;
  left: 18px; right: 18px; bottom: 18px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.fund-pill { padding: 5px 10px; border-radius: var(--r999); font-size: 10px; font-weight: 800; letter-spacing: 0.6px; text-transform: uppercase; }
.fund-pill--fundraiser { background: var(--c-fundraising); color: #fff; }
.fund-pill--days { background: rgba(0, 0, 0, 0.55); color: #fff; }
.fund-pill--direct { background: var(--pri); color: var(--pal-ink); }

.fund-detail__body { padding: 20px 20px 140px; display: flex; flex-direction: column; gap: 16px; }
.fund-detail__title { margin: 0; color: var(--app-ink); }
.fund-detail__desc { margin: 0; color: var(--n-fg-deep); }

.fund-progress { padding: 16px; border-radius: var(--r18); background: var(--pri-soft); }
.fund-progress__labels { display: flex; align-items: baseline; gap: 6px; }
.fund-progress__amount { font-size: 28px; font-weight: 800; letter-spacing: -0.6px; color: var(--ok-deep); }
.fund-progress__goal { font-size: 12px; font-weight: 600; color: var(--ok-deep); }
.fund-progress__track { margin-top: 12px; height: 12px; border-radius: var(--r999); background: #e5e7eb; overflow: hidden; }
.fund-progress__fill { height: 100%; border-radius: var(--r999); background: var(--pri); width: 0; transition: width 700ms cubic-bezier(0.16, 1, 0.3, 1); }
.fund-progress__meta-row { display: flex; align-items: center; justify-content: space-between; margin-top: 10px; }
.fund-progress__pct { font-size: 12px; font-weight: 600; color: var(--ok-deep); }
.fund-progress__reached { font-size: 12px; font-weight: 700; color: var(--ok-deep); }
@media (prefers-reduced-motion: reduce) {
  .fund-progress__fill { transition: none; }
}

.fund-tools { padding: 14px 16px; border-radius: var(--r14); background: var(--n-bg-soft); border: 1px solid var(--n-line); }
.fund-tools__eyebrow { color: var(--n-fg2); margin-bottom: 10px; }
.fund-tools__row { display: flex; flex-wrap: wrap; justify-content: space-between; row-gap: 12px; column-gap: 16px; }
.fund-tools__action { background: none; border: 0; padding: 4px 0; font-size: 14px; font-weight: 700; color: var(--app-ink); cursor: pointer; }
.fund-tools__action--danger { color: var(--bad); }

.fund-cta-dock {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 5;
  padding: 28px 20px 20px;
  background: linear-gradient(to bottom, transparent, var(--n-bg) 42%);
}
.fund-cta {
  width: 100%;
  padding: 16px;
  border-radius: var(--r16);
  border: 0;
  background: var(--pri);
  color: var(--pal-ink);
  font-size: 16px;
  font-weight: 800;
  cursor: pointer;
  transition: transform 120ms ease;
}
.fund-cta:active { transform: scale(0.985); }

/* ---- donations sheet (View donations) ---- */
.donors-sheet { display: flex; flex-direction: column; gap: 10px; padding-bottom: 6px; }
.donors-sheet__title { margin: 0; color: var(--app-ink); }
.donors-sheet__empty { color: var(--n-fg1); padding: 22px 0 8px; text-align: center; }
.donors-sheet__list { display: flex; flex-direction: column; }
.donors-sheet__row { display: flex; align-items: center; justify-content: space-between; padding: 12px 0; border-top: 1px solid var(--n-line-soft); }
.donors-sheet__row:first-child { border-top: 0; }
.donors-sheet__name { color: var(--app-ink); }
.donors-sheet__amount { color: var(--ok-deep); font-weight: 700; }

/* ---- donate sheet (chips / custom amount / spinner / success) ---- */
.donate { display: flex; flex-direction: column; gap: 16px; padding-top: 4px; }
.donate__eyebrow { color: var(--n-fg1); }
.donate__heading { margin: 0; color: var(--app-ink); }
.donate__chips { display: flex; gap: 10px; }
.donate__chip {
  flex: 1;
  padding: 14px 6px;
  text-align: center;
  border-radius: var(--r14);
  border: 1.5px solid var(--n-line);
  background: var(--n-bg);
  color: var(--app-ink);
  font-size: 16px;
  font-weight: 700;
  cursor: pointer;
}
.donate__chip.is-active { background: var(--pal-ink); border-color: var(--pal-ink); color: #fff; }
.donate__custom { display: flex; align-items: center; gap: 8px; padding: 12px 14px; border-radius: var(--r14); background: var(--n-bg-soft); }
.donate__custom-prefix { font-size: 20px; font-weight: 800; color: var(--n-fg1); }
.donate__custom-input { flex: 1; min-width: 0; border: 0; background: none; outline: none; font-family: inherit; font-size: 20px; font-weight: 800; color: var(--app-ink); }
.donate__custom-input::placeholder { color: var(--n-fg2); }

.donate__spinner-wrap { display: flex; flex-direction: column; align-items: center; gap: 14px; padding: 34px 0 14px; }
.donate__spinner { width: 40px; height: 40px; border-radius: 50%; border: 3px solid var(--n-line); border-top-color: var(--pri); animation: donate-spin 800ms linear infinite; }
.donate__spinner-label { color: var(--n-fg1); }
@keyframes donate-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .donate__spinner { animation: none; }
}

.donate__success { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 6px; padding: 18px 0 8px; }
.donate__check {
  width: 64px; height: 64px;
  margin-bottom: 6px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--ok) 18%, var(--n-bg));
  color: var(--ok);
  display: grid;
  place-items: center;
}
.donate__success-title { margin: 0; color: var(--app-ink); }
.donate__success-note { margin: 0 0 10px; color: var(--n-fg1); }

/* ---- confetti (donate success -> close) ---- */
#overlay > .confetti-layer { position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 50; }
.confetti-piece { position: absolute; top: 0; border-radius: 2px; will-change: transform, opacity; }

/* ==========================================================================
   CHATS — list (tab root) + thread (pushed, no tab bar) + composer
   ========================================================================== */

/* ---- list: fixed "Chats" title, scrolling eyebrow + rows ---- */
.chats { background: var(--n-bg); min-height: 100%; }
.chats__header {
  position: sticky;
  top: 0;
  z-index: 4;
  padding: calc(var(--sb-h) + 10px) 20px 8px;
  background: color-mix(in srgb, var(--n-bg) 82%, transparent);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
}
.chats__title { margin: 0; color: var(--app-ink); }
.chats__eyebrow { padding: 10px 20px 12px; color: var(--n-fg2); }
.chats__list { display: flex; flex-direction: column; padding-bottom: 24px; }

.chat-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  text-align: left;
  border: 0;
  background: none;
  padding: 10px 20px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.chat-row:active { background: var(--n-bg-soft); }
/* Inset divider — starts after the avatar column (20 pad + 48 avatar + 12
   gap = 80px), matching the real app's `divider { marginLeft: 80 }`. */
.chat-row:not(:last-child)::after {
  content: "";
  position: absolute;
  left: 80px; right: 20px; bottom: 0;
  height: 1px;
  background: var(--n-line);
}

.chat-row__avatar {
  flex: 0 0 auto;
  width: 48px; height: 48px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  color: #fff;
  font-size: 18px;
  font-weight: 800;
}
.chat-row__avatar--coral { background: var(--pri); }
.chat-row__avatar--teal { background: var(--c-events); }
.chat-row__avatar--indigo { background: var(--c-resources); }
.chat-row__avatar--pink { background: var(--c-fundraising); }
.chat-row__avatar--amber { background: var(--c-volunteer); }

.chat-row__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.chat-row__title-row { display: flex; align-items: baseline; gap: 8px; }
.chat-row__title {
  flex: 1; min-width: 0;
  margin: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 15px; font-weight: 700; color: var(--app-ink);
}
.chat-row__date { flex: 0 0 auto; font-size: 12px; color: var(--n-fg2); }
.chat-row__preview {
  margin: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 13px; color: var(--n-fg2);
}
.chat-row__preview.is-unread { color: var(--app-ink); font-weight: 700; }

.chat-row__trailing { flex: 0 0 auto; display: flex; flex-direction: column; align-items: flex-end; gap: 5px; }
.chat-row__time { font-size: 11px; color: var(--n-fg2); }
.chat-row__chevron { font-size: 20px; color: var(--n-fg3); line-height: 1; }
.chat-row__dot { width: 10px; height: 10px; border-radius: 50%; background: var(--pri); }

/* ---- thread: back-circle + centered title, bubbles, composer ---- */
.chat-thread { background: var(--n-bg); min-height: 100%; }
.chat-thread__header {
  position: sticky;
  top: 0;
  z-index: 4;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  padding: calc(var(--sb-h) + 8px) 14px 14px;
  background: color-mix(in srgb, var(--n-bg) 82%, transparent);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid var(--n-line);
}
.chat-thread__back {
  grid-column: 1;
  justify-self: start;
  width: 40px; height: 40px;
  border-radius: var(--r999);
  border: 0;
  background: var(--n-bg-soft);
  color: var(--app-ink);
  display: grid;
  place-items: center;
  cursor: pointer;
}
.chat-thread__title {
  grid-column: 2;
  margin: 0;
  max-width: 220px;
  text-align: center;
  color: var(--app-ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.chat-thread__messages { display: flex; flex-direction: column; gap: 10px; padding: 16px 14px 150px; }

.chat-bubble-row { display: flex; }
.chat-bubble-row.is-mine { justify-content: flex-end; }
.chat-bubble-row.is-theirs { justify-content: flex-start; }

.chat-bubble {
  max-width: 78%;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 9px 14px;
  border-radius: var(--r16);
}
/* Mine: coral bg, white text — matches app/chat/[eventId].tsx's
   bubbleMine/textMine exactly (fontWeight 500, Brand.ctaForeground). At
   ~2.9:1 this fails WCAG AA for 15px body text; replicated faithfully per
   the real source rather than silently bumped — flagged for a dedicated
   a11y pass in the task report. */
.chat-bubble--mine {
  background: var(--pri);
  border-bottom-right-radius: 4px;
  box-shadow: 0 4px 14px -6px color-mix(in srgb, var(--pri) 55%, transparent);
}
/* Task 18 a11y fix (adjudicated): white-on-var(--pri) only fails in
   midnightCoral (~2.82:1) — slateCitrus/forestApricot/tealGold all use a
   dark --cta-fg on a lighter --pri and clear 7.8:1+ already, so they're
   untouched. White text is already maximum luminance (can't lighten further
   to fix contrast), so this bumps the BUBBLE instead, for this palette
   only: --pri-deep mixed with a touch of --pal-ink (92/8), a subtle darker
   coral used ONLY here in the demo — not a new brand color, not applied to
   any other coral surface (buttons, chips, etc. all keep plain --pri).
   Measured: #C84637 vs #FFFFFF = 4.79:1 (was 2.82:1). This is a deliberate
   divergence from the real app's own bubbleMine color for a11y — flagged
   to Adam as a recommendation for the app itself, not just this demo. */
:root[data-palette="midnightCoral"] .chat-bubble--mine {
  background: color-mix(in srgb, var(--pri-deep) 92%, var(--pal-ink) 8%);
  box-shadow: 0 4px 14px -6px color-mix(in srgb, var(--pri-deep) 55%, transparent);
}
:root[data-palette="midnightCoral"] .chat-bubble--mine .chat-bubble__text { font-weight: 600; }
/* Theirs: Neutral.bgSoft (--n-bg-soft) per the real source — one shade
   lighter than --n-tile, which the app reserves for the idle Send pill. */
.chat-bubble--theirs { background: var(--n-bg-soft); border-bottom-left-radius: 4px; }

.chat-bubble__name { font-size: 12px; font-weight: 700; color: var(--n-fg1b); margin-bottom: 2px; }
.chat-bubble__text { font-size: 15px; line-height: 21px; font-weight: 500; white-space: pre-wrap; }
.chat-bubble--mine .chat-bubble__text { color: var(--cta-fg); }
.chat-bubble--theirs .chat-bubble__text { color: var(--app-ink); }
.chat-bubble__time { align-self: flex-end; font-size: 10px; margin-top: 3px; }
.chat-bubble--mine .chat-bubble__time { color: var(--cta-fg); opacity: 0.7; font-weight: 600; }
.chat-bubble--theirs .chat-bubble__time { color: var(--n-fg2); }

/* ---- typing indicator: 3 bouncing dots; a static "…" under reduced motion ---- */
.chat-bubble--typing { padding: 12px 16px; }
.chat-typing-dots { display: flex; align-items: center; gap: 4px; }
.chat-typing-dots span {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--n-fg2);
  animation: chat-typing-bounce 1.2s ease-in-out infinite;
}
.chat-typing-dots span:nth-child(2) { animation-delay: 0.15s; }
.chat-typing-dots span:nth-child(3) { animation-delay: 0.3s; }
@keyframes chat-typing-bounce {
  0%, 80%, 100% { transform: translateY(0); opacity: 0.5; }
  40% { transform: translateY(-4px); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .chat-typing-dots { display: none; }
  .chat-bubble--typing::after { content: "…"; color: var(--n-fg2); font-size: 15px; font-weight: 700; }
}

/* ---- composer: fixed above the home indicator once the tab bar is hidden ---- */
.chat-composer {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px 14px;
  background: color-mix(in srgb, var(--n-bg) 88%, transparent);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  border-top: 1px solid var(--n-line);
}
.chat-composer__camera {
  flex: 0 0 auto;
  width: 34px; height: 34px;
  border: 0;
  background: none;
  color: var(--pri);
  display: grid;
  place-items: center;
  cursor: pointer;
}
.chat-composer__input {
  flex: 1;
  min-width: 0;
  border: 0;
  border-radius: var(--r999);
  padding: 10px 14px;
  background: var(--n-bg-soft);
  color: var(--app-ink);
  outline: none;
}
.chat-composer__input::placeholder { color: var(--n-fg2); }
.chat-composer__send {
  flex: 0 0 auto;
  border: 0;
  padding: 10px 16px;
  border-radius: var(--r999);
  background: var(--n-tile);
  color: var(--n-fg2);
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
}
.chat-composer__send:not(:disabled) {
  background: var(--pri);
  color: var(--cta-fg);
  box-shadow: 0 6px 16px -6px color-mix(in srgb, var(--pri) 55%, transparent);
}
.chat-composer__send:disabled { cursor: not-allowed; }

/* ==========================================================================
   RESOURCES — Resource Library (tab root) + New Resource create form
   ========================================================================== */
.resources { background: var(--n-bg); min-height: 100%; position: relative; }
.resources__header {
  position: sticky;
  top: 0;
  z-index: 4;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: calc(var(--sb-h) + 8px) 20px 12px;
  background: color-mix(in srgb, var(--n-bg) 82%, transparent);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
}
.resources__title { color: var(--app-ink); }
.resources__search {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 14px;
  border-radius: var(--r999);
  background: var(--n-bg-soft);
}
.resources__search svg { width: 16px; height: 16px; flex: 0 0 auto; color: var(--n-fg2); }
.resources__search-input { flex: 1; border: 0; background: none; color: var(--app-ink); padding: 0; outline: none; }
.resources__search-input::placeholder { color: var(--n-fg2); }
.resources__chips { display: flex; gap: 8px; overflow-x: auto; overscroll-behavior: contain; scrollbar-width: none; }
.resources__chips::-webkit-scrollbar { display: none; }
.chip-filter {
  flex: 0 0 auto;
  padding: 7px 14px;
  border-radius: var(--r999);
  border: 1px solid transparent;
  background: var(--n-bg-soft);
  color: var(--app-ink);
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}
.chip-filter.is-active {
  background: color-mix(in srgb, var(--pri) 16%, var(--n-bg));
  border-color: color-mix(in srgb, var(--pri) 32%, transparent);
  color: var(--pri-deep);
}
.resources__section-title { margin: 18px 20px 6px; color: var(--app-ink); }
.resources__list { display: flex; flex-direction: column; padding: 0 0 120px; }

/* Icon-above-text stack, per capture 06-resources (see resources.js header
   comment for why this diverges from the app's other horizontal rows). */
.resource-row { position: relative; padding: 18px 20px 20px; }
.resource-row:not(:last-child)::after {
  content: "";
  position: absolute;
  left: 84px; right: 20px; bottom: 0;
  height: 1px;
  background: var(--n-line);
}
.resource-row__icon {
  width: 44px; height: 44px;
  margin-bottom: 14px;
  border-radius: var(--r12);
  display: grid;
  place-items: center;
  background: color-mix(in srgb, var(--c-fundraising) 16%, var(--n-bg));
  color: var(--c-fundraising);
}
.resource-row__title { margin: 0 0 4px; color: var(--app-ink); }
.resource-row__meta { margin: 0 0 12px; color: var(--n-fg1); }
.resource-row__actions { display: flex; align-items: center; gap: 10px; }
.resource-row__dl {
  width: 34px; height: 34px;
  border-radius: var(--r999);
  border: 0;
  background: var(--pri);
  color: var(--cta-fg);
  display: grid;
  place-items: center;
  cursor: pointer;
}
.resource-row__trash {
  width: 34px; height: 34px;
  border-radius: var(--r999);
  border: 0;
  background: none;
  color: var(--n-fg1);
  display: grid;
  place-items: center;
  cursor: pointer;
}
.resources__fab {
  position: fixed;
  right: 20px;
  bottom: calc(var(--tab-h) + 16px);
  z-index: 5;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 0;
  padding: 14px 20px;
  border-radius: var(--r999);
  background: var(--pri);
  color: var(--cta-fg);
  font-size: 15px;
  font-weight: 800;
  cursor: pointer;
  box-shadow: 0 14px 30px -8px color-mix(in srgb, var(--pri) 55%, transparent);
}
.resources__fab svg { width: 14px; height: 14px; }

/* ---- New Resource create form (fake file-pick row) ---- */
.file-row {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 14px;
  border-radius: var(--r12);
  border: 1.5px dashed var(--n-line);
  background: var(--n-bg-soft);
  color: var(--app-ink);
  text-align: left;
  cursor: pointer;
}
.file-row svg { flex: 0 0 auto; color: var(--n-fg2); }
.file-row__text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.file-row__label { color: var(--app-ink); font-weight: 700; }
.file-row__meta { color: var(--n-fg2); }
.file-row.is-picked { border-style: solid; border-color: var(--pri); background: var(--n-bg); }
.file-row.is-picked svg { color: var(--pri); }

/* ==========================================================================
   SURVEYS — Surveys & Feedback (pushed) + New Survey create form
   ========================================================================== */
.surveys { background: var(--n-bg); min-height: 100%; }
.surveys__list { display: flex; flex-direction: column; gap: 16px; padding: 12px 16px 110px; }
.surveys__fab {
  position: fixed;
  right: 20px; bottom: 24px;
  z-index: 5;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 0;
  padding: 14px 20px;
  border-radius: var(--r999);
  background: var(--pri);
  color: var(--cta-fg);
  font-size: 15px;
  font-weight: 800;
  cursor: pointer;
  box-shadow: 0 14px 30px -8px color-mix(in srgb, var(--pri) 55%, transparent);
}
.surveys__fab svg { width: 14px; height: 14px; }

.survey-card {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 16px;
  border-radius: var(--r16);
  border: 1px solid var(--n-line);
}
.survey-card__question { margin: 0; color: var(--app-ink); }
.survey-card__caption { color: var(--n-fg1); }
.survey-options { display: flex; flex-direction: column; gap: 10px; }

.survey-option {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 14px;
  border-radius: var(--r12);
  border: 1.5px solid var(--n-line);
  background: var(--n-bg);
  text-align: left;
  cursor: pointer;
  transition: transform 120ms ease;
}
.survey-option:active { transform: scale(0.985); }
.survey-option__radio {
  width: 20px; height: 20px;
  flex: 0 0 auto;
  border-radius: 50%;
  border: 2px solid var(--n-line);
}
.survey-option__label { flex: 1; color: var(--app-ink); }

.survey-result {
  position: relative;
  overflow: hidden;
  width: 100%;
  padding: 13px 14px;
  border-radius: var(--r12);
  border: 1.5px solid transparent;
  background: var(--n-bg-soft);
  cursor: pointer;
  text-align: left;
}
.survey-result__fill {
  position: absolute;
  inset: 0;
  width: 0;
  background: color-mix(in srgb, var(--pri) 16%, var(--n-bg-soft));
  transition: width 500ms cubic-bezier(0.16, 1, 0.3, 1);
}
.survey-result.is-mine { border-color: var(--pri); }
.survey-result.is-mine .survey-result__fill { background: color-mix(in srgb, var(--pri) 26%, var(--n-bg-soft)); }
.survey-result__row { position: relative; z-index: 1; display: flex; align-items: center; gap: 8px; }
.survey-result__row svg { flex: 0 0 auto; color: var(--pri-deep); }
.survey-result__label { flex: 1; min-width: 0; color: var(--app-ink); font-weight: 600; }
.survey-result.is-mine .survey-result__label { color: var(--pri-deep); }
.survey-result__count { color: var(--n-fg1); }
.survey-result__pct { flex: 0 0 auto; color: var(--n-fg1); font-weight: 700; }
@media (prefers-reduced-motion: reduce) {
  .survey-result__fill { transition: none; }
}

/* ---- New Survey create form (2–4 removable option fields) ---- */
.survey-create__options { display: flex; flex-direction: column; gap: 14px; }
.option-field-row { display: flex; align-items: flex-end; gap: 8px; }
.option-field-row .field { flex: 1; min-width: 0; }
.option-remove {
  flex: 0 0 auto;
  width: 38px; height: 38px;
  margin-bottom: 1px;
  border-radius: var(--r10);
  border: 0;
  background: var(--n-bg-soft);
  color: var(--bad);
  display: grid;
  place-items: center;
  cursor: pointer;
}
.add-option-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 100%;
  padding: 14px;
  border-radius: var(--r12);
  border: 1.5px dashed var(--n-line);
  background: none;
  color: var(--pri-deep);
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
}
.add-option-btn svg { width: 13px; height: 13px; }

/* ==========================================================================
   WISHLIST — classroom needs (pushed) + add-item sheet
   ========================================================================== */
.wishlist { background: var(--n-bg); min-height: 100%; }
.wishlist__intro { margin: 0; padding: 4px 20px 16px; color: var(--n-fg1); }
.wishlist__list { display: flex; flex-direction: column; gap: 14px; padding: 0 16px 44px; }

.wish-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 16px;
  border-radius: var(--r16);
  border: 1px solid var(--n-line);
}
.wish-card__name { margin: 0; color: var(--app-ink); }
.wish-card__note { margin: 0; color: var(--n-fg1); }
.wish-claim {
  align-self: flex-start;
  margin-top: 4px;
  padding: 9px 18px;
  border-radius: var(--r999);
  border: 1.5px solid var(--pri);
  background: none;
  color: var(--pri);
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
}
.wish-claimed {
  align-self: flex-start;
  margin-top: 4px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--ok-deep);
  font-weight: 700;
}

.wish-sheet { display: flex; flex-direction: column; gap: 14px; padding-bottom: 6px; }
.wish-sheet__title { margin: 0; color: var(--app-ink); }

/* ==========================================================================
   SPONSORS — Our Sponsors (pushed, tier-grouped)
   ========================================================================== */
.sponsors { background: var(--n-bg); min-height: 100%; }
.sponsors__body { padding: 4px 16px 8px; display: flex; flex-direction: column; gap: 8px; }
.sponsors__section { display: flex; flex-direction: column; gap: 10px; }
.sponsors__section-title { margin: 14px 4px 0; color: var(--n-fg1); }
.sponsors__cards { display: flex; flex-direction: column; gap: 10px; }
.sponsors__footer { padding: 20px 20px 44px; text-align: center; color: var(--n-fg2); }

.sponsor-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 16px;
  border-radius: var(--r16);
  border: 1px solid var(--n-line);
}
.sponsor-card__top { display: flex; align-items: center; gap: 10px; }
.sponsor-card__name { flex: 1; min-width: 0; margin: 0; color: var(--app-ink); }
.sponsor-card__blurb { margin: 0; color: var(--n-fg1); }
.sponsor-card__thank {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 0;
  background: none;
  padding: 0;
  color: var(--n-fg1);
  font-weight: 700;
  cursor: pointer;
}
.sponsor-card__thank svg { color: var(--n-fg2); }
.sponsor-card__thanked {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--c-fundraising);
  font-weight: 700;
}

.tier-chip {
  flex: 0 0 auto;
  padding: 4px 10px;
  border-radius: var(--r999);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.4px;
  text-transform: uppercase;
}
.tier-chip--gold { background: color-mix(in srgb, var(--c-volunteer) 20%, var(--n-bg)); color: var(--c-volunteer); }
.tier-chip--silver { background: var(--n-bg-soft); color: var(--n-fg1); }
.tier-chip--bronze { background: color-mix(in srgb, var(--bronze) 20%, var(--n-bg)); color: var(--bronze); }

/* ==========================================================================
   GUIDED TOUR — coach-mark overlay (tour.js)
   A full-canvas navy dim built from four panels that frame a rounded-rect
   spotlight; the cutout gap has no element, so taps pass through to the real
   control. Sits below #overlay (z40) so a real donation sheet opens above it.
   ========================================================================== */
.tour {
  position: absolute;
  inset: 0;
  z-index: 35;
  pointer-events: none;                 /* the cutout gap is click-through */
  opacity: 0;
  transition: opacity 240ms ease;
}
.tour.is-in { opacity: 1; }

.tour__dim { position: absolute; inset: 0; pointer-events: none; }
.tour__panel {
  position: absolute;
  background: rgba(10, 15, 40, 0.55);
  pointer-events: auto;                 /* the dim blocks taps; the gap doesn't */
  transition: left 280ms ease, top 280ms ease, width 280ms ease, height 280ms ease;
}
.tour__ring {
  position: absolute;
  border-radius: 16px;
  pointer-events: none;
  box-shadow:
    0 0 0 2px var(--pri),
    0 0 0 6px color-mix(in srgb, var(--pri) 30%, transparent),
    0 14px 44px -10px rgba(0, 0, 0, 0.55);
  transition: left 280ms ease, top 280ms ease, width 280ms ease, height 280ms ease;
  animation: tour-pulse 2.2s ease-in-out infinite;
}
@keyframes tour-pulse {
  0%, 100% { box-shadow: 0 0 0 2px var(--pri), 0 0 0 5px color-mix(in srgb, var(--pri) 30%, transparent), 0 14px 44px -10px rgba(0, 0, 0, 0.55); }
  50%      { box-shadow: 0 0 0 2px var(--pri), 0 0 0 11px color-mix(in srgb, var(--pri) 8%, transparent), 0 14px 44px -10px rgba(0, 0, 0, 0.55); }
}

.tour-bubble {
  position: absolute;
  width: 300px;
  max-width: calc(100% - 32px);
  padding: 16px 16px 14px;
  background: var(--n-bg);
  color: var(--app-ink);
  border: 1px solid var(--n-line);
  border-radius: var(--r18);
  box-shadow: 0 24px 60px -18px rgba(0, 0, 0, 0.55);
  pointer-events: auto;
  opacity: 0;
  transform: translateY(6px) scale(0.98);
  transition: opacity 200ms ease, transform 200ms ease, top 260ms ease, left 260ms ease;
}
.tour-bubble.is-shown { opacity: 1; transform: translateY(0) scale(1); }
.tour-bubble.is-card { text-align: center; }

.tour-bubble__spark {
  display: none;
  color: var(--pri);
  margin: 0 auto 6px;
  width: 34px; height: 34px;
  align-items: center; justify-content: center;
  border-radius: 999px;
  background: color-mix(in srgb, var(--pri) 14%, var(--n-bg));
}
.tour-bubble.is-card .tour-bubble__spark { display: flex; }

.tour-bubble__check {
  position: absolute;
  top: -18px; left: 50%;
  width: 40px; height: 40px;
  margin-left: -20px;
  border-radius: 50%;
  background: var(--ok);
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 8px 22px -6px rgba(0, 0, 0, 0.45);
  opacity: 0;
  transform: scale(0.5);
  transition: opacity 180ms ease, transform 260ms cubic-bezier(0.2, 1.4, 0.4, 1);
  pointer-events: none;
}
.tour-bubble__check.is-on { opacity: 1; transform: scale(1); }

.tour-bubble__title { margin: 0 0 5px; color: var(--app-ink); }
.tour-bubble__body { margin: 0 0 14px; color: var(--n-fg1); }

.tour-bubble__foot { display: flex; flex-direction: column; gap: 12px; }
.tour-bubble__dots { display: flex; align-items: center; gap: 5px; }
.tour-bubble.is-card .tour-bubble__dots { justify-content: center; }
.tour-bubble__dot {
  width: 6px; height: 6px;
  border-radius: 999px;
  background: var(--n-line);
  transition: width 200ms ease, background 200ms ease;
}
.tour-bubble__dot.is-active { width: 16px; background: var(--pri); }

.tour-bubble__actions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; }
.tour-bubble.is-card .tour-bubble__actions { justify-content: center; }
.tour-btn {
  font-family: inherit;
  font-size: 14px;
  font-weight: 700;
  border: 0;
  border-radius: var(--r999);
  padding: 9px 15px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform 120ms ease, background 140ms ease, color 140ms ease;
}
.tour-btn:active { transform: scale(0.95); }
.tour-btn--primary { background: var(--pri); color: var(--cta-fg); }
.tour-btn--ghost { background: transparent; color: var(--n-fg1); padding: 9px 8px; }
.tour-btn--ghost:hover { color: var(--app-ink); }
.tour-btn:focus-visible { outline: 2px solid var(--pri); outline-offset: 2px; }

/* screen-reader-only live region for step announcements */
.tour-sr {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* standalone "Take the tour" pill (no ambush on direct visits). It floats
   just above the tab bar, so it only makes sense on the six tab-root
   screens: on pushed/no-tabbar screens (event/fundraiser detail, every
   create form, chat thread, …) #screen reclaims that space for real
   content (router.js's .no-tabbar toggle), and a bottom-docked primary
   button (e.g. "Create event") can land exactly where the pill floats,
   silently swallowing its click. Hiding the pill there removes the
   overlap; starting the tour always begins by navigating to '/' anyway,
   so no entry point is lost. */
.demo-root.no-tabbar .tour-pill { display: none; }
.tour-pill {
  position: absolute;
  left: 50%; bottom: 100px;
  transform: translateX(-50%) translateY(10px);
  z-index: 34;
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 6px 6px 6px 14px;
  background: var(--pri);
  color: var(--cta-fg);
  border-radius: var(--r999);
  box-shadow: 0 14px 34px -10px rgba(0, 0, 0, 0.5),
              0 0 0 4px color-mix(in srgb, var(--pri) 16%, transparent);
  opacity: 0;
  pointer-events: none;
  transition: opacity 260ms ease, transform 260ms ease;
}
.tour-pill.is-in { opacity: 1; transform: translateX(-50%) translateY(0); pointer-events: auto; }
.tour-pill__start {
  font-family: inherit;
  font-size: 14px;
  font-weight: 700;
  background: none;
  border: 0;
  color: inherit;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 4px;
}
.tour-pill__spark { font-size: 13px; }
.tour-pill__close {
  font-family: inherit;
  font-size: 12px;
  line-height: 1;
  width: 24px; height: 24px;
  border-radius: 999px;
  background: color-mix(in srgb, #000 16%, transparent);
  color: inherit;
  border: 0;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.tour-pill__start:focus-visible,
.tour-pill__close:focus-visible { outline: 2px solid var(--cta-fg); outline-offset: 2px; }

/* Reduced motion: no pulse, no fades, instant positioning. */
@media (prefers-reduced-motion: reduce) {
  .tour,
  .tour__panel,
  .tour__ring,
  .tour-bubble { transition: none; }
  .tour__ring { animation: none; }
  .tour-bubble { transform: none; }
  .tour-bubble.is-shown { transform: none; }
  .tour-bubble__check { transition: opacity 100ms linear; transform: none; }
  .tour-pill { transition: opacity 120ms linear; transform: translateX(-50%); }
  .tour-pill.is-in { transform: translateX(-50%); }
}
.tour.is-reduced .tour__panel,
.tour.is-reduced .tour__ring,
.tour.is-reduced .tour-bubble { transition: none; }
.tour.is-reduced .tour__ring { animation: none; }
