/* Daily AI Sprints landing page.
   Tokens come from DESIGN.md (Solarized Native). Do not introduce a colour here
   that is not in that file, and do not give any colour its only definition
   inside a media query. */

/* ---------- Light palette: the base definition ---------- */
/* ---------- Fonts ----------
   Self-hosted from this origin, so a page that collects email addresses makes
   no third-party request. One variable WOFF2 per family, latin subset, weights
   200 to 800, SIL Open Font License 1.1; the licence text sits beside the files
   in assets/fonts/. swap: the fallback stack is legible on its own, so text
   shows at once and re-renders when the file lands. */
@font-face {
  font-family: "Atkinson Hyperlegible Next";
  src: url("../assets/fonts/atkinson-hyperlegible-next-latin.woff2") format("woff2");
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Atkinson Hyperlegible Mono";
  src: url("../assets/fonts/atkinson-hyperlegible-mono-latin.woff2") format("woff2");
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  color-scheme: light;

  --canvas: #fdf6e3;
  --surface: #eee8d5;
  --card: #fdf6e3;
  --text: #073642;
  --muted: #4e6168;
  --border-ui: #657b83;
  --divider: #93a1a1;
  --link: #1a649e;
  --link-hover: #14507f;
  --link-visited: #6d3c9e;
  --cta: #cb4b16;
  --cta-hover: #b7420f;
  --on-cta: #ffffff;
  --accent-text: #9a370c;
  --focus: #1a649e;
  --error: #c0201f;
  --success: #4f6b00;

  /* Brand mark, "outline" treatment: the face always matches the page, so the
     frame and hands are the only marks and the logo reads the same weight in
     both themes. The lockup is a closed two-colour system: --logo-line carries
     this block's --link, the blue of "AI Sprints", and --logo-accent carries
     --accent-text, the orange of "Daily". The hour hand that fixes the clock at
     8:00 is the only accented stroke. Nothing in the mark is body-text navy,
     because nothing in the wordmark is either. */
  --logo-face: #fdf6e3;
  --logo-line: #1a649e;
  --logo-accent: #9a370c;

  --font-body: "Atkinson Hyperlegible Next", "Atkinson Hyperlegible", system-ui,
    -apple-system, "Segoe UI", sans-serif;
  --font-eyebrow: "Atkinson Hyperlegible Mono", ui-monospace, SFMono-Regular,
    Consolas, monospace;

  --space-xs: 0.25rem;
  --space-sm: 0.5rem;
  --space-md: 1rem;
  --space-lg: 1.5rem;
  --space-xl: 2rem;
  --space-xxl: 3rem;
  --space-section: 4rem;
  --space-hero: 4rem;

  --radius: 6px;
  --container-max: 1200px;
  --container-narrow: 800px;
  --reading-width: 68ch;
  --target-min: 44px;
}

/* System preference resolves to dark, unless the visitor explicitly chose light. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;

    --canvas: #002b36;
    --surface: #073642;
    --card: #0a3a47;
    --text: #eee8d5;
    --muted: #93a1a1;
    --border-ui: #839496;
    --divider: #586e75;
    --link: #6fb6ee;
    --link-hover: #9ccdf5;
    --link-visited: #c7a6e8;
    --cta: #f08a4b;
    --cta-hover: #f59b63;
    --on-cta: #002b36;
    --accent-text: #f59b63;
    --focus: #b58900;
    --error: #ff9c93;
    --success: #7dc77a;

    --logo-face: #002b36;
    --logo-line: #6fb6ee;
    --logo-accent: #f59b63;
  }
}

/* Explicit dark choice wins regardless of the OS setting. */
:root[data-theme="dark"] {
  color-scheme: dark;

  --canvas: #002b36;
  --surface: #073642;
  --card: #0a3a47;
  --text: #eee8d5;
  --muted: #93a1a1;
  --border-ui: #839496;
  --divider: #586e75;
  --link: #6fb6ee;
  --link-hover: #9ccdf5;
  --link-visited: #c7a6e8;
  --cta: #f08a4b;
  --cta-hover: #f59b63;
  --on-cta: #002b36;
  --accent-text: #f59b63;
  --focus: #b58900;
  --error: #ff9c93;
  --success: #7dc77a;

  --logo-face: #002b36;
  --logo-line: #6fb6ee;
  --logo-accent: #f59b63;
}

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

body {
  margin: 0;
  background: var(--canvas);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 1.125rem;
  line-height: 1.55;
}

h1,
h2,
h3 {
  margin: 0;
  line-height: 1.2;
  text-wrap: balance;
}

h1 {
  font-size: 3.5rem;
}
h2 {
  font-size: 2rem;
}
h3 {
  font-size: 1.5rem;
  line-height: 1.25;
}

p {
  margin: 0;
  max-width: var(--reading-width);
}

/* Body links keep their underline in every state, including hover. */
a {
  color: var(--link);
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-thickness: 1px;
}

a:hover {
  color: var(--link-hover);
  text-decoration-thickness: 2px;
}

a:visited {
  color: var(--link-visited);
}

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

/* ---------- Layout ---------- */
.container {
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--space-md);
}

.band {
  padding-block: var(--space-section);
}

.band--tinted {
  background: var(--surface);
}

