/*
 * CommentAura — landing site stylesheet.
 *
 * ── Nothing here is fetched ───────────────────────────────────────────────────────────
 *
 * Not a font, not an icon set, not a beacon. The product's headline claim is that it makes
 * zero outbound requests; a site arguing that while quietly calling Google Fonts is making
 * the argument badly. Every typeface is a system stack and every icon is an inline symbol.
 *
 * ── The palette is the plugin's own ───────────────────────────────────────────────────
 *
 * The neutrals are the charcoal of the directory icon (#1d2327 — WordPress's own admin
 * grey, which is where this plugin lives), and `--ca-blue` is the steel blue of the
 * directory banner raised to a value that clears 4.5:1 as text on white. The product
 * itself is deliberately near-monochrome and inherits its colour from the host theme, so
 * this accent belongs to the website, not to the thread.
 *
 * ── Two typefaces, and the split means something ──────────────────────────────────────
 *
 * The serif is the POST's voice: display headings, and the article excerpt in the hero
 * demo. The sans is the DISCUSSION's voice: every comment, control, label and caption. So
 * in the demo — where an excerpt sits directly above the thread it started — the two are
 * visibly two different speakers, which is the shape of the product expressed in type.
 *
 * ── Theme ────────────────────────────────────────────────────────────────────────────
 *
 * `data-ca-theme` on <body> is the resolved theme ("light" or "dark"); `data-ca-theme-choice`
 * records what the reader picked, which may be "auto". script.js owns both, and nothing in
 * here reads prefers-color-scheme directly, so the toggle wins in every direction.
 */

:root {
  /* Neutrals — a cool ramp off the icon's charcoal, opened out for a full-width page. */
  --ca-bg: #fbfcfd;
  --ca-surface: #ffffff;
  --ca-surface-2: #f3f5f8;
  --ca-surface-3: #e9edf2;
  --ca-border: #e2e7ee;
  --ca-border-strong: #c9d2de;
  --ca-text: #10151a;
  --ca-heading: #070b0f;
  --ca-muted: #56616f;

  /*
   * The banner's steel blue is #3d576e, which is 6.9:1 as text but muddy as a button fill
   * and almost invisible as a small icon. This is the same hue with the saturation the web
   * needs: 6.4:1 against white, so one token serves both link text and a white-on-blue
   * button without splitting.
   */
  --ca-blue: #1f6390;
  --ca-blue-hover: #1a5578;
  --ca-blue-deep: #16455f;

  --ca-success: #15803d;
  /*
   * A second green, for green *text*. The icon green is fine as a graphic — a check mark
   * only has to clear 3:1 — and it fails AA the moment the same colour carries a word on a
   * tinted ground. Every place the palette says "yes" in words uses this one.
   */
  --ca-success-text: #0f6b31;
  --ca-warn: #a5560a;
  --ca-warn-text: #8a4708;
  --ca-danger: #b4232a;
  --ca-info: #0f6390;

  /* Tints for status grounds. Low enough that the colour drawn on top still clears 4.5:1. */
  --ca-tint: 8%;
  --ca-tint-soft: 5%;

  --ca-link: #1f6390;
  --ca-link-hover: #16455f;

  --ca-shadow: 0 22px 60px rgba(13, 26, 38, 0.11);
  --ca-shadow-soft: 0 12px 34px rgba(13, 26, 38, 0.07);
  --ca-shadow-inset: inset 0 0 0 1px var(--ca-border);

  --ca-radius: 16px;
  --ca-radius-sm: 10px;
  --ca-radius-lg: 22px;
  --ca-container: 1220px;
  --ca-header-h: 70px;

  --ca-sans:
    -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, 'Helvetica Neue', Arial, sans-serif;
  --ca-serif:
    ui-serif, 'Iowan Old Style', 'Palatino Linotype', Palatino, Georgia, 'Times New Roman', serif;
  --ca-mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
}

