/*
 * The stylesheet for user-built pages.
 *
 * Loaded in two places that must agree: inside the builder canvas, and on the
 * published page. Tailwind is deliberately absent — its JIT scan cannot see
 * markup that lives in the database, so a utility class a user picks would
 * work in the canvas and vanish once published.
 *
 * Three layers, applied in this order:
 *
 *   1. --site-*    the per-site theme. Site#theme_css emits it as a :root rule
 *                  in an inline <style> after this file.
 *   2. --sb-*      the tokens below. Palette tokens read a --site-* value with
 *                  a fallback; expression tokens say how a page is drawn —
 *                  surface, border, shadow, rhythm, motion.
 *   3. .sb-style-* a style pack on <body>, overriding expression tokens only.
 *
 * The tokens live on :root and NOT on .sb-section, and that is load-bearing.
 * A pack class sits on <body>, so inheritance is the only way it can reach a
 * section. A token re-declared on .sb-section would beat the ancestor, and
 * every pack would silently do nothing.
 *
 * So: blocks consume tokens, they do not set them. A rule with a hard-coded
 * colour, radius, shadow or gap is a rule no pack can restyle.
 *
 * Tag-qualified selectors (p.sb-text, div.sb-contact) are deliberate. Every
 * section carries a mechanical "sb-<type>" wrapper class, which collides with
 * the element class of the same name — an unqualified .sb-text also matches
 * <section class="sb-section sb-text">. The tag is what tells the two apart.
 */

/* The browser gives <body> an 8px margin; without this rule that margin frames
   the canvas and every published page. */
body { margin: 0; }

