/* ============================================================================
   Scoreflection — Marketing Components  (LANDING PAGE ONLY)
   ----------------------------------------------------------------------------
   Navigation, hero, listening-engine explainer, instrument-family cards, music
   flourishes, pricing, testimonial, CTA banner, footer. Specific to the
   marketing site — the future web app does NOT load this file.

   Requires: tokens.css + base.css (load them BEFORE this file).
============================================================================ */


/* ---------- Navigation --------------------------------------------------- */

.sf-nav {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in oklch, var(--sf-bg) 75%, transparent);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid var(--sf-outline-variant);
}
.sf-nav__inner {
  display: flex; align-items: center; justify-content: space-between;
  height: 72px;
}
.sf-nav__brand {
  display: inline-flex; align-items: center; gap: var(--sf-s-3);
  font-family: var(--sf-font-display);
  font-size: 22px; font-weight: 500; letter-spacing: -0.02em;
  color: var(--sf-on-surface);
}
.sf-nav__brand:hover { color: var(--sf-on-surface); }
.sf-nav__links { display: none; gap: var(--sf-s-7); align-items: center; }
.sf-nav__links a {
  color: var(--sf-on-surface-variant);
  font-weight: 500; font-size: 15px;
  position: relative; padding: 6px 0;
}
.sf-nav__links a:hover { color: var(--sf-on-surface); }
.sf-nav__links a.is-active { color: var(--sf-primary); }
.sf-nav__cta { display: flex; gap: var(--sf-s-3); align-items: center; }

/* Language switcher (EN | DE) */
.sf-lang {
  display: inline-flex; align-items: center;
  padding: 2px; gap: 2px;
  border: 1px solid var(--sf-outline-variant);
  border-radius: var(--sf-r-full);
}
.sf-lang__opt {
  font: 600 12px/1 var(--sf-font-ui); letter-spacing: 0.04em;
  padding: 6px 10px; border-radius: var(--sf-r-full);
  color: var(--sf-on-surface-variant);
}
.sf-lang__opt:hover { color: var(--sf-on-surface); }
.sf-lang__opt.is-active {
  color: var(--sf-on-primary); background: var(--sf-primary);
}

@media (min-width: 880px) {
  .sf-nav__links { display: flex; }
}

/* On a narrow phone the brand + language switcher + toggle + button don't fit on
   one row: the nav grew wider than the viewport and pushed the whole document
   sideways. Shrink the wordmark and drop the nav button — the hero repeats the
   same call to action a few hundred pixels below it. */
@media (max-width: 620px) {
  .sf-nav__brand { font-size: 19px; gap: var(--sf-s-2); }
  .sf-nav__cta > .sf-btn:last-child { display: none; }
}

/* Brand mark — the Clefbot badge, assets/clefbot-mark.svg.
   It's an <img>, not a lettermark: the antenna, ears and face are all part of
   the artwork, so this needs no pseudo-elements. The 10px radius matches the
   rounded square drawn inside the SVG, so the shadow hugs the corners. */
.sf-mark {
  width: 36px; height: 36px;
  flex: none;
  border-radius: 10px;
  box-shadow: 0 2px 10px color-mix(in oklch, var(--sf-primary) 32%, transparent);
}


/* ---------- Hero --------------------------------------------------------- */

.sf-hero {
  position: relative; overflow: hidden;
  padding-block: clamp(56px, 8vw, 96px) clamp(72px, 10vw, 120px);
}
.sf-hero__grid {
  display: grid; gap: clamp(40px, 6vw, 80px);
  grid-template-columns: 1fr;
  align-items: center;
}
@media (min-width: 980px) {
  .sf-hero__grid { grid-template-columns: 1.15fr 1fr; }
}
.sf-hero__title { font-size: var(--sf-display-l); }
.sf-hero__sub {
  font-size: clamp(17px, 1.4vw, 20px);
  color: var(--sf-on-surface-variant);
  max-width: 52ch; margin-top: var(--sf-s-5);
  text-wrap: pretty;
}
.sf-hero__cta { display: flex; gap: var(--sf-s-3); margin-top: var(--sf-s-8); flex-wrap: wrap; }
.sf-hero__meta {
  display: flex; gap: var(--sf-s-7); margin-top: var(--sf-s-9);
  flex-wrap: wrap;
}
.sf-hero__meta-item { display: flex; flex-direction: column; gap: 2px; }
/* The figure slot is a fixed-height box with its text bottom-aligned, so the
   three stats share a baseline and their labels all start at the same y. The
   sizes differ — 36px for a real figure, 24px for the phrase — and left to
   themselves the shorter line box rides up and drags its label with it. */
.sf-hero__meta-num {
  font-family: var(--sf-font-display);
  font-size: 36px; font-weight: 500; letter-spacing: -0.025em; line-height: 1.1;
  color: var(--sf-on-surface);
  display: flex; align-items: flex-end; min-height: 40px;
}
/* For a stat whose "number" is actually a phrase. At 36px a few words swamp the
   real figures beside them and wrap the row onto two lines. */
.sf-hero__meta-num--word { font-size: 24px; letter-spacing: -0.01em; }
.sf-hero__meta-label {
  font-size: var(--sf-label-m); letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--sf-on-surface-variant);
  font-weight: 600;
}

/* Hero stage — three real screenshots fanned out, the way the pitch deck does it:
   the session result front and centre, the library and the score tucked behind.
   These are photos of the actual app, not a mockup; see assets/screenshots/. */
.sf-phones {
  position: relative;
  aspect-ratio: 1 / 1;
  display: grid; place-items: center;
  isolation: isolate;
}
/* Soft halo behind the fan, so the phones sit on something rather than float */
.sf-phones::before {
  content: "";
  position: absolute; inset: 4% -4% 2%;
  border-radius: 50%;
  background: radial-gradient(closest-side,
    color-mix(in oklch, var(--sf-primary) 45%, transparent) 0%,
    color-mix(in oklch, var(--sf-primary) 18%, transparent) 55%,
    transparent 78%);
  filter: blur(28px);
  z-index: 0;
}