/* ---------- Visually hidden ----------
   One definition of the clip technique, for anything the eye does not need
   but assistive technology does. Not display:none and not visibility:hidden:
   either would take the element out of the accessibility tree along with the
   pixels, and would drop a focusable control out of the tab order.

   The theme radios are here for that second reason. They have to stay
   focusable, because their labels are the whole visible control. */
.visually-hidden,
.theme-choice input {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---------- Skip link ---------- */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 10;
  background: var(--card);
  color: var(--link);
  border: 1px solid var(--border-ui);
  border-radius: var(--radius);
  padding: var(--space-sm) var(--space-md);
  min-height: var(--target-min);
  display: inline-flex;
  align-items: center;
  font-weight: 600;
}

.skip-link:focus {
  left: var(--space-md);
  top: var(--space-md);
}

/* ---------- Header ---------- */
.site-header {
  background: var(--canvas);
  border-bottom: 1px solid var(--divider);
}

.site-header .container {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md);
  align-items: center;
  justify-content: space-between;
  padding-block: var(--space-md);
}

/* The whole lockup is one link to home, so the mark and the words cannot be
   tabbed to separately. */
.brand {
  display: flex;
  align-items: center;
  /* Between --space-sm and --space-md. The mark's frame is a solid stroke and
     needs more air against the type than 8px gives it. */
  gap: 0.75rem;
  min-width: 0;
  color: inherit;
  text-decoration: none;
}

.brand:hover,
.brand:visited {
  color: inherit;
  text-decoration: none;
}

.brand-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.brand-name {
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1.1;
}

/* Two-tone wordmark, the same split Rapid AI Sprints uses: warm on the first
   word, cool on the rest, and neither is body text. Borrowing the link colour
   for "AI Sprints" is safe here only because the entire lockup is itself a
   link to home, so it cannot mislead anyone about what is clickable.
   Light 6.65:1 and 5.79:1, dark 6.97:1 and 6.86:1. */
.brand-name-accent {
  color: var(--accent-text);
}

.brand-name-cool {
  color: var(--link);
}

.brand-tagline {
  font-size: 0.875rem;
  color: var(--muted);
  line-height: 1.3;
}

/* The mark carries no fill of its own. Three tokens colour it, which is the
   whole reason one file serves both themes. */
.dais-mark {
  width: 48px;
  height: 48px;
  flex: none;
}

.dais-mark__face {
  fill: var(--logo-face);
  stroke: var(--logo-line);
}

.dais-mark__hand {
  stroke: var(--logo-line);
  stroke-linecap: round;
}

/* The hour hand is the only accented stroke. It is what says 8:00 rather than
   leaving the face a generic clock, so it is the part worth colouring.
   Declared after .dais-mark__hand: same specificity, so source order wins. */
.dais-mark__hand--hour {
  stroke: var(--logo-accent);
}

/* The "now" marker, added by script (see index.html): a dot on the inside of
   the frame at the visitor's local hour. Muted because it is decoration and
   carries nothing a visitor needs, so it is exempt from contrast. Between
   08:00 and 08:45, while the sprint is live, it takes the accent so the mark
   reads "8, and it is 8 now". The two states are the only ones there are. */
.dais-mark__now {
  fill: var(--muted);
}

.dais-mark__now--live {
  fill: var(--logo-accent);
}

/* Both options sit on a surface track, at the 6px radius the rest of the page
   uses. Tailwind, HeroUI and fumadocs all draw this control as a pill, and
   DESIGN.md rules pill shapes out: the squarer geometry is part of what makes
   the page read as Solarized.

   position: relative contains the absolutely positioned legend and radios. */
.theme-choice {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 2px;
  margin: 0;
  padding: 3px;
  background: var(--surface);
  border: 1px solid var(--border-ui);
  border-radius: var(--radius);
}

/* The radios themselves are clipped by the visually-hidden rule above.
   The label is the whole target, so it carries the 44px minimum rather than
   the 1px input it names. Inner radius is the outer radius less the track
   padding, so the chip sits concentric inside the track. */
.theme-choice label {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.45em;
  min-width: var(--target-min);
  min-height: var(--target-min);
  padding-inline: 0.7em;
  color: var(--muted);
  border-radius: calc(var(--radius) - 3px);
  font-size: 0.9375rem;
  font-weight: 600;
  cursor: pointer;
}

.theme-choice svg {
  width: 20px;
  height: 20px;
  flex: none;
  stroke-width: 1.9;
}

/* The live option takes the link blue as a solid fill, with its icon and word
   on canvas. Roughly 5.6:1 against the track in light and 7.6:1 in dark, where
   SC 1.4.11 asks 3:1 of a control carrying state.

   The fill is a hue on purpose. Marking this particular control with a tone
   backfires, because tone is the subject: filling the live option with text
   makes a dark block say "Light" in the light theme and a bright block say
   "Dark" in the dark one, so the colour contradicts the word it sits under.
   Blue belongs to neither theme, so it can only mean "this one is on". It is
   blue rather than the warm accent because the header must not carry the
   loudest colour on the page; that belongs to the hero's call to action.

   The tonal chip that Tailwind, HeroUI and fumadocs use is a canvas-on-surface
   step, 1.14:1 here, and a tonal step is not a boundary. Four cues stack in
   this version, fill, position, stroke weight and the word, so nothing rests
   on colour alone and it survives a blurred glance. */