:root {
  /* --- Palette ----------------------------------------------------------- */

  --sb-accent: var(--site-accent, #4f46e5);
  --sb-background: var(--site-background, #ffffff);
  --sb-text: var(--site-text, #111827);
  --sb-muted: var(--site-muted, #6b7280);

  /* Text sitting on an accent fill. A pale accent needs a dark value here,
     which is why it is a theme key and not a hard-coded white. */
  --sb-on-accent: var(--site-on-accent, #ffffff);

  --sb-font-body: var(--site-font-body, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif);
  --sb-font-heading: var(--site-font-heading, var(--sb-font-body));

  /* --- Derived surfaces -------------------------------------------------- */

  /* Mixed from the text colour, not the muted one: a theme is free to set
     muted close to the background, and every border would fade out with it. */
  --sb-surface: color-mix(in srgb, var(--sb-text) 5%, var(--sb-background));
  --sb-border-color: color-mix(in srgb, var(--sb-text) 12%, transparent);
  --sb-border-strong: color-mix(in srgb, var(--sb-text) 22%, transparent);
  --sb-accent-soft: color-mix(in srgb, var(--sb-accent) 9%, var(--sb-background));
  --sb-accent-line: color-mix(in srgb, var(--sb-accent) 32%, transparent);
  --sb-shadow-color: color-mix(in srgb, var(--sb-text) 16%, transparent);

  /* --- Expression: what a style pack overrides --------------------------- */

  --sb-radius: var(--site-radius, 12px);

  --sb-card-surface: var(--sb-background);
  --sb-card-border: 1px solid var(--sb-border-color);
  --sb-card-padding: 26px;
  --sb-card-shadow: none;
  --sb-card-shadow-hover: 0 14px 34px -14px var(--sb-shadow-color);
  --sb-card-lift: -3px;

  --sb-divider: 1px solid var(--sb-border-color);

  --sb-button-padding: 13px 26px;
  --sb-button-weight: 600;
  --sb-button-shadow: 0 1px 2px color-mix(in srgb, var(--sb-text) 9%, transparent);
  --sb-button-shadow-hover: 0 10px 22px -10px color-mix(in srgb, var(--sb-accent) 60%, transparent);
  --sb-button-lift: -1px;

  --sb-heading-weight: 650;
  --sb-heading-tracking: -0.02em;
  --sb-heading-leading: 1.12;
  --sb-title-size: clamp(2.25rem, 5vw, 3.5rem);
  --sb-heading-size: clamp(1.5rem, 3vw, 2.25rem);

  --sb-eyebrow-transform: uppercase;
  --sb-eyebrow-tracking: 0.08em;

  --sb-media-ratio: 4 / 3;

  --sb-rhythm: 88px;
  --sb-gutter: 24px;
  --sb-gap: 26px;
  --sb-measure: 68ch;
  --sb-container: 1080px;


  --sb-duration: 180ms;
  --sb-ease: cubic-bezier(0.2, 0.7, 0.3, 1);
}

/* --- Style packs ---------------------------------------------------------
 *
 * Site#style_pack_class puts one of these on <body>. They override expression
 * tokens only — never a palette token, which belongs to the site's own theme.
 *
 * "refined" is what :root already holds, so it has no block here: selecting it
 * means falling back to the defaults above.
 *
 * Each pack states a fallback rather than a value wherever the theme has a say,
 * so var(--site-radius, 2px) still lets an owner who picked 16px keep it.
 *
 * A token on :root must never read another token a pack overrides. var() inside
 * a custom property is substituted where that property is declared, so such a
 * token computes on :root and inherits down already resolved — a pack changing
 * the token it read cannot move it. Derive at the point of use instead, which
 * is why .sb-card writes var(--sb-radius) rather than an --sb-card-radius
 * alias. SiteBlocksStylesheetTest holds the line.
 */

/* Rules, not boxes. Cards lose their border and become divided blocks, the
   type turns to a serif at a lighter weight, and the sections breathe wider. */
.sb-style-editorial {
  --sb-font-heading: var(--site-font-heading, Georgia, "Iowan Old Style", "Palatino Linotype", "Times New Roman", serif);
  --sb-radius: var(--site-radius, 2px);

  --sb-card-surface: transparent;
  --sb-card-border: 0;
  --sb-card-padding: 28px 0 0;
  --sb-card-shadow: none;
  --sb-card-shadow-hover: none;
  --sb-card-lift: 0;

  --sb-button-padding: 14px 28px;
  --sb-button-shadow: none;
  --sb-button-shadow-hover: none;
  --sb-button-lift: 0;

  --sb-heading-weight: 500;
  --sb-heading-tracking: -0.01em;
  --sb-heading-leading: 1.08;
  --sb-title-size: clamp(2.75rem, 6vw, 4.25rem);
  --sb-heading-size: clamp(1.75rem, 3.4vw, 2.5rem);
  --sb-eyebrow-tracking: 0.16em;

  --sb-media-ratio: 3 / 2;
  --sb-rhythm: 116px;
  --sb-gap: 40px;
}

/* The rule a card lost its border for. Only the top edge, so a row of cards
   reads as columns under a shared line rather than as three boxes. */
.sb-style-editorial .sb-card { border-top: 2px solid var(--sb-text); }
.sb-style-editorial .sb-quote { font-size: 1.875rem; font-style: italic; }
.sb-style-editorial .sb-step-number { border-radius: 0; background: none; border-bottom: 2px solid var(--sb-accent); }

/* Soft, rounded and lifted. Cards sit on a tinted surface with no border, and
   buttons are pills. */
.sb-style-bold {
  --sb-radius: var(--site-radius, 20px);

  --sb-card-surface: var(--sb-surface);
  --sb-card-border: 0;
  --sb-card-padding: 30px;
  --sb-card-shadow: 0 2px 8px -4px var(--sb-shadow-color);
  --sb-card-shadow-hover: 0 22px 44px -16px var(--sb-shadow-color);
  --sb-card-lift: -5px;

  --sb-button-radius: 999px;
  --sb-button-padding: 15px 32px;
  --sb-button-weight: 700;

  --sb-heading-weight: 750;
  --sb-heading-tracking: -0.035em;
  --sb-title-size: clamp(2.5rem, 5.5vw, 3.75rem);

  --sb-media-ratio: 1;
  --sb-rhythm: 96px;
}

.sb-style-bold .sb-cta { background: var(--sb-accent); color: var(--sb-on-accent); }
.sb-style-bold .sb-cta .sb-title,
.sb-style-bold .sb-cta .sb-heading { color: var(--sb-on-accent); }
.sb-style-bold .sb-cta p.sb-text { color: var(--sb-on-accent); opacity: 0.85; }
.sb-style-bold .sb-cta .sb-button { background: var(--sb-background); color: var(--sb-accent); }

.sb-section {
  box-sizing: border-box;
  padding: var(--sb-rhythm) var(--sb-gutter);
  background: var(--sb-background);
  color: var(--sb-text);
  font-family: var(--sb-font-body);
  line-height: 1.6;
}

.sb-section *,
.sb-section *::before,
.sb-section *::after { box-sizing: inherit; }

/* One ring for everything focusable. Only inputs had any before, which left a
   keyboard user unable to see where they were on every link and button. */
.sb-section :focus-visible {
  outline: 2px solid var(--sb-accent);
  outline-offset: 2px;
}

.sb-container {
  max-width: var(--sb-container);
  margin: 0 auto;
}

/* --- Type ---------------------------------------------------------------- */

.sb-title,
.sb-heading,
.sb-card-title {
  font-family: var(--sb-font-heading);
  color: var(--sb-text);
  margin: 0 0 16px;
  line-height: var(--sb-heading-leading);
  letter-spacing: var(--sb-heading-tracking);
  font-weight: var(--sb-heading-weight);
  text-wrap: balance;
}

.sb-title { font-size: var(--sb-title-size); }
.sb-heading { font-size: var(--sb-heading-size); }
.sb-card-title { font-size: 1.125rem; letter-spacing: 0; line-height: 1.3; }

.sb-eyebrow {
  display: block;
  margin: 0 0 12px;
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: var(--sb-eyebrow-tracking);
  text-transform: var(--sb-eyebrow-transform);
  color: var(--sb-muted);
}

p.sb-text {
  margin: 0 0 16px;
  color: var(--sb-muted);
  font-size: 1.0625rem;
  text-wrap: pretty;
}

.sb-prose { max-width: var(--sb-measure); }
.sb-fine-print { font-size: 0.875rem; color: var(--sb-muted); margin: 0; }

/* --- Controls ------------------------------------------------------------ */

.sb-button {
  display: inline-block;
  padding: var(--sb-button-padding);
  /* Fallback rather than a :root alias: a token that reads another token on
     :root freezes there, and no pack could round a button after that. */
  border-radius: var(--sb-button-radius, var(--sb-radius));
  background: var(--sb-accent);
  color: var(--sb-on-accent);
  font-weight: var(--sb-button-weight);
  text-decoration: none;
  box-shadow: var(--sb-button-shadow);
  transition:
    transform var(--sb-duration) var(--sb-ease),
    box-shadow var(--sb-duration) var(--sb-ease),
    filter var(--sb-duration) var(--sb-ease);
}

.sb-button:hover {
  filter: brightness(0.94);
  transform: translateY(var(--sb-button-lift));
  box-shadow: var(--sb-button-shadow-hover);
}

.sb-button:active { transform: translateY(0); }

.sb-link {
  color: var(--sb-accent);
  font-weight: 600;
  text-decoration: none;
  text-underline-offset: 3px;
}

.sb-link:hover { text-decoration: underline; }

/* --- Media --------------------------------------------------------------- */

.sb-image {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--sb-radius);
  background: color-mix(in srgb, var(--sb-muted) 12%, transparent);
  min-height: 120px;
}

/* An untouched slot has no src at all. A dashed edge reads as "nothing here
   yet" rather than as a broken picture. Deliberately no aspect-ratio: this rule
   also catches the hero, where a 4/3 box 900px wide is 675px of empty grey.
   Blocks that need a uniform grid set their own ratio. */
.sb-image:not([src]) {
  content: linear-gradient(transparent, transparent);
  min-height: 220px;
  border: 1px dashed var(--sb-border-strong);
  background: var(--sb-surface);
}

.sb-logo {
  width: auto;
  max-height: 40px;
  border-radius: 0;
  min-height: 0;
  opacity: 0.65;
  transition: opacity var(--sb-duration) var(--sb-ease);
}

.sb-logo:hover { opacity: 1; }
/* An empty slot has to be sized outright. aspect-ratio alone lets the alt text
   set the height, which pushes the logo row into the section below it, and
   transparent text is what keeps that text from spilling past the box. The alt
   stays in the DOM for anyone reading the page aloud. */
.sb-logo:not([src]) {
  content: linear-gradient(transparent, transparent);
  width: 112px;
  height: 40px;
  max-height: none;
  overflow: hidden;
  color: transparent;
  opacity: 1;
  border: 1px dashed var(--sb-border-strong);
  border-radius: calc(var(--sb-radius) / 2);
  background: var(--sb-surface);
}

div.sb-logos { text-align: center; }
div.sb-logos .sb-eyebrow { margin: 0 0 28px; }

.sb-logo-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 40px;
}

/* --- Layout -------------------------------------------------------------- */

.sb-grid { display: grid; gap: var(--sb-gap); }
.sb-grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.sb-grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

.sb-card {
  padding: var(--sb-card-padding);
  border-radius: var(--sb-radius);
  border: var(--sb-card-border);
  background: var(--sb-card-surface);
  box-shadow: var(--sb-card-shadow);
  transition:
    transform var(--sb-duration) var(--sb-ease),
    box-shadow var(--sb-duration) var(--sb-ease),
    border-color var(--sb-duration) var(--sb-ease);
}

.sb-card:hover {
  transform: translateY(var(--sb-card-lift));
  box-shadow: var(--sb-card-shadow-hover);
}

.sb-card > :last-child { margin-bottom: 0; }

.sb-split { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 56px; align-items: center; }
.sb-split-copy > :last-child { margin-bottom: 0; }

/* --- Individual sections ------------------------------------------------- */

.sb-hero { text-align: center; }
.sb-hero .sb-image { max-width: 900px; margin: 52px auto 0; }
.sb-hero-copy { max-width: 44ch; margin-inline: auto; }
.sb-hero-copy > :last-child { margin-bottom: 0; }

.sb-cta { background: var(--sb-accent-soft); text-align: center; }
.sb-cta-copy { max-width: 44ch; margin-inline: auto; }
.sb-cta-copy > :last-child { margin-bottom: 0; }

div.sb-testimonial { max-width: 60ch; margin-inline: auto; text-align: center; }

.sb-quote {
  margin: 0 0 20px;
  font-family: var(--sb-font-heading);
  font-size: 1.5rem;
  font-weight: 500;
  line-height: 1.4;
  text-wrap: pretty;
}

.sb-attribution { font-size: 0.9375rem; margin: 0; color: var(--sb-muted); }

.sb-price {
  font-family: var(--sb-font-heading);
  font-size: 2rem;
  font-weight: var(--sb-heading-weight);
  letter-spacing: var(--sb-heading-tracking);
  color: var(--sb-text);
  margin: 0 0 8px;
}

.sb-tier > :last-child { margin-bottom: 0; }

/* --- Announcement --------------------------------------------------------- */

.sb-banner {
  padding: 12px var(--sb-gutter);
  background: var(--sb-accent-soft);
  border-bottom: 1px solid var(--sb-accent-line);
}

.sb-banner-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 6px 16px;
}

.sb-banner-text { margin: 0; font-size: 0.9375rem; color: var(--sb-text); }

/* --- Hero, split ---------------------------------------------------------- */

/* A headline sharing the width with a picture cannot take the full display
   size the centred hero uses. */
.sb-hero-split .sb-title { font-size: clamp(2rem, 4vw, 3rem); }
.sb-hero-split .sb-split-copy > :last-child { margin-bottom: 0; }

/* --- Feature list --------------------------------------------------------- */

.sb-feature-list .sb-split { align-items: start; }

.sb-checklist {
  display: grid;
  gap: 14px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.sb-checklist-item { position: relative; padding-left: 36px; }

/* A disc and a tick, both drawn from borders, so the list needs no image and
   no <svg> the renderer would drop. */
.sb-checklist-item::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.1em;
  width: 22px;
  height: 22px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--sb-accent) 14%, transparent);
}