.ca-page[data-ca-theme='dark'] {
  --ca-bg: #0c1013;
  --ca-surface: #14191d;
  --ca-surface-2: #1a2026;
  --ca-surface-3: #222a31;
  --ca-border: #28323a;
  --ca-border-strong: #3c4854;
  --ca-text: #eef1f4;
  --ca-heading: #ffffff;
  --ca-muted: #9ca8b4;

  --ca-blue: #78aad6;
  --ca-blue-hover: #96bfe3;
  /* The fill a white label sits on. `--ca-blue` here is 2.5:1 under white — far too low. */
  --ca-blue-deep: #2f6f9f;

  --ca-success: #4ade80;
  --ca-success-text: #4ade80;
  --ca-warn: #f0a742;
  /* On the dark ground the icon colour already clears AA as text; no second value needed. */
  --ca-warn-text: #f0a742;
  --ca-danger: #f87171;
  --ca-info: #7cc0e8;

  --ca-tint: 15%;
  --ca-tint-soft: 9%;

  --ca-link: #96bfe3;
  --ca-link-hover: #b6d4ee;

  --ca-shadow: 0 22px 60px rgba(0, 0, 0, 0.46);
  --ca-shadow-soft: 0 12px 34px rgba(0, 0, 0, 0.32);
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

.ca-page {
  margin: 0;
  min-width: 320px;
  overflow-x: hidden;
  background: var(--ca-bg);
  color: var(--ca-text);
  font-family: var(--ca-sans);
  font-size: 16px;
  line-height: 1.6;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

/*
 * A reset, so it must not win anything. Written as `.ca-page a` this rule scores (0,1,1)
 * and quietly beats `.ca-button-primary` at (0,1,0) — which would paint the primary
 * buttons with the page's near-black text colour on a blue fill. `:where()` scores zero,
 * which is what a reset should have scored from the start.
 */
:where(.ca-page a) {
  color: inherit;
  text-decoration: none;
}

:where(.ca-page img, .ca-page svg) {
  display: block;
}

:where(.ca-page p) {
  margin: 0;
}

.ca-page :focus-visible {
  outline: 3px solid var(--ca-blue);
  outline-offset: 3px;
  border-radius: 6px;
}

.ca-page code {
  font-family: var(--ca-mono);
  font-size: 0.875em;
  padding: 1px 5px;
  border-radius: 5px;
  background: var(--ca-surface-2);
  color: var(--ca-text);
  overflow-wrap: anywhere;
}

.ca-section-alt code,
.ca-footer code {
  background: var(--ca-surface-3);
}

.ca-svg-sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

.ca-container {
  width: min(calc(100% - 48px), var(--ca-container));
  margin-inline: auto;
}

/* Reachable by keyboard, invisible until it has focus. */
.ca-skip {
  position: absolute;
  left: 16px;
  top: -80px;
  z-index: 60;
  padding: 12px 20px;
  border-radius: 10px;
  color: #ffffff;
  background: var(--ca-blue-deep);
  font-weight: 800;
  transition: top 0.2s ease;
}

.ca-skip:focus {
  top: 16px;
}

/* ───────────────────────────────────────────────────────────────────────── type scale ── */

/*
 * Resets, so they must not win anything — `:where()` scores zero. Written as `.ca-page h2`
 * this rule scores (0,1,1) and beats any single-class component rule at (0,1,0), which
 * silently eats margins on anything that sets its own.
 */
:where(.ca-page h1, .ca-page h2, .ca-page h3, .ca-page h4) {
  color: var(--ca-heading);
  margin: 0;
  text-wrap: balance;
}

/*
 * The ramp is steeper than it looks like it needs to be, and the reason is the hero line.
 *
 * The headline is two phrases that each want one line: "Comments that stay" and "WordPress
 * comments." The second is the longer of the two, so it sets the size — at the old floor of
 * 2.25rem it measured 339px against the 326px a 358px phone has to offer, and the headline
 * came apart into four lines on exactly the widths most people hold.
 *
 * Every number below is measured rather than guessed, and carries about six per cent of
 * slack so that a different font stack on a different platform does not reopen the problem:
 * 26px at 320px wide, rising with the viewport because the container rises with it too, and
 * stopping at 3.25rem — the largest size the hero's copy column can hold the phrase at
 * without breaking it again at the far end.
 */
.ca-page h1 {
  font-family: var(--ca-serif);
  font-size: clamp(1.65rem, 9.2vw - 0.1875rem, 3.25rem);
  font-weight: 600;
  line-height: 1.08;
  letter-spacing: -0.022em;
}

.ca-page h2 {
  font-family: var(--ca-serif);
  font-size: clamp(1.7rem, 1.2rem + 1.6vw, 2.35rem);
  font-weight: 600;
  line-height: 1.16;
  letter-spacing: -0.018em;
}

.ca-page h3 {
  font-size: 1.0625rem;
  font-weight: 680;
  line-height: 1.34;
  letter-spacing: -0.008em;
}

.ca-eyebrow {
  display: inline-flex;
  /* Top, not centre: on a phone this label wraps to two lines, and an icon floating
     halfway down the pair reads as a mistake. */
  align-items: flex-start;
  gap: 8px;
  margin: 0;
  color: var(--ca-blue);
  font-size: 0.75rem;
  font-weight: 750;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.ca-eyebrow svg {
  width: 16px;
  height: 16px;
  flex: none;
  margin-top: 1px;
}

.ca-lede {
  max-width: 64ch;
  color: var(--ca-muted);
  font-size: 1.0625rem;
}

.ca-section-head {
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-width: 66ch;
  margin-bottom: 44px;
}

.ca-nowrap {
  white-space: nowrap;
}

/* ─────────────────────────────────────────────────────────────────────────── controls ── */

.ca-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  padding: 13px 22px;
  border: 1px solid transparent;
  border-radius: 12px;
  font-size: 0.9375rem;
  font-weight: 680;
  letter-spacing: -0.006em;
  cursor: pointer;
  transition:
    background 0.16s ease,
    border-color 0.16s ease,
    transform 0.16s ease;
}

.ca-button svg {
  width: 18px;
  height: 18px;
  flex: none;
}

/*
 * Deliberately NOT `--ca-blue` in dark mode. There the link colour is light (#78aad6) and
 * white on it is 2.5:1 — under the floor. The deep token is the fill; the bright one is
 * for text and icons on the page ground.
 */
.ca-button-primary {
  background: var(--ca-blue-deep);
  color: #ffffff;
}

.ca-page[data-ca-theme='light'] .ca-button-primary,
.ca-page:not([data-ca-theme='dark']) .ca-button-primary {
  background: var(--ca-blue);
}

.ca-button-primary:hover {
  background: var(--ca-blue-hover);
  transform: translateY(-1px);
}

.ca-page[data-ca-theme='dark'] .ca-button-primary:hover {
  background: #3b82b4;
}

.ca-button-secondary {
  background: var(--ca-surface);
  border-color: var(--ca-border-strong);
  color: var(--ca-text);
}

.ca-button-secondary:hover {
  border-color: var(--ca-blue);
  color: var(--ca-blue);
  transform: translateY(-1px);
}

.ca-button-quiet {
  padding: 12px 18px;
  background: transparent;
  border-color: var(--ca-border);
  color: var(--ca-muted);
  font-size: 0.875rem;
}

.ca-button-quiet:hover {
  border-color: var(--ca-border-strong);
  color: var(--ca-text);
}

.ca-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.ca-icon-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 1px solid var(--ca-border);
  border-radius: 11px;
  background: var(--ca-surface);
  color: var(--ca-muted);
  cursor: pointer;
  transition:
    color 0.16s ease,
    border-color 0.16s ease;
}

.ca-icon-button svg {
  width: 19px;
  height: 19px;
}

.ca-icon-button:hover {
  border-color: var(--ca-border-strong);
  color: var(--ca-text);
}

/* ───────────────────────────────────────────────────────────────────────────── header ── */

.ca-header {
  position: sticky;
  top: 0;
  z-index: 50;
  backdrop-filter: saturate(150%) blur(14px);
  background: color-mix(in srgb, var(--ca-bg) 86%, transparent);
  border-bottom: 1px solid var(--ca-border);
}

.ca-header-inner {
  display: flex;
  align-items: center;
  gap: 24px;
  height: var(--ca-header-h);
}

.ca-brand {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  flex: none;
}

.ca-brand img {
  border-radius: 9px;
}

/* The mark and the name, and nothing else. The tagline earns its place in the copy. */
.ca-brand-name {
  font-size: 1.125rem;
  font-weight: 750;
  line-height: 1.2;
  letter-spacing: -0.018em;
  color: var(--ca-heading);
}

.ca-nav {
  display: flex;
  align-items: center;
  gap: 2px;
  margin-inline: auto;
}

.ca-nav a {
  padding: 8px 11px;
  border-radius: 9px;
  color: var(--ca-muted);
  font-size: 0.9375rem;
  font-weight: 560;
  white-space: nowrap;
  transition: color 0.16s ease;
}

.ca-nav a:hover,
.ca-nav a.is-active {
  color: var(--ca-text);
  background: var(--ca-surface-2);
}

.ca-header-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: none;
}

