@font-face {
  font-family: "Figtree";
  src: url("../fonts/Figtree-VariableFont_wght.ttf") format("truetype-variations"),
       url("../fonts/Figtree-VariableFont_wght.ttf") format("truetype");
  font-weight: 300 900;
  font-style: normal;
  font-display: swap;
}

/* Design tokens — locked palette from LANDING-PAGE-BRIEF.md, plus two additions:
   --primary/--primary-text (flipped-background CTA) and --fg/--fg-muted
   (body text colors, not specified in the brief's animation-only token set). */
html[data-theme="dark"] {
  --pg:  #161b1e;
  --bd:  #262d34;
  --av:  #15181c;
  --rim: rgba(255,255,255,.10);
  --sh:  0;
  --primary: #ffffff;
  --primary-text: #161b1e;
  --fg: #f5f6f7;
  --fg-muted: #9aa3ab;
  --accent: #4D9BFF;
  --accent-50: rgba(77, 155, 255, .50);
  --accent-30: rgba(77, 155, 255, .30);
  --accent-15: rgba(77, 155, 255, .15);
  --success: #4ec9a8;
  --success-30: rgba(78, 201, 168, .30);
  --success-15: rgba(78, 201, 168, .15);
  --highlight: rgba(255, 255, 255, .30);
  --pg-30: rgba(22, 27, 30, .30);
  --glass: rgba(255, 255, 255, .28);
}
html[data-theme="light"] {
  --pg:  #ffffff;
  --bd:  #e0e3e7;
  --av:  #f8fafc;
  --rim: transparent;
  --sh:  1;
  --primary: #161b1e;
  --primary-text: #ffffff;
  --fg: #14171a;
  --fg-muted: #5b6470;
  --accent: #0570f5;
  --accent-50: rgba(5, 112, 245, .50);
  --accent-30: rgba(5, 112, 245, .30);
  --accent-15: rgba(5, 112, 245, .15);
  --success: #268d76;
  --success-30: rgba(38, 141, 118, .30);
  --success-15: rgba(38, 141, 118, .15);
  --highlight: rgba(20, 23, 26, .14);
  --pg-30: rgba(255, 255, 255, .30);
  --glass: rgba(20, 23, 26, .05);
}

:root {
  --dur: .45s;
  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-full: 999px;
  --header-h: 84px;
  --container-max: 1440px;
}

* { box-sizing: border-box; }

/* body must be allowed to grow: clamping it to the viewport confines
   position:sticky to the first screenful, so the header un-sticks. */
html { height: 100%; }
body { min-height: 100%; }

body {
  margin: 0;
  font-family: "Figtree", system-ui, -apple-system, "Segoe UI", sans-serif;
  background: var(--pg);
  color: var(--fg);
  transition: background var(--dur) ease, color var(--dur) ease;
}

a { color: inherit; }

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

/* --- Header / navigation --- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--pg-30);
  -webkit-backdrop-filter: blur(5px);
  backdrop-filter: blur(5px);
  border-bottom: 1px solid var(--bd);
  transition: border-color var(--dur) ease, background var(--dur) ease;
}

/* anchors must clear the sticky header */
section[id] { scroll-margin-top: calc(var(--header-h) + 8px); }

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  max-width: var(--container-max);
  margin: 0 auto;
  height: var(--header-h);
  padding-inline: clamp(1.5rem, 4vw, 4rem);
}

.site-header__logo {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  line-height: 0;
  text-decoration: none;
}

.site-header__tagline {
  margin-left: 16px;
  font-size: 12px;
  line-height: 1;
  font-weight: 500;
  color: var(--fg-muted);
  transition: color var(--dur) ease;
}

.logo-lottie {
  display: block;
  height: 28px;
  width: auto;
  aspect-ratio: 1100 / 230;
}

.logo-lottie svg { width: 100%; height: 100%; display: block; }

.site-header__right {
  display: flex;
  align-items: center;
  gap: 1.5rem;
}

.site-nav {
  display: flex;
  align-items: center;
  gap: 2rem;
}

.site-nav a {
  text-decoration: none;
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--fg-muted);
  transition: color var(--dur) ease;
}

.site-nav a:hover { color: var(--fg); }

/* --- Theme switch --- */

.theme-switch {
  position: relative;
  display: inline-flex;
  padding: 3px;
  border-radius: var(--radius-full);
  background: var(--av);
  border: 1px solid var(--bd);
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

.theme-switch__thumb {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-full);
  background: var(--primary);
  transition: transform var(--dur) ease, background var(--dur) ease;
}

html[data-theme="dark"] .theme-switch__thumb { transform: translateX(32px); }
html[data-theme="light"] .theme-switch__thumb { transform: translateX(0); }

.theme-switch__option {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: none;
  border-radius: var(--radius-full);
  background: none;
  color: var(--fg-muted);
  cursor: pointer;
  transition: color var(--dur) ease;
}

.theme-switch__option[aria-pressed="true"] {
  color: var(--primary-text);
}

.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 5px;
  width: 40px;
  height: 40px;
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
}

.nav-toggle__bar {
  display: block;
  width: 22px;
  height: 2px;
  background: var(--fg);
  transition: transform var(--dur) ease, opacity var(--dur) ease, background var(--dur) 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); }

.mobile-nav {
  display: none;
  flex-direction: column;
  border-top: 1px solid var(--bd);
  padding: 1rem clamp(1.5rem, 4vw, 4rem) 1.5rem;
}

.mobile-nav__links a {
  text-decoration: none;
  color: var(--fg);
  font-size: 1.05rem;
  font-weight: 500;
  padding: 0.75rem 0;
}

@media (max-width: 720px) {
  .site-nav { display: none; }
  .nav-toggle { display: flex; }
  .mobile-nav:not([hidden]) { display: flex; }

  /* 16px gutters on the bar, and the overlay matches it so its links
     line up under the logo rather than sitting inboard of it. */
  .site-header__inner { padding-inline: 1rem; gap: 0.75rem; }
  .site-header__right { gap: 0.625rem; }

  /* Full-screen overlay hanging below the fixed bar. z-index sits under
     the header's 100 so the bar and its blur stay on top. */
  .mobile-nav {
    position: fixed;
    top: calc(var(--header-h) + 1px);
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 90;
    background: var(--pg);
    border-top: 0;
    padding: 1.5rem 1rem 2rem;
    gap: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    transition: background var(--dur) ease;
  }

  .mobile-nav__links { display: flex; flex-direction: column; gap: 16px; }

  .mobile-nav__links a {
    font-size: 32px;
    line-height: 1.25;
    letter-spacing: -0.01em;
    padding: 0.4rem 0;
  }

  .mobile-nav__foot {
    margin-top: auto;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 1rem;
    padding-top: 2rem;
  }

  .mobile-nav__cta.button--sm,
  .mobile-nav__cta {
    align-self: stretch;
    text-align: center;
    font-size: 1.05rem;
    padding: 0.875rem 1.75rem;
  }

  .mobile-nav__foot .playsoon { font-size: 0.85rem; align-self: center; }

  /* NO overflow-based scroll lock here. Setting overflow:hidden on html
     or body removes the scrolling context, and a position:sticky header
     then falls back to its static document position — scrolled mid-page
     it lands far above the viewport and simply vanishes. The overlay is
     fixed and opaque, so it covers the page anyway; overscroll-behavior
     on it keeps drags from chaining. */

  /* the overlay carries its own CTA, so the bar's steps aside */
  html.nav-open .site-header__cta { display: none; }
}

/* Overlay entrance. Kept in a no-preference block so reduced motion
   simply gets the finished state — nothing is hidden without the
   transition running, same rule the rest of the site follows. */
@media (max-width: 720px) and (prefers-reduced-motion: no-preference) {
  .mobile-nav {
    opacity: 0;
    transition: opacity 0.25s ease, background var(--dur) ease;
  }

  .mobile-nav.is-open { opacity: 1; }

  .mobile-nav__links a,
  .mobile-nav__foot > * {
    opacity: 0;
    transform: translateY(10px);
    transition: opacity 0.4s ease, transform 0.4s cubic-bezier(.2, .7, .3, 1);
  }

  .mobile-nav.is-open .mobile-nav__links a,
  .mobile-nav.is-open .mobile-nav__foot > * {
    opacity: 1;
    transform: none;
  }

  /* 100ms between each, links first then the footer block */
  .mobile-nav.is-open .mobile-nav__links a:nth-child(1) { transition-delay: 0.10s; }
  .mobile-nav.is-open .mobile-nav__links a:nth-child(2) { transition-delay: 0.20s; }
  .mobile-nav.is-open .mobile-nav__links a:nth-child(3) { transition-delay: 0.30s; }
  .mobile-nav.is-open .mobile-nav__links a:nth-child(4) { transition-delay: 0.40s; }
  .mobile-nav.is-open .mobile-nav__foot > *:nth-child(1) { transition-delay: 0.50s; }
  .mobile-nav.is-open .mobile-nav__foot > *:nth-child(2) { transition-delay: 0.56s; }
  .mobile-nav.is-open .mobile-nav__foot > *:nth-child(3) { transition-delay: 0.62s; }

  /* closing: everything leaves together, no staggered exit */
  .mobile-nav:not(.is-open) .mobile-nav__links a,
  .mobile-nav:not(.is-open) .mobile-nav__foot > * {
    transition-delay: 0s;
    transition-duration: 0.15s;
  }

  /* .site-header__cta alone ties with .button--sm, which is declared
     later in the file and would win — qualify it to take the cascade. */
  .site-header__cta.button--sm { font-size: 0.82rem; padding: 0.45rem 0.75rem; }
}

/* Narrow phones: the bar carries logo + theme + CTA + menu, so the logo
   gives ground first. Below 360px the theme switch drops out — the page
   still follows the OS colour scheme, and losing the CTA or the menu
   would cost more. */
@media (max-width: 420px) {
  .logo-lottie { height: 22px; }
  .site-header__tagline { margin-left: 10px; font-size: 11px; }
  .site-header__inner { gap: 0.5rem; }
  .site-header__right { gap: 0.4rem; }
  .site-header__cta.button--sm { font-size: 0.8rem; padding: 0.42rem 0.65rem; }
}

@media (max-width: 359px) {
  .site-header__tagline { display: none; }
}

/* Fold cover screens and similar. The CTA browser frame's pill tabs have
   a min-content width just over 280px, which is what pushed the page
   wider there — let them wrap at this size only. */
@media (max-width: 319px) {
  .logo-lottie { height: 18px; }
  .mock-tabs--pill { flex-wrap: wrap; }
}

/* --- Legal / simple content pages --- */

.legal {
  max-width: 760px;
  margin: 0 auto;
  padding: clamp(3rem, 7vw, 5.5rem) clamp(1.5rem, 4vw, 4rem) clamp(4rem, 8vw, 6rem);
}

.legal__head { margin-bottom: clamp(2rem, 4vw, 3rem); }

.legal__title {
  margin: 0.5rem 0 0.75rem;
  font-size: clamp(1.875rem, 2.5vw + 0.75rem, 2.75rem);
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: -0.015em;
}

.legal__updated {
  margin: 0;
  font-size: 0.9rem;
  color: var(--fg-muted);
}

.legal__body {
  font-size: 1.125rem; /* handoff: body ~18px, these get read on phones */
  line-height: 1.7;
  color: var(--fg-muted);
}

.legal__body h2 {
  margin: 2.75rem 0 0.75rem;
  font-size: 1.375rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--fg);
}

.legal__body h2 a {
  color: inherit;
  text-decoration: none;
}

.legal__body h2 a:hover { text-decoration: underline; }

.legal__body h3 {
  margin: 1.75rem 0 0.5rem;
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--fg);
}

.legal__body p { margin: 0 0 1rem; }
.legal__body ul, .legal__body ol { margin: 0 0 1rem; padding-left: 1.25rem; }
.legal__body li { margin-bottom: 0.5rem; }
.legal__body a { color: var(--fg); }
.legal__body strong { color: var(--fg); }

.table-scroll { overflow-x: auto; margin: 0 0 1rem; }

.legal__body table {
  border-collapse: collapse;
  width: 100%;
  font-size: 0.9rem;
  line-height: 1.5;
}

.legal__body th,
.legal__body td {
  border: 1px solid var(--bd);
  padding: 0.5rem 0.75rem;
  text-align: left;
  vertical-align: top;
}

.legal__body th {
  color: var(--fg);
  font-weight: 600;
  background: var(--av);
}