.sb-checklist-item::after {
  content: "";
  position: absolute;
  left: 8px;
  top: 0.45em;
  width: 5px;
  height: 9px;
  border-right: 2px solid var(--sb-accent);
  border-bottom: 2px solid var(--sb-accent);
  transform: rotate(45deg);
}

/* --- Timeline ------------------------------------------------------------- */

.sb-milestone {
  position: relative;
  padding: 0 0 32px 34px;
  border-left: 2px solid var(--sb-border-color);
}

/* The rail stops at the last milestone; its dot does not. */
.sb-milestone:last-child { border-left-color: transparent; padding-bottom: 0; }
.sb-milestone > :last-child { margin-bottom: 0; }
.sb-milestone .sb-eyebrow { margin: 0 0 6px; }

.sb-milestone::before {
  content: "";
  position: absolute;
  left: -7px;
  top: 3px;
  width: 12px;
  height: 12px;
  border-radius: 999px;
  background: var(--sb-accent);
  /* A ring of page colour, so the dot reads as sitting on the rail rather
     than threaded onto it. */
  box-shadow: 0 0 0 4px var(--sb-background);
}

/* --- Card row ------------------------------------------------------------- */

/* The picture reaches the card's edge, so the card's own padding moves onto
   the words and the frame gives up its corners to the card's. */