.ca-header-cta {
  padding: 10px 16px;
  font-size: 0.875rem;
}

.ca-menu-toggle {
  display: none;
}

.ca-mobile-nav {
  border-top: 1px solid var(--ca-border);
  background: var(--ca-surface);
  padding-block: 12px 18px;
  max-height: calc(100vh - var(--ca-header-h));
  max-height: calc(100dvh - var(--ca-header-h));
  overflow-y: auto;
  /* Reaching the end of the sheet must not start scrolling the page behind it. */
  overscroll-behavior: contain;
}

.ca-mobile-nav ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.ca-mobile-nav a {
  display: block;
  padding: 13px 12px;
  border-radius: 10px;
  color: var(--ca-text);
  font-weight: 600;
}

.ca-mobile-nav a:hover {
  background: var(--ca-surface-2);
}

/*
 * `.ca-mobile-nav a` scores (0,2,0) and beats `.ca-button`'s (0,1,0), so its `display: block`
 * won and stacked the button's icon above its label. The display mode has to be restated here
 * or the call to action in the sheet renders as two left-aligned lines.
 */
.ca-mobile-nav .ca-button {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-top: 8px;
  width: 100%;
  color: #ffffff;
}

/* ─────────────────────────────────────────────────────────────────────────────── hero ── */

.ca-hero {
  position: relative;
  padding-block: 72px 84px;
}

/*
 * The only decorative colour on the site — two very faint washes at the shoulders of the
 * hero. Everything else that carries a hue is carrying a signal.
 */
.ca-hero-bg {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(circle at 12% 0%, rgba(31, 99, 144, 0.1), transparent 26rem),
    radial-gradient(circle at 88% 6%, rgba(31, 99, 144, 0.06), transparent 24rem);
}

.ca-page[data-ca-theme='dark'] .ca-hero-bg {
  background:
    radial-gradient(circle at 12% 0%, rgba(120, 170, 214, 0.16), transparent 26rem),
    radial-gradient(circle at 88% 6%, rgba(120, 170, 214, 0.08), transparent 24rem);
}

.ca-hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.06fr);
  align-items: center;
  gap: 52px;
}

.ca-hero-copy {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 20px;
}

.ca-hero-copy h1 span {
  display: block;
  color: var(--ca-blue);
}

.ca-hero-text {
  max-width: 48ch;
  color: var(--ca-muted);
  font-size: 1.125rem;
}

.ca-trust-list {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 8px 20px;
  margin: 4px 0 0;
  padding: 0;
  color: var(--ca-muted);
  font-size: 0.875rem;
}

.ca-trust-list li {
  display: inline-flex;
  align-items: center;
  gap: 7px;
}

.ca-trust-list svg {
  width: 16px;
  height: 16px;
  flex: none;
  color: var(--ca-success);
}

/* ────────────────────────────────────────────────────────────── the deactivation demo ── */

/*
 * The product's headline claim, demonstrated rather than asserted.
 *
 * Two radios drive it, and CSS reads them with `:has()`. That is not a stylistic choice:
 * the claim being made is "this works without JavaScript", and a demonstration of that
 * claim that needs JavaScript would be arguing against itself. Where `:has()` is not
 * supported the page keeps the active state, which is the honest default — it shows the
 * product doing its job.
 *
 * Everything marked `.ca-x` is something CommentAura ADDS: the vote pills, the reaction
 * chips, the edit affordance, the pinned badge, the sort control. Everything else is a
 * native WordPress comment, and none of it moves between the two states.
 */

.ca-demo {
  margin: 0;
  border-radius: var(--ca-radius-lg);
  background: var(--ca-surface);
  box-shadow: var(--ca-shadow), var(--ca-shadow-inset);
  overflow: hidden;
}

.ca-demo__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  padding: 14px 20px;
  border-bottom: 1px solid var(--ca-border);
}

.ca-demo__title {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  color: var(--ca-muted);
  font-size: 0.75rem;
  font-weight: 640;
  letter-spacing: 0.01em;
}

.ca-demo__title svg {
  width: 15px;
  height: 15px;
  flex: none;
  color: var(--ca-blue);
}

/* A segmented control built from two radios, so it is keyboard-operable for free. */
.ca-demo__switch {
  display: inline-flex;
  padding: 3px;
  border-radius: 999px;
  background: var(--ca-surface-2);
  box-shadow: inset 0 0 0 1px var(--ca-border);
}