.theme-choice input:checked + label {
  background: var(--link);
  color: var(--canvas);
}

.theme-choice input:checked + label svg {
  stroke-width: 2.4;
}

/* The input is clipped to a pixel, so the outline has to be drawn on the
   label the visitor is actually looking at. */
.theme-choice input:focus-visible + label {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
}

/* ---------- Hero ---------- */
.hero {
  background: var(--surface);
  padding-block: var(--space-hero);
}

.hero-eyebrow {
  font-family: var(--font-eyebrow);
  font-size: 0.875rem;
  line-height: 1.4;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 var(--space-sm);
}

/* A class, not ".hero p": the eyebrow is also a paragraph in the hero, and
   so is every step in the rail. */
.hero-lede {
  font-size: 1.1875rem;
  line-height: 1.7;
  color: var(--muted);
  margin-block: var(--space-md) var(--space-lg);
}

.hero-layout {
  display: grid;
  gap: var(--space-xl);
  align-items: start;
}

/* Top-aligned, not centred: the copy block is shorter than the rail, and
   centring it left the headline floating in the middle of the band with the
   eyebrow's cap line meeting nothing. Now it meets the rail's top edge. */
@media (min-width: 1000px) {
  .hero-layout {
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
    gap: var(--space-xxl);
    align-items: start;
  }
}

/* The rail explains the core session rather than introducing another offer.
   border-ui on the edge, like every card: the step from card to band is about
   1.14:1, and a reader with low vision needs the edge to see what belongs
   together. The input is told apart from cards by weight, not by tone. */
.session-rail {
  background: var(--card);
  border: 1px solid var(--border-ui);
  border-radius: var(--radius);
  padding: var(--space-lg);
}

.session-rail__title {
  font-family: var(--font-eyebrow);
  font-size: 0.875rem;
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 var(--space-md);
}

.session-rail__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.session-rail__list li {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--space-md);
  padding-block: var(--space-md);
  border-top: 1px solid var(--divider);
}

.session-rail__list h3 {
  font-size: 1.125rem;
  margin-bottom: var(--space-xs);
}

.session-rail__list p {
  color: var(--muted);
  font-size: 1rem;
  line-height: 1.5;
  margin: 0;
}

.session-rail__num {
  font-family: var(--font-eyebrow);
  font-size: 0.875rem;
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: 0.06em;
  color: var(--accent-text);
  font-variant-numeric: tabular-nums;
}

/* ---------- Actions ---------- */
.action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--target-min);
  padding: var(--space-sm) var(--space-lg);
  background: var(--cta);
  color: var(--on-cta);
  border: 0;
  border-radius: var(--radius);
  font-family: inherit;
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.4;
  text-decoration: none;
  cursor: pointer;
}

.action:hover,
.action:visited {
  background: var(--cta-hover);
  color: var(--on-cta);
  text-decoration: none;
}

/* The hero's action is the one the page exists for, so it gets a larger label
   and a taller target than the card actions. */
.hero .action {
  min-height: 52px;
  padding: var(--space-md) var(--space-xl);
  font-size: 1.0625rem;
}

/* The secondary action starts a conversation rather than a checkout. Outlined
   in the link colour so the page keeps exactly one solid orange button per
   card row. Declared after .action:visited so a visited secondary link does not
   turn into a primary one. */
.action--secondary,
.action--secondary:visited {
  background: transparent;
  color: var(--link);
  border: 1px solid var(--link);
}

.action--secondary:hover {
  background: var(--surface);
  color: var(--link-hover);
  border-color: var(--link-hover);
}

/* ---------- Membership ---------- */
.membership-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-lg);
  margin-block: var(--space-lg) var(--space-md);
  padding: 0;
  list-style: none;
}

/* Each card is a flex column so actions align within each grid row even when
   the offer descriptions have different lengths. */
.membership-card {
  display: flex;
  flex-direction: column;
  background: var(--card);
  border: 1px solid var(--border-ui);
  border-radius: var(--radius);
  padding: var(--space-lg);
}

.membership-card p {
  color: var(--muted);
  margin-block: var(--space-sm);
}

.membership-card__kicker {
  font-family: var(--font-eyebrow);
  font-size: 0.875rem;
  line-height: 1.4;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin: 0 0 var(--space-xs);
}

/* Scoped to the card on purpose. A bare .price loses to the .membership-card p
   rule above, which is one class plus an element and therefore more specific,
   so the price rendered in muted grey rather than accent for as long as both
   rules have existed. The design-system gate caught it; no human review did. */
.membership-card .price {
  color: var(--accent-text);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  margin-block: var(--space-sm) var(--space-lg);
}

.membership-card .action {
  margin-top: auto;
  align-self: flex-start;
}

.terms {
  color: var(--muted);
  font-size: 0.9375rem;
}

/* What the money actually buys. Approved 2026-08-16, and it has to sit above
   the checkout link rather than below it. */
.access-terms {
  color: var(--muted);
  font-size: 0.9375rem;
  margin-block: 0 var(--space-lg);
}