.sb-article { padding: 0; overflow: clip; display: grid; align-content: start; }
.sb-article-frame { border-radius: 0; background: var(--sb-surface); }
.sb-article-copy { display: grid; gap: 8px; padding: 22px 24px 24px; }
.sb-article-copy .sb-eyebrow { margin: 0; }
.sb-article-copy .sb-card-title { margin: 0; }
.sb-article-copy p.sb-text { margin: 0; }
.sb-article-copy .sb-link { justify-self: start; margin-top: 4px; }

/* --- Bento grid ----------------------------------------------------------- */

/* Named areas rather than spans: the arrangement reads in one line here, and a
   panel carries only which of the four it is. */
.sb-bento-grid {
  display: grid;
  gap: var(--sb-gap);
  grid-template-columns: repeat(3, minmax(0, 1fr));
  grid-template-areas:
    "wide wide tall"
    "left right tall";
}

.sb-bento-1 { grid-area: wide; }
.sb-bento-2 { grid-area: tall; }
.sb-bento-3 { grid-area: left; }
.sb-bento-4 { grid-area: right; }

.sb-bento-panel { display: grid; align-content: start; }
.sb-bento-panel > :last-child { margin-bottom: 0; }
.sb-bento-2 { align-content: center; }

/* --- Pricing with features ------------------------------------------------ */