.sf-phone {
  position: absolute;
  width: 52%;
  margin: 0;
  padding: 4px;
  background: #07162C;                      /* the bezel — ink-20 */
  border-radius: 22px;
  box-shadow: 0 18px 44px var(--sf-shadow-strong);
  overflow: hidden;
}
.sf-phone img {
  display: block; width: 100%; height: auto;
  border-radius: 18px;
}
.sf-phone--center { z-index: 3; width: 58%; }
.sf-phone--left   { z-index: 1; transform: translate(-57%, 7%) rotate(-6deg) scale(0.88); }
.sf-phone--right  { z-index: 2; transform: translate( 57%, 7%) rotate( 6deg) scale(0.88); }

/* On a phone the fan is too cramped to read — show the payoff shot alone. */
@media (max-width: 560px) {
  .sf-phones { aspect-ratio: 3 / 4; }
  .sf-phone--left,
  .sf-phone--right { display: none; }
  .sf-phone--center { width: 72%; }
}


/* ---------- Section dividers (full-bleed SVG bands) ---------------------- */

/* Works for both an <img src="assets/divider-*.svg"> and an inlined <svg>.
   The inlined form is preferred on index.html: it can paint itself with the
   theme tokens, so the band still looks right in dark mode. Both use
   preserveAspectRatio="none" so they stretch to any width. */
.sf-divider {
  display: block; width: 100%; height: clamp(48px, 6vw, 96px);
  object-fit: fill;
}


/* ---------- Listening engine --------------------------------------------- */

/* Two-column explainer: the signal chain on the left, the spec card on right */
.sf-engine {
  display: grid; gap: clamp(40px, 5vw, 72px);
  grid-template-columns: 1fr;
  align-items: start;
}
@media (min-width: 980px) {
  .sf-engine { grid-template-columns: 1.2fr 1fr; }
}

/* The signal chain — numbered steps joined by a vertical line */
.sf-chain { list-style: none; counter-reset: sf-step; display: grid; gap: var(--sf-s-7); }
.sf-chain > li {
  counter-increment: sf-step;
  position: relative;
  display: grid; grid-template-columns: 40px 1fr; gap: var(--sf-s-4);
  align-items: start;
}
.sf-chain > li::before {
  content: counter(sf-step);
  width: 40px; height: 40px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--sf-surface);
  color: var(--sf-primary);
  border: 1.5px solid color-mix(in oklch, var(--sf-primary) 35%, transparent);
  font: 600 15px/1 var(--sf-font-ui);
  position: relative; z-index: 1;
}
/* connector down to the next step */
.sf-chain > li:not(:last-child)::after {
  content: "";
  position: absolute; left: 19px; top: 40px;
  bottom: calc(-1 * var(--sf-s-7));
  width: 2px;
  background: linear-gradient(
    to bottom,
    color-mix(in oklch, var(--sf-primary) 35%, transparent),
    color-mix(in oklch, var(--sf-primary) 10%, transparent));
}
.sf-chain__title { font: 600 17px/1.35 var(--sf-font-ui); color: var(--sf-on-surface); }
.sf-chain__body {
  color: var(--sf-on-surface-variant);
  font-size: 15px; line-height: 1.6; margin-top: var(--sf-s-1);
  text-wrap: pretty;
}

/* Spec card — the "under the hood" numbers */
.sf-spec {
  background: var(--sf-surface);
  border: 1px solid var(--sf-outline-variant);
  border-radius: var(--sf-r-2xl);
  padding: var(--sf-s-7);
  box-shadow: var(--sf-elev-2);
}
.sf-spec__head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sf-s-3); flex-wrap: wrap;
  margin-bottom: var(--sf-s-5);
}
.sf-spec__name { font-family: var(--sf-font-display); font-size: 20px; font-weight: 500; }
.sf-spec__rows { display: flex; flex-direction: column; }
.sf-spec__row {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--sf-s-4);
  padding: 11px 0;
  border-top: 1px solid var(--sf-outline-variant);
}
.sf-spec__row:first-child { border-top: 0; padding-top: 0; }
.sf-spec__k { font-size: 14px; color: var(--sf-on-surface-variant); }
.sf-spec__v {
  font-family: var(--sf-font-mono); font-size: 13px;
  color: var(--sf-on-surface); text-align: right;
}
.sf-spec__note {
  margin-top: var(--sf-s-5); padding-top: var(--sf-s-5);
  border-top: 1px solid var(--sf-outline-variant);
  font-size: 13px; line-height: 1.55; color: var(--sf-on-surface-variant);
  text-wrap: pretty;
}

/* Notehead legend — a copy of the app's own "What do the colors mean?" panel.
   The app doesn't label notes with words or pills: it repaints the notehead, and
   the SHAPE carries as much meaning as the color (a note released early becomes a
   half-head; one held too long stretches into a wide oval; one you never played
   stays a hollow ring). So the swatches here are noteheads, drawn with the app's
   palette from tokens.css — not chips. Anyone who reads this legend can read the
   score in the app. Sits on the score-paper background for the same reason. */
.sf-legend {
  list-style: none;
  background: var(--sf-score-bg);
  border: 1px solid var(--sf-outline-variant);
  border-radius: var(--sf-r-xl);
  padding: var(--sf-s-7) var(--sf-s-8);
  display: grid; gap: var(--sf-s-5) var(--sf-s-9);
  grid-template-columns: 1fr;
}
/* Two columns of four — and flowing down each column rather than across the rows,
   so the reading order stays the app's: the three "correct" variants and the wrong
   note together on the left, then everything about timing, misses and extras on the
   right. Row-flow would split the correct-note family across two rows. */
@media (min-width: 900px) {
  .sf-legend {
    grid-template-columns: 1fr 1fr;
    grid-template-rows: repeat(4, auto);
    grid-auto-flow: column;
  }
}
.sf-legend li {
  display: flex; align-items: center; gap: var(--sf-s-3);
  font-size: 14px; line-height: 1.35;
  color: color-mix(in oklch, var(--sf-score-ink) 78%, transparent);
  text-wrap: pretty;
}
.sf-legend b { color: var(--sf-score-ink); font-weight: 600; }
.sf-legend-head { max-width: 62ch; }

/* A real marked-up score. The screenshot is a photo of a light-themed app screen,
   so it keeps its own white paper in both themes rather than being tinted — same
   reasoning as --sf-score-bg, which stays warm in dark mode too. */