/* ---------- Progress framework ----------
   Canvas, like every second band. The rules are the boundary against the hero
   above, whose tonal step is only about 1.14:1. */
.band--progress {
  background: var(--canvas);
  border-block: 1px solid var(--divider);
}

.progress-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-lg);
  margin: 0;
  padding: 0;
  list-style: none;
}

.progress-grid li {
  border-top: 2px solid var(--divider);
  padding-top: var(--space-md);
}

.progress-grid__num {
  display: block;
  color: var(--accent-text);
  font-family: var(--font-eyebrow);
  font-size: 0.875rem;
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: 0.06em;
  font-variant-numeric: tabular-nums;
  margin-bottom: var(--space-sm);
}

.progress-grid h3 {
  margin-bottom: var(--space-sm);
}

.progress-grid p {
  color: var(--muted);
}

/* ---------- Bring a problem, leave with something built ---------- */
.pair-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-xl) var(--space-xxl);
  margin-top: var(--space-lg);
}

.pair-grid h3 {
  margin-bottom: var(--space-xs);
}

.pair-grid__note {
  color: var(--muted);
  font-size: 0.9375rem;
  margin-block: 0 var(--space-md);
}

/* Accent markers so the list reads as a set of offers, not a rule list. */
.example-list {
  margin: 0;
  padding-left: var(--space-lg);
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.example-list li::marker {
  color: var(--accent-text);
}

.leave-list {
  list-style: none;
  margin: var(--space-md) 0 0;
  padding: 0;
}

.leave-list li {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--space-md);
  padding-block: var(--space-md);
  border-top: 1px solid var(--divider);
}

/* margin: 0 on top as well. h4 is outside the base heading reset, and the
   browser's 1.33em top margin pushed the heading a line below its numeral. */
.leave-list h4 {
  font-size: 1.125rem;
  margin: 0 0 var(--space-xs);
}

.leave-list p {
  color: var(--muted);
  font-size: 1rem;
  line-height: 1.5;
  margin: 0;
}

.leave-list__num {
  font-family: var(--font-eyebrow);
  font-size: 0.875rem;
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: 0.06em;
  color: var(--accent-text);
  font-variant-numeric: tabular-nums;
}

/* ---------- Questions ---------- */
.faq-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-lg) var(--space-xxl);
  margin-top: var(--space-lg);
}

.faq-grid > div {
  border-top: 1px solid var(--divider);
  padding-top: var(--space-md);
}

.faq-grid h3 {
  font-size: 1.125rem;
  margin-bottom: var(--space-xs);
}

.faq-grid p {
  color: var(--muted);
  font-size: 1rem;
  line-height: 1.5;
}

/* ---------- Team ---------- */
.section-intro {
  color: var(--muted);
  margin-block: var(--space-sm) var(--space-xl);
}

.team-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
  gap: var(--space-lg);
  padding: 0;
  list-style: none;
}

.bio-card {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border-ui);
  border-radius: var(--radius);
  padding: var(--space-lg);
}

/* Photo beside name and credential, all left-aligned, so the card reads as one
   layout top to bottom. */
.bio-card__header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-md);
  margin-bottom: var(--space-lg);
}

/* Below about 14rem of remaining width the text drops under the photo instead
   of wrapping into a six-line column beside it. */
.bio-card__header > div {
  flex: 1 1 14rem;
  min-width: 0;
}

.bio-photo {
  width: 96px;
  height: 96px;
  flex: none;
  border-radius: 50%;
  object-fit: cover;
  border: 1px solid var(--divider);
}

.bio-card h3 {
  margin: 0;
}

/* Muted, not accent: the one warm colour on this page belongs to prices and
   the wordmark, and a job title is not a call to action. */
.bio-role {
  color: var(--muted);
  font-size: 0.9375rem;
  line-height: 1.5;
  margin-block: var(--space-xs) 0;
  max-width: none;
}

/* A left rule, not a background tint: the step from card to surface is about
   1.15:1 and would not read as a boundary on its own. */
.bio-quote {
  margin: 0 0 var(--space-lg);
  padding-left: var(--space-md);
  border-left: 3px solid var(--divider);
  font-style: italic;
}

.bio-quote p {
  color: var(--text);
}

/* A standalone link, not one inside a sentence, so it carries the full 44px
   target the system promises rather than the inline-link exemption. */
.bio-link {
  display: inline-flex;
  align-items: center;
  min-height: var(--target-min);
  margin-top: auto;
  align-self: flex-start;
  font-weight: 600;
}

/* ---------- Newsletter ----------
   Lives in the footer. A small opt-in beside the legal lines, the way most
   sites keep one, rather than a band of its own competing with the offers. */
.newsletter-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  max-width: 30rem;
}

.newsletter-form__title {
  font-size: 1.125rem;
  margin: 0 0 var(--space-xs);
}

.newsletter-form label {
  font-size: 0.9375rem;
  font-weight: 600;
}

.field-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
}

input[type="email"] {
  flex: 1 1 16rem;
  min-height: var(--target-min);
  padding: var(--space-sm);
  font-family: inherit;
  font-size: 1.125rem;
  color: var(--text);
  background: var(--card);
  /* 2px, where cards carry 1px: the one input on the page is told apart from
     the cards around it by weight, so both can share the border-ui tone. */
  border: 2px solid var(--border-ui);
  border-radius: var(--radius);
}