@media print {
  .site-header, .site-footer { display: none; }
  body { background: #fff; color: #14171a; }
  .legal__body, .legal__updated { color: #14171a; }
  .legal__body a { color: #14171a; }
}

/* --- Bug report form --- */

.bug-form {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  align-items: flex-start;
}

.bug-form__hp { position: absolute; left: -9999px; }

.bug-form__field {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  width: 100%;
}

.bug-form__field label {
  font-size: 0.9rem;
  font-weight: 600;
}

.bug-form__optional {
  font-weight: 400;
  color: var(--fg-muted);
}

.bug-form__field small {
  font-size: 0.8rem;
  color: var(--fg-muted);
}

.bug-form__field input,
.bug-form__field select,
.bug-form__field textarea {
  width: 100%;
  padding: 0.75rem 0.875rem;
  font: inherit;
  font-size: 0.95rem;
  color: var(--fg);
  background: var(--av);
  border: 1px solid var(--bd);
  border-radius: var(--radius-md);
  transition: background var(--dur) ease, border-color var(--dur) ease, color var(--dur) ease;
}

.bug-form__field textarea { resize: vertical; }

.bug-form__field input::placeholder,
.bug-form__field textarea::placeholder { color: var(--fg-muted); opacity: 0.7; }

.bug-form__field input:focus-visible,
.bug-form__field select:focus-visible,
.bug-form__field textarea:focus-visible {
  outline: 2px solid var(--fg);
  outline-offset: 1px;
}

/* --- How-it-works pages (draft, on the testing branch) ---
   Walkthrough pages built from tokens only. .shot-slot boxes are labeled
   placeholders for the S-numbered app screenshots; swap each for a real
   <img> without touching layout. */

.hiw {
  /* same container as .site-header__inner, so the page edge lines up
     with the nav */
  max-width: var(--container-max);
  margin: 0 auto;
  padding: clamp(2.5rem, 6vw, 4.5rem) clamp(1.5rem, 4vw, 4rem) clamp(3rem, 6vw, 5rem);
}

/* --- Getting-started layout (Dribbble-referenced) ---
   RULE (from Andrew): step sections are just text + image — no parent
   background container around each step. A full-width container is the
   rare exception, used sparingly. The media card is the image itself. */

/* the giant page title (~120px at desktop) with its subtitle */
.hiw__pagehead { margin-bottom: clamp(3rem, 7vw, 6rem); }

.hiw__pagehead h1 {
  margin: 0 0 1.25rem;
  font-size: clamp(3rem, 8.3vw, 7.5rem);
  font-weight: 500;
  line-height: 1.02;
  letter-spacing: -0.03em;
}

.hiw__pagehead p {
  margin: 0;
  /* full width, balanced wrap: no widows under the giant title */
  font-size: clamp(1.375rem, 1.05rem + 1.9vw, 2.75rem);
  line-height: 1.3;
  color: var(--fg-muted);
  text-wrap: balance;
}

.hiw__head {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
  align-items: center;
  gap: clamp(1.5rem, 4vw, 5rem);
  margin-bottom: clamp(2.5rem, 5vw, 4.5rem);
}

.hiw__head-main h1,
.hiw__head-main h2 {
  margin: 0;
  font-size: clamp(2.25rem, 3.4vw + 0.8rem, 3.5rem);
  font-weight: 500;
  line-height: 1.08;
  letter-spacing: -0.02em;
}

.hiw__head-side {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1.25rem;
  justify-self: end;
  max-width: 34rem;
}

.hiw__head-side p {
  margin: 0;
  font-size: 1.125rem;
  line-height: 1.6;
  color: var(--fg-muted);
}

/* three setup steps: media card, number rule, title, two lines */
.steps3 {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1.5rem, 3vw, 2.5rem);
}

.steps3__item h2,
.steps3__item h3 {
  margin: 0 0 0.5rem;
  font-size: 1.25rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.steps3__item > p {
  margin: 0;
  max-width: 40ch;
  font-size: 0.98rem;
  line-height: 1.65;
  color: var(--fg-muted);
}

.steps3__num {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  margin: 1.75rem 0 1rem;
}

.steps3__num span {
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--fg-muted);
}

.steps3__num i {
  height: 1px;
  width: clamp(5rem, 8vw, 9rem);
  background: var(--bd);
  transition: background var(--dur) ease;
}

/* the automation hand-off: same split header, one wide image */
.hiw__auto { margin-top: clamp(3.5rem, 7vw, 6rem); }

.hiw__head--sub { margin-bottom: clamp(1.75rem, 3.5vw, 3rem); }

.hiw__head--sub .steps3__num { margin: 0 0 1rem; }

.hiw__head--sub .eyebrow { margin-bottom: 0.75rem; }

.hiw__head--sub h2 {
  margin: 0;
  font-size: clamp(1.6rem, 2vw + 0.6rem, 2.25rem);
  font-weight: 500;
  letter-spacing: -0.015em;
  line-height: 1.1;
}

.shot-slot--wide {
  aspect-ratio: 21 / 9;
  background: var(--av);
  border: 1px solid var(--bd);
  border-radius: 16px;
  box-shadow: 0 12px 24px -10px rgba(0, 0, 0, calc(.10 * var(--sh))), inset 0 1px 0 var(--rim);
}

.hiw__soon { font-size: 0.95rem; font-weight: 600; color: var(--fg-muted); }

/* leader/member flows: same three-column rhythm, no media cards */
.hiw__roles { margin-top: clamp(3.5rem, 7vw, 6rem); }

.steps3--bare .steps3__num { margin-top: 0; }

/* --- Leader-step app cards (Figma 24280:625) ---
   Flat recreated app screens under each leader step: event settings,
   curriculum progress, attendance. Natural heights, cqw+em sizing.
   The toggle and the "happened" banner use --success (app-vignette
   status, same rule as the Going chip); the percentage chips use
   --accent (completion). */

.leadc {
  container-type: inline-size;
  margin: 1.5rem 0 0;
}

.leadc__body {
  display: flex;
  flex-direction: column;
  gap: 0.8em;
  padding: 1.2em 1.1em;
  font-size: clamp(9px, 3.8cqw, 17px);
  background: var(--pg);
  border: 0.07em solid var(--bd);
  border-radius: 8px;
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

html[data-theme="dark"] .leadc__body { background: var(--av); }

.leadc__title { font-size: 1.5em; font-weight: 700; letter-spacing: -0.01em; color: var(--fg); }
.leadc__title--sm { font-size: 1.25em; }

.leadc__sub { margin: 0; font-size: 0.82em; line-height: 1.45; color: var(--fg-muted); }
.leadc__sub--xs { font-size: 0.7em; }

.leadc__field {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5em;
  padding: 0.8em 0.9em;
  border: 0.07em solid var(--bd);
  border-radius: 0.5em;
  font-size: 0.88em;
  color: var(--fg-muted);
  transition: border-color var(--dur) ease;
}

.leadc__field svg {
  width: 1.1em;
  height: 1.1em;
  flex: none;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.leadc__setting {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1em;
}

.leadc__setting-text { display: flex; flex-direction: column; gap: 0.3em; }
.leadc__setting-text strong { font-size: 0.95em; font-weight: 700; color: var(--fg); }
.leadc__setting-text small { font-size: 0.75em; line-height: 1.45; color: var(--fg-muted); }

.leadc__switch {
  flex: none;
  display: block;
  width: 2.9em;
  height: 1.7em;
  margin-top: 0.2em;
  border-radius: var(--radius-full);
  background: var(--bd);
  position: relative;
  cursor: pointer;
  transition: background 0.25s ease;
}

.leadc__switch:has(input:checked) { background: var(--success); }

.leadc__switch input {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.leadc__switch i {
  position: absolute;
  top: 0.2em;
  left: 0.2em;
  width: 1.3em;
  height: 1.3em;
  border-radius: 50%;
  background: #fff;
  pointer-events: none;
  transition: transform 0.25s ease;
}

.leadc__switch:has(input:checked) i { transform: translateX(1.2em); }

.leadc__bar {
  display: block;
  height: 0.5em;
  border-radius: var(--radius-full);
  background: var(--bd);
  overflow: hidden;
  transition: background var(--dur) ease;
}

.leadc__bar i {
  display: block;
  height: 100%;
  width: var(--p, 0%);
  border-radius: inherit;
  background: var(--fg);
  transition: background var(--dur) ease;
}

.leadc__caps {
  font-size: 0.72em;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--fg-muted);
}

.leadc__member { display: flex; gap: 0.7em; }

.leadc__member img,
.leadc__row img {
  width: 2.6em;
  height: 2.6em;
  flex: none;
  border-radius: 50%;
  object-fit: cover;
}

.leadc__member-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.35em; }
.leadc__member-top { display: flex; align-items: center; justify-content: space-between; gap: 0.5em; }
.leadc__member-top strong { font-size: 0.95em; font-weight: 700; color: var(--fg); }
.leadc__member-main small { font-size: 0.72em; color: var(--fg-muted); }

.leadc__pct {
  overflow: hidden;
  padding: 0.25em 0.6em;
  border-radius: 0.4em;
  background: var(--accent-15);
  color: var(--accent);
  font-size: 0.78em;
  font-weight: 700;
  transition: background var(--dur) ease, color var(--dur) ease;
}

.leadc__pct-roll { display: block; height: 1.35em; overflow: hidden; }
.leadc__pct-roll span { display: block; height: 1.35em; line-height: 1.35; }

.leadc__event { display: flex; gap: 0.75em; }

.leadc__date {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 2.8em;
  height: 3em;
  flex: none;
  border: 0.07em solid var(--bd);
  border-radius: 0.5em;
  transition: border-color var(--dur) ease;
}

.leadc__date b { font-size: 1.15em; font-weight: 700; color: var(--fg); }
.leadc__date small { font-size: 0.65em; text-transform: uppercase; color: var(--fg-muted); }

.leadc__event-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.25em; }
.leadc__event-top { display: flex; align-items: baseline; justify-content: space-between; gap: 0.5em; }
.leadc__event-top strong { font-size: 1.05em; font-weight: 700; color: var(--fg); }
.leadc__event-top span { font-size: 0.95em; font-weight: 700; color: var(--fg); }
.leadc__event-main small { font-size: 0.72em; color: var(--fg-muted); }

.leadc__row { display: flex; align-items: center; gap: 0.7em; }
.leadc__row-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.2em; }
.leadc__row-main strong {
  font-size: 0.92em;
  font-weight: 700;
  color: var(--fg);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.leadc__row-main small { font-size: 0.72em; color: var(--fg-muted); }

.leadc__check {
  flex: none;
  width: 1.5em;
  height: 1.5em;
  border: 0.09em solid var(--bd);
  border-radius: 50%;
  transition: border-color var(--dur) ease;
}

.leadc__guests {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1em;
}

.leadc__guests > span:first-child { font-size: 0.8em; line-height: 1.4; color: var(--fg-muted); max-width: 11em; }

.leadc__stepper {
  flex: none;
  display: flex;
  align-items: center;
  gap: 1.1em;
  padding: 0.5em 0.9em;
  border: 0.07em solid var(--bd);
  border-radius: 0.5em;
  transition: border-color var(--dur) ease;
}

.leadc__stepper i { font-style: normal; font-size: 1em; color: var(--fg-muted); }
.leadc__stepper b { font-size: 1em; font-weight: 600; color: var(--fg); }

.leadc__happened {
  display: block;
  padding: 0.7em;
  border: 0.07em solid var(--success-30);
  border-radius: 0.4em;
  background: var(--success-15);
  font-size: 0.78em;
  font-weight: 600;
  text-align: center;
  color: var(--fg);
  transition: background var(--dur) ease, border-color var(--dur) ease,
              opacity 0.3s ease;
}

/* hover-animation scaffolding: the check paths, the rolling guest
   count, and the banner/button swap stay inert (checks undrawn,
   button hidden) anywhere the hover block below doesn't apply */
.leadc__check { position: relative; }

.leadc__check svg {
  position: absolute;
  inset: 0.28em;
  stroke: var(--success);
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 11;
  stroke-dashoffset: 11;
}

.leadc__count { display: inline-flex; flex-direction: column; height: 1.4em; overflow: hidden; }
.leadc__count span { display: block; height: 1.4em; line-height: 1.4; }

.leadc__swap { position: relative; display: block; }

.leadc__mark {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 0.4em;
  background: var(--primary);
  color: var(--primary-text);
  font-size: 0.78em;
  font-weight: 600;
  opacity: 0;
  transform: translateY(0.4em);
  pointer-events: none;
}

/* --- Leader-card hover choreography ---
   01 spotlights the auto-create toggle (blue ring, everything else
   recedes), 02 steps every progress bar forward (~360ms moves with
   600ms pauses), 03 checks everyone in, rolls the guest count up,
   and swaps the happened banner for a Mark Attendance button. All
   cards lift on the shared shadow. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .leadc__body {
    transition: background var(--dur) ease, border-color var(--dur) ease,
                transform 0.35s ease, box-shadow 0.35s ease;
  }

  .leadc:hover .leadc__body {
    transform: translateY(-3px);
    box-shadow: 0 18px 32px -12px rgba(0, 0, 0, calc(.16 * var(--sh)));
  }

  /* 01: fade the rest, ring the toggle. The padding/negative-margin
     pair grows the highlight box without moving the layout. */
  .leadc--settings .leadc__body > * { transition: opacity 0.35s ease; }

  .leadc--settings .leadc__setting {
    padding: 0.7em;
    margin: -0.7em;
    border: 0.09em solid transparent;
    border-radius: 0.6em;
    transition: border-color 0.35s ease, box-shadow 0.35s ease;
  }

  .leadc--settings:hover .leadc__body > :not(.leadc__setting) { opacity: 0.3; }

  .leadc--settings:hover .leadc__setting {
    border-color: var(--accent);
    box-shadow: 0 0 0 0.3em var(--accent-15), 0 0.6em 1.4em var(--accent-15);
  }

  /* 02: bars inch forward — 360ms moves, 600ms holds */
  .leadc--plan .leadc__bar i { transition: width 0.5s ease; }

  .leadc--plan:hover .leadc__bar i {
    animation: leadc-advance 3.1s ease-in-out forwards;
  }

  .leadc__pct-roll span { transition: transform 0.4s ease; }

  .leadc--plan:hover .leadc__pct-roll span {
    animation: leadc-count 3.1s ease forwards;
  }

  /* each roll lands with the end of a bar move; % is of one row */
  @keyframes leadc-count {
    0%, 8%      { transform: translateY(0); }
    11.6%       { transform: translateY(-100%); }
    39%         { transform: translateY(-100%); }
    42.6%       { transform: translateY(-200%); }
    70%         { transform: translateY(-200%); }
    73.6%       { transform: translateY(-300%); }
    100%        { transform: translateY(-300%); }
  }

  @keyframes leadc-advance {
    0%     { width: var(--p); }
    11.6%  { width: calc(var(--p) + 16%); }
    31%    { width: calc(var(--p) + 16%); }
    42.6%  { width: calc(var(--p) + 32%); }
    62%    { width: calc(var(--p) + 32%); }
    73.6%  { width: calc(var(--p) + 48%); }
    100%   { width: calc(var(--p) + 48%); }
  }

  /* 03: checks draw in sequence, the count rolls, the button lands */
  .leadc--attend .leadc__check {
    transition: border-color 0.3s ease, background 0.3s ease;
  }

  .leadc--attend .leadc__check svg { transition: stroke-dashoffset 0.35s ease; }
  .leadc--attend .leadc__row + .leadc__row .leadc__check svg { transition-delay: 0.13s; }
  .leadc--attend .leadc__row + .leadc__row + .leadc__row .leadc__check svg { transition-delay: 0.26s; }

  .leadc--attend:hover .leadc__check {
    border-color: var(--success-30);
    background: var(--success-15);
  }

  .leadc--attend:hover .leadc__check svg { stroke-dashoffset: 0; }

  .leadc__count span { transition: transform 0.35s ease 0.45s; }
  .leadc--attend:hover .leadc__count span { transform: translateY(-100%); }

  .leadc--attend .leadc__happened { transition-delay: 0s, 0s, 0.55s; }
  .leadc--attend:hover .leadc__happened { opacity: 0; }

  .leadc__mark { transition: opacity 0.3s ease 0.6s, transform 0.3s ease 0.6s; }
  .leadc--attend:hover .leadc__mark { opacity: 1; transform: none; }
}

@media (max-width: 900px) {
  .hiw__head { grid-template-columns: minmax(0, 1fr); }
  .hiw__head-side { justify-self: start; }
  .steps3 { grid-template-columns: minmax(0, 1fr); gap: 2.25rem; }
}

.hiw__hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.1rem;
  max-width: 46rem;
  margin: 0 auto clamp(2.5rem, 5vw, 4rem);
  text-align: center;
}