.sf-score-shot {
  margin: 0;
  border-radius: var(--sf-r-xl);
  border: 1px solid var(--sf-outline-variant);
  box-shadow: var(--sf-elev-2);
  overflow: hidden;
  background: #f2f2f7;                 /* matches the screenshot's own paper */
}
.sf-score-shot img { display: block; width: 100%; height: auto; }
/* The same frame around a looping clip. The clips in assets/video/ are cut from
   the product video, which is shot on a cream slide — so the frame takes that
   cream rather than the score's white, and the edges of the crop disappear into
   it. Capped at the clip's own width so it is never upscaled into mush. */
.sf-video-shot { max-width: 960px; background: #f4efe8; }
.sf-video-shot video { display: block; width: 100%; height: auto; }
.sf-score-shot figcaption {
  padding: var(--sf-s-4) var(--sf-s-6);
  border-top: 1px solid var(--sf-outline-variant);
  background: var(--sf-surface);
  font-size: 13px; line-height: 1.5;
  color: var(--sf-on-surface-variant);
  text-wrap: pretty;
}
.sf-legend__note { flex: none; width: 26px; height: 26px; }
/* The staff line the notehead sits on — the same hairline the score draws. */
.sf-legend__note line.staff { stroke: var(--sf-score-lines); stroke-width: 1; opacity: 0.35; }

/* "Also in the app" — a compact two/three-column feature roll-up.
   The minimum is wide on purpose: these entries are a sentence long, and at
   four-up the columns get too narrow to read. */
/* Eight entries, so two columns divide evenly (4+4). max() caps the count at two;
   min() keeps the floor from outgrowing a narrow phone, which would make the whole
   page scroll sideways. */
.sf-more {
  list-style: none;
  display: grid; gap: var(--sf-s-5) var(--sf-s-7);
  grid-template-columns: repeat(auto-fit,
    minmax(min(100%, max(300px, (100% - var(--sf-s-7)) / 2)), 1fr));
}
/* NOT flex: a flex container turns every child ELEMENT into its own flex item, so
   the <b> lead-in would be torn out of its sentence and laid out as a separate
   column. Block + hanging indent keeps the label inline where it belongs. */
.sf-more li {
  position: relative;
  padding-left: 26px;
  font-size: 15px; line-height: 1.55;
  color: var(--sf-on-surface-variant);
  text-wrap: pretty;
}
.sf-more li::before {
  content: "♪";
  position: absolute; left: 0; top: 0;
  font-family: var(--sf-font-display); font-size: 17px; line-height: 1.45;
  color: var(--sf-primary);
}
.sf-more b { color: var(--sf-on-surface); font-weight: 600; }

/* Readability fixes for the bullet list on the dark (ink) band */
.sf-section--ink .sf-list li { color: color-mix(in oklch, var(--sf-inverse-on-surface) 85%, transparent); }
.sf-section--ink .sf-list li::before,
.sf-section--ink .sf-eyebrow { color: color-mix(in oklch, var(--sf-inverse-on-surface) 60%, var(--sf-primary)); }
.sf-section--ink .sf-list li strong { color: var(--sf-inverse-on-surface); font-weight: 600; }


/* ---------- Family color system ------------------------------------------ */

.sf-fam {
  --_p: var(--sf-fam-keys);
  --_c: var(--sf-fam-keys-c);
}
.sf-fam--keys       { --_p: var(--sf-fam-keys);       --_c: var(--sf-fam-keys-c); }
.sf-fam--strings    { --_p: var(--sf-fam-strings);    --_c: var(--sf-fam-strings-c); }
.sf-fam--brass      { --_p: var(--sf-fam-brass);      --_c: var(--sf-fam-brass-c); }
.sf-fam--woodwind   { --_p: var(--sf-fam-woodwind);   --_c: var(--sf-fam-woodwind-c); }
.sf-fam--percussion { --_p: var(--sf-fam-percussion); --_c: var(--sf-fam-percussion-c); }
.sf-fam--vocal      { --_p: var(--sf-fam-vocal);      --_c: var(--sf-fam-vocal-c); }
.sf-fam--maestro    { --_p: var(--sf-fam-maestro);    --_c: var(--sf-fam-maestro-c); }

.sf-fam-card {
  background: var(--sf-surface);
  border: 1px solid var(--sf-outline-variant);
  border-radius: var(--sf-r-xl);
  padding: var(--sf-s-7) var(--sf-s-6) var(--sf-s-6);
  display: flex; flex-direction: column; gap: var(--sf-s-4);
  position: relative; overflow: hidden;
  transition: transform var(--sf-dur-2) var(--sf-ease-out), box-shadow var(--sf-dur-2) var(--sf-ease-out);
}
.sf-fam-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 12px 32px color-mix(in oklch, var(--_p) 25%, transparent);
}
/* The panel is washed back toward the surface color rather than sitting at full
   --_c, so the family tint reads without competing with the art on top of it.
   (Under v1 this was load-bearing: the bot's head was painted --_c too, so an
   untempered panel swallowed it and left floating eyes. The v2 bots have ink
   heads, which read on any tint — but the wash still keeps the tint a backdrop.)
   Square, because the v2 bots are square: head on the left, instrument on the
   right. The old 4:5 portrait was cut for the v1 bots, which stood upright. */
.sf-fam-card__art {
  aspect-ratio: 1 / 1;
  background:
    radial-gradient(120% 90% at 50% 100%,
      color-mix(in oklch, var(--_p) 16%, transparent) 0%,
      transparent 70%),
    color-mix(in oklch, var(--_c) 45%, var(--sf-surface));
  border-radius: var(--sf-r-lg);
  display: grid; place-items: center;
  position: relative;
  font-size: 56px;
  padding: var(--sf-s-2);
  overflow: hidden;
}
.sf-fam-card__art svg { width: 72%; height: auto; }
/* Clefbot mascot art (assets/clefbots/) — portrait, so bound it by height.
   The drop shadow lifts the instrument off the panel; without it the body reads
   as part of the background tint. */
.sf-fam-card__art img {
  width: auto; max-width: 100%;
  height: 100%; object-fit: contain;
  filter: drop-shadow(0 3px 6px color-mix(in oklch, var(--_p) 30%, transparent));
}
.sf-fam-card__name {
  font-family: var(--sf-font-display);
  font-weight: 500; font-size: 22px; letter-spacing: -0.01em;
}
.sf-fam-card__meta {
  font: 600 11px/1 var(--sf-font-ui);
  text-transform: uppercase; letter-spacing: 0.12em;
  color: var(--_p);
}
/* Whether the listener for this family has actually been measured.
   Two states and no third: a family is either one we have checked against real
   recordings or one we have not, and "partly" would be the word that lets an
   unchecked instrument read as available. --wip deliberately does NOT use the
   family tint: it has to look like a caveat from across the card, and a badge in
   the same colour as everything else on the card reads as decoration. */