.sb-tier-list { margin: 4px 0 20px; }
.sb-tier-list .sb-checklist-item { font-size: 0.9375rem; }
.sb-tier { display: grid; align-content: start; }
.sb-tier .sb-button { justify-self: start; }

/* The marked tier stands out by its edge and its lift, both of which a style
   pack has already redefined for every other card. */
.sb-tier-featured {
  border: 1px solid var(--sb-accent);
  box-shadow: var(--sb-card-shadow-hover);
}

/* --- Call to action, split ------------------------------------------------ */

.sb-cta-split { background: var(--sb-accent-soft); }

.sb-cta-split-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}

.sb-cta-split-copy { max-width: 52ch; }
.sb-cta-split-copy > :last-child { margin-bottom: 0; }

/* --- Testimonial wall ----------------------------------------------------- */

.sb-quote-card { display: grid; align-content: start; gap: 14px; }
.sb-quote-card .sb-quote { margin: 0; font-size: 1.125rem; font-weight: 500; }
.sb-quote-card .sb-attribution { margin: 0; }

/* --- Pictures with captions ----------------------------------------------- */

.sb-gallery-grid {
  display: grid;
  gap: var(--sb-gap);
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

/* One wide picture over two smaller ones. Rows are not spanned on purpose:
   a spanned row has to reconcile its own height with the caption under it. */
.sb-mosaic {
  display: grid;
  gap: var(--sb-gap);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.sb-mosaic-lead { grid-column: 1 / -1; }
.sb-mosaic-lead .sb-figure-image { aspect-ratio: 21 / 9; }

.sb-figure { margin: 0; display: grid; gap: 12px; }

/* The frame clips; the caption sits outside it. One box doing both would clip
   the caption along with the picture it scales. */
.sb-figure-frame {
  overflow: clip;
  border-radius: var(--sb-radius);
  background: var(--sb-surface);
}

.sb-figure-image {
  display: block;
  width: 100%;
  aspect-ratio: var(--sb-media-ratio);
  object-fit: cover;
  transition: transform 400ms var(--sb-ease);
}

.sb-figure-frame:hover .sb-figure-image { transform: scale(1.04); }

/* The dashed edge goes on the frame, not the picture: a border inside a
   clipped box loses its corners to the clip. */
.sb-figure-frame:has(.sb-figure-image:not([src])) { border: 1px dashed var(--sb-border-strong); }
.sb-figure-image:not([src]) { content: linear-gradient(transparent, transparent); color: transparent; }

.sb-figure-caption { font-size: 0.9375rem; color: var(--sb-muted); text-wrap: pretty; }

/* --- Questions ------------------------------------------------------------ */

/* An accordion needs a narrower column than a three-across grid does. */
.sb-faq-list { max-width: 780px; margin-inline: auto; }

/* Sections built before Questions became a disclosure still stack plain divs. */
div.sb-faq { margin-bottom: var(--sb-gap); }
div.sb-faq > :last-child { margin-bottom: 0; }

details.sb-faq { border-top: var(--sb-divider); }
details.sb-faq:last-of-type { border-bottom: var(--sb-divider); }

.sb-faq-question {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 20px 0;
  cursor: pointer;
  list-style: none;
  font-family: var(--sb-font-heading);
  font-size: 1.0625rem;
  font-weight: 600;
  color: var(--sb-text);
  transition: color var(--sb-duration) var(--sb-ease);
}

.sb-faq-question::-webkit-details-marker { display: none; }
.sb-faq-question:hover { color: var(--sb-accent); }

/* Two borders rotated into a chevron, so the markup stays a bare <summary>
   and the page fetches nothing to draw one. */
.sb-faq-question::after {
  content: "";
  flex: none;
  width: 9px;
  height: 9px;
  margin-right: 4px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: translateY(-3px) rotate(45deg);
  transition: transform var(--sb-duration) var(--sb-ease);
}

details.sb-faq[open] .sb-faq-question::after { transform: translateY(2px) rotate(-135deg); }

.sb-faq-answer { margin: 0; padding: 0 0 22px; max-width: 62ch; color: var(--sb-muted); text-wrap: pretty; }

/*
 * There is deliberately no open and close animation.
 *
 * Sliding the answer needs a length to animate towards, which means
 * block-size: 0 on ::details-content with interpolate-size, plus a discrete
 * transition on content-visibility. Measured in Chrome, that combination keeps
 * the answer hidden after the disclosure opens — checkVisibility() reports
 * false on an open entry — so the animation costs the block the one thing it
 * exists to do. The chevron carries the state instead.
 *
 * Probe with element.checkVisibility() if you revisit this. Both obvious
 * alternatives lie about a closed <details>, in opposite directions:
 * getBoundingClientRect() reports the full laid-out size of the skipped
 * subtree, and WebDriver reports hidden even where an author rule reveals it.
 */

/* Sliding the answer open needs a length to animate towards, which only
   interpolate-size provides. Where it is missing the answer still appears; it
   simply appears at once. */


/* --- Contact form -------------------------------------------------------- */

div.sb-contact { max-width: 52ch; }

.sb-form { display: grid; gap: 16px; margin-top: 8px; }
.sb-field { display: grid; gap: 6px; }
.sb-label { font-size: 0.9375rem; font-weight: 600; color: var(--sb-text); }

.sb-input,
.sb-textarea {
  width: 100%;
  padding: 11px 14px;
  border: 1px solid var(--sb-border-strong);
  border-radius: calc(var(--sb-radius) / 2);
  background: var(--sb-background);
  color: var(--sb-text);
  font: inherit;
  transition:
    border-color var(--sb-duration) var(--sb-ease),
    box-shadow var(--sb-duration) var(--sb-ease);
}

.sb-input:focus,
.sb-textarea:focus {
  outline: none;
  border-color: var(--sb-accent);
  box-shadow: 0 0 0 3px var(--sb-accent-line);
}

.sb-textarea { min-height: 120px; resize: vertical; }

/* One field and a button on one line. The honeypot is display:none, so it
   takes no cell, and the note spans both columns underneath. */
.sb-signup .sb-container { max-width: 60ch; }
.sb-signup-form { grid-template-columns: minmax(0, 1fr) auto; align-items: end; }
.sb-signup-form .sb-form-note { grid-column: 1 / -1; }

.sb-form-submit {
  border: 0;
  cursor: pointer;
  font: inherit;
  font-weight: var(--sb-button-weight);
  justify-self: start;
}

/* People never see the honeypot; a value in it marks the submission as a bot's. */
.sb-form-extra { display: none !important; }

/* Hidden until the success redirect's #fragment matches the note's id. */
.sb-form-note { display: none; margin: 0; color: var(--sb-accent); font-weight: 600; }
.sb-form-note:target { display: block; }

/* The chat block is a marker: the bubble is mounted by the bootstrap script,
   so the section itself stays invisible (and out of the accessibility tree)
   on a published page. The canvas re-displays it — see site_blocks_canvas. */
section.sb-chat { display: none; }

/* --- Footers ------------------------------------------------------------- */

.sb-footer { padding: 36px var(--sb-gutter); border-top: var(--sb-divider); }
.sb-footer-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px; }

.sb-footer-columns { padding: 60px var(--sb-gutter) 32px; border-top: var(--sb-divider); }
.sb-footer-column { display: grid; justify-items: start; gap: 8px; }
.sb-footer-column .sb-eyebrow { margin: 0 0 4px; }
.sb-footer-link { font-weight: 500; }

.sb-footer-columns .sb-fine-print {
  margin-top: 44px;
  padding-top: 24px;
  border-top: var(--sb-divider);
}

/* --- Navigation bar ------------------------------------------------------ */

/*
 * A published page runs no JavaScript for its layout, so <details> holds the
 * open state of the phone menu and CSS does the rest.
 *
 * On a wide screen the links have to show while that <details> is still closed.
 * Only ::details-content can do that: the browser hides the closed content in a
 * shadow slot no author rule can reach.
 */

.sb-navbar {
  padding: 14px var(--sb-gutter);
  border-bottom: var(--sb-divider);
}

.sb-nav-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}