input[type="email"][aria-invalid="true"] {
  border-width: 2px;
  border-color: var(--error);
}

.field-hint {
  color: var(--muted);
  font-size: 0.9375rem;
}

.field-error {
  color: var(--error);
  font-size: 0.9375rem;
  font-weight: 600;
}

.field-error:empty {
  display: none;
}

.form-status {
  color: var(--success);
  font-weight: 600;
}

.form-status:empty {
  display: none;
}

.consent {
  color: var(--muted);
  font-size: 0.9375rem;
}

/* ---------- Footer ----------
   Surface, so the bands keep alternating all the way down: hero tinted,
   the five live-hour bands canvas first, team canvas behind a rule,
   bring-and-leave tinted, progress canvas, membership tinted, questions
   canvas, footer tinted. Two adjacent bands of the same tone read as one
   section, which is why the team band carries a rule. The border remains
   because the tonal step is only about 1.14:1 and is not a boundary on its
   own. */
.site-footer {
  background: var(--surface);
  border-top: 1px solid var(--divider);
  padding-block: var(--space-xl);
}

.site-footer__layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 30rem);
  gap: var(--space-xl) var(--space-xxl);
  align-items: start;
}

.site-footer p {
  color: var(--muted);
  font-size: 0.9375rem;
  margin-block: var(--space-xs);
}

/* The privacy link stands alone on its line, so it gets the full target. The
   consent line's link is inline in a sentence and keeps the exemption. */
.site-footer__meta a {
  display: inline-flex;
  align-items: center;
  min-height: var(--target-min);
}

/* ---------- Live-hour sections ----------
   Five bands, one per stage of the rail, alternating canvas, surface, canvas,
   surface, canvas. Shared pieces first, then one block per section. Every
   image is a labelled placeholder drawn in CSS and inline SVG, so nothing here
   depends on an asset that needs permission. */

/* Odd count of new bands leaves Meet the Team on canvas after a canvas band.
   The rule is the boundary, as on the progress band. */
.band--ruled {
  border-top: 1px solid var(--divider);
}

/* The rail numeral, repeated as the section's step. Same style as the rail. */
.step-num {
  font-family: var(--font-eyebrow);
  font-size: 0.875rem;
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: 0.06em;
  color: var(--accent-text);
  font-variant-numeric: tabular-nums;
  margin: 0 0 var(--space-sm);
}

/* Short mono labels inside the sections: beat kickers, guest labels, the
   screen-share bar. The hero eyebrow, in a different colour context. */
.eyebrow {
  font-family: var(--font-eyebrow);
  font-size: 0.875rem;
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0;
}

/* Captions and small notes, at the body-small size. */
.figure-note {
  color: var(--muted);
  font-size: 1rem;
  line-height: 1.5;
}

figcaption.figure-note {
  margin-top: var(--space-md);
}

/* Photographs sit at the card's radius with a border-ui edge, like every
   other object whose edge must be seen against a tonal step. */
.beat__photo,
.portrait__photo,
.tile__photo {
  display: block;
  width: 100%;
  height: auto;
  object-fit: cover;
  border: 1px solid var(--border-ui);
  border-radius: var(--radius);
}

.beat__photo {
  aspect-ratio: 4 / 3;
}

.portrait__photo {
  aspect-ratio: 4 / 5;
}

.tile__photo {
  position: absolute;
  inset: 0;
  height: 100%;
  border: 0;
  border-radius: 0;
}

.silhouette {
  width: 96px;
  height: 96px;
  color: var(--muted);
}

.timeline,
.portrait,
.room,
.stage {
  margin: 0;
}

/* 01 AI Headlines: the ruler and the three beats.

   The ruler is a 104px strip of positioned rules. Every horizontal position
   is a percentage of the content width, worked out on the 1168px column:
   day 0 at 1.37%, day 91 at 98.63%, one tick per week 7.4817% apart. The
   connectors drop to 16px inside each card's left edge, so they line up
   exactly at 1168px and drift by a pixel or two at other widths. Rules are
   borders rather than backgrounds so forced colours keep them. */
.ruler {
  position: relative;
  height: 104px;
}

.ruler__line {
  position: absolute;
  left: 0;
  right: 0;
  top: 43px;
  border-top: 2px solid var(--border-ui);
}

.ruler__tick {
  position: absolute;
  top: 38px;
  height: 12px;
  border-left: 1.5px solid var(--border-ui);
}

.ruler__tick:nth-child(1) { left: 1.37%; }
.ruler__tick:nth-child(2) { left: 8.85%; }
.ruler__tick:nth-child(3) { left: 16.33%; }
.ruler__tick:nth-child(4) { left: 23.82%; }
.ruler__tick:nth-child(5) { left: 31.3%; }
.ruler__tick:nth-child(6) { left: 38.78%; }
.ruler__tick:nth-child(7) { left: 46.26%; }
.ruler__tick:nth-child(8) { left: 53.74%; }
.ruler__tick:nth-child(9) { left: 61.22%; }
.ruler__tick:nth-child(10) { left: 68.71%; }
.ruler__tick:nth-child(11) { left: 76.19%; }
.ruler__tick:nth-child(12) { left: 83.67%; }
.ruler__tick:nth-child(13) { left: 91.15%; }
.ruler__tick:nth-child(14) { left: 98.63%; }