.sf-fam-card__status {
  font: 600 11px/1 var(--sf-font-ui);
  text-transform: uppercase; letter-spacing: 0.1em;
  padding: 5px 9px; border-radius: var(--sf-r-full);
  align-self: flex-start;
}
.sf-fam-card__status--live {
  background: color-mix(in oklch, var(--_p) 16%, transparent);
  color: var(--_p);
}
.sf-fam-card__status--wip {
  background: color-mix(in oklch, var(--sf-on-surface-variant) 12%, transparent);
  color: var(--sf-on-surface-variant);
}
/* An unchecked family is still shown — it is on the roadmap and people ask for
   theirs — but it must not compete with the two that work. */
.sf-fam-card--wip { opacity: 0.72; }
.sf-fam-card__list {
  list-style: none; display: flex; flex-wrap: wrap; gap: 6px;
  margin-top: auto;
}
.sf-fam-card__list li {
  font: 500 12px/1 var(--sf-font-ui);
  padding: 5px 10px; border-radius: var(--sf-r-full);
  background: color-mix(in oklch, var(--_p) 10%, transparent);
  color: var(--_p);
}

.sf-swatch {
  width: 100%; aspect-ratio: 1 / 1;
  background: var(--_p);
  border-radius: var(--sf-r-lg);
  position: relative;
  box-shadow: inset 0 0 0 1px color-mix(in oklch, black 8%, transparent);
}
.sf-swatch::after {
  content: ""; position: absolute; right: 10px; bottom: 10px;
  width: 36%; aspect-ratio: 1/1; border-radius: var(--sf-r-md);
  background: var(--_c);
}


/* ---------- Music-flavored flourishes ------------------------------------ */

/* Staff-line divider — five horizontal lines like a music staff */
.sf-staff {
  width: 100%; height: 36px;
  background-image: repeating-linear-gradient(
    to bottom,
    transparent 0 7px,
    var(--sf-outline-variant) 7px 8px
  );
  background-size: 100% 40px;
  background-repeat: no-repeat;
  background-position: center;
  position: relative;
  opacity: 0.7;
}
.sf-staff::before {
  /* treble-clef-like glyph */
  content: "𝄞";
  position: absolute; left: 0; top: 50%;
  transform: translateY(-55%);
  font-family: var(--sf-font-display);
  font-size: 56px; color: var(--sf-primary);
  line-height: 1;
}

/* Antenna dot — the ClefBot's signature topknot, reusable as a list bullet */
.sf-antenna {
  position: relative; display: inline-block;
  width: 14px; height: 18px;
}
.sf-antenna::before {
  content: ""; position: absolute; left: 50%; top: 8px;
  width: 2.5px; height: 8px; background: var(--sf-primary);
  border-radius: 2px; transform: translateX(-50%);
}
.sf-antenna::after {
  content: ""; position: absolute; left: 50%; top: 0;
  width: 12px; height: 12px; background: var(--sf-primary);
  border-radius: 50%; transform: translateX(-50%);
  box-shadow: 0 0 0 3px color-mix(in oklch, var(--sf-primary) 22%, transparent);
}

.sf-list { list-style: none; display: flex; flex-direction: column; gap: var(--sf-s-3); }
.sf-list li {
  display: flex; align-items: flex-start; gap: var(--sf-s-3);
  font-size: 16px; line-height: 1.5;
}
.sf-list li::before {
  content: "♪";
  font-family: var(--sf-font-display);
  font-size: 18px; line-height: 1.2;
  color: var(--sf-primary);
  flex: none; width: 24px; text-align: center;
}

/* Score panel — a piece of sheet-music styled surface for embedding content */
.sf-score {
  background:
    repeating-linear-gradient(
      to bottom,
      transparent 0 19px,
      color-mix(in oklch, var(--sf-score-lines) 22%, transparent) 19px 20px
    ),
    var(--sf-score-bg);
  background-size: 100% 100px;
  border-radius: var(--sf-r-xl);
  border: 1px solid var(--sf-outline-variant);
  padding: var(--sf-s-8);
  color: var(--sf-score-ink);
  font-family: var(--sf-font-display);
  position: relative;
}

/* Mood swatch row — a quick visual fingerprint of the bot palette */
.sf-mood-strip { display: flex; gap: var(--sf-s-2); flex-wrap: wrap; }
.sf-mood-strip > * {
  width: 32px; height: 32px; border-radius: 50%;
  box-shadow: inset 0 0 0 1px color-mix(in oklch, black 10%, transparent);
}


/* ---------- Pricing ------------------------------------------------------ */

/* One plan per column, and the count follows the number of plans — which is now
   two, not three. This rule beats the .sf-grid-N class on the element (an id
   selector), so leaving it at three left the second card beside a hole where Pro
   used to be. Two plans divide evenly into two columns or one; there is no
   arrangement that strands one on its own row. */
#pricing .sf-grid { grid-template-columns: 1fr; }
@media (min-width: 700px) {
  #pricing .sf-grid { grid-template-columns: repeat(2, 1fr); }
}