.sb-nav-brand {
  color: var(--sb-text);
  font-family: var(--sb-font-heading);
  font-size: 1.125rem;
  font-weight: var(--sb-heading-weight);
  text-decoration: none;
}

.sb-nav-links { display: flex; align-items: center; gap: 4px; }

.sb-nav-link {
  padding: 8px 12px;
  border-radius: calc(var(--sb-radius) / 2);
  color: var(--sb-text);
  font-weight: 500;
  text-decoration: none;
  transition: color var(--sb-duration) var(--sb-ease), background-color var(--sb-duration) var(--sb-ease);
}

.sb-nav-link:hover { color: var(--sb-accent); background: var(--sb-surface); }
.sb-nav-cta { margin-left: 8px; }
.sb-nav-cta:hover { background: var(--sb-accent); }

@media (min-width: 768px) {
  .sb-nav-disclosure::details-content { content-visibility: visible; block-size: auto; }
}

/* Three bars drawn from the text colour, so the markup stays a bare <summary>
   and the page fetches nothing to show a menu. */
.sb-nav-toggle {
  display: none;
  position: relative;
  width: 40px;
  height: 40px;
  border-radius: calc(var(--sb-radius) / 2);
  color: var(--sb-text);
  cursor: pointer;
  list-style: none;
}