.ruler__label {
  position: absolute;
  top: 10px;
  transform: translateX(-50%);
  white-space: nowrap;
  font-family: var(--font-eyebrow);
  font-size: 0.875rem;
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}

.ruler__label--week-4 { left: 31.3%; }
.ruler__label--week-8 { left: 61.22%; }
.ruler__label--week-12 { left: 91.15%; }

.ruler__label--stretch {
  top: 60px;
  left: 49.47%;
}

.ruler__connector {
  position: absolute;
  top: 57px;
}

/* Beat 1 drops straight. Beats 2 and 3 elbow to their cards: a box with a
   left or right edge and a bottom edge draws the L, and a second span
   drops the rest of the way. */
.ruler__connector--1 {
  left: 1.37%;
  height: 47px;
  border-left: 1.5px solid var(--border-ui);
}

.ruler__connector--2 {
  left: 4.58%;
  width: 30.81%;
  height: 31px;
  border-left: 1.5px solid var(--border-ui);
  border-bottom: 1.5px solid var(--border-ui);
}

.ruler__connector--2-drop {
  left: 35.39%;
  top: 88px;
  height: 16px;
  border-left: 1.5px solid var(--border-ui);
}

.ruler__connector--3 {
  left: 69.41%;
  width: 29.22%;
  height: 31px;
  border-right: 1.5px solid var(--border-ui);
  border-bottom: 1.5px solid var(--border-ui);
}

.ruler__connector--3-drop {
  left: 69.41%;
  top: 88px;
  height: 16px;
  border-left: 1.5px solid var(--border-ui);
}

/* Numbered markers on the line, the same numeral the cards repeat.
   Canvas on accent, 6.65:1 light and 6.97:1 dark. */
.ruler__marker {
  position: absolute;
  top: 31px;
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--accent-text);
  color: var(--canvas);
  font-family: var(--font-eyebrow);
  font-size: 0.875rem;
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: 0.06em;
}

.ruler__marker--1 { left: 1.37%; }
.ruler__marker--2 { left: 4.58%; }
.ruler__marker--3 { left: 98.63%; }

.beats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-lg);
  margin: 0;
  padding: 0;
  list-style: none;
}

.beat {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  background: var(--card);
  border: 1px solid var(--border-ui);
  border-radius: var(--radius);
  padding: var(--space-lg);
}

.beat__head {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

/* The same numeral as the ruler marker, so the card and its point on the
   line read as one thing. Canvas on accent, 6.65:1 light and 6.97:1 dark. */
.beat__num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  flex: none;
  border-radius: 50%;
  background: var(--accent-text);
  color: var(--canvas);
  font-family: var(--font-eyebrow);
  font-size: 0.875rem;
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: 0.06em;
}

/* Dates do the visual work, so they are the largest thing on the card. */
.beat__date {
  display: block;
  font-family: var(--font-eyebrow);
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1.2;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  margin: 0;
}

/* A post-shaped placeholder that copies no platform's interface. */
.post {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  border: 1px solid var(--divider);
  border-radius: var(--radius);
  padding: var(--space-md);
}

.post__who {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

.post__avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  flex: none;
  border-radius: 50%;
  border: 1px dashed var(--border-ui);
}

.post__avatar .silhouette {
  width: 26px;
  height: 26px;
}

.post__name {
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.4;
}

.post__title,
.post__text {
  color: var(--muted);
  font-size: 1rem;
  line-height: 1.5;
}

/* 02 Guest of the Day */
.guest {
  display: grid;
  grid-template-columns: minmax(0, 4fr) minmax(0, 8fr);
  gap: var(--space-xxl);
  align-items: start;
}

.guest-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.guest-card__name {
  font-size: 2rem;
  line-height: 1.2;
}

.guest-card__line {
  color: var(--muted);
}

.technique {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  border-top: 1px solid var(--divider);
  padding-top: var(--space-md);
}

/* The base reset covers h1 to h3; h4 keeps the browser's 1.33em margins
   unless a component clears them. */
.technique h4 {
  margin: 0;
  font-size: 1.5rem;
  line-height: 1.25;
}

/* 03 Group Check-In: the room and the three things members compare. */
.checkin {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: var(--space-xxl);
  align-items: start;
}

.room__frame {
  background: var(--surface);
  border: 1px solid var(--border-ui);
  border-radius: var(--radius);
  padding: var(--space-sm);
}

.room__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-sm);
  margin: 0;
  padding: 0;
  list-style: none;
}

.tile {
  position: relative;
  aspect-ratio: 16 / 9;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background: var(--card);
  border: 1px solid var(--border-ui);
  border-radius: var(--radius);
  color: var(--muted);
}

/* Weight, not colour, marks the speaker; the label says it in words. */
.tile--speaking {
  border-width: 3px;
}

.tile__label {
  position: absolute;
  left: 6px;
  bottom: 6px;
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  font-family: var(--font-eyebrow);
  font-size: 0.875rem;
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text);
  background: var(--canvas);
  border: 1px solid var(--divider);
  border-radius: var(--radius);
  padding: 0.1em 0.5em;
}