.sf-price {
  background: var(--sf-surface);
  border: 1px solid var(--sf-outline-variant);
  border-radius: var(--sf-r-2xl);
  padding: var(--sf-s-8) var(--sf-s-7);
  display: flex; flex-direction: column; gap: var(--sf-s-5);
  position: relative;
  transition: transform var(--sf-dur-2) var(--sf-ease-out), box-shadow var(--sf-dur-2) var(--sf-ease-out);
}
.sf-price:hover { transform: translateY(-3px); box-shadow: var(--sf-elev-2); }
.sf-price--feature {
  background: var(--sf-inverse-surface);
  color: var(--sf-inverse-on-surface);
  border-color: transparent;
  box-shadow: var(--sf-elev-3);
}
.sf-price--feature .sf-price__name,
.sf-price--feature .sf-price__amount,
.sf-price--feature .sf-price__features li { color: var(--sf-inverse-on-surface); }
.sf-price--feature .sf-price__sub,
.sf-price--feature .sf-price__per { color: color-mix(in oklch, var(--sf-inverse-on-surface) 70%, transparent); }
.sf-price--feature .sf-price__flag {
  position: absolute; top: -14px; left: 50%; transform: translateX(-50%);
  background: var(--sf-primary); color: var(--sf-on-primary);
  padding: 6px 14px; border-radius: var(--sf-r-full);
  font: 600 11px/1 var(--sf-font-ui); letter-spacing: 0.12em; text-transform: uppercase;
}
.sf-price__name { font-family: var(--sf-font-display); font-size: 22px; font-weight: 500; }
.sf-price__sub  { font-size: 14px; color: var(--sf-on-surface-variant); margin-top: -10px; }
.sf-price__row  { display: flex; align-items: baseline; gap: 6px; }
.sf-price__amount {
  font-family: var(--sf-font-display);
  font-size: 56px; font-weight: 500; letter-spacing: -0.03em;
  line-height: 1;
}
.sf-price__per   { font-size: 14px; color: var(--sf-on-surface-variant); }
.sf-price__features { list-style: none; display: flex; flex-direction: column; gap: var(--sf-s-3); margin: var(--sf-s-3) 0; }
/* Plans have different numbers of features, so pin the button to the bottom —
   otherwise the three call-to-actions sit at three different heights. */
.sf-price > .sf-btn { margin-top: auto; }
.sf-price__features li { display: flex; gap: var(--sf-s-3); align-items: flex-start; font-size: 15px; }
.sf-price__features li::before {
  content: ""; flex: none; width: 18px; height: 18px; border-radius: 50%;
  /* The tick is a data: URI, so its colour has to be a literal — a data: URI is
     its own document and `var()` does not cross that boundary, and `%23` hides
     the hex from a plain search for `#`. It is ink-34, the light-theme primary.
     If the palette moves, this line moves by hand. */
  background: color-mix(in oklch, var(--sf-primary) 18%, transparent) center / 10px no-repeat
              url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path d='M3.5 8.5l3 3 6-7' stroke='%23193763' stroke-width='2.2' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  margin-top: 2px;
}
/* The featured card is --sf-inverse-surface, which is DARK in light mode and
   LIGHT in dark mode. The disc follows that automatically, but the tick inside
   it is a data: URI and cannot read a var(), so the two cases are spelled out.
   A single white tick was only ever right for the light theme; in dark mode the
   card flips light and the tick disappeared into it. */
.sf-price--feature .sf-price__features li::before {
  background-color: color-mix(in oklch, var(--sf-inverse-on-surface) 18%, transparent);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path d='M3.5 8.5l3 3 6-7' stroke='%23E6ECF3' stroke-width='2.2' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>");
}
[data-theme="dark"] .sf-price--feature .sf-price__features li::before {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path d='M3.5 8.5l3 3 6-7' stroke='%230C1723' stroke-width='2.2' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>");
}


/* ---------- Testimonial -------------------------------------------------- */

.sf-quote {
  display: flex; flex-direction: column; gap: var(--sf-s-6);
  background: var(--sf-surface);
  border: 1px solid var(--sf-outline-variant);
  border-radius: var(--sf-r-2xl);
  padding: var(--sf-s-8);
  position: relative;
}
.sf-quote::before {
  content: "\201C"; position: absolute; top: 8px; left: 24px;
  font-family: var(--sf-font-display);
  font-size: 88px; line-height: 1;
  color: var(--sf-primary);
  opacity: 0.5;
}
.sf-quote__body {
  font-family: var(--sf-font-display);
  font-size: 22px; line-height: 1.4; letter-spacing: -0.005em;
  font-weight: 400;
  text-wrap: pretty;
  margin-top: var(--sf-s-7);
}
.sf-quote__by  { display: flex; align-items: center; gap: var(--sf-s-3); }
.sf-quote__avatar {
  width: 44px; height: 44px; border-radius: 50%;
  background: var(--sf-primary-container);
  color: var(--sf-on-primary-container);
  display: grid; place-items: center;
  font-family: var(--sf-font-display); font-weight: 500; font-size: 18px;
  flex: none;
}
.sf-quote__name  { font-weight: 600; font-size: 15px; }
.sf-quote__role  { font-size: 13px; color: var(--sf-on-surface-variant); }


/* ---------- CTA banner --------------------------------------------------- */

/* The banner art is a baked DARK surface in both themes (an <img>-style
   background can't follow the palette), so the ink on it must not follow the
   palette either. --sf-on-primary flips to a deep navy in dark mode, which put
   dark text on the dark banner; --_ink is pinned light instead. Everything
   inside .sf-cta paints with --_ink rather than --sf-on-primary for that
   reason. */
.sf-cta {
  --_ink: #FFFFFF;   /* slate-000 */
  --_on-ink: #193763; /* ink-34 — for the solid button sitting on the banner */
  background: url("../assets/cta-banner.svg") center / cover no-repeat,
              #031D44;   /* ink-24 — matches the art's top stop if it fails to load */
  color: var(--_ink);
  border-radius: var(--sf-r-3xl);
  padding: clamp(40px, 6vw, 72px);
  display: grid; grid-template-columns: 1fr; gap: var(--sf-s-7);
  align-items: center;
  position: relative; overflow: hidden;
  box-shadow: var(--sf-elev-3);
}
/* The copy and the buttons BOTH stack in the left column, which leaves the
   right one empty for the Clefbot painted by cta-banner.svg underneath. The
   obvious reading of this grid — copy left, buttons right — puts the buttons
   directly on top of the mascot, with "How it works" unreadable against its
   face. If you change these rows, move the bot in the SVG to match. */
@media (min-width: 880px) {
  .sf-cta { grid-template-columns: 1.4fr 1fr; row-gap: 0; }
  .sf-cta > :first-child { grid-column: 1; grid-row: 1; }
  .sf-cta__actions       { grid-column: 1; grid-row: 2; }
}
/* The Clefbot is its own layer rather than part of cta-banner.svg, because that
   banner is painted `center / cover` and the box aspect swings from ~3.8:1 to
   ~1.5:1 — at 900px a bot drawn into the SVG lost half its face off the right
   edge. Pinned here and sized by `contain`, it cannot crop at any width. */