.ca-demo__radio {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.ca-demo__switch label {
  padding: 6px 14px;
  border-radius: 999px;
  color: var(--ca-muted);
  font-size: 0.75rem;
  font-weight: 700;
  cursor: pointer;
  white-space: nowrap;
  transition:
    background 0.16s ease,
    color 0.16s ease;
}

.ca-demo__switch label:hover {
  color: var(--ca-text);
}

.ca-demo__radio:checked + label {
  background: var(--ca-surface);
  box-shadow: var(--ca-shadow-soft);
  color: var(--ca-heading);
}

.ca-demo__radio:focus-visible + label {
  outline: 3px solid var(--ca-blue);
  outline-offset: 2px;
}

.ca-demo__body {
  padding: 22px;
}

/* The post's voice, in the serif — so the thread below it reads as a different speaker. */
.ca-demo__excerpt {
  padding-bottom: 18px;
  margin-bottom: 18px;
  border-bottom: 1px solid var(--ca-border);
  font-family: var(--ca-serif);
  font-size: 1rem;
  font-style: italic;
  line-height: 1.5;
  color: var(--ca-muted);
}

.ca-thread {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.ca-thread__bar {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding-bottom: 10px;
  font-size: 0.8125rem;
  color: var(--ca-muted);
}

.ca-thread__bar strong {
  color: var(--ca-text);
  font-weight: 700;
}

.ca-thread__bar .ca-x {
  text-decoration: underline;
  text-underline-offset: 3px;
}

.ca-c {
  position: relative;
  padding: 12px 14px;
  border-radius: 12px;
  background: var(--ca-surface-2);
  transition:
    background 0.22s ease,
    box-shadow 0.22s ease,
    padding 0.22s ease;
}

.ca-c--child {
  margin-top: 12px;
  background: var(--ca-surface-3);
}

.ca-c__badge {
  display: inline-block;
  margin-bottom: 8px;
  padding: 2px 9px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--ca-blue) var(--ca-tint), var(--ca-surface));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ca-blue) 26%, transparent);
  color: var(--ca-blue);
  font-size: 0.6875rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.ca-c__row {
  display: flex;
  gap: 11px;
}

.ca-c__avatar {
  flex: none;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 999px;
  background: var(--ca-surface);
  box-shadow: inset 0 0 0 1px var(--ca-border);
  color: var(--ca-muted);
  font-size: 0.75rem;
  font-weight: 750;
}

.ca-c__main {
  min-width: 0;
  flex: 1;
}

.ca-c__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 8px;
  font-size: 0.75rem;
  color: var(--ca-muted);
}

.ca-c__meta b {
  color: var(--ca-heading);
  font-weight: 700;
  font-size: 0.8125rem;
}

.ca-c__text {
  margin-top: 5px;
  font-size: 0.875rem;
  line-height: 1.5;
  overflow-wrap: anywhere;
}

.ca-c__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 9px;
  font-size: 0.6875rem;
  color: var(--ca-muted);
}

.ca-c__reply,
.ca-c__edit {
  font-weight: 700;
}

.ca-c__pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--ca-surface);
  box-shadow: inset 0 0 0 1px var(--ca-border);
  font-weight: 640;
  font-variant-numeric: tabular-nums;
}

/*
 * The deactivated state. CommentAura's own additions go; the comments do not. The cards
 * flatten into the plain, unstyled list a theme renders on its own, which is exactly what
 * a reader would see the moment the plugin is switched off.
 */
.ca-demo:has(#ca-demo-off:checked) .ca-x {
  display: none;
}

.ca-demo:has(#ca-demo-off:checked) .ca-c {
  padding-inline: 0;
  background: transparent;
  border-radius: 0;
}

.ca-demo:has(#ca-demo-off:checked) .ca-c + .ca-c {
  border-top: 1px solid var(--ca-border);
}

.ca-demo:has(#ca-demo-off:checked) .ca-c--child {
  padding-left: 22px;
  border-left: 2px solid var(--ca-border);
}

.ca-demo:has(#ca-demo-off:checked) .ca-c__avatar {
  background: var(--ca-surface-2);
}

.ca-demo__note {
  display: flex;
  gap: 11px;
  padding: 15px 20px;
  border-top: 1px solid var(--ca-border);
  background: var(--ca-surface-2);
  color: var(--ca-muted);
  font-size: 0.8125rem;
  line-height: 1.5;
}

.ca-demo__note svg {
  width: 16px;
  height: 16px;
  flex: none;
  margin-top: 3px;
  color: var(--ca-blue);
}

.ca-demo__note b {
  color: var(--ca-heading);
}

/* One of the two sentences at a time — whichever matches the state the switch is in. */
.ca-demo__off {
  display: none;
}

.ca-demo:has(#ca-demo-off:checked) .ca-demo__off {
  display: inline;
}

.ca-demo:has(#ca-demo-off:checked) .ca-demo__on {
  display: none;
}

/* ─────────────────────────────────────────────────────────────────────────── diagram ── */

/*
 * Two drawings of one claim. The wide one reads left to right; below the breakpoint the
 * same nodes stack, because scaling the wide one down would take its labels under 10px.
 * Neither is decorative: the dashed box is the trust boundary the whole product is about.
 */
.ca-dia {
  margin: 0;
  padding: 26px 24px 20px;
  border-radius: var(--ca-radius);
  background: var(--ca-bg);
  box-shadow: var(--ca-shadow-inset);
  color: var(--ca-text);
}

.ca-dia__canvas svg {
  width: 100%;
  height: auto;
}

.ca-dia__tall {
  display: none;
  max-width: 420px;
  margin-inline: auto;
}

.ca-dia__node {
  fill: currentColor;
  font-family: var(--ca-sans);
  font-size: 15px;
  font-weight: 620;
  text-anchor: middle;
}

.ca-dia__node--store {
  font-family: var(--ca-mono);
  font-size: 14px;
  font-weight: 500;
}

.ca-dia__edge {
  fill: currentColor;
  fill-opacity: 0.7;
  font-family: var(--ca-sans);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-anchor: middle;
}

.ca-dia__edge--start {
  text-anchor: start;
}

.ca-dia__edge--end {
  text-anchor: end;
}

.ca-dia__edge--never {
  fill: var(--ca-danger);
  fill-opacity: 1;
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

.ca-dia__zone {
  fill: currentColor;
  fill-opacity: 0.5;
  font-family: var(--ca-sans);
  font-size: 11px;
  font-weight: 750;
  letter-spacing: 0.13em;
}

/* The one element the claim turns on, so the one element with a hue. */
.ca-dia__store {
  color: var(--ca-blue);
}

.ca-dia__out {
  opacity: 0.55;
}

.ca-dia figcaption {
  max-width: 60ch;
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--ca-border);
  color: var(--ca-muted);
  font-size: 0.875rem;
  line-height: 1.55;
}

.ca-dia figcaption b {
  color: var(--ca-heading);
}

/* ────────────────────────────────────────────────────────────────────────── sections ── */