.sb-nav-toggle::-webkit-details-marker { display: none; }

.sb-nav-toggle::before {
  content: "";
  position: absolute;
  top: 13px;
  left: 10px;
  width: 20px;
  height: 2px;
  background: currentColor;
  box-shadow: 0 6px 0 currentColor, 0 12px 0 currentColor;
}

/* --- Numbers, team and steps --------------------------------------------- */

.sb-stat { text-align: center; }

.sb-stat-value {
  margin: 0 0 4px;
  font-family: var(--sb-font-heading);
  font-size: clamp(2rem, 4vw, 2.75rem);
  font-weight: var(--sb-heading-weight);
  letter-spacing: var(--sb-heading-tracking);
  color: var(--sb-text);
  line-height: 1.1;
}

.sb-stat-label { margin: 0; font-size: 0.9375rem; color: var(--sb-muted); }

.sb-member { text-align: center; }
.sb-member > :last-child { margin-bottom: 0; }

.sb-portrait {
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 999px;
  max-width: 160px;
  min-height: 0;
  margin: 0 auto 18px;
}

.sb-portrait:not([src]) {
  width: 160px;
  height: 160px;
  /* A portrait carries sb-image too, so the generic placeholder floor reaches
     it and stretches the circle into an oval. */
  min-height: 0;
  overflow: hidden;
  color: transparent;
}
.sb-member-role { margin: 0; font-size: 0.9375rem; color: var(--sb-muted); }