.sf-cta::after {
  content: ""; position: absolute; z-index: 0;
  right: clamp(16px, 4%, 64px); top: 50%; translate: 0 -50%;
  width: clamp(120px, 20%, 210px); aspect-ratio: 380 / 370;
  background: url("../assets/cta-mascot.svg") center / contain no-repeat;
  pointer-events: none;
}
.sf-cta > * { position: relative; z-index: 1; }
/* Single column below the breakpoint: nothing is holding the right side open,
   so the bot would sit under the copy. */
@media (max-width: 879.98px) { .sf-cta::after { display: none; } }
.sf-cta::before {
  content: ""; position: absolute; right: -80px; top: -80px;
  width: 360px; height: 360px; border-radius: 50%;
  background: color-mix(in oklch, white 18%, transparent);
  filter: blur(20px);
  pointer-events: none;
}
.sf-cta__title {
  font-family: var(--sf-font-display);
  font-size: clamp(32px, 4.4vw, 52px);
  letter-spacing: -0.025em; line-height: 1.05; font-weight: 400;
  color: var(--_ink); text-wrap: balance;
}
.sf-cta__sub  { color: color-mix(in oklch, var(--_ink) 85%, transparent); margin-top: var(--sf-s-4); max-width: 48ch; }
.sf-cta__actions { display: flex; gap: var(--sf-s-3); margin-top: var(--sf-s-5); flex-wrap: wrap; }
.sf-cta .sf-btn--secondary { background: var(--_ink); color: var(--_on-ink); border-color: transparent; }
.sf-cta .sf-btn--secondary:hover { background: color-mix(in oklch, white 90%, var(--_on-ink)); }
.sf-cta .sf-btn--ghost { color: var(--_ink); border-color: color-mix(in oklch, var(--_ink) 40%, transparent); }
.sf-cta .sf-btn--ghost:hover { background: color-mix(in oklch, white 12%, transparent); }


/* ---------- Error / status pages ----------------------------------------- */

.sf-error {
  min-height: calc(100dvh - 72px);   /* full height minus the sticky nav */
  display: grid; place-items: center;
  padding: var(--sf-s-9) var(--sf-s-5);
  text-align: center;
}
.sf-error__inner { display: flex; flex-direction: column; align-items: center; gap: var(--sf-s-6); }
.sf-error__art {
  display: block; width: min(520px, 100%); height: auto;
  border-radius: var(--sf-r-2xl);
  border: 1px solid var(--sf-outline-variant);
  box-shadow: var(--sf-elev-2);
}
.sf-error__actions { display: flex; gap: var(--sf-s-3); flex-wrap: wrap; justify-content: center; }


/* ---------- Content / legal pages (long-form prose) ---------------------- */

.sf-prose { max-width: 70ch; }
.sf-prose > * + * { margin-top: var(--sf-s-4); }
.sf-prose h2 {
  font-family: var(--sf-font-display);
  font-size: 26px; font-weight: 500; letter-spacing: -0.01em;
  line-height: 1.2;
  margin-top: var(--sf-s-8);
}
.sf-prose h3 {
  font-size: 18px; font-weight: 600; letter-spacing: -0.005em;
  margin-top: var(--sf-s-6);
}
.sf-prose p,
.sf-prose li { color: var(--sf-on-surface-variant); font-size: 16px; line-height: 1.65; }
.sf-prose ul,
.sf-prose ol { padding-left: 1.25em; display: flex; flex-direction: column; gap: var(--sf-s-2); }
.sf-prose a { text-decoration: underline; text-underline-offset: 2px; }
.sf-prose strong { color: var(--sf-on-surface); font-weight: 600; }
.sf-prose dt { font-weight: 600; color: var(--sf-on-surface); margin-top: var(--sf-s-4); }
.sf-prose dd { color: var(--sf-on-surface-variant); }
/* The model withdrawal form in the AGB is quoted statutory text, not our voice.
   Set it off with a rule rather than the browser's 40px indent on both sides. */
.sf-prose blockquote {
  margin: 0;
  padding-left: var(--sf-s-4);
  border-left: 2px solid var(--sf-outline-variant);
}

.sf-page-meta {
  font: 600 var(--sf-label-m)/1.4 var(--sf-font-ui);
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--sf-on-surface-variant);
  margin-top: var(--sf-s-4);
}


/* ---------- Comparison table (compare.html) ------------------------------- */
/* Apps down, criteria across. On a phone that is wider than the screen, so the
   wrapper scrolls sideways and the app names stay pinned on the left — the name
   is what the row means.

   The verdict marks deliberately stay OFF green and red. Those hues belong to
   the practice-feedback system (see README, "The palette"), and a comparison
   table in traffic-light colours reads as "we are good, they are bad", which is
   the tone § 6 UWG and the rest of this site both avoid. A yes is ink, a no is
   muted, a partly is brass, and every cell also says it in words. */

.sf-compare {
  margin-top: var(--sf-s-7);
  overflow-x: auto;
  border: 1px solid var(--sf-outline-variant);
  border-radius: var(--sf-r-lg);
  background: var(--sf-surface);
}
.sf-compare:focus-visible { outline: 2px solid var(--sf-primary); outline-offset: 2px; }
.sf-compare table {
  width: 100%; min-width: 760px;
  border-collapse: collapse;
  font-size: 14px; line-height: 1.45;
}
.sf-compare caption {
  caption-side: bottom; text-align: left;
  padding: var(--sf-s-3) var(--sf-s-4);
  font-size: 13px; color: var(--sf-on-surface-variant);
  border-top: 1px solid var(--sf-outline-variant);
}
.sf-compare th,
.sf-compare td {
  padding: var(--sf-s-3) var(--sf-s-4);
  text-align: left; vertical-align: top;
  border-bottom: 1px solid var(--sf-outline-variant);
  color: var(--sf-on-surface-variant);
}
.sf-compare tbody tr:last-child > * { border-bottom: 0; }
.sf-compare thead th {
  font: 600 var(--sf-label-m)/1.3 var(--sf-font-ui);
  letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--sf-on-surface);
  background: var(--sf-surface-variant);
}
.sf-compare tbody th {
  position: sticky; left: 0; z-index: 1;
  min-width: 150px;
  background: var(--sf-surface);
  color: var(--sf-on-surface); font-weight: 600;
}
.sf-compare thead th:first-child { position: sticky; left: 0; z-index: 2; }
.sf-compare__kind {
  display: block; margin-top: 2px;
  font-size: 12px; font-weight: 400; color: var(--sf-on-surface-variant);
}
/* Our own row is set off, not shouted: a tint, and nothing louder. */
.sf-compare tr.is-us > * { background: var(--sf-primary-container); color: var(--sf-on-primary-container); }