.hiw__hero h1 {
  margin: 0;
  font-size: clamp(2rem, 3vw + 0.8rem, 3rem);
  font-weight: 500;
  line-height: 1.1;
  letter-spacing: -0.02em;
}

.hiw__sub {
  margin: 0;
  max-width: 42ch;
  font-size: 1.125rem;
  line-height: 1.6;
  color: var(--fg-muted);
}

.cta-row--center { justify-content: center; }

/* the four-step strip mirrors the in-app onboarding checklist */
.hiw__strip {
  list-style: none;
  margin: 0 0 clamp(3rem, 6vw, 5rem);
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(0.75rem, 1.5vw, 1.25rem);
}

.hiw__strip li {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  padding: 1.1rem 1.2rem 1.25rem;
  background: var(--av);
  border: 1px solid var(--bd);
  border-radius: var(--radius-md);
  box-shadow: 0 12px 24px -8px rgba(0, 0, 0, calc(.10 * var(--sh))), inset 0 1px 0 var(--rim);
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

.hiw__strip .step-num { margin-bottom: 0.35rem; }
.hiw__strip strong { font-size: 1rem; font-weight: 600; }
.hiw__strip span:not(.step-num) { font-size: 0.85rem; color: var(--fg-muted); line-height: 1.45; }

/* one step per band: text | screenshots, sides alternating */
.hiw__step {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: clamp(1.5rem, 4vw, 3.5rem);
  align-items: start;
  padding: clamp(2rem, 4vw, 3rem) 0;
  border-top: 1px solid var(--bd);
  transition: border-color var(--dur) ease;
}

.hiw__step:nth-of-type(even) .hiw__text { order: 2; }
.hiw__step:nth-of-type(even) .hiw__media { order: 1; }

.hiw__text h2 {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin: 0 0 0.35rem;
  font-size: clamp(1.35rem, 1.6vw + 0.6rem, 1.75rem);
  font-weight: 500;
  letter-spacing: -0.015em;
}

.hiw__text h2 .step-num { flex: none; }

/* the per-H2 screenshot note from the content brief — visible while the
   pages are in design iteration */
.hiw__shot-note {
  margin: 0 0 1.1rem;
  font-size: 0.78rem;
  color: var(--fg-muted);
}

.hiw__text > p { margin: 0 0 0.9rem; font-size: 0.98rem; line-height: 1.65; color: var(--fg-muted); }
.hiw__text > p a { color: var(--fg); }

.hiw__walk {
  margin: 0 0 1.1rem;
  padding-left: 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  font-size: 0.98rem;
  line-height: 1.65;
}

.hiw__walk strong { color: var(--fg); font-weight: 600; }
.hiw__walk li::marker { color: var(--fg-muted); font-weight: 600; }

.hiw__walk ol {
  list-style: lower-alpha;
  margin: 0.6rem 0 0;
  padding-left: 1.35rem;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  color: var(--fg-muted);
}

.hiw__callout {
  padding: 1rem 1.15rem;
  background: var(--av);
  border: 1px solid var(--bd);
  border-radius: var(--radius-md);
  font-size: 0.92rem;
  line-height: 1.6;
  color: var(--fg-muted);
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

.hiw__callout strong { display: block; margin-bottom: 0.2rem; color: var(--fg); }
.hiw__callout a { color: var(--fg); }

/* screenshot placeholders */
.hiw__media { display: flex; flex-direction: column; gap: 0.75rem; }

.shot-slot {
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  aspect-ratio: 16 / 10;
  background: var(--av);
  border: 1px dashed var(--bd);
  border-radius: var(--radius-md);
  color: var(--fg-muted);
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

.shot-slot__tag {
  display: grid;
  place-items: center;
  min-width: 2.2rem;
  padding: 0.25rem 0.5rem;
  border: 1px solid var(--bd);
  border-radius: var(--radius-full);
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--fg);
}

.shot-slot figcaption { font-size: 0.78rem; text-align: center; padding-inline: 0.75rem; }

.hiw__minis {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.75rem;
}

.shot-slot--mini { aspect-ratio: 4 / 3; }
.shot-slot--mini .shot-slot__tag { font-size: 0.7rem; padding: 0.15rem 0.4rem; }
.shot-slot--mini figcaption { font-size: 0.68rem; }

/* --- Getting-started step cards (Figma 24266:9722) ---
   Three 411x500 cards. Card 01 is a baked photo render awaiting export
   (kept as a .shot-slot placeholder); 02 and 03 are recreated in
   HTML/CSS so they stay themeable. Everything inside is em on a
   clamped-cqw root, so the mocks scale with the column. NOTE: these
   rules must stay AFTER the base .shot-slot rule (source order). */

.shot-slot--step { aspect-ratio: 411 / 500; border-radius: 8px; }

.stepc {
  container-type: inline-size;
  position: relative;
  margin: 0;
  aspect-ratio: 411 / 500;
  overflow: hidden;
  border: 1px solid var(--bd);
  border-radius: 8px;
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

.stepc--group { background: var(--av); }

.stepc--invite { background: var(--pg); border-style: dashed; }

.stepc--photo img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* the wide admin video: its own ratio, no controls, muted autoplay
   (site.js pulls autoplay under prefers-reduced-motion) */
.stepc--video { aspect-ratio: 1736 / 1080; }

.stepc--video video { display: block; width: 100%; height: auto; }

/* card 02: the group page, pushed low so the card's bottom edge cuts
   it off; hover slides it up to reveal the rest */
.gapp {
  position: absolute;
  inset: 8% 6.5% auto;
  display: flex;
  flex-direction: column;
  gap: 0.75em;
  padding: 1.25em 1.1em;
  font-size: clamp(9px, 3.6cqw, 19px);
  background: var(--pg);
  border: 0.07em solid var(--bd);
  border-radius: 0.75em;
  box-shadow: 0 0.6em 1.5em -0.75em rgba(0, 0, 0, calc(.18 * var(--sh)));
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

.gapp__name { font-size: 1.5em; font-weight: 700; letter-spacing: -0.01em; color: var(--fg); }

.gapp__desc { margin: 0; font-size: 0.8em; line-height: 1.45; color: var(--fg-muted); }

.gapp__tabs { display: flex; align-items: center; gap: 1em; }

.gapp__tab { font-size: 0.8em; font-weight: 500; color: var(--fg-muted); white-space: nowrap; }

.gapp__tab--active {
  padding: 0.35em 1em;
  border: 0.09em solid var(--fg);
  border-radius: var(--radius-full);
  background: var(--av);
  color: var(--fg);
  font-weight: 600;
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

.gapp__tray {
  display: flex;
  flex-direction: column;
  gap: 0.7em;
  padding: 1em 1em 0;
  border: 0.07em solid var(--bd);
  border-radius: 0.75em;
  transition: border-color var(--dur) ease;
}

.gapp__tray-title { font-size: 1.25em; font-weight: 700; color: var(--fg); }

.gapp__tray-hint { font-size: 0.75em; color: var(--fg-muted); }

.gapp__event { display: flex; gap: 0.75em; }

.gapp__date {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 2.8em;
  height: 3em;
  flex: none;
  border: 0.07em solid var(--bd);
  border-radius: 0.5em;
  transition: border-color var(--dur) ease;
}

.gapp__date b { font-size: 1.15em; font-weight: 700; color: var(--fg); }
.gapp__date small { font-size: 0.65em; text-transform: uppercase; color: var(--fg-muted); }

.gapp__meta { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.gapp__topline { display: flex; align-items: baseline; justify-content: space-between; gap: 0.5em; }
.gapp__topline strong { font-size: 1.05em; font-weight: 700; color: var(--fg); }
.gapp__topline span { font-size: 0.95em; font-weight: 700; color: var(--fg); }
.gapp__host { font-size: 0.78em; color: var(--fg-muted); }
.gapp__addr { font-size: 0.72em; font-style: italic; color: var(--fg-muted); }

.gapp__label {
  font-size: 0.7em;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--fg-muted);
}

.gapp__lesson {
  display: flex;
  flex-direction: column;
  gap: 0.3em;
  padding: 0.85em;
  border: 0.07em solid var(--bd);
  border-radius: 0.6em;
  transition: border-color var(--dur) ease;
}

.gapp__lesson-top { display: flex; align-items: center; justify-content: space-between; gap: 0.5em; font-size: 0.85em; color: var(--fg); }

.gapp__lesson strong { font-size: 1.15em; font-weight: 700; color: var(--fg); }
.gapp__lesson small { font-size: 0.7em; color: var(--fg-muted); }

.gapp__chevron {
  width: 1.1em;
  height: 1.1em;
  flex: none;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  color: var(--fg-muted);
}

.gapp__foot { display: flex; align-items: center; justify-content: space-between; gap: 0.5em; }
.gapp__foot > span:first-child { font-size: 0.78em; color: var(--fg-muted); }

.gapp__chip {
  padding: 0.4em 1em;
  border-radius: 0.45em;
  background: var(--success-30);
  color: var(--success);
  font-size: 0.75em;
  font-weight: 700;
  white-space: nowrap;
  transition: background var(--dur) ease, color var(--dur) ease;
}

.gapp__stats {
  display: flex;
  gap: 1.5em;
  margin-inline: -1em;
  padding: 0.9em 1em;
  background: var(--av);
  font-size: 0.78em;
  color: var(--fg-muted);
  transition: background var(--dur) ease;
}

.gapp__stats b { font-weight: 700; color: var(--fg); }

/* card 03: cast web up-right, haze, isometric invite card low-left */
.invweb {
  position: absolute;
  top: -13%;
  right: -13%;
  width: 126%;
  height: auto;
}

.invweb__rings circle {
  fill: none;
  stroke: var(--bd);
  stroke-width: 1.3;
  stroke-dasharray: 1.5 7;
  stroke-linecap: round;
  transition: stroke var(--dur) ease;
}

.invweb__nodes circle {
  stroke: var(--pg);
  stroke-width: 4;
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, calc(.18 * var(--sh))));
  transition: stroke var(--dur) ease;
}

/* depth of field: the periphery falls out of focus, like the mock */
.invweb__nodes .invweb__soft { filter: blur(2.5px); }

.stepc__haze {
  position: absolute;
  inset: 0;
  background: linear-gradient(200deg, transparent 35%, var(--pg-30) 75%);
  backdrop-filter: blur(1.5px);
  -webkit-backdrop-filter: blur(1.5px);
  mask-image: linear-gradient(200deg, transparent 30%, #000 65%);
  -webkit-mask-image: linear-gradient(200deg, transparent 30%, #000 65%);
  pointer-events: none;
}

.invcard {
  position: absolute;
  left: -2%;
  top: 52%;
  width: 80%;
  display: flex;
  flex-direction: column;
  gap: 0.7em;
  padding: 1.4em 1.3em;
  /* type scales with the 80% card so the composition just shrinks */
  font-size: clamp(8px, 2.72cqw, 15px);
  transform-origin: top left;
  background: var(--pg);
  border: 0.07em solid var(--bd);
  border-radius: 0.75em;
  /* same isometric family as the home invite card; ledge survives dark
     mode, cast shadow rides --sh */
  transform: rotate(-7.84deg) scaleY(.87) skewX(29.63deg);
  box-shadow: 0 0.35em 0 var(--bd),
              0.55em 0.9em 0.9em rgba(0, 0, 0, calc(.2 * var(--sh)));
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

.invcard__title { font-size: 1.7em; font-weight: 700; letter-spacing: -0.01em; color: var(--fg); }

.invcard__sub { margin: 0; font-size: 0.85em; line-height: 1.4; color: var(--fg-muted); }

.invcard__input {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5em;
  padding: 0.65em 0.9em;
  border: 0.07em solid var(--bd);
  border-radius: 0.5em;
  background: var(--av);
  font-size: 0.85em;
  color: var(--fg-muted);
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

/* mock geometry: the pill spans the card minus 12px each side — wider
   than the text's 1.3em inset, hence the negative margins */
.invcard__input { align-self: stretch; margin-inline: calc(12px - 1.3em); }

.invcard__rows {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: calc(0.9em + 8px);
}

.invcard__rows li {
  font-size: 1.05em;
  font-weight: 500;
  color: var(--fg);
}

.invcard__input svg {
  width: 1em;
  height: 1em;
  flex: none;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.6;
  stroke-linecap: round;
  color: var(--fg-muted);
}

/* dark mode: the card's --pg face melts into the --pg card ground, so
   lift it a step; the border stays the theme's --bd */
html[data-theme="dark"] .invcard { background: var(--av); }

html[data-theme="dark"] .invcard__input { background: var(--pg); }

.invcard__btn {
  align-self: flex-end;
  padding: 0.5em 1.2em;
  border: 0.09em solid var(--fg);
  border-radius: 0.5em;
  font-size: 0.85em;
  font-weight: 600;
  color: var(--fg);
  transition: border-color var(--dur) ease, color var(--dur) ease;
}

@media (max-width: 900px) {
  /* single column: cap the mock cards so they don't tower */
  .steps3__item .stepc,
  .steps3__item .shot-slot--step { max-width: 26rem; }
}

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .gapp {
    transition: background var(--dur) ease, border-color var(--dur) ease,
                transform .45s cubic-bezier(.2, .7, .3, 1);
  }

  .stepc--group:hover .gapp { transform: translateY(-3em); }
}

/* editorial flag kept visible during iteration */
.verify {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--fg-muted);
  border: 1px dashed var(--bd);
  border-radius: var(--radius-sm);
  padding: 0.05rem 0.3rem;
}

/* the weekly loop (page B) */
.hiw-loop {
  margin: 0 0 clamp(2.5rem, 5vw, 4rem);
  padding: clamp(1.25rem, 2.5vw, 2rem);
  background: var(--av);
  border: 1px solid var(--bd);
  border-radius: var(--radius-md);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.9rem;
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

.hiw-loop__ring {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 0.6rem;
}

.hiw-loop__ring li {
  padding: 0.45rem 0.85rem;
  background: var(--pg);
  border: 1px solid var(--bd);
  border-radius: var(--radius-full);
  font-size: 0.88rem;
  font-weight: 500;
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

/* the arrow between chips */
.hiw-loop__ring li + li::before { content: none; }

.hiw-loop__ring li:not(:last-child) {
  position: relative;
  margin-right: 1.1rem;
}

.hiw-loop__ring li:not(:last-child)::after {
  content: "\2192";
  position: absolute;
  right: -1.05rem;
  color: var(--fg-muted);
}

.hiw-loop__back { font-size: 0.82rem; color: var(--fg-muted); }

/* closing */
.hiw__close {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  padding-top: clamp(2rem, 4vw, 3rem);
  border-top: 1px solid var(--bd);
  transition: border-color var(--dur) ease;
}

.hiw__next { font-size: 0.95rem; font-weight: 600; color: var(--fg); }

@media (max-width: 900px) {
  .hiw__strip { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hiw__step { grid-template-columns: minmax(0, 1fr); }
  .hiw__step:nth-of-type(even) .hiw__text { order: 1; }
  .hiw__step:nth-of-type(even) .hiw__media { order: 2; }
}

@media (max-width: 480px) {
  .hiw__strip { grid-template-columns: minmax(0, 1fr); }
  .hiw__minis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* --- Footer --- */

/* the CTA band carries its own integrated footer; ~ works because both
   are body-level siblings, and only index has a .cta */
.cta ~ .site-footer { display: none; }

.site-footer {
  background: var(--av);
  border-top: 1px solid var(--bd);
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

.site-footer__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1rem 1.5rem;
  max-width: var(--container-max);
  margin: 0 auto;
  padding: clamp(1.5rem, 3vw, 2.5rem) clamp(1.5rem, 4vw, 4rem);
}

.site-footer__copy {
  font-size: 0.85rem;
  color: var(--fg-muted);
}

.site-footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
}

.site-footer__links a {
  text-decoration: none;
  font-size: 0.85rem;
  color: var(--fg-muted);
  transition: color var(--dur) ease;
}

.site-footer__links a:hover { color: var(--fg); }

/* --- Hero layout --- */

.hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: center;
  gap: clamp(2rem, 5vw, 4rem);
  min-height: calc(100dvh - var(--header-h));
  max-width: var(--container-max);
  margin: 0 auto;
  padding: clamp(1.5rem, 4vw, 4rem);
}

.hero__text {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1.25rem;
  min-width: 0;
}

.eyebrow {
  margin: 0;
  font-size: 0.85rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fg-muted);
}

.hero__headline {
  margin: 0;
  font-size: clamp(2.25rem, 4.5vw + 1rem, 3.75rem);
  font-weight: 500;
  line-height: 1.08;
  letter-spacing: -0.02em;
}

.hero__subhead {
  margin: 0;
  max-width: 46ch;
  font-size: 1.125rem;
  line-height: 1.6;
  color: var(--fg-muted);
}

.hero__trial {
  /* Rule: 16px between a button and its supporting text (hero__text gap is 20px) */
  margin: -0.25rem 0 0;
  font-size: 0.9rem;
  color: var(--fg-muted);
}

.button {
  display: inline-block;
  text-decoration: none;
  font-family: inherit;
  font-weight: 600;
  font-size: 1.05rem;
  padding: 0.875rem 1.75rem;
  border-radius: var(--radius-md);
  border: 1px solid transparent;
  transition: filter var(--dur) ease, background var(--dur) ease,
              color var(--dur) ease, border-color var(--dur) ease;
}

/* Compact variant — the header has 84px of height to work inside */
.button--sm {
  font-size: 0.9rem;
  padding: 0.5rem 1rem;
  white-space: nowrap;
}

.button--primary {
  background: var(--primary);
  color: var(--primary-text);
}

.button--primary:hover {
  filter: brightness(0.92);
}

/* Outlined CTA (Figma 24003:44770): a 2px --fg outline over a translucent
   fill, with the file's "Button Effect 2" inset bottom edge. --glass is
   the fill: the file's info30 (#ffffff4d) verbatim on dark, and much
   lighter on light, where 14% of the text color (what --highlight carries
   for .mark) reads as a disabled grey pill instead of a glass one. */
.button--outline {
  border-width: 2px;
  border-color: var(--fg);
  background: var(--glass);
  color: var(--fg);
  box-shadow: inset 0 -2px 0 rgba(0, 0, 0, 0.25);
}

.button--outline:hover {
  background: var(--fg);
  color: var(--pg);
}

/* The store-mark sprite sits before <header> in the DOM, so it has to take
   up no space at all — an inline 0x0 <svg> still generates a line box, and
   that line box would push a sticky header off its top edge. */
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/* --- Download row: org CTA beside the App Store badge --- */

.cta-row {
  /* one shared height so the two buttons read as a pair, 64px at desktop */
  --cta-h: clamp(3.25rem, 1.6rem + 2.7vw, 4rem);
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: 1rem;
}

.cta-row .button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--cta-h);
  padding-block: 0;
}

/* Apple ships the badge in two variants and asks that you use whichever
   contrasts with the background — which is exactly what --primary /
   --primary-text already do, so the badge is white-on-dark in dark mode
   (the Figma rendering) and black-on-light in light mode, with no
   hardcoded colors. */
.appstore {
  display: inline-flex;
  align-items: center;
  gap: 0.85rem;
  min-height: var(--cta-h, 4rem);
  padding: 0.5rem 1.5rem;
  border-radius: var(--radius-md);
  background: var(--primary);
  border: 1px solid var(--primary);
  color: var(--primary-text);
  text-decoration: none;
  transition: filter var(--dur) ease, background var(--dur) ease,
              border-color var(--dur) ease, color var(--dur) ease;
}

.appstore:hover { filter: brightness(0.95); }

.appstore__logo {
  width: 1.55rem;
  height: 1.9rem;
  flex: none;
  fill: currentColor;
}

.appstore__text { display: flex; flex-direction: column; line-height: 1; }
.appstore__text small { font-size: 0.72rem; font-weight: 500; }
.appstore__text strong {
  margin-top: 0.2rem;
  font-size: 1.35rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

/* footer-sized */
.appstore--sm {
  gap: 0.55rem;
  min-height: 2.6rem;
  padding: 0.35rem 0.85rem;
  border-radius: var(--radius-sm);
}

.appstore--sm .appstore__logo { width: 1rem; height: 1.25rem; }
.appstore--sm .appstore__text small { font-size: 0.52rem; }
.appstore--sm .appstore__text strong { margin-top: 0.1rem; font-size: 0.9rem; }

/* mobile menu: full width, like the CTA above it */
.appstore--block { align-self: stretch; justify-content: center; min-height: 3.5rem; }

.playsoon {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0;
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--fg);
  opacity: 0.9;
}

.playsoon svg { width: 1.25rem; height: 1.25rem; flex: none; }

/* once the row wraps, two half-width buttons read as an accident */
@media (max-width: 560px) {
  .cta-row > * { flex: 1 1 100%; justify-content: center; }
}

.hero__animation {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
}

/* --- Animation embed — rules carried over from hero-embed.html, unmodified --- */

#wrap {
  width: 100%;
  max-width: 100%;
  min-width: 0;
  aspect-ratio: 1 / 1;
  margin-inline-start: -6%;
}

#wrap svg { width: 100%; height: 100%; display: block; max-width: 100%; overflow: visible; }

.lk {
  fill: none;
  stroke: var(--bd);
  stroke-width: 6;
  stroke-linecap: round;
  transition: stroke var(--dur) ease;
}

circle, image {
  transition: fill var(--dur) ease, stroke var(--dur) ease;
}

.nd {
  filter: drop-shadow(0 8px 12px rgba(0, 0, 0, calc(.16 * var(--sh))));
}

/* Highlighted word in a heading — a rounded tint of the text color
   behind one word. Figma uses info30 (#ffffff4d), i.e. 30% of the
   primary text on dark; --highlight carries the light-mode equivalent. */
.mark {
  background: var(--highlight);
  color: inherit;
  border-radius: var(--radius-md);
  padding: 0.04em 0.22em 0.1em;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
  transition: background var(--dur) ease;
}

/* --- Phone home screen (empathy phone) ---
   The "before" state: the six scattered tools as app icons plus the one
   dark Uncomn tile the fragments collapse into. CSS keeps it hidden and
   the app screen visible, so reduced motion and no-JS get the payoff —
   the scrub timeline reveals this at progress 0 via fromTo. */

.phone-frame--empathy .phone-frame__screen { position: relative; }

.app-home {
  position: absolute;
  inset: 0;
  opacity: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5em;
  padding: 0.6em 1.2em 0.7em;
  font-size: 4.05cqw;
  /* a wallpaper, not a blank panel: the tint keeps the outlined tiles
     legible in both themes without inventing a new colour */
  background:
    radial-gradient(120% 70% at 50% 0%, var(--av) 0%, transparent 65%),
    var(--pg);
  transition: background var(--dur) ease;
}

.app-home .app-screen__statusbar { padding-top: 0.85em; font-size: 0.62em; }

.app-home__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 2em 0.4em;
  margin-top: 1.2em;
}

.app-home__app {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3em;
}

.app-home__icon {
  display: grid;
  place-items: center;
  width: 4.9em;
  height: 4.9em;
  border-radius: 1.3em;
  background: var(--av);
  border: 1px solid var(--bd);
  color: var(--fg-muted);
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

.app-home__icon svg { width: 2.45em; height: 2.45em; }

.app-home__label {
  font-size: 0.66em;
  color: var(--fg-muted);
  text-align: center;
}

/* page dots — the detail that makes it read as a phone, not a panel */
.app-home__dots {
  margin-top: auto;
  display: flex;
  justify-content: center;
  gap: 0.35em;
  padding-bottom: 0.7em;
}

.app-home__dots i {
  width: 0.35em;
  height: 0.35em;
  border-radius: 50%;
  background: var(--fg-muted);
  opacity: 0.3;
}

.app-home__dots i.is-on { opacity: 0.8; }

.app-home__dock {
  display: flex;
  justify-content: center;
  padding: 0.55em 0;
  border-radius: 1.1em;
  background: var(--av);
  transition: background var(--dur) ease;
}

/* the one that stays: real app icon, no outline */
.app-home__uncomn {
  background: none;
  /* the artwork is a dark tile; keep the hairline so it still reads
     against the dark-theme wallpaper */
  border: 1px solid var(--bd);
  overflow: hidden;
}

.app-home__uncomn img { width: 100%; height: 100%; display: block; border-radius: inherit; }

/* --- Empathy line --- */

.empathy {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: clamp(4rem, 10vw, 7rem) clamp(1.5rem, 4vw, 4rem) clamp(2rem, 5vw, 3.5rem);
  text-align: center;
}

.empathy .eyebrow { margin-bottom: 0.75rem; }

.empathy__line {
  margin: 0 auto;
  max-width: 32ch;
  font-size: clamp(1.5rem, 1.5vw + 1rem, 2.25rem);
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: -0.01em;
}

.empathy__sub {
  margin: 1rem auto 0;
  max-width: 52ch;
  font-size: 1.125rem;
  line-height: 1.6;
  color: var(--fg-muted);
}

/* The whole beat pins as one composition: heading, subtitle and stage
   travel together, so the phone sits under the text for the entire
   scrub. Chrome is vh-based because the pinned block must fit a single
   viewport — that budget is what sizes the phone. */

.empathy__pin {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.empathy__stage {
  position: relative;
  width: 100%;
  max-width: 1000px;
  margin-inline: auto;
  margin-top: clamp(1rem, 3vh, 2.5rem);
  min-height: 460px;
  display: grid;
  align-items: stretch;
  justify-items: center;
}

/* Fragments flank the phone, three per side. No --fx/--fy coordinates:
   the columns distribute themselves at any stage height, which matters
   because the stage height now varies with the viewport. */

.empathy__chips {
  position: absolute;
  inset: 0;
  display: flex;
  justify-content: space-between;
  align-items: stretch;
}

.empathy__col {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  height: 100%;
}

/* Height comes from the stage (align-self: stretch), width follows from
   the ratio on the FRAME. Putting the ratio on the screen instead makes
   width and height mutually dependent and the browser falls back to an
   intrinsic size — the phone then ignores the stage entirely. */
.phone-frame--empathy {
  flex: none;
  position: relative;
  z-index: 1;
  width: auto;
  height: auto;
  max-height: 760px;
  aspect-ratio: 9 / 17.8;
}

/* container-type lets the screen's type scale with its own width */
.phone-frame--empathy .phone-frame__screen {
  container-type: inline-size;
  height: 100%;
  min-height: 0;
}

.app-screen__org {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding-top: 1.125rem; /* clears the notch */
}

.app-screen__org .mock__meta strong { font-size: 0.82rem; }

.app-screen__disciples {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.app-screen__disciples .mock-caption { font-size: 0.66rem; }

@media (min-width: 981px) {
  .empathy__pin {
    min-height: calc(100vh - var(--header-h) - 1px);
    padding-top: clamp(1.5rem, 5vh, 3.5rem);
    padding-bottom: clamp(0.75rem, 3vh, 1.75rem);
  }
  .empathy__stage { flex: 1 1 auto; min-height: 0; }
}

/* Short viewports: buy the stage back some height so the phone stays
   large enough to read. */
@media (min-width: 981px) and (max-height: 820px) {
  .empathy__line { font-size: 1.75rem; }
  .empathy__sub { font-size: 1rem; margin-top: 0.75rem; }
}

/* Below the pin breakpoint there is no 100vh block, so the stage has no
   height to stretch into: size the phone by width and let the ratio give
   its height instead. */
@media (max-width: 980px) {
  .empathy__stage { min-height: 0; align-items: center; }
  .phone-frame--empathy {
    width: clamp(240px, 34vw, 300px);
    height: auto;
    max-height: none;
  }
}

@media (max-width: 720px) {
  .empathy__stage {
    min-height: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2rem;
  }
  .empathy__chips {
    position: static;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.875rem 1rem;
  }
  .empathy__col { display: contents; }
  .phone-frame--empathy { width: min(70vw, 260px); }
}


/* Artifact fragment cards — icon + skeleton preview + one real line.
   Skeleton language matches the leader-welcome video composition; every
   placeholder is a --bd fill on the --av card, so it themes for free and
   never needs a color of its own. */

.frag {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  width: 186px;
  padding: 0.6rem 0.7rem;
  text-align: left;
  background: var(--av);
  border: 1px solid var(--bd);
  border-radius: var(--radius-md);
  box-shadow: 0 8px 16px -6px rgba(0, 0, 0, calc(.1 * var(--sh))),
              inset 0 1px 0 var(--rim);
  transform: rotate(var(--tilt, 0deg));
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

.frag__head {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  color: var(--fg-muted);
}

.frag__icon {
  width: 14px;
  height: 14px;
  flex: none;
}

.frag__app {
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.frag__body {
  font-size: 0.8rem;
  font-weight: 500;
  line-height: 1.35;
  color: var(--fg);
}

/* --- Skeleton previews --- */

.frag__skel {
  display: flex;
  flex-direction: column;
  gap: 4px;
  height: 38px;
  padding: 6px 7px;
  background: var(--pg);
  border: 1px solid var(--bd);
  border-radius: var(--radius-sm);
  overflow: hidden;
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

.frag__skel i {
  display: block;
  background: var(--bd);
  border-radius: 2px;
  transition: background var(--dur) ease;
}

/* text lines (doc, notes) */
.frag__skel .l { width: var(--w, 100%); height: 4px; }

/* chat bubbles */
.frag__skel--chat { gap: 5px; }
.frag__skel .b { width: 54%; height: 8px; border-radius: 4px; }
.frag__skel .b--out { align-self: flex-end; width: 44%; background: var(--fg-muted); opacity: .45; }
.frag__skel .b--short { width: 34%; }

/* calendar grid */
.frag__skel--cal { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; align-content: center; }
.frag__skel .c { width: 100%; height: 6px; border-radius: 1px; }
.frag__skel .c.is-on { background: var(--fg-muted); opacity: .55; }

/* spreadsheet: header bar then a cell grid */
.frag__skel--sheet { display: grid; grid-template-columns: repeat(4, 1fr); gap: 3px; align-content: center; }
.frag__skel .hd { grid-column: 1 / -1; height: 6px; background: var(--fg-muted); opacity: .4; }
.frag__skel .cell { height: 5px; }

/* notes: title line then checkbox rows */
.frag__skel--note { gap: 5px; }
.frag__skel .ck {
  height: 6px;
  background: none;
  display: grid;
  grid-template-columns: 6px 1fr;
  gap: 5px;
  align-items: center;
}
.frag__skel .ck::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 1px;
  border: 1px solid var(--bd);
}
.frag__skel .ck::after {
  content: "";
  height: 4px;
  border-radius: 2px;
  background: var(--bd);
}
.frag__skel .ck:nth-child(3)::after { width: 78%; }
.frag__skel .ck:nth-child(4)::after { width: 64%; }

/* email thread: avatar dot + lines */
.frag__skel--mail { gap: 6px; }
.frag__skel .m {
  height: 7px;
  background: none;
  display: grid;
  grid-template-columns: 7px 1fr;
  gap: 5px;
  align-items: center;
}
.frag__skel .m::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: var(--radius-full);
  background: var(--bd);
}
.frag__skel .m::after {
  content: "";
  height: 4px;
  border-radius: 2px;
  background: var(--bd);
}
.frag__skel .m:nth-child(2)::after { width: 72%; }
.frag__skel .m:nth-child(3)::after { width: 86%; }

/* Phones: pair the cards into three rows of two. Below ~455px the fixed
   194px card can no longer fit two across and the flex wrap above drops
   to a single column — six rows, ~350px of extra scroll. Column-first
   flow keeps the desktop left/right pairing intact now that the .col
   wrappers are display:contents. */
@media (max-width: 560px) {
  .empathy__chips {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-rows: repeat(3, auto);
    grid-auto-flow: column;
    gap: 0.7rem;
  }
  .empathy__stage { gap: 1.5rem; }

  /* fluid width is the actual fix; min-width/overflow-wrap stop the long
     "attendance_tracker_2026" token forcing the page wider than 320px */
  .frag {
    width: auto;
    min-width: 0;
    transform: rotate(calc(var(--tilt, 0deg) * 0.6));
  }
  /* smaller body keeps "attendance_tracker_2026" on one line down to
     ~375px; overflow-wrap stays as the safety net below that */
  .frag__body { font-size: 0.72rem; }
  .frag__app { font-size: 0.62rem; }
  .frag__body, .frag__app { overflow-wrap: anywhere; }
}

/* --- Pricing --- */

.pricing {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: clamp(2rem, 5vw, 4rem) clamp(1.5rem, 4vw, 4rem) clamp(4rem, 8vw, 6rem);
}

.pricing__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 440px);
  gap: clamp(2rem, 4vw, 4rem);
  align-items: center;
}

.pricing__text .eyebrow { margin-bottom: 0.75rem; }

.pricing__title {
  margin: 0 0 0.75rem;
  font-size: clamp(1.875rem, 2.5vw + 0.75rem, 2.75rem);
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: -0.015em;
}

.pricing__sub {
  margin: 0 0 1rem;
  max-width: 48ch;
  font-size: 1.125rem;
  line-height: 1.6;
  color: var(--fg-muted);
}

.pricing__promise {
  margin: 0;
  max-width: 52ch;
  font-size: 0.9rem;
  line-height: 1.6;
  color: var(--fg-muted);
}

.price-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1.25rem;
  padding: clamp(1.75rem, 3vw, 2.5rem);
  background: var(--av);
  border: 1px solid var(--bd);
  border-radius: var(--radius-md);
  box-shadow: 0 12px 24px -8px rgba(0, 0, 0, calc(.12 * var(--sh))),
              inset 0 1px 0 var(--rim);
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

.price-card__price {
  margin: 0;
  font-size: clamp(2.5rem, 3vw + 1rem, 3.25rem);
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.02em;
}

.price-card__price span {
  font-size: 1rem;
  font-weight: 500;
  color: var(--fg-muted);
  letter-spacing: 0;
}

.price-card__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
}

.price-card__list li {
  display: flex;
  align-items: flex-start;
  gap: 0.625rem;
  font-size: 0.95rem;
  line-height: 1.5;
  color: var(--fg-muted);
}

.price-card__list svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  margin-top: 3px;
  color: var(--fg);
}

.price-card__cta {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1rem; /* Rule: 16px between a button and its supporting text */
}

.price-card__cta .hero__trial { margin: 0; }

@media (max-width: 980px) {
  .pricing__grid { grid-template-columns: minmax(0, 1fr); }
  .price-card { width: 100%; }
}

/* --- Closing CTA --- */

/* The closing CTA is a dark photographic island (Figma 24198:4418): it
   keeps the same appearance in both themes, because the photo does. The
   cheapest way to make everything inside behave is to redefine the tokens
   on the section — .eyebrow, .cta__title, .button--outline, .appstore and
   .playsoon then all resolve correctly with no per-element overrides. */
.cta {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  border-top: 1px solid #262d34;
  padding: clamp(3.5rem, 6vw, 5rem) 0 0;
  background: #14171a;

  --fg: #f5f6f7;
  --fg-muted: rgba(245, 246, 247, 0.84);
  --primary: #ffffff;
  --primary-text: #161b1e;
  --glass: rgba(255, 255, 255, 0.28);

  /* `color` inherits a computed value, so body's already-resolved --fg
     rides straight through a token override. Re-resolving it here is what
     makes the override reach elements that only inherit their color. */
  color: var(--fg);
}

/* .button--outline:hover fills with var(--fg) and flips its text to
   var(--pg) — but this island pins --fg light while leaving --pg themed
   (the footer band needs it), so in light mode that hover was white on
   white. The fill here is always #f5f6f7, so the hover text is always
   dark. */
.cta .button--outline:hover { color: #14171a; }

.cta__bg {
  position: absolute;
  inset: 0;
  z-index: -1;
  background: url("../assets/cta-bg.jpg") center / cover no-repeat;
}

/* The file's diagonal ramp, dark toward the text corner, plus a flat
   layer it does not have. The photo is a bright sky — the ramp alone
   leaves white type short of AA against it, so the flat layer is what
   buys the contrast. Re-measure if the photo changes. */
.cta__bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(-58.54deg, rgba(20, 23, 26, 0) 44.5%, rgba(20, 23, 26, 0.7) 92.1%),
    linear-gradient(to bottom, rgba(20, 23, 26, 0.44), rgba(20, 23, 26, 0.26));
}

.cta__panel {
  padding-inline: clamp(1.5rem, 4vw, 4rem);
  display: grid;
  grid-template-columns: minmax(0, 0.82fr) minmax(0, 1fr);
  align-items: center;
  gap: clamp(2rem, 4vw, 3.5rem);
  max-width: var(--container-max);
  margin: 0 auto;
}

/* The device group is far wider than its column and runs off the right
   edge, exactly as the file draws it; .cta clips it. Percentages come
   from the file's own geometry: the group is 1549.93 x 679, the iPad
   867 x 650 at (0, 21.78) and the iPhone 679 x 679 at (870.93, 0). */
.cta__devices {
  position: relative;
  width: 224%;
  margin-left: -12.5%;
  aspect-ratio: 1549.93 / 679;
  min-width: 0;
}

.cta__devices img {
  position: absolute;
  max-width: none;
  filter: drop-shadow(0 24px 48px rgba(0, 0, 0, 0.45));
}

.cta__pad { left: 0; top: 3.21%; width: 55.94%; height: 95.73%; }

/* --- Integrated footer band (Figma 24225:11429) ---
   Part of the same photo island: a scrim that fades to --pg with a 4px
   backdrop blur, the wordmark + nav row, then the giant watermark. --pg
   is deliberately NOT among the tokens .cta pins, so the band ends on
   the page background in either theme — white in light (the file
   verbatim), dark in dark. The row's text colors are re-pinned per
   theme below, since .cta fixed --fg for the photo area above. */
.cta__footer {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: clamp(2.5rem, 6vw, 5.5rem);
  margin-top: calc(-1 * clamp(1.5rem, 4vw, 3.75rem));
  padding: clamp(7rem, 12.5vw, 11.25rem) clamp(1.5rem, 4vw, 4rem) 0;
  background: linear-gradient(to bottom, rgba(255, 255, 255, 0), var(--pg));
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  --fg: #14171a;
  color: var(--fg);
}

html[data-theme="dark"] .cta__footer { --fg: #f5f6f7; }

.cta__footer-row {
  width: 100%;
  max-width: var(--container-max);
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1rem 2rem;
}

.cta__footer-brand {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.35rem 1rem;
}

.cta__footer-logo {
  display: inline-flex;
  align-items: flex-start;
  gap: 0.45rem;
  color: var(--fg);
  text-decoration: none;
}

.cta__footer-logo svg { display: block; width: clamp(96px, 9vw, 130px); aspect-ratio: 1100 / 146; }

.cta__beta {
  padding: 0.1rem 0.45rem;
  border: 1px solid currentColor;
  border-radius: var(--radius-full);
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  opacity: 0.75;
}

.cta__footer-end {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  padding-bottom: 1.25rem;
}

.cta__copy { font-size: 0.85rem; font-weight: 500; text-align: center; opacity: 0.75; }


.cta__footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem clamp(1rem, 2vw, 1.5rem);
}

.cta__footer-links a {
  font-size: clamp(1.05rem, 1.6vw, 1.4rem);
  font-weight: 700;
  color: var(--fg);
  text-decoration: none;
  transition: opacity var(--dur) ease;
}

.cta__footer-links a:hover { opacity: 0.7; }

/* Five links, two columns on mobile — the fifth starts row three, and
   that is fine. Must sit AFTER the base .cta__footer-links rule: a media
   query adds no specificity, so its display:grid only beats the base
   display:flex on source order. */
@media (max-width: 720px) {
  .cta__footer-links {
    width: 100%;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.75rem 1rem;
  }
}

/* the watermark: the uploaded logo_main render (soft emboss baked in),
   resized/quantized to assets/wordmark-large.png. It is white artwork, so
   opacity — not color — sets its weight against the band. */
.cta__wordmark {
  display: block;
  width: min(100%, var(--container-max));
  height: auto;
  margin: 0 auto;
  opacity: 0.85;
}
/* The file's own x for the phone is 56.19%, but at that offset the two
   renders do not touch — their transparent padding sits between them —
   while the file's rendered frame clearly overlaps them. 29% is measured
   off that render: the phone lands on the iPad's right third and runs off
   the section edge, which is the composition the frame actually shows. */
.cta__phone-shot { left: 29%; top: 0; width: 43.81%; height: 100%; }

.cta__text {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.cta__text .eyebrow { margin-bottom: 0.75rem; }

.cta__title {
  margin: 0 0 0.75rem;
  font-size: clamp(1.75rem, 2vw + 0.75rem, 2.5rem);
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: -0.015em;
}

.cta__sub {
  margin: 0 0 1.5rem;
  max-width: 44ch;
  font-size: 1.125rem;
  line-height: 1.6;
  color: var(--fg-muted);
}

.cta__text .playsoon { margin-top: 0.75rem; }

/* Phone mock frame — device bezel is representational, so its radius is
   its own (not a UI radius token); everything else uses tokens */

.phone-frame {
  position: relative;
  flex: 0 0 clamp(150px, 22%, 190px);
  padding: 10px;
  background: var(--pg);
  border: 1px solid var(--bd);
  border-radius: 28px;
  box-shadow: 0 8px 20px -6px rgba(0, 0, 0, calc(.14 * var(--sh))),
              inset 0 1px 0 var(--rim);
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

.phone-frame__notch {
  position: absolute;
  top: 18px;
  left: 50%;
  transform: translateX(-50%);
  width: 64px;
  height: 14px;
  border-radius: var(--radius-full);
  background: var(--bd);
  /* .app-home is positioned and comes later in the DOM, so without this
     it paints over the notch */
  z-index: 2;
  transition: background var(--dur) ease;
}

.phone-frame__screen {
  height: 100%;
  min-height: 100%;
  border: 1px solid var(--bd);
  border-radius: 20px;
  overflow: hidden;
  transition: border-color var(--dur) ease;
}

.phone-frame__screen img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.phone-frame__screen--placeholder {
  display: grid;
  place-items: center;
  padding: 1rem;
}

.phone-frame__screen--placeholder .mock-chip {
  text-align: center;
  white-space: normal;
}

@media (max-width: 980px) {
  .cta__panel { grid-template-columns: minmax(0, 1fr); }
}

/* --- Stakes --- */

/* Hidden for now by request — kept in the markup so the copy and the
   video slot underneath it survive. Remove `display: none` and the
   `hidden` attribute on the section to bring it back. */
.stakes { display: none; }

.stakes {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: clamp(2rem, 5vw, 4rem) clamp(1.5rem, 4vw, 4rem) clamp(3rem, 6vw, 5rem);
  text-align: center;
}

.stakes .eyebrow { margin-bottom: 0.75rem; }

.stakes__title {
  margin: 0 auto;
  max-width: 30ch;
  font-size: clamp(1.5rem, 1.5vw + 1rem, 2.25rem);
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: -0.01em;
}

.stakes__copy {
  margin: 1rem auto 0;
  max-width: 58ch;
  font-size: 1.0625rem;
  line-height: 1.7;
  color: var(--fg-muted);
}

/* --- Features bento --- */

.features {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: clamp(2rem, 5vw, 4rem) clamp(1.5rem, 4vw, 4rem) clamp(4rem, 8vw, 7rem);
}

.section-head {
  max-width: 62ch;
  margin-bottom: clamp(2rem, 4vw, 3rem);
}

.section-head h2 {
  margin: 0 0 0.75rem;
  font-size: clamp(1.875rem, 2.5vw + 0.75rem, 2.75rem);
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: -0.015em;
}

.section-head p {
  margin: 0;
  font-size: 1.125rem;
  line-height: 1.6;
  color: var(--fg-muted);
}

/* .section-head p is (0,0,1,1) and outspecifies .eyebrow (0,0,1,0), so
   an eyebrow in here needs two classes to keep its own size. */
.section-head .eyebrow {
  font-size: 0.85rem;
  margin-bottom: 0.75rem;
}

/* --- Event card ---
   One card with hairline dividers instead of separate rows, so the
   meeting reads as a single object: when, where, what, who. Card chrome
   matches .mock__row so it sits in the same family. */

.ev {
  width: 100%;
  background: var(--pg);
  border: 1px solid var(--bd);
  border-radius: var(--radius-md);
  box-shadow: 0 4px 10px rgba(0, 0, 0, calc(.06 * var(--sh)));
  overflow: hidden;
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

.ev__sec { padding: 0.625rem 0.75rem; }
.ev__sec + .ev__sec { border-top: 1px solid var(--bd); transition: border-color var(--dur) ease; }

.ev__head { display: flex; align-items: center; gap: 0.75rem; }

.ev__loc { display: flex; align-items: center; gap: 0.75rem; }

.ev__map { width: 96px; height: 64px; flex: none; border-radius: var(--radius-sm); }
.map__bg { fill: var(--av); transition: fill var(--dur) ease; }
.map__road { stroke: var(--bd); stroke-width: 5; fill: none; transition: stroke var(--dur) ease; }
.map__road--thin { stroke-width: 2.5; }
.map__block { fill: var(--bd); opacity: .55; transition: fill var(--dur) ease; }
.map__halo { fill: var(--fg); opacity: .12; }
.map__pin { fill: var(--fg); transition: fill var(--dur) ease; }

.ev__loc-text { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }
.ev__loc-text strong { font-size: 0.85rem; font-weight: 600; color: var(--fg); }
.ev__loc-text > span { font-size: 0.75rem; color: var(--fg-muted); }

.ev__links { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 0.15rem; }

.ev__link {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--fg);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}

.ev__link .app-icon { width: 12px; height: 12px; stroke-width: 1.5; }

.ev__lesson { margin-top: 0.3rem; }

.ev__rsvp { display: flex; flex-direction: column; gap: 0.35rem; }
.ev__rsvp-top { display: flex; align-items: baseline; justify-content: space-between; gap: 0.5rem; }
.ev__rsvp-count { font-size: 0.75rem; font-weight: 600; color: var(--fg); }
.ev__rsvp-detail { font-size: 0.72rem; color: var(--fg-muted); }

@media (max-width: 560px) {
  .ev__map { width: 76px; height: 54px; }
}

/* --- Audience toggle (features bento) ---
   Without JS both panels render, each with its own heading, so nothing
   is hidden from a reader or a crawler. site.js adds .has-js, which
   reveals the control and lets it hide the inactive panel. */

.aud { display: flex; }

.aud__toggle { display: none; }

html.has-js .aud__toggle {
  display: inline-flex;
  gap: 0.25rem;
  padding: 4px;
  margin-bottom: clamp(1.5rem, 3vw, 2rem);
  background: var(--av);
  border: 1px solid var(--bd);
  border-radius: var(--radius-full);
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

.aud__btn {
  font: inherit;
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--fg-muted);
  padding: 0.5rem 1rem;
  border: 0;
  border-radius: var(--radius-full);
  background: none;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--dur) ease, color var(--dur) ease;
}

.aud__btn.is-active {
  background: var(--primary);
  color: var(--primary-text);
}

.aud__label {
  margin: 0 0 1rem;
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--fg-muted);
}

html.has-js .aud__label { display: none; }
html.has-js .aud__panel + .aud__panel { margin-top: 0; }
.aud__panel + .aud__panel { margin-top: clamp(2rem, 4vw, 3rem); }

@media (prefers-reduced-motion: no-preference) {
  html.has-js .aud__panel { animation: aud-in 0.3s ease both; }
}

@keyframes aud-in {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}

@media (max-width: 460px) {
  .aud__btn { font-size: 0.82rem; padding: 0.45rem 0.7rem; }
}

.bento {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: clamp(1rem, 2vw, 1.5rem);
}

.bento__card {
  display: flex;
  flex-direction: column;
  padding: clamp(1.5rem, 2.5vw, 2.25rem);
  background: var(--av);
  border: 1px solid var(--bd);
  border-radius: var(--radius-md);
  box-shadow: 0 12px 24px -8px rgba(0, 0, 0, calc(.12 * var(--sh))),
              inset 0 1px 0 var(--rim);
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

.bento__vignette {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 1.5rem;
}

.bento__title {
  margin: 0 0 0.5rem;
  font-size: 1.25rem;
  font-weight: 500;
  letter-spacing: -0.01em;
}

.bento__copy {
  margin: 0;
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--fg-muted);
}

.bento__card--half { grid-column: span 3; }
.bento__card--third { grid-column: span 2; }

.bento__card--wide {
  grid-column: span 4;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr);
  align-items: center;
  gap: clamp(1.5rem, 3vw, 2.5rem);
}

.bento__card--wide .bento__vignette { margin-bottom: 0; }

/* --- Church-leadership bento (Figma 24194:926) ---
   Two "bleed" cards on the top row: the mock runs past the card's edge and
   the copy sits in a gradient scrim over it. Both mocks size themselves off
   the card width in cqw with everything inside in em, the same
   size-independent trick the empathy phone uses — tune once, correct at
   every viewport. Do not reintroduce px/rem inside .ovc or .evc. */

/* the Figma row heights only hold once there is room for them; below this
   the copy outgrows a fixed row and gets clipped, so let the rows size
   themselves */
@media (min-width: 1100px) {
  .bento--lead { grid-template-rows: clamp(400px, 31vw, 450px) clamp(330px, 25vw, 360px); }
}

.bento__card--bleed { position: relative; padding: 0; overflow: hidden; }

/* min-height:0 lets the mock grow past this box; the card clips it and the
   scrim below paints over the tail */
.bento__bleed {
  flex: 1;
  min-height: 0;
  padding: 0.75rem;
  container-type: inline-size;
}

/* z-index is load-bearing: .bento__bleed carries container-type, whose
   implied `contain: layout` makes it a stacking context that otherwise
   paints the overflowing mock straight over this scrim. */
.bento__overlay {
  position: relative;
  z-index: 1;
  padding: 2.75rem clamp(1.25rem, 2vw, 1.5rem) clamp(1.25rem, 2vw, 1.5rem);
  background: linear-gradient(to bottom, var(--pg-30), var(--pg));
}

/* the dashboard card fades behind a frosted scrim instead of a solid one,
   so the table keeps reading as a table underneath */
.bento__overlay--frost {
  padding: clamp(1.25rem, 2vw, 1.5rem);
  background: linear-gradient(to bottom, var(--pg-30), var(--pg) 59%);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
}

/* --- Org overview mock (bleed card 1) ---
   Rings show completion rates, which is exactly the scope --accent is
   sanctioned for (see Principles). r=15.9155 makes the circumference
   exactly 100, so stroke-dasharray reads as the percentage directly. */

.ovc {
  font-size: clamp(9px, 1.754cqw, 11px);
  display: flex;
  flex-direction: column;
  background: var(--pg);
  border: 1px solid var(--bd);
  border-radius: 0.52em;
  box-shadow: 0 0.78em 1.57em rgba(0, 0, 0, calc(.05 * var(--sh)));
  overflow: hidden;
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

.ovc__head {
  display: flex;
  flex-direction: column;
  gap: 0.39em;
  padding: 1.04em;
  border-bottom: 1px solid var(--bd);
  transition: border-color var(--dur) ease;
}

.ovc__head strong { font-size: 1.57em; font-weight: 700; color: var(--fg); }
.ovc__head span { font-size: 0.91em; line-height: 1.28; font-weight: 500; color: var(--fg-muted); }

.ovc__rings {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 2.09em;
  padding: 1.57em 2.09em;
}

.ovc__metric { display: flex; flex-direction: column; align-items: center; gap: 1.04em; }
.ovc__metric-text { display: flex; flex-direction: column; gap: 0.26em; width: 100%; }
.ovc__metric-text b { font-size: 1.04em; font-weight: 700; color: var(--fg); }
.ovc__metric-text span { font-size: 0.78em; line-height: 1.3; color: var(--fg-muted); }

.ovc__ring { width: 7.83em; height: 7.83em; }
.ovc__ring svg { width: 100%; height: 100%; display: block; }

.ring__track { stroke: var(--bd); transition: stroke var(--dur) ease; }
.ring__val { stroke: var(--accent); transition: stroke var(--dur) ease; }

.ring__pct {
  fill: var(--fg);
  font-family: inherit;
  font-size: 9px;
  font-weight: 700;
  transition: fill var(--dur) ease;
}

.ovc__stats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1.04em;
  padding: 1.04em 2.09em 1.83em;
}

.ovc__stat { display: flex; flex-direction: column; gap: 0.52em; }
.ovc__stat-num { display: flex; align-items: center; gap: 0.65em; }

.ovc__icon {
  width: 1.3em;
  height: 1.3em;
  flex: none;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
  color: var(--fg-muted);
}

.ovc__stat-num b { font-size: 2.09em; font-weight: 700; line-height: 1; color: var(--fg); }
.ovc__stat-label { font-size: 0.78em; line-height: 1.17; font-weight: 500; color: var(--fg-muted); }

.ovc__table { display: flex; flex-direction: column; }

.ovc__tr {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 6.52em 6.52em 9.13em 7.17em 7.17em;
  align-items: center;
  gap: 1.3em;
  padding: 1.04em 2.09em;
  border-bottom: 1px solid var(--bd);
  transition: border-color var(--dur) ease;
}

.ovc__tr > span {
  font-size: 0.91em;
  color: var(--fg);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ovc__tr > span:first-child { font-size: 0.98em; font-weight: 700; }

.ovc__tr--head {
  padding: 0.91em 2.09em;
  background: var(--av);
  border-top: 1px solid var(--bd);
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

.ovc__tr--head > span,
.ovc__tr--head > span:first-child { font-size: 0.85em; font-weight: 600; }

/* --- Tilted event card (bleed card 2) ---
   The isometric transform is the Figma one verbatim: rotate, then flatten
   on y, then skew on x. Order matters — reordering these three reads as a
   different plane. */

.bento__bleed--iso { display: grid; place-items: center; padding: 0; }

.iso {
  font-size: clamp(9px, 2.74cqw, 18px);
  transform: rotate(-18.43deg) scaleY(.89) skewX(26.57deg);
}

.evc {
  width: 22.08em;
  height: 20.8em;
  display: flex;
  flex-direction: column;
  gap: 0.5em;
  padding: 1em;
  background: var(--pg);
  border: 0.06em solid var(--bd);
  border-radius: 0.5em;
  /* the flat ledge survives dark mode; the cast shadow rides --sh */
  box-shadow: 0 0.27em 0 var(--bd),
              0.4em 0.68em 0.68em rgba(0, 0, 0, calc(.2 * var(--sh)));
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

.evc__event { display: flex; gap: 0.75em; }

.evc__badge {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 3em;
  height: 3.25em;
  flex: none;
  border: 0.06em solid var(--bd);
  border-radius: 0.5em;
  transition: border-color var(--dur) ease;
}

.evc__badge b { font-size: 1.25em; font-weight: 700; color: var(--fg); }
.evc__badge small { font-size: 0.69em; text-transform: uppercase; color: var(--fg-muted); }

.evc__meta { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.evc__topline { display: flex; align-items: center; justify-content: space-between; gap: 0.5em; }
.evc__topline strong { font-size: 1.13em; font-weight: 700; color: var(--fg); }
.evc__topline > span { font-size: 1em; font-weight: 700; color: var(--fg); }
.evc__host { font-size: 0.81em; color: var(--fg-muted); }
.evc__addr { font-size: 0.75em; font-style: italic; color: var(--fg-muted); }

.evc__foot { display: flex; align-items: center; justify-content: space-between; gap: 0.5em; }
.evc__foot > span { font-size: 0.81em; color: var(--fg-muted); }

.evc__chip {
  padding: 0.46em 0.92em;
  border-radius: 0.46em;
  background: var(--success-30);
  color: var(--success);
  font-size: 0.81em;
  font-weight: 700;
  white-space: nowrap;
  transition: background var(--dur) ease, color var(--dur) ease;
}

.evc__block { display: flex; flex-direction: column; gap: 0.5em; }
.evc__label { font-size: 0.81em; font-weight: 500; color: var(--fg-muted); }
.evc__assign { margin: 0; font-size: 0.94em; font-weight: 700; line-height: 1.4; color: var(--fg); }

.evc__lesson {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5em;
  padding: 0.75em;
  background: var(--pg);
  border: 0.06em solid var(--bd);
  border-radius: 0.5em;
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

.evc__lesson-text { display: flex; flex-direction: column; gap: 0.25em; min-width: 0; }
.evc__lesson-text span { font-size: 0.81em; color: var(--fg-muted); }
.evc__lesson-text strong { font-size: 1em; font-weight: 700; color: var(--fg); }
.evc__lesson-text small { font-size: 0.69em; color: var(--fg-muted); }

.evc__chevron {
  width: 1.25em;
  height: 1.25em;
  flex: none;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  color: var(--fg-muted);
}

/* --- Attendance vignette (row 2, narrow card) --- */

.bento__vignette--att { align-items: stretch; }

.att { display: flex; flex-direction: column; gap: 0.9rem; width: 100%; }

.att__chart { display: flex; align-items: flex-end; gap: 6px; height: clamp(72px, 9vw, 96px); }

.att__chart i {
  flex: 1;
  height: var(--h);
  min-width: 0;
  background: var(--accent-30);
  border-radius: 3px 3px 0 0;
  transition: background var(--dur) ease;
}

.att__chart i.is-now { background: var(--accent); }

/* the wide card carries the display-size heading in the Figma layout */
.bento__title--display { font-size: clamp(1.6rem, 2.4vw, 2rem); font-weight: 700; }

@media (max-width: 1099px) {
  .bento__bleed { min-height: 280px; }
}

/* a container query, not a viewport one: these cards go full-width when the
   grid stacks, so viewport width says nothing about how much room the table
   actually has */
@container (max-width: 480px) {
  .ovc__tr { grid-template-columns: minmax(0, 1fr) 6.52em 6.52em; }
  .ovc__tr > span:nth-child(n + 4) { display: none; }
}

/* --- Steps ("how it works") section --- */

.steps {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: clamp(2rem, 5vw, 4rem) clamp(1.5rem, 4vw, 4rem);
}

.bento__card--third-wide { grid-column: span 2; }

.step-num {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  margin-bottom: 1.25rem;
  border-radius: var(--radius-full);
  background: var(--pg);
  border: 1px solid var(--bd);
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--fg-muted);
  transition: background var(--dur) ease, border-color .6s ease,
              color .6s ease, box-shadow .6s ease;
}

/* Completion glow — the accent's ONLY sanctioned home (see DESIGN.md).
   Lit by motion.js as each step lands; ships lit when JS is absent. */
.step-num.is-lit {
  border-color: var(--accent);
  color: var(--accent);
  box-shadow: 0 0 0 5px var(--accent-15), 0 0 18px var(--accent-30);
}

html:not(.js-motion) .step-num {
  border-color: var(--accent);
  color: var(--accent);
  box-shadow: 0 0 0 5px var(--accent-15), 0 0 18px var(--accent-30);
}

.steps__cta {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem; /* Rule: 16px between a button and its supporting text */
  margin-top: clamp(2rem, 4vw, 3rem);
  text-align: center;
}

/* Mock UI vignettes — built from tokens only, echoing real app surfaces */

.mock {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
}

.mock__row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.625rem 0.875rem;
  background: var(--pg);
  border: 1px solid var(--bd);
  border-radius: var(--radius-md);
  box-shadow: 0 4px 10px rgba(0, 0, 0, calc(.06 * var(--sh)));
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

.mock__meta {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
}

.mock__meta strong {
  font-size: 0.9rem;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.mock__meta span {
  font-size: 0.75rem;
  color: var(--fg-muted);
}

.mock__note {
  font-size: 0.75rem;
  color: var(--fg-muted);
  text-align: center;
  padding-top: 0.25rem;
}


.mock-avatar {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-full);
  background: var(--av);
  border: 1px solid var(--bd);
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--fg-muted);
  flex-shrink: 0;
}

.mock-chip {
  padding: 0.25rem 0.625rem;
  border-radius: var(--radius-full);
  background: var(--av);
  border: 1px solid var(--bd);
  font-size: 0.7rem;
  font-weight: 500;
  color: var(--fg-muted);
  white-space: nowrap;
}
.mock__row--ghost {
  justify-content: center;
  background: transparent;
  border-style: dashed;
  box-shadow: none;
  font-size: 0.85rem;
  color: var(--fg-muted);
}

.mock-chip--action {
  background: var(--primary);
  color: var(--primary-text);
  border-color: transparent;
  font-weight: 600;
}


.mock-date {
  width: 40px;
  padding: 0.25rem 0;
  text-align: center;
  background: var(--av);
  border: 1px solid var(--bd);
  border-radius: var(--radius-sm);
  flex-shrink: 0;
}

.mock-date b { display: block; font-size: 0.95rem; }
.mock-date small { display: block; font-size: 0.65rem; text-transform: uppercase; color: var(--fg-muted); }

.mock-avatars { display: flex; }
.mock-avatars .mock-avatar { border: 2px solid var(--av); margin-left: -8px; background: var(--pg); }
.mock-avatars .mock-avatar:first-child { margin-left: 0; }
.mock-avatar--more { font-size: 0.65rem; }

/* photo avatars: the initials treatment stays the default everywhere the
   cast isn't the point */
.mock-avatar--photo { overflow: hidden; background: var(--av); }
.mock-avatar--photo img { width: 100%; height: 100%; display: block; object-fit: cover; border-radius: inherit; }



.mock-caption {
  font-size: 0.75rem;
  color: var(--fg-muted);
}

/* Real-app vignette pieces — keep AFTER all base .mock* rules (cascade) */

.mock-progress {
  display: block;
  height: 6px;
  border-radius: var(--radius-full);
  background: var(--bd);
  overflow: hidden;
  transition: background var(--dur) ease;
}

.mock-progress i {
  display: block;
  height: 100%;
  width: var(--p, 0%);
  background: var(--fg-muted);
  border-radius: inherit;
  transform-origin: left center;
  transition: background var(--dur) ease;
}


.mock-member {
  display: flex;
  align-items: center;
  gap: 0.625rem;
}

.mock-member__info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}

.mock-member__info strong {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--fg);
}

.mock-member__pct {
  font-size: 0.75rem;
  color: var(--fg-muted);
}

.mock-tabs {
  display: flex;
  gap: 0.875rem;
  font-size: 0.72rem;
  font-weight: 500;
  color: var(--fg-muted);
  border-bottom: 1px solid var(--bd);
  transition: border-color var(--dur) ease;
}

.mock-tabs span { padding-bottom: 0.45rem; }

.mock-tabs .is-active {
  color: var(--fg);
  box-shadow: inset 0 -2px 0 var(--fg);
}

.mock-post {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.625rem;
  background: var(--pg);
  border: 1px solid var(--bd);
  border-radius: var(--radius-md);
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

.mock-post__head { display: flex; align-items: center; gap: 0.5rem; }

.mock-post p {
  margin: 0;
  font-size: 0.78rem;
  line-height: 1.45;
  color: var(--fg);
}

.mock-post__stats { font-size: 0.68rem; color: var(--fg-muted); }

/* In-frame app screens (CTA phone now; empathy phone reuses this) */

.app-screen {
  height: 100%;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  padding: 0.875rem 0.75rem;
}

.app-screen .mock__row { padding: 0.5rem 0.625rem; }
.app-screen .mock__meta strong { font-size: 0.78rem; }
.app-screen .mock__meta span { font-size: 0.66rem; }
.app-screen .mock-avatar { width: 26px; height: 26px; font-size: 0.58rem; }

.app-screen__title {
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--fg);
}

.app-screen__label { font-size: 0.7rem; font-weight: 600; color: var(--fg); }
.app-screen__tagline { font-size: 0.66rem; color: var(--fg-muted); line-height: 1.4; }
.app-screen__badge { align-self: center; margin-top: auto; }

.mock-avatar--org { border-radius: var(--radius-md); }

/* --- Figma-sourced app screens (group detail: Events + Curriculum) ---
   Recreated from the Uncomn app designs. Everything is token-driven so
   both themes work; --success is the one semantic color allowed here and
   it is limited to status (Going chip, attendance checkmark). Keep these
   rules AFTER the base .mock* rules — same specificity, source order
   decides. */

/* Screen chrome */

.app-screen--detail { gap: 0.4rem; padding: 0.7rem 0.6rem 0.5rem; }

.app-screen__statusbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-top: 0.9rem; /* clears the notch */
  font-size: 0.52rem;
  font-weight: 600;
  color: var(--fg);
}

.app-screen__statusbar i {
  display: inline-block;
  width: 0.36em;
  height: 0.72em;
  margin-left: 0.18em;
  border-radius: 0.12em;
  background: var(--fg);
}

.app-screen__statusbar i:nth-child(1) { margin-left: 0; }
.app-screen__statusbar i:nth-child(2) { height: 0.96em; }
.app-screen__statusbar i:nth-child(3) { height: 1.2em; }

/* signal, wi-fi and battery, sized off the status bar's own font-size
   so the same markup works on the rem-based CTA screen and the
   cqw-based empathy screen without a second set of numbers */
.app-screen__status-right {
  display: flex;
  align-items: center;
  gap: 0.34em;
}

.app-screen__status-right .status-bars { display: flex; align-items: flex-end; }

.app-screen__status-right svg {
  height: 0.86em;
  width: auto;
  flex: none;
  color: var(--fg);
}

.app-screen__nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  color: var(--fg);
}