.tile__label svg {
  width: 14px;
  height: 14px;
  flex: none;
}

.tile--notes {
  align-items: stretch;
  justify-content: flex-start;
  padding: var(--space-sm) var(--space-md);
}

.notes-list {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.35rem;
  width: 100%;
  margin: 0;
  padding: 0;
  list-style: none;
}

.notes-list li {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 1.0625rem;
  font-weight: 600;
  line-height: 1.4;
  color: var(--text);
}

.notes-list svg {
  width: 18px;
  height: 18px;
  flex: none;
  color: var(--accent-text);
}

.compare {
  margin: var(--space-md) 0 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--divider);
}

.compare li {
  padding-block: var(--space-md);
  border-bottom: 1px solid var(--divider);
}

.compare h4 {
  margin: 0 0 var(--space-xs);
}

.compare p {
  color: var(--muted);
  font-size: 1rem;
  line-height: 1.5;
}

/* 04 Challenge of the Day: how the room chooses, and the ballot. */
.challenge {
  display: grid;
  grid-template-columns: minmax(0, 4fr) minmax(0, 8fr);
  gap: var(--space-xxl);
  align-items: start;
}

.challenge .leave-list {
  margin-top: var(--space-md);
}

.ballot-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-sm) var(--space-md);
  margin-bottom: var(--space-md);
}

.ballot {
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--divider);
}

.ballot li {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--space-md);
  align-items: start;
  padding: var(--space-md) var(--space-sm);
  border-bottom: 1px solid var(--divider);
}

.ballot__mark {
  width: 24px;
  height: 24px;
  flex: none;
  margin-top: 2px;
  color: var(--border-ui);
}

.ballot__body {
  display: grid;
  grid-template-columns: 9.5rem minmax(0, 1fr) auto;
  gap: var(--space-md);
  align-items: start;
}

.ballot__cat {
  font-family: var(--font-eyebrow);
  font-size: 0.875rem;
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  padding-top: 0.3rem;
}

.ballot__status {
  font-family: var(--font-eyebrow);
  font-size: 0.875rem;
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent-text);
  white-space: nowrap;
  padding-top: 0.3rem;
}

/* The chosen row: filled check, bold text, a bordered card, and the words.
   Four cues, so the choice never rests on colour. */
.ballot li.is-chosen {
  background: var(--card);
  border: 1px solid var(--border-ui);
  border-radius: var(--radius);
  margin-block: var(--space-xs);
}

.ballot li.is-chosen .ballot__mark {
  color: var(--accent-text);
}

.ballot__mark-check {
  stroke: var(--canvas);
}

.ballot li.is-chosen .ballot__text {
  font-weight: 700;
}

/* 05 Solve It Together: the screen share and the people beside it. */
.stage__layout {
  display: grid;
  grid-template-columns: minmax(0, 8fr) minmax(0, 4fr);
  gap: var(--space-lg);
  align-items: stretch;
}

.screen__frame {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  aspect-ratio: 16 / 9;
  background: var(--card);
  border: 1px solid var(--border-ui);
  border-radius: var(--radius);
  padding: var(--space-lg);
}

.screen__bar {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-sm);
  border-bottom: 1px solid var(--divider);
  padding-bottom: var(--space-sm);
}

.turn {
  max-width: 80%;
  border-radius: var(--radius);
  padding: var(--space-sm) var(--space-md);
  font-size: 1rem;
  line-height: 1.5;
}

.turn--member {
  align-self: flex-end;
  background: var(--surface);
  border: 1px solid var(--divider);
  color: var(--text);
}

.turn--ai {
  align-self: flex-start;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  width: 80%;
  border: 1px dashed var(--border-ui);
  color: var(--muted);
}

.turn--ai p {
  color: var(--muted);
}

.turn__list {
  margin: 0;
  padding-left: 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  color: var(--text);
}

/* Two columns of 16:9 tiles beside the screen, so faces stay whole. */
.people {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-content: start;
  gap: var(--space-sm);
  margin: 0;
  padding: 0;
  list-style: none;
}

.tile__photo {
  object-position: 50% 30%;
}

.leave {
  margin-top: var(--space-xl);
  color: var(--muted);
}