.sf-yes, .sf-no, .sf-part { font-weight: 600; white-space: nowrap; }
.sf-yes  { color: var(--sf-primary); }
.sf-no   { color: var(--sf-on-surface-variant); font-weight: 500; }
.sf-part { color: var(--sf-tertiary); }
.sf-compare tr.is-us .sf-yes { color: var(--sf-on-primary-container); }
.sf-compare small { display: block; font-size: 12px; font-weight: 400; white-space: normal; }

/* The "which one should you pick" cards under the table. */
.sf-pick { margin-top: var(--sf-s-7); }
.sf-pick h3 { font-size: 17px; font-weight: 600; color: var(--sf-on-surface); }
.sf-pick p { margin-top: var(--sf-s-2); font-size: 15px; line-height: 1.6; color: var(--sf-on-surface-variant); }
.sf-prose .sf-sources li { font-size: 14px; }


/* ---------- FAQ page (accordion) ----------------------------------------- */
/* Built on native <details>/<summary>: no JavaScript, keyboard-accessible for
   free, and the answers still print and still show up in a browser's find.
   main.js only opens the one item a #hash points at. */

.sf-faq-nav {
  display: flex; flex-wrap: wrap; gap: var(--sf-s-2);
  margin-top: var(--sf-s-6);
}
.sf-faq-nav a {
  display: inline-flex; align-items: center;
  padding: var(--sf-s-2) var(--sf-s-4);
  border: 1px solid var(--sf-outline-variant);
  border-radius: var(--sf-r-full);
  background: var(--sf-surface);
  color: var(--sf-on-surface-variant);
  font-size: 14px; font-weight: 500;
  text-decoration: none;
  transition: color var(--sf-dur-1) var(--sf-ease-out),
              border-color var(--sf-dur-1) var(--sf-ease-out);
}
.sf-faq-nav a:hover {
  color: var(--sf-primary);
  border-color: var(--sf-primary);
}

.sf-faq__group { margin-top: var(--sf-s-9); }
.sf-faq__group > h2 {
  font-family: var(--sf-font-display);
  font-size: 26px; font-weight: 500; letter-spacing: -0.01em;
  line-height: 1.2;
  /* Anchored from the topic nav, so keep it clear of the sticky header. */
  scroll-margin-top: 96px;
}

.sf-faq__list {
  margin-top: var(--sf-s-5);
  border-top: 1px solid var(--sf-outline-variant);
}

.sf-faq__item {
  border-bottom: 1px solid var(--sf-outline-variant);
  scroll-margin-top: 96px;
}
.sf-faq__item > summary {
  display: flex; align-items: flex-start; gap: var(--sf-s-4);
  padding: var(--sf-s-5) 0;
  cursor: pointer;
  list-style: none;                       /* kill the default marker … */
  color: var(--sf-on-surface);
  font-size: 17px; font-weight: 600; line-height: 1.45;
  transition: color var(--sf-dur-1) var(--sf-ease-out);
}
.sf-faq__item > summary::-webkit-details-marker { display: none; }  /* … Safari */
.sf-faq__item > summary:hover { color: var(--sf-primary); }
.sf-faq__item > summary:focus-visible {
  outline: 2px solid var(--sf-primary);
  outline-offset: 4px;
  border-radius: var(--sf-r-xs);
}

/* Our own marker: a chevron that turns when the item opens. */
.sf-faq__item > summary::after {
  content: "";
  flex: none;
  width: 10px; height: 10px;
  margin-left: auto; margin-top: 6px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  transform-origin: 60% 60%;
  opacity: 0.55;
  transition: transform var(--sf-dur-2) var(--sf-ease-out);
}
.sf-faq__item[open] > summary::after { transform: rotate(-135deg); }
.sf-faq__item[open] > summary { color: var(--sf-primary); }

.sf-faq__body { padding-bottom: var(--sf-s-6); max-width: 68ch; }
.sf-faq__body > * + * { margin-top: var(--sf-s-4); }
.sf-faq__body p,
.sf-faq__body li { color: var(--sf-on-surface-variant); font-size: 16px; line-height: 1.65; }
.sf-faq__body ul,
.sf-faq__body ol { padding-left: 1.25em; display: flex; flex-direction: column; gap: var(--sf-s-2); }
.sf-faq__body a { text-decoration: underline; text-underline-offset: 2px; }
.sf-faq__body strong { color: var(--sf-on-surface); font-weight: 600; }

/* Screenshots inside an answer. Phone shots are portrait and would tower over
   the text at full width, so they are capped and left-aligned rather than
   stretched. The frame keeps a light-mode screenshot from floating on the dark
   theme's background. */
.sf-faq__shot { margin-top: var(--sf-s-5); }
.sf-faq__shot img {
  display: block;
  width: 100%; max-width: 300px; height: auto;
  border-radius: var(--sf-r-lg);
  border: 1px solid var(--sf-outline-variant);
  box-shadow: var(--sf-elev-2);
  background: var(--sf-surface);
}
.sf-faq__shot--wide img { max-width: 100%; }
.sf-faq__shot figcaption {
  margin-top: var(--sf-s-3);
  color: var(--sf-on-surface-variant);
  font-size: 13px; line-height: 1.5;
}

/* Instant search over the answers (faq-search.js).

   Ships hidden and is revealed by the script, so the page without JS never
   shows a box that cannot do anything. `[hidden]` is the only visibility
   mechanism the script touches — style-src has no 'unsafe-inline', so nothing
   may write a style attribute — and .sf-faq__item carries a border, so the
   attribute needs saying twice as loudly as the UA sheet says it. */
.sf-faq-search { margin-top: var(--sf-s-6); }
.sf-faq-search[hidden],
.sf-faq__item[hidden],
.sf-faq__group[hidden],
.sf-faq-nav[hidden] { display: none !important; }