.ca-section {
  padding-block: 84px;
  /* Clears the 70px sticky header when the nav jumps here. */
  scroll-margin-top: calc(var(--ca-header-h) + 16px);
}

.ca-section-alt {
  background: var(--ca-surface-2);
  border-block: 1px solid var(--ca-border);
}

.ca-section-tight {
  padding-block: 56px;
}

.ca-grid-3 {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 18px;
}

.ca-card {
  display: flex;
  flex-direction: column;
  gap: 11px;
  padding: 24px;
  border-radius: var(--ca-radius);
  background: var(--ca-surface);
  box-shadow: var(--ca-shadow-inset);
}

.ca-section-alt .ca-card {
  background: var(--ca-bg);
}

.ca-card p {
  color: var(--ca-muted);
  font-size: 0.9375rem;
}

.ca-card-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 38px;
  height: 38px;
  border-radius: 11px;
  background: color-mix(in srgb, var(--ca-blue) var(--ca-tint), var(--ca-surface-2));
  color: var(--ca-blue);
}

.ca-card-icon svg {
  width: 19px;
  height: 19px;
}

/* ─────────────────────────────────────────────────────────────────── the count strip ── */

.ca-count-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 28px 44px;
  padding: 26px 30px;
  margin-bottom: 30px;
  border-radius: var(--ca-radius);
  background: var(--ca-surface);
  box-shadow: var(--ca-shadow-inset);
}

.ca-section-alt .ca-count-strip {
  background: var(--ca-bg);
}

.ca-count {
  display: flex;
  flex-direction: column;
  gap: 3px;
  flex: 1 1 200px;
}

.ca-count b {
  font-family: var(--ca-serif);
  font-size: 2.1rem;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--ca-heading);
}

.ca-count span {
  color: var(--ca-muted);
  font-size: 0.8125rem;
  line-height: 1.45;
}

/* ─────────────────────────────────────────────────────────────────────────── screens ── */

/*
 * Six columns rather than two, because the screens are not all the same shape and forcing
 * them into equal halves is what makes a screenshot grid look broken.
 *
 * The phone capture is the reason. It is a 400px viewport, and the only honest way to show
 * it is at 400px — any wider and the reader is looking at a phone screen blown up to the
 * size of a laptop, which is not what anyone's phone does. A four-and-two split gives it
 * exactly that width beside the front-end thread, and the cap below holds it there at every
 * other width too.
 */
.ca-shots {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 22px;
  align-items: start;
}

.ca-shot {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.ca-shot--thread {
  grid-column: span 4;
}

.ca-shot--phone {
  grid-column: span 2;
}

.ca-shot--full {
  grid-column: span 6;
}

.ca-shot--half {
  grid-column: span 3;
}

.ca-shot--phone .ca-shot__frame,
.ca-shot--phone figcaption {
  max-width: 400px;
  margin-inline: auto;
}

.ca-shot__frame {
  overflow: hidden;
  border-radius: var(--ca-radius);
  background: var(--ca-surface);
  box-shadow: var(--ca-shadow-soft), var(--ca-shadow-inset);
}

.ca-shot__frame img {
  width: 100%;
  height: auto;
}

.ca-shot figcaption {
  color: var(--ca-muted);
  font-size: 0.875rem;
  line-height: 1.5;
}

/* Only true below the breakpoint where the admin screens stop sharing a row. */
.ca-shot-hint {
  display: none;
  gap: 10px;
  margin-top: 22px;
  color: var(--ca-muted);
  font-size: 0.8125rem;
  line-height: 1.5;
}

.ca-shot-hint svg {
  width: 15px;
  height: 15px;
  flex: none;
  margin-top: 3px;
  color: var(--ca-blue);
}

.ca-shot-hint a {
  color: var(--ca-link);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ────────────────────────────────────────────────────────────────────── feature grid ── */

.ca-feature-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 18px;
}

.ca-feature {
  display: flex;
  gap: 14px;
  padding: 22px;
  border-radius: var(--ca-radius);
  background: var(--ca-surface);
  box-shadow: var(--ca-shadow-inset);
}

.ca-section-alt .ca-feature {
  background: var(--ca-bg);
}

.ca-feature-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 36px;
  height: 36px;
  border-radius: 11px;
  background: var(--ca-surface-2);
  color: var(--ca-blue);
}

.ca-section-alt .ca-feature-icon {
  background: var(--ca-surface-3);
}

.ca-feature-icon svg {
  width: 18px;
  height: 18px;
}

.ca-feature h3 {
  margin-bottom: 6px;
}

.ca-feature p {
  color: var(--ca-muted);
  font-size: 0.875rem;
  line-height: 1.55;
}

/* ────────────────────────────────────────────────────────────────────────── callouts ── */

.ca-note {
  display: flex;
  gap: 13px;
  padding: 18px 20px;
  border-radius: var(--ca-radius-sm);
  background: color-mix(in srgb, var(--ca-info) var(--ca-tint-soft), var(--ca-surface));
  box-shadow: inset 3px 0 0 0 var(--ca-info);
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--ca-text);
}

.ca-section-alt .ca-note {
  background: color-mix(in srgb, var(--ca-info) var(--ca-tint-soft), var(--ca-bg));
}

.ca-note > svg {
  width: 18px;
  height: 18px;
  flex: none;
  margin-top: 3px;
  color: var(--ca-info);
}

.ca-note strong {
  color: var(--ca-heading);
}

.ca-note-warn {
  background: color-mix(in srgb, var(--ca-warn) var(--ca-tint-soft), var(--ca-surface));
  box-shadow: inset 3px 0 0 0 var(--ca-warn);
}

.ca-section-alt .ca-note-warn {
  background: color-mix(in srgb, var(--ca-warn) var(--ca-tint-soft), var(--ca-bg));
}

.ca-note-warn > svg {
  color: var(--ca-warn);
}

.ca-note-good {
  background: color-mix(in srgb, var(--ca-success) var(--ca-tint-soft), var(--ca-surface));
  box-shadow: inset 3px 0 0 0 var(--ca-success);
}