.sb-step > :last-child { margin-bottom: 0; }

.sb-step-number {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  margin: 0 0 18px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--sb-accent) 12%, transparent);
  color: var(--sb-accent);
  font-family: var(--sb-font-heading);
  font-weight: 700;
}

/* --- Screens ------------------------------------------------------------- */

/* Tablet. Three and four columns both step down to two here; before this tier
   a four-column row was still four columns at 800px. */
@media (max-width: 1023px) {
  .sb-grid-3,
  .sb-grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .sb-bento-grid { grid-template-areas: "wide wide" "left right" "tall tall"; }
  .sb-split { gap: 36px; }
}

@media (max-width: 767px) {
  :root { --sb-rhythm: 56px; --sb-gutter: 20px; --sb-gap: 20px; }

  .sb-grid-3 { grid-template-columns: minmax(0, 1fr); }
  .sb-split { grid-template-columns: minmax(0, 1fr); gap: 28px; }
  .sb-bento-grid { grid-template-columns: minmax(0, 1fr); grid-template-areas: "wide" "tall" "left" "right"; }
  .sb-signup-form { grid-template-columns: minmax(0, 1fr); }
  .sb-hero .sb-image { margin-top: 32px; }

  /* The menu becomes a card under the burger, in normal flow. It must not be
     positioned against anything outside the <details>: an absolutely placed
     panel escapes the subtree the browser skips while the menu is closed, and
     then the closed menu stays on screen. */
  .sb-nav-bar { align-items: flex-start; }
  .sb-nav-toggle { display: block; }

  .sb-nav-links {
    flex-direction: column;
    align-items: stretch;
    min-width: 190px;
    margin-top: 8px;
    padding: 8px;
    border: 1px solid var(--sb-border-color);
    border-radius: var(--sb-radius);
    background: var(--sb-background);
    box-shadow: var(--sb-card-shadow-hover);
  }

  .sb-nav-cta { margin: 4px 0 0; text-align: center; }

  .sb-footer-columns .sb-grid-3 { gap: 32px; }
}

@media (max-width: 560px) {
  .sb-grid-4 { grid-template-columns: minmax(0, 1fr); }
  .sb-logo-row { gap: 28px; }
}

/* Motion is decoration here: every transition above only moves something that
   is already in its final place, so switching them off costs nothing. */
@media (prefers-reduced-motion: reduce) {
  .sb-section *,
  .sb-section *::before,
  .sb-section *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }

  .sb-card:hover,
  .sb-button:hover { transform: none; }
}