.sf-faq-search__label {
  display: block;
  font-size: 13px; font-weight: 600;
  color: var(--sf-on-surface);
  margin-bottom: var(--sf-s-2);
}
.sf-faq-search__field {
  display: flex; align-items: center; gap: var(--sf-s-2);
  border: 1px solid var(--sf-outline-variant);
  border-radius: var(--sf-r-lg);
  background: var(--sf-surface);
  padding: var(--sf-s-2) var(--sf-s-3);
}
.sf-faq-search__field:focus-within {
  border-color: var(--sf-primary);
  box-shadow: var(--sf-elev-1);
}
.sf-faq-search__input {
  flex: 1; min-width: 0;
  border: 0; outline: 0; background: transparent;
  font: inherit; font-size: 16px;   /* 16px or iOS zooms the page on focus */
  color: var(--sf-on-surface);
  padding: var(--sf-s-2);
}
.sf-faq-search__input::placeholder { color: var(--sf-on-surface-variant); opacity: 0.8; }
/* The native clear affordance would sit next to ours and do the same job. */
.sf-faq-search__input::-webkit-search-cancel-button { display: none; }

.sf-faq-search__clear {
  flex: none;
  border: 1px solid var(--sf-outline-variant);
  border-radius: var(--sf-r-lg);
  background: transparent;
  color: var(--sf-on-surface-variant);
  font: inherit; font-size: 13px;
  padding: var(--sf-s-1) var(--sf-s-3);
  cursor: pointer;
}
.sf-faq-search__clear:hover { color: var(--sf-on-surface); border-color: var(--sf-outline); }

.sf-faq-search__status {
  margin-top: var(--sf-s-3);
  font-size: 13px;
  color: var(--sf-on-surface-variant);
}
.sf-faq-search__status:empty { display: none; }

/* While a search is running the groups lose their spacing: a heading with two
   answers under it should not be pushed a screenful from the one above. */
.sf-faq-search.is-active ~ .sf-faq__group { margin-top: var(--sf-s-7); }

/* faq-search.js wraps each question's own nodes in this, so that highlighting
   inside it cannot multiply the flex items of the <summary> around it. */
.sf-faq__q { min-width: 0; }

.sf-faq__item mark {
  background: var(--sf-primary-container);
  color: var(--sf-on-surface);
  border-radius: 3px;
  padding: 0 2px;
}

/* "Also asked as" — the other words people use for the same thing, printed
   under an answer whose vocabulary genuinely varies (voice / part / stave /
   hand / track all mean one row of the voices list). Visible on purpose: it is
   a reading aid and a Ctrl+F target first, and only incidentally the reason a
   search for "mute one hand" can land on an answer that says "silence a voice".
   Hiding it would make it cloaking and cost the page more than it ever paid. */
.sf-faq__body .sf-faq__also {
  margin-top: var(--sf-s-4);
  padding-top: var(--sf-s-3);
  border-top: 1px dashed var(--sf-outline-variant);
  color: var(--sf-on-surface-variant);
  font-size: 13px; line-height: 1.6;
}
.sf-faq__body .sf-faq__also b {
  color: var(--sf-on-surface);
  font-weight: 600;
}

/* The landing page's link out to the full FAQ, under the teaser list. */
.sf-faq-more { margin-top: var(--sf-s-8); text-align: center; }

/* Closing "still stuck?" card. */
.sf-faq-help {
  margin-top: var(--sf-s-10);
  padding: var(--sf-s-7);
  border: 1px solid var(--sf-outline-variant);
  border-radius: var(--sf-r-xl);
  background: var(--sf-surface);
  box-shadow: var(--sf-elev-1);
}
.sf-faq-help h2 {
  font-family: var(--sf-font-display);
  font-size: 22px; font-weight: 500; letter-spacing: -0.01em;
}
.sf-faq-help p { margin-top: var(--sf-s-3); color: var(--sf-on-surface-variant); font-size: 16px; }

@media (prefers-reduced-motion: reduce) {
  .sf-faq__item > summary::after { transition: none; }
}


/* ---------- Footer ------------------------------------------------------- */

.sf-footer {
  border-top: 1px solid var(--sf-outline-variant);
  padding-block: var(--sf-s-10) var(--sf-s-9);
  background: var(--sf-bg);
}
/* The link columns are sized to their CONTENT, not stretched. With `1fr` tracks
   the three short lists each took a third of whatever was left, so on a wide
   window "Product / Company / Legal" drifted to opposite ends of the screen with
   an ocean between them. The brand column takes the slack instead and the lists
   stay a cluster. auto-fit still drops them onto their own rows on a phone,
   because the repeat count is figured from the 140px floor. */
.sf-footer__grid {
  display: grid; gap: var(--sf-s-8) var(--sf-s-9);
  grid-template-columns: minmax(220px, 1fr) repeat(auto-fit, minmax(140px, max-content));
  justify-content: space-between;
}
/* Once there is no spare width to distribute, content-sized tracks stop helping
   and start overflowing — a 140px track cannot hold "Cancel your contract here"
   on one line. Below these widths the columns share the row evenly and wrap
   their text instead; minmax(0, 1fr) is what lets them shrink past min-content. */
@media (max-width: 700px) {
  .sf-footer__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 430px) {
  .sf-footer__grid { grid-template-columns: minmax(0, 1fr); }
}
.sf-footer__brand { display: flex; flex-direction: column; gap: var(--sf-s-4); max-width: 320px; }
.sf-footer__brand p { color: var(--sf-on-surface-variant); font-size: 14px; }
.sf-footer__col h4 {
  font-size: 12px; font-weight: 700; letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--sf-on-surface);
  margin-bottom: var(--sf-s-4);
}
.sf-footer__col ul { list-style: none; display: flex; flex-direction: column; gap: var(--sf-s-3); }
.sf-footer__col a { color: var(--sf-on-surface-variant); font-size: 14px; }
.sf-footer__col a:hover { color: var(--sf-on-surface); }
/* The § 312k BGB cancellation link. The statute wants it "unmittelbar und leicht
   erreichbar", so it is not allowed to recede into the list around it — it keeps
   the body text colour and an underline while its neighbours are muted. */
.sf-footer__cancel {
  color: var(--sf-on-surface) !important;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.sf-footer__base {
  margin-top: var(--sf-s-9); padding-top: var(--sf-s-6);
  border-top: 1px solid var(--sf-outline-variant);
  display: flex; justify-content: space-between; gap: var(--sf-s-4);
  flex-wrap: wrap;
  color: var(--sf-on-surface-variant); font-size: 13px;
}