.ca-section-alt .ca-note-good {
  background: color-mix(in srgb, var(--ca-success) var(--ca-tint-soft), var(--ca-bg));
}

.ca-note-good > svg {
  color: var(--ca-success);
}

.ca-notes {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
  align-items: start;
}

/* ─────────────────────────────────────────────────────────────────────────── roadmap ── */

/*
 * A list, not a chart. A Gantt bar implies a date, and there are no dates here: the plan
 * is sequenced and each stage ships when the one before it has evidence behind it. The
 * rail carries that sequence, and the status chip carries the honesty — including the
 * last stage, which says in as many words that it is not a promise.
 */
.ca-timeline {
  list-style: none;
  margin: 0 0 34px;
  padding: 0;
  display: flex;
  flex-direction: column;
}

.ca-stage {
  position: relative;
  padding: 0 0 30px 34px;
}

/* The rail. It stops at the last stage rather than running off the end of the list. */
.ca-stage::before {
  content: '';
  position: absolute;
  left: 7px;
  top: 22px;
  bottom: 0;
  width: 2px;
  background: var(--ca-border);
}

.ca-stage:last-child {
  padding-bottom: 0;
}

.ca-stage:last-child::before {
  display: none;
}

/* The node. Filled for what exists, hollow for what does not — the difference is the point. */
.ca-stage::after {
  content: '';
  position: absolute;
  left: 0;
  top: 7px;
  width: 16px;
  height: 16px;
  border-radius: 999px;
  border: 3px solid var(--ca-border-strong);
  background: var(--ca-bg);
}

.ca-section-alt .ca-stage::after {
  background: var(--ca-surface-2);
}

.ca-stage--now::after {
  border-color: var(--ca-success);
  background: var(--ca-success);
}

.ca-stage--next::after {
  border-color: var(--ca-blue);
}

.ca-stage--maybe::after {
  border-style: dashed;
}

.ca-stage__head {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 9px;
}

.ca-stage__status {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  gap: 7px;
  padding: 4px 11px;
  border-radius: 999px;
  background: var(--ca-surface-2);
  box-shadow: inset 0 0 0 1px var(--ca-border);
  color: var(--ca-muted);
  font-size: 0.6875rem;
  font-weight: 780;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

.ca-section-alt .ca-stage__status {
  background: var(--ca-surface-3);
}

.ca-stage__status svg {
  width: 14px;
  height: 14px;
  flex: none;
}

.ca-stage--now .ca-stage__status {
  background: color-mix(in srgb, var(--ca-success) var(--ca-tint), var(--ca-surface));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ca-success) 30%, transparent);
  color: var(--ca-success-text);
}

.ca-stage--next .ca-stage__status,
.ca-stage--planned .ca-stage__status {
  background: color-mix(in srgb, var(--ca-blue) var(--ca-tint-soft), var(--ca-surface));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ca-blue) 26%, transparent);
  color: var(--ca-blue);
}

.ca-stage h3 {
  font-size: 1.1875rem;
  font-weight: 700;
}

.ca-stage > p {
  max-width: 76ch;
  color: var(--ca-muted);
  font-size: 0.9375rem;
}

.ca-stage__meta {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--ca-border);
  font-size: 0.8125rem;
  color: var(--ca-muted);
}

.ca-stage--maybe .ca-stage__meta,
.ca-stage--maybe > p {
  font-style: italic;
}

/*
 * Wide enough for two columns, the stage splits: what it is on the left, what it contains
 * on the right. Stacked, a 76ch paragraph leaves half the page empty beside it and the
 * section reads as a column of text that forgot to fill its container.
 */
@media (min-width: 1001px) {
  .ca-stage {
    display: grid;
    grid-template-columns: 300px minmax(0, 1fr);
    column-gap: 48px;
  }

  .ca-stage__head {
    grid-column: 1;
    grid-row: 1 / -1;
    margin-bottom: 0;
  }

  .ca-stage > p {
    grid-column: 2;
    max-width: 70ch;
  }
}

/* The guarantee band. It is the load-bearing promise of the whole section. */
.ca-guarantee {
  padding: 30px 32px;
  border-radius: var(--ca-radius);
  background: var(--ca-surface);
  box-shadow:
    inset 0 0 0 1.5px color-mix(in srgb, var(--ca-success) 34%, transparent),
    var(--ca-shadow-soft);
}

.ca-section-alt .ca-guarantee {
  background: var(--ca-bg);
}

.ca-guarantee__head {
  display: flex;
  gap: 16px;
  padding-bottom: 20px;
  margin-bottom: 20px;
  border-bottom: 1px solid var(--ca-border);
}

.ca-guarantee__head .ca-card-icon {
  background: color-mix(in srgb, var(--ca-success) var(--ca-tint), var(--ca-surface-2));
  color: var(--ca-success-text);
}

.ca-guarantee__head h3 {
  margin-bottom: 8px;
  font-size: 1.1875rem;
  font-weight: 700;
}

.ca-guarantee__head p {
  max-width: 78ch;
  color: var(--ca-muted);
  font-size: 0.9375rem;
}

.ca-guarantee__list {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px 26px;
  margin: 0;
  padding: 0;
  font-size: 0.9375rem;
}

.ca-guarantee__list li {
  display: flex;
  gap: 10px;
  align-items: flex-start;
}

.ca-guarantee__list svg {
  width: 17px;
  height: 17px;
  flex: none;
  margin-top: 4px;
  color: var(--ca-success);
}

/* ─────────────────────────────────────────────────────────────────────────────── FAQ ── */

.ca-faq {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
  align-items: start;
}

.ca-faq-item {
  border-radius: var(--ca-radius-sm);
  background: var(--ca-surface);
  box-shadow: var(--ca-shadow-inset);
  overflow: hidden;
}

.ca-section-alt .ca-faq-item {
  background: var(--ca-bg);
}

.ca-faq-item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 18px 20px;
  cursor: pointer;
  font-weight: 640;
  list-style: none;
}

.ca-faq-item summary::-webkit-details-marker {
  display: none;
}

.ca-faq-item summary::after {
  content: '+';
  flex: none;
  font-family: var(--ca-mono);
  font-size: 1.1rem;
  color: var(--ca-blue);
}