@media (max-width: 760px) {
  .ruler {
    display: none;
  }

  .beats,
  .guest,
  .checkin,
  .challenge,
  .stage__layout {
    grid-template-columns: 1fr;
    gap: var(--space-lg);
  }

  /* The ruler is gone, so a dashed gap before the third beat stands in for
     the thirteen weeks; the card's own date says it in words. */
  .beat:nth-child(3) {
    position: relative;
    margin-top: var(--space-xxl);
  }

  .beat:nth-child(3)::before {
    content: "";
    position: absolute;
    left: var(--space-lg);
    top: calc(-1 * var(--space-xxl) - var(--space-lg));
    height: calc(var(--space-xxl) + var(--space-lg));
    border-left: 2px dashed var(--border-ui);
  }

  .guest-card__name {
    font-size: 1.625rem;
  }

  /* Two columns of tiles are too small for a label to sit over a
     silhouette, so the label drops under it and the row grows to fit the
     shared note. */
  .room__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .room__grid .tile {
    aspect-ratio: auto;
    flex-direction: column;
    gap: var(--space-xs);
    min-height: 96px;
    padding: var(--space-xs);
  }

  .room__grid .tile__photo,
  .people .tile__photo {
    position: static;
    aspect-ratio: 4 / 3;
    height: auto;
    border-radius: calc(var(--radius) - 2px);
  }

  .room__grid .tile__label {
    position: static;
    white-space: normal;
    text-align: center;
  }

  .tile--notes {
    padding: var(--space-sm);
  }

  .ballot__body {
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
  }

  .ballot__cat,
  .ballot__status {
    padding-top: 0;
  }

  .ballot__status {
    white-space: normal;
  }

  .screen__frame {
    aspect-ratio: auto;
  }

  .turn {
    max-width: 100%;
  }

  .turn--ai {
    width: 100%;
  }

  .people {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .people .tile {
    flex-direction: column;
    gap: var(--space-xs);
    min-height: 72px;
    padding: var(--space-xs);
  }

  .people .tile__label {
    position: static;
  }
}

/* ---------- Responsive ---------- */
@media (max-width: 760px) {
  h1 {
    font-size: 2.25rem;
  }
  h2 {
    font-size: 1.625rem;
  }
  .hero {
    padding-block: var(--space-xxl);
  }
  .band {
    padding-block: var(--space-xl);
  }
  .membership-grid {
    grid-template-columns: 1fr;
  }
  .progress-grid,
  .pair-grid,
  .faq-grid,
  .site-footer__layout {
    grid-template-columns: 1fr;
  }
  .field-row {
    flex-direction: column;
  }
  /* The 16rem flex-basis above is a width. In a column it would become a
     height, and the field rendered 256px tall. */
  input[type="email"] {
    flex-basis: auto;
  }
  .action,
  .theme-choice label,
  input[type="email"] {
    min-height: 48px;
  }
  .team-grid {
    grid-template-columns: 1fr;
  }

  /* Narrow enough that the header cannot hold two words beside the wordmark.
     The icons carry the meaning here, and the words stay in the accessibility
     tree so each radio keeps the name it had at full width. Same treatment as
     .visually-hidden, spelled out because it only applies at this width. */
  .theme-choice__word {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}

/* ---------- Motion ----------
   Hover transitions only. A theme change must repaint instantly: cross-fading
   the whole page reads as a smear, and it also leaves the page in a half-applied
   palette that automated contrast checks will sample and fail on. The
   theme-switching class is added for one frame while the palette swaps. */
@media (prefers-reduced-motion: no-preference) {
  a,
  .action {
    transition: background-color 150ms ease-out, color 150ms ease-out;
  }
}

:root.theme-switching *,
:root.theme-switching *::before,
:root.theme-switching *::after {
  transition: none !important;
}

/* ---------- Forced colors ----------
   Preserve system colours rather than simulating Solarized. Backgrounds are
   dropped in this mode, so the action fill and the input border need explicit
   boundaries to stay perceivable. */
@media (forced-colors: active) {
  .action {
    border: 1px solid ButtonText;
    background: ButtonFace;
    color: ButtonText;
    forced-color-adjust: none;
  }

  .action:hover {
    background: Highlight;
    color: HighlightText;
  }

  .membership-card,
  .bio-card,
  .session-rail,
  .theme-choice,
  input[type="email"] {
    border: 1px solid CanvasText;
  }

  /* The live-hour sections fill their markers and the chosen check with
     the accent, and forced colours drop fills. Both fall back to CanvasText
     on Canvas so they stay visible; the ruler's rules are borders and
     survive on their own. */
  .ruler__marker,
  .beat__num {
    border: 1px solid CanvasText;
    forced-color-adjust: none;
    background: CanvasText;
    color: Canvas;
  }

  .ballot li.is-chosen .ballot__mark {
    color: CanvasText;
  }

  .ballot__mark-check {
    stroke: Canvas;
  }

  .skeleton span {
    border: 1px solid GrayText;
  }

  /* The inverted chip has nothing to invert once backgrounds are dropped, and
     the radios themselves are clipped, so without this the live option would
     be unmarked. Highlight and HighlightText are the system's own "this one
     is selected" pair, which is why they are worth opting back in for. */
  .theme-choice input:checked + label {
    background: Highlight;
    color: HighlightText;
    forced-color-adjust: none;
  }

  /* Backgrounds are dropped here, so the mark has to fall back to system
     colours or it disappears into the page. */
  .dais-mark__face {
    fill: Canvas;
    stroke: CanvasText;
  }

  /* --hour is named explicitly rather than left to source order, so the accent
     hand cannot survive into a mode that has dropped the palette. The 8:00
     still reads because the hour hand is the thicker of the two. */
  .dais-mark__hand,
  .dais-mark__hand--hour {
    stroke: CanvasText;
  }

  /* GrayText is the system's own "secondary" tone, which is what muted means.
     The live state loses its accent like the hour hand does, and still reads
     because the live dot is larger. */
  .dais-mark__now {
    fill: GrayText;
  }

  .dais-mark__now--live {
    fill: CanvasText;
  }

  :focus-visible {
    outline: 3px solid Highlight;
  }
}