.app-screen__nav-right { display: flex; align-items: center; gap: 0.62rem; }

.app-icon {
  width: 13px;
  height: 13px;
  flex: none;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* the brand back arrow: a filled path on an 18x14 viewBox, so it needs
   fill instead of stroke and an auto width to keep its ratio. Must sit
   after .app-icon — same specificity, source order decides. */
.app-icon--back {
  width: auto;
  height: 11px;
  fill: currentColor;
  stroke: none;
}

.app-screen__h1 {
  font-size: 0.98rem;
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.01em;
  color: var(--fg);
}

.app-screen__desc {
  font-size: 0.6rem;
  line-height: 1.45;
  color: var(--fg-muted);
}

.app-screen__tagrow {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  color: var(--fg-muted);
}

.app-screen__tagrow .mock-chip { flex: none; background: var(--bd); border-color: transparent; color: var(--fg); }
.app-screen__tagrow span { font-size: 0.56rem; flex: 1; min-width: 0; }

/* Pill tabs (the app underlines nothing — the active tab is a pill) */

.mock-tabs--pill {
  gap: 0.25rem;
  border-bottom: 0;
  font-size: 0.6rem;
}

.mock-tabs--pill span {
  padding: 0.2rem 0.4rem;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
}

.mock-tabs--pill .is-active {
  box-shadow: none;
  border-color: var(--fg);
  font-weight: 600;
}

/* Panels and rows */

.mock-panel {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  padding: 0.55rem;
  background: var(--pg);
  border: 1px solid var(--bd);
  border-radius: var(--radius-md);
  box-shadow: 0 6px 14px -8px rgba(0, 0, 0, calc(.12 * var(--sh)));
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

.mock-panel__head strong { display: block; font-size: 0.76rem; font-weight: 700; color: var(--fg); }
.mock-panel__head span { display: block; font-size: 0.56rem; color: var(--fg-muted); }

.mock-eventrow { display: flex; align-items: flex-start; gap: 0.45rem; }
.mock-eventrow .mock__meta { flex: 1; min-width: 0; }
.mock-eventrow .mock__meta strong { font-size: 0.7rem; font-weight: 700; }
.mock-eventrow .mock__meta span { font-size: 0.55rem; white-space: normal; }
.mock-eventrow__time { font-size: 0.58rem; font-weight: 600; color: var(--fg); white-space: nowrap; }

.mock-label {
  /* negative margin tightens label-to-content against the parent's flex
     gap, so the label groups with what it introduces */
  margin-bottom: -0.15em;
  font-size: 0.5rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--fg-muted);
}

.mock-lesson {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  padding: 0.45rem 0.5rem;
  border: 1px solid var(--bd);
  border-radius: var(--radius-md);
  transition: border-color var(--dur) ease;
}

.mock-lesson__top { display: flex; align-items: center; justify-content: space-between; gap: 0.35rem; color: var(--fg-muted); }
.mock-lesson__top span { font-size: 0.58rem; color: var(--fg); }
.mock-lesson b { font-size: 0.82rem; font-weight: 700; color: var(--fg); }
.mock-lesson small { font-size: 0.52rem; color: var(--fg-muted); }

.mock-leadrow { display: flex; align-items: center; justify-content: space-between; gap: 0.35rem; }
.mock-leadrow span { font-size: 0.56rem; color: var(--fg-muted); }

.mock-chip--success {
  background: var(--success-15);
  border-color: transparent;
  color: var(--success);
  font-weight: 600;
}

.mock-statusrow {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.3rem 0.45rem;
  background: var(--av);
  border-radius: var(--radius-sm);
  font-size: 0.54rem;
  color: var(--fg-muted);
  transition: background var(--dur) ease;
}

.mock-statusrow b { font-weight: 700; color: var(--fg); }
.mock-statusrow .mock-check { margin-left: auto; width: 10px; height: 10px; color: var(--success); }

/* margin:0 is load-bearing — this renders as a <p>, and the UA default
   1em margin put it at ~14px inside a panel whose rhythm is 5px */
.mock-note-line { margin: 0; font-size: 0.55rem; line-height: 1.45; color: var(--fg-muted); }

.mock-divider { height: 1px; background: var(--bd); transition: background var(--dur) ease; }

/* Curriculum member rows: the % reads as a chip, not plain text */

.mock-member__pct--chip {
  padding: 0.1rem 0.3rem;
  background: var(--accent-15);
  border-radius: var(--radius-sm);
  font-size: 0.55rem;
  font-weight: 600;
  color: var(--accent);
}

.mock-member__when { font-size: 0.52rem; color: var(--fg-muted); }

/* --- Empathy phone: same screen vocabulary as the CTA, scaled ---
   Every size below is em, and the root font-size is cqw (a share of the
   screen's own width). Content height therefore scales linearly with
   screen width, and so does screen height via the fixed aspect ratio —
   so the fit is size-independent: tune once, correct at every viewport.
   Do not reintroduce rem/px sizes in here or that property is lost. */

.app-screen--empathy {
  /* the empathy section is text-align:center; an app screen is not */
  text-align: left;
  font-size: 4.05cqw;
  gap: 0.5em;
  padding: 0.6em 1.2em 0.4em;
}

.app-screen--empathy .app-screen__statusbar { padding-top: 0.85em; font-size: 0.62em; }

.app-screen--empathy .app-screen__nav-right { gap: 1em; }
.app-screen--empathy .app-icon { width: 1.1em; height: 1.1em; stroke-width: 1.4; }
.app-screen--empathy .app-icon--back { width: auto; height: 1em; }

.app-screen--empathy .app-screen__h1 { font-size: 1.42em; }
.app-screen--empathy .app-screen__desc { font-size: 0.76em; }

.app-screen--empathy .app-screen__tagrow { gap: 0.4em; }
.app-screen--empathy .app-screen__tagrow span { font-size: 0.7em; }
.app-screen--empathy .mock-chip { padding: 0.2em 0.5em; font-size: 0.72em; border-radius: 999px; }

.app-screen--empathy .mock-tabs--pill { gap: 0.25em; font-size: 0.78em; }
.app-screen--empathy .mock-tabs--pill span { padding: 0.22em 0.45em; border-radius: 0.5em; }

.app-screen--empathy .mock-panel { gap: 0.42em; padding: 0.6em; border-radius: 0.6em; }
.app-screen--empathy .mock-panel__head strong { font-size: 0.96em; }
.app-screen--empathy .mock-panel__head span { font-size: 0.72em; }

.app-screen--empathy .mock-eventrow { gap: 0.45em; }
.app-screen--empathy .mock-date { width: 2.6em; height: 2.6em; border-radius: 0.35em; }
.app-screen--empathy .mock-date b { font-size: 1em; }
.app-screen--empathy .mock-date small { font-size: 0.62em; }
.app-screen--empathy .mock-eventrow .mock__meta strong { font-size: 0.9em; }
.app-screen--empathy .mock-eventrow .mock__meta span { font-size: 0.7em; }
.app-screen--empathy .mock-eventrow__time { font-size: 0.74em; }

.app-screen--empathy .mock-label { font-size: 0.62em; }

.app-screen--empathy .mock-lesson { padding: 0.45em 0.5em; border-radius: 0.5em; }
.app-screen--empathy .mock-lesson__top span { font-size: 0.74em; }
.app-screen--empathy .mock-lesson b { font-size: 1.05em; }
.app-screen--empathy .mock-lesson small { font-size: 0.66em; }

.app-screen--empathy .mock-leadrow span { font-size: 0.72em; }
.app-screen--empathy .mock-note-line { margin: 0 0 0.15em; font-size: 0.82em; line-height: 1.5; }

.app-screen--empathy .mock-statusrow { gap: 0.6em; padding: 0.3em 0.45em; font-size: 0.7em; border-radius: 0.35em; }
.app-screen--empathy .mock-statusrow .mock-check { width: 0.95em; height: 0.95em; }

/* --- Message board (CTA phone) ---
   The group's Messages tab: a scrollable thread with a composer pinned to
   the bottom of the screen, so the phone reads as a live conversation
   rather than a second copy of the events screen. */

.mock-thread {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  overflow: hidden;      /* the thread clips like a real scroll view */
}

/* Browser-frame app screen (CTA) */

/* Growth web SVG — same connector language as the hero animation */

.growth-svg { width: 100%; height: auto; display: block; overflow: visible; }

.growth-link {
  fill: none;
  stroke: var(--bd);
  stroke-width: 3.5;
  stroke-linecap: round;
  transition: stroke var(--dur) ease;
}

.growth-link--next { stroke-dasharray: 2 8; }

.growth-node {
  fill: var(--pg);
  stroke: var(--bd);
  stroke-width: 3.5;
  transition: fill var(--dur) ease, stroke var(--dur) ease;
}

.growth-node--next { fill: none; stroke-dasharray: 3 7; }

/* Which face is data on the element (--face), the same convention as --tilt
   and --p elsewhere. Must stay AFTER .growth-node — both are single-class
   selectors, so source order is the only thing deciding whose fill wins. */
.growth-node--photo { fill: var(--face); }

.growth-plus {
  font-size: 14px;
  font-weight: 600;
  fill: var(--fg-muted);
  text-anchor: middle;
  dominant-baseline: middle;
}

.growth-label {
  font-size: 12px;
  font-weight: 500;
  fill: var(--fg-muted);
  text-anchor: middle;
}

@media (max-width: 980px) {
  .bento__card--half,
  .bento__card--third,
  .bento__card--third-wide,
  .bento__card--wide { grid-column: span 6; }
  .bento__card--wide { grid-template-columns: minmax(0, 1fr); }
  .bento__card--wide .bento__vignette { order: -1; }
}

/* --- Hover micro-interactions (pointer devices, motion-tolerant only) --- */

@keyframes dash-march {
  to { stroke-dashoffset: -20; }
}

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .bento__card {
    transition: background var(--dur) ease, border-color var(--dur) ease,
                transform .35s ease, box-shadow .35s ease;
  }

  .bento__card:hover {
    transform: translateY(-3px);
    box-shadow: 0 18px 32px -10px rgba(0, 0, 0, calc(.16 * var(--sh))),
                inset 0 1px 0 var(--rim);
  }

  .bento__card .mock__row {
    transition: background var(--dur) ease, border-color var(--dur) ease,
                transform .3s ease;
  }

  /* groups card: rows step right in sequence */
  .bento__card--half:hover .mock--list .mock__row { transform: translateX(4px); }
  .bento__card--half:hover .mock--list .mock__row:nth-child(2) { transition-delay: .06s; }
  .bento__card--half:hover .mock--list .mock__row:nth-child(3) { transition-delay: .12s; }

  /* growth card: the not-yet link marches toward the next disciple */
  .bento__card--wide:hover .growth-link--next {
    animation: dash-march 1.4s linear infinite;
  }

  /* curriculum card: progress fills brighten */
  .mock-progress i { transition: background .3s ease; }
  .bento__card--third:hover .mock-progress i { background: var(--fg); }

  /* Events card: the lesson lifts off the isometric plane toward the
     viewer. "Toward the viewer" is straight UP on screen, but this element
     inherits .iso's matrix, so a plain translateY would slide it ALONG the
     plane instead. These numbers are that matrix inverted:

       M    = rotate(-18.43deg) scaleY(.89) skewX(26.57deg)
            = [[0.9487, 0.7558], [-0.3162, 0.6624]]
       M⁻¹·(0, -d) = (0.8714d, -1.0938d)

     so translate(0.741em, -0.93em) renders as exactly 0.85em of screen-up.
     Recompute these if the plane ever changes. The shadow stays in LOCAL
     down-right, matching the light direction .evc's own shadow already
     uses. */
  .evc__lesson {
    position: relative;
    z-index: 1;
    box-shadow: 0 0 0 rgba(0, 0, 0, 0);
    transition: transform .35s cubic-bezier(.2, .7, .3, 1),
                box-shadow .35s ease, border-color var(--dur) ease;
  }

  .evc__lesson:hover {
    z-index: 2;
    transform: translate(0.741em, -0.93em) scale(1.035);
    box-shadow: 0.3em 0.5em 0.85em rgba(0, 0, 0, calc(.30 * var(--sh)));
  }

  /* dark mode drops the cast shadow with --sh, so the lift needs separation
     it can keep: a brighter edge and a face lighter than the surface */
  html[data-theme="dark"] .evc__lesson:hover {
    background: var(--bd);
    border-color: var(--fg-muted);
  }
}

/* --- Mobile: stack, drop the leftward nudge --- */

@media (max-width: 720px) {
  .hero {
    grid-template-columns: minmax(0, 1fr);
    min-height: auto;
    padding-top: 3rem;
    padding-bottom: 3rem;
  }

  .hero__animation {
    order: 2;
    margin-top: 2.5rem;
  }

  #wrap {
    margin-inline-start: 0;
  }
}