.ca-faq-item[open] summary::after {
  content: '\2212';
}

.ca-faq-answer {
  padding: 0 20px 20px;
  color: var(--ca-muted);
  font-size: 0.9375rem;
}

.ca-faq-answer p + p {
  margin-top: 10px;
}

.ca-faq-answer a {
  color: var(--ca-link);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.ca-faq-answer a:hover {
  color: var(--ca-link-hover);
}

/* ─────────────────────────────────────────────────────────────────────────── install ── */

.ca-install-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
  max-width: 680px;
  margin-inline: auto;
  padding: 42px 34px;
  border-radius: var(--ca-radius-lg);
  background: var(--ca-surface);
  box-shadow: var(--ca-shadow-inset);
  text-align: center;
}

.ca-section-alt .ca-install-card {
  background: var(--ca-bg);
}

.ca-install-mark img {
  border-radius: 14px;
  box-shadow: var(--ca-shadow-soft);
}

.ca-install-card > p {
  max-width: 54ch;
  color: var(--ca-muted);
}

.ca-steps-inline {
  counter-reset: ca-step;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: 100%;
  max-width: 480px;
  margin: 4px 0 0;
  padding: 0;
  text-align: left;
  color: var(--ca-muted);
  font-size: 0.9375rem;
}

.ca-steps-inline li {
  display: flex;
  gap: 12px;
}

.ca-steps-inline li > span {
  min-width: 0;
}

.ca-steps-inline li::before {
  counter-increment: ca-step;
  content: counter(ca-step, decimal-leading-zero);
  flex: none;
  padding-top: 1px;
  font-family: var(--ca-mono);
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--ca-blue);
}

.ca-steps-inline b {
  color: var(--ca-text);
  font-weight: 680;
}

.ca-spec-list {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin: 4px 0 0;
  padding: 0;
}

.ca-spec-list li {
  padding: 5px 12px;
  border-radius: 999px;
  background: var(--ca-surface-2);
  box-shadow: inset 0 0 0 1px var(--ca-border);
  color: var(--ca-muted);
  font-size: 0.75rem;
  font-weight: 640;
  white-space: nowrap;
}

/* ─────────────────────────────────────────────────────────────────────────── support ── */

.ca-support {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 24px;
  padding: 30px 34px;
  border-radius: var(--ca-radius);
  background: var(--ca-surface);
  box-shadow: var(--ca-shadow-inset);
}

.ca-section-alt .ca-support {
  background: var(--ca-bg);
}

.ca-support p:not(.ca-eyebrow) {
  max-width: 58ch;
  margin-top: 10px;
  color: var(--ca-muted);
  font-size: 0.9375rem;
}

/* ──────────────────────────────────────────────────────────────────────────── footer ── */

.ca-footer {
  position: relative;
  padding-block: 56px 26px;
  border-top: 1px solid var(--ca-border);
  background: var(--ca-surface-2);
}

.ca-footer-grid {
  display: grid;
  grid-template-columns: 1.7fr 1fr 1fr 1.1fr;
  gap: 40px;
  padding-bottom: 36px;
}

.ca-footer-brand p {
  margin-top: 14px;
  max-width: 44ch;
  color: var(--ca-muted);
  font-size: 0.875rem;
}

.ca-footer-links,
.ca-footer-install {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.ca-footer h2 {
  font-family: var(--ca-sans);
  font-size: 0.6875rem;
  font-weight: 750;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ca-muted);
}

.ca-footer-links a {
  color: var(--ca-muted);
  font-size: 0.875rem;
}

.ca-footer-links a:hover {
  color: var(--ca-text);
}

.ca-footer-install a {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  gap: 11px;
  padding: 12px 16px;
  border-radius: 12px;
  background: var(--ca-surface);
  box-shadow: var(--ca-shadow-inset);
  color: var(--ca-text);
  font-size: 0.8125rem;
  font-weight: 620;
  line-height: 1.3;
}

.ca-footer-install a:hover {
  box-shadow: inset 0 0 0 1px var(--ca-blue);
  color: var(--ca-blue);
}

.ca-footer-install svg {
  width: 22px;
  height: 22px;
  flex: none;
}

.ca-copyright {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 12px 24px;
  padding-top: 22px;
  border-top: 1px solid var(--ca-border);
  width: min(calc(100% - 48px), var(--ca-container));
  margin-inline: auto;
  color: var(--ca-muted);
  font-size: 0.8125rem;
}

.ca-copyright a {
  color: var(--ca-link);
}

.ca-scroll-top {
  position: fixed;
  right: 22px;
  bottom: 22px;
  z-index: 40;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border: 1px solid var(--ca-border);
  border-radius: 999px;
  background: var(--ca-surface);
  color: var(--ca-text);
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  transform: translateY(10px);
  transition:
    opacity 0.2s ease,
    transform 0.2s ease,
    visibility 0.2s;
  box-shadow: var(--ca-shadow-soft);
}

.ca-scroll-top svg {
  width: 19px;
  height: 19px;
}

.ca-scroll-top.is-visible {
  opacity: 1;
  visibility: visible;
  transform: none;
}

/* ─────────────────────────────────────────────────────────────────────────── reveals ── */

[data-ca-reveal] {
  opacity: 0;
  transform: translateY(14px);
  transition:
    opacity 0.55s ease,
    transform 0.55s ease;
}

[data-ca-reveal].is-visible {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  .ca-page *,
  .ca-page *::before,
  .ca-page *::after {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }

  [data-ca-reveal] {
    opacity: 1;
    transform: none;
  }
}

/* ───────────────────────────────────────────────────────────────────────── utilities ── */

/*
 * Three spacing utilities and no more. They exist so that no element on the page carries
 * an inline style: the stylesheet stays the only place a spacing value appears.
 */
.ca-gap-top-lg {
  margin-top: 30px;
}

.ca-gap-top {
  margin-top: 22px;
}

.ca-gap-sm {
  margin-top: 12px;
}

/* ═══════════════════════════════════════════════════════════════════════ responsive ══
 *
 * Additive and deliberately last, so each block wins on order without anything above it
 * needing to be edited. Checked by measurement at 320, 360, 390, 480, 620, 700, 768, 900,
 * 1024, 1180, 1440 and 1920 in both themes: no horizontal overflow, no text under 11px,
 * no tap target under 40px, and no grid left with an unfilled row.
 */

@media (max-width: 1180px) {
  .ca-nav a {
    padding: 8px 9px;
    font-size: 0.875rem;
  }
}

/*
 * The hero stacks here rather than at the 1080 the rest of the page turns on. Below this the
 * copy column is narrower than the headline phrase needs, and a stacked hero reads far better
 * than a headline broken across three lines. The exact number is measured: at 1240 the column
 * comes out at 554px against the 535px the phrase needs, and every width below it is worse.
 */
@media (max-width: 1240px) {
  .ca-hero-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 40px;
  }

  /* The demo is the argument, so it stays first-class rather than shrinking to a thumbnail. */
  .ca-demo {
    max-width: 640px;
  }
}

@media (max-width: 1080px) {
  .ca-hero {
    padding-block: 52px 64px;
  }

  .ca-feature-grid,
  .ca-guarantee__list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* Below this width the wide drawing's labels would fall under 10px. The stacked one
     carries the identical claim at full size. */
  .ca-dia__wide {
    display: none;
  }

  .ca-dia__tall {
    display: block;
  }
}

@media (max-width: 1000px) {
  .ca-nav {
    display: none;
  }

  .ca-menu-toggle {
    display: inline-flex;
  }

  .ca-header-inner {
    justify-content: space-between;
  }
}

@media (max-width: 900px) {
  .ca-section {
    padding-block: 64px;
  }

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

  /*
   * Four counts on a wrapping row fit three across here and drop the fourth onto a line of
   * its own, where it stretches to the full width and reads as a different kind of thing
   * from the three above it. Two by two keeps them one set.
   */
  .ca-count-strip {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .ca-footer-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 32px;
  }

  /* Every tap target reaches 44px once there is a thumb on the screen. */
  .ca-button,
  .ca-icon-button,
  .ca-faq-item summary {
    min-height: 44px;
  }

  .ca-demo__switch label {
    min-height: 36px;
    display: inline-flex;
    align-items: center;
  }

  /*
   * Every link that is its own row — nav, footer column, brand — gets a 40px box once
   * there is a thumb on the screen. A 22px footer link is a target you hit on the third
   * try. Links inside a sentence are deliberately NOT in this list: growing an inline link
   * to 40px would break the line it sits in, and WCAG exempts them for exactly that reason.
   */
  .ca-nav a,
  .ca-footer-links a,
  .ca-copyright > a,
  .ca-brand {
    min-height: 40px;
    display: flex;
    align-items: center;
  }

  /* Each row is its own 40px box now, so the gap between them can come back down. */
  .ca-footer-links {
    gap: 2px;
  }
}

@media (max-width: 760px) {
  /*
   * The screenshots stop sharing a row. Two admin screens side by side at this width are
   * two illegible thumbnails, and the caption under each is doing more work than the image.
   * The phone keeps its 400px cap and simply centres itself in the column.
   */
  .ca-shot--thread,
  .ca-shot--phone,
  .ca-shot--half {
    grid-column: span 6;
  }

  .ca-shot-hint {
    display: flex;
  }

  .ca-faq,
  .ca-notes {
    grid-template-columns: minmax(0, 1fr);
  }

  .ca-support {
    flex-direction: column;
    align-items: flex-start;
  }

  .ca-demo__body {
    padding: 18px;
  }
}

@media (max-width: 620px) {
  .ca-container,
  .ca-copyright {
    width: calc(100% - 32px);
  }

  .ca-section {
    padding-block: 52px;
  }

  .ca-section-tight {
    padding-block: 44px;
  }

  .ca-section-head {
    margin-bottom: 30px;
  }

  .ca-hero {
    padding-block: 36px 52px;
  }

  .ca-grid-3,
  .ca-feature-grid,
  .ca-footer-grid,
  .ca-guarantee__list {
    grid-template-columns: minmax(0, 1fr);
  }

  /* The call to action lands above the fold at 320px, the narrowest width this is checked at. */
  .ca-actions {
    width: 100%;
    flex-direction: column;
  }

  .ca-actions .ca-button {
    width: 100%;
  }

  /*
   * Hidden rather than shrunk to its icon. A 44px blue square with an unlabelled glyph is
   * not a call to action — nobody can tell what it does. The menu sheet carries the same
   * destination as a full-width labelled button, and the hero's own CTA is a thumb-flick
   * below the fold.
   */
  .ca-header-cta {
    display: none;
  }

  .ca-count-strip {
    gap: 20px 22px;
    padding: 20px 22px;
  }

  .ca-count b {
    font-size: 1.75rem;
  }

  /*
   * The switch moves under its own label rather than being squeezed beside it. At 320px
   * the two sit side by side at 11px, which is a control nobody can read the state of.
   */
  .ca-demo__head {
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
  }

  .ca-demo__switch {
    width: 100%;
  }

  .ca-demo__switch label {
    flex: 1;
    justify-content: center;
    text-align: center;
  }

  .ca-demo,
  .ca-install-card,
  .ca-support,
  .ca-guarantee,
  .ca-dia {
    border-radius: var(--ca-radius);
  }

  .ca-install-card,
  .ca-support,
  .ca-guarantee {
    padding: 26px 20px;
  }

  .ca-dia {
    padding: 20px 16px 16px;
  }

  /* The head stacks: a 38px icon beside a three-line heading leaves a 200px text column. */
  .ca-guarantee__head {
    flex-direction: column;
    gap: 12px;
  }

  .ca-stage {
    padding-left: 28px;
  }

  .ca-scroll-top {
    right: 14px;
    bottom: 14px;
  }
}

@media (max-width: 380px) {
  /* Long single words in the trust row would otherwise push the page sideways. */
  .ca-trust-list {
    flex-direction: column;
    gap: 7px;
  }

  .ca-demo__switch label {
    padding-inline: 8px;
    font-size: 0.6875rem;
  }
}
