/* ============================================================
   @bp-labs-tech/site-kit — site.css
   ------------------------------------------------------------
   Layout and primitives for the server-rendered public sites.
   Loaded AFTER tokens.css, which site-kit:assets publishes beside it.

   EVERY COLOUR IS A TOKEN. A literal colour here fails
   tests/Unit/SiteCssTest.php — a hex written in this file is one
   no brand can change and no dark mode can invert.

   Mobile-first: the base rules are the 360px layout; min-width
   queries only ever add room.

   TYPE AND CONTROLS ARE B-01's (operator 2026-10-27, BP-1795): every
   font-size is a role token from tokens.css, set with the line
   height of the same name (--fs-lg with --lh-lg or --lh-lg-loose);
   touch vs desktop follows the pointer inside those tokens, so no
   rule here asks which it is. Weights are 400 and 600; 700 is only
   the public headline and the public title. A control is
   --control-h (small) / --control-h-md (the default) /
   --control-h-lg, and nothing a pointer hits is smaller than
   --min-target.
   ============================================================ */

:root {
  color-scheme: light dark;
  --sk-font:
    "Fira Sans", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue",
    Arial, sans-serif;
  --sk-max: 1120px;
  /* The page margin (B-01): 16 / 24 / 32 at the 600 and 1024 breakpoints. */
  --sk-gutter: var(--page-margin);

  /* The solid-fill button. --accent-text, NOT --accent: ffree's coral (and
     every accent too light for type) measures 2.2:1 under a white label.
     tests/Unit/ContrastTest.php measures every pair below. */
  --sk-btn-bg: var(--accent-text);
  --sk-btn-fg: var(--accent-fg);
}

/* ffuse is the one brand whose --accent-fg is INK: gold carries dark type, so
   the fill stays the brand hue instead of the darkened text shade. (aa's label
   is ink too since the LIBRARY ruling; aa-app/site sets its own fill in both
   themes, and ContrastTest names that.) */
[data-brand="ffuse"] {
  --sk-btn-bg: var(--accent);
}

@media (prefers-color-scheme: dark) {
  /* On dark, --accent-text is the LIGHT shade, so the label flips to the
     darkest surface. --accent-fg cannot be used: ffuse's is var(--ink), which
     dark mode turns near-white. */
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --sk-btn-bg: var(--accent-text);
    --sk-btn-fg: var(--canvas);
  }
}

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

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  /* An in-page anchor lands below the sticky nav, not under it. */
  scroll-padding-top: calc(var(--topbar-h) + var(--sp-4));
}

body {
  margin: 0;
  background: var(--canvas);
  color: var(--ink);
  font-family: var(--sk-font);
  /* Body (B-01). Prose blocks below opt into Long reading. */
  font-size: var(--fs-base);
  line-height: var(--lh-base);
  -webkit-font-smoothing: antialiased;
}

img {
  max-width: 100%;
  height: auto;
}

h1,
h2,
h3,
p {
  margin: 0;
}

h1,
h2,
h3 {
  color: var(--ink);
  font-weight: 600;
}

/* A heading with no class of its own takes its role: the page title, the
   section title, the card title. */
h1 {
  font-size: var(--fs-2xl);
  line-height: var(--lh-2xl);
}

h2 {
  font-size: var(--fs-xl);
  line-height: var(--lh-xl);
}

h3 {
  font-size: var(--fs-lg);
  line-height: var(--lh-lg);
}

a {
  color: var(--accent-text);
  text-underline-offset: 0.15em;
}

a:hover {
  text-decoration-thickness: 2px;
}

:focus-visible {
  /* L-09 (2026-10-27): the ring is tokens.css's --focus-ring, drawn 2px. */
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

.sk-skip {
  position: absolute;
  top: calc(-1 * var(--sp-16));
  left: var(--sp-2);
  z-index: 10;
  display: flex;
  align-items: center;
  min-height: var(--min-target);
  padding: var(--sp-2) var(--sp-4);
  border-radius: var(--r-md);
  background: var(--surface);
  color: var(--ink);
  box-shadow: var(--sh-md);
  /* A short viewport (landscape phone, 200% zoom) scrolls the bar, never hides
     its buttons; the page reserves at most this much (site.js reads the capped height). */
  max-height: 85vh;
  overflow-y: auto;
}

.sk-skip:focus {
  top: var(--sp-2);
}

.sk-container {
  width: 100%;
  max-width: var(--sk-max);
  margin-inline: auto;
  padding-inline: var(--sk-gutter);
}

/* ── Header + footer ──────────────────────────────────────── */
/* The BREAKPOINTS are B-01's 600 and 1024 and nothing else
   (tests/Unit/EngineCssTest.php fails on any other min-width):
     600   a phone becomes a tablet: sign-in link, two-up grids, inline form,
           the steps in a row, the cookie bar in a row, roomier panels
     1024  desktop: the nav anchors, three-up grids, the split hero and split
           blocks side by side
   The public headline, public title and page margin change at the same two
   widths inside tokens.css. */

/* Sticky nav (R013). Border + blur are the DEFAULT, so a page where site.js
   never runs still has a legible bar; site.js sets data-top while the page is
   at the top, which drops them. */
.sk-header {
  position: sticky;
  top: 0;
  z-index: 20;
  border-bottom: 1px solid var(--border);
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  transition:
    border-color var(--t-fast) var(--ease),
    background-color var(--t-fast) var(--ease);
}

.sk-header[data-top] {
  border-bottom-color: transparent;
  background: var(--surface);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

.sk-header__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-1) var(--sp-4);
  min-height: var(--topbar-h);
}

.sk-wordmark {
  display: inline-flex;
  align-items: center;
  /* A link like any other: never under the target floor. */
  min-height: var(--min-target);
  gap: var(--sp-2);
  color: var(--ink);
  font-size: var(--fs-xl);
  line-height: var(--lh-xl);
  /* The wordmark is the brand's logotype, not a type role: its 700 stays. */
  font-weight: 700;
  letter-spacing: -0.01em;
  text-decoration: none;
}

/* The brand's glyph beside the name (B1-39, Q34; Library "Web / Brand row":
   a 32px glyph, 8px, then the name). Decorative: alt="" in the markup. */
.sk-wordmark__glyph {
  flex: none;
  width: var(--sp-8);
  height: var(--sp-8);
}

/* The kit's header no longer draws this dot (B1-39: the glyph replaced it); kept
   for a site that still prints it in its own markup (bp-labs.tech's footer). */
.sk-wordmark__dot {
  width: 10px;
  height: 10px;
  border-radius: var(--r-full);
  background: var(--accent);
}

.sk-header__nav {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  /* When the wordmark, Sign in and a long button cannot share a row (320px, or
     large text), the nav drops under the wordmark rather than being cut off. */
  margin-inline-start: auto;
}

.sk-header__nav a:not(.sk-btn),
.sk-header__links a {
  display: inline-flex;
  align-items: center;
  /* "Sign in" never breaks into two lines. */
  white-space: nowrap;
  /* A nav item is a default-size control: 40 on a desktop, 48 on touch. */
  min-height: var(--control-h-md);
  padding-inline: var(--sp-3);
  border-radius: var(--r-md);
  font-weight: 600;
  text-decoration: none;
}

.sk-header__nav a:not(.sk-btn):hover,
.sk-header__links a:hover {
  background: var(--accent-50);
}

/* The anchors in the centre of the bar: wordmark + CTA only on a phone. */
.sk-header__links {
  display: none;
}

/* With a CTA present the quiet sign-in link also steps aside on a phone. */
.sk-header--cta .sk-header__nav a:not(.sk-btn) {
  display: none;
}

.sk-header__cta {
  /* On a phone with large text the label may take two lines rather than be cut off. */
  max-width: 100%;
  text-align: center;
}

/* Q1045 A: a site that asks for it keeps the quiet link on a phone too (one text
   link and one button, never two buttons: R013). */
.sk-header--phone-signin .sk-header__nav a:not(.sk-btn) {
  display: inline-flex;
}

/* Q1047: on a phone the bar's button waits while the page's own Start free is on
   screen (set by site.js from data-sk-cta-after); computers always show it. */
.sk-header[data-cta-hidden] .sk-header__cta {
  display: none;
}

@media (min-width: 600px) {
  .sk-header--cta .sk-header__nav a:not(.sk-btn) {
    display: inline-flex;
  }

  .sk-header__cta {
    white-space: nowrap;
  }

  .sk-header[data-cta-hidden] .sk-header__cta {
    display: inline-flex;
  }
}

/* 1024, not 600: 768 retired, and at 600 the anchors, Sign in and the call to
   action do not fit one row (fflo's four anchors need about 650px), so the bar
   would scroll sideways. */
@media (min-width: 1024px) {
  .sk-header__links {
    display: flex;
    gap: var(--sp-1);
  }
}

.sk-footer {
  margin-top: var(--sp-12);
  padding-block: var(--sp-8);
  border-top: 1px solid var(--border);
  color: var(--ink-muted);
  font-size: var(--fs-sm);
  line-height: var(--lh-sm);
}

.sk-footer__inner > * + * {
  margin-top: var(--sp-6);
}

/* Columns stack on a phone and sit side by side from 600px; min-width: 0 on the
   grid items stops a long link from pushing the page wider than 375px. */
.sk-footer__cols {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-6);
}

.sk-footer__col {
  min-width: 0;
}

.sk-footer__head {
  margin-bottom: var(--sp-2);
  color: var(--ink);
  font-size: var(--fs-sm);
  line-height: var(--lh-sm);
  font-weight: 600;
}

.sk-footer__list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.sk-footer__list a {
  /* A row of links, not a sentence: each one a target of its own. */
  display: inline-flex;
  align-items: center;
  min-height: var(--min-target);
  padding-block: var(--sp-1);
  color: inherit;
  text-decoration: underline;
  overflow-wrap: anywhere;
}

.sk-footer__copy strong {
  color: var(--ink);
}

/* Tracks follow the number of columns drawn (--n1..--n4 modifier, set by the
   footer view), so a site with only the Legal column has no empty tracks.
   1 / 2 / 4 breakpoints: one column on a phone, two from 600px, all from 1024px. */
@media (min-width: 600px) {
  .sk-footer__cols--2,
  .sk-footer__cols--3,
  .sk-footer__cols--4 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1024px) {
  .sk-footer__cols--3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .sk-footer__cols--4 {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* The brand footer (B2-020, BP-1887; S8A-01 549:792, Library "Web / PublicFooter",
   Kind=Full). Dark whatever the page's theme: the footer carries
   data-theme="dark" and the site's data-brand, so every token inside it is the
   dark one, measured by ContrastTest like the rest. The brand first and wider
   (2 : 1 : 1 : 1 from 1024px, as drawn), the columns, then a bar. */
.sk-footer--brand {
  padding-block: var(--sp-12) var(--sp-8);
  border-top-color: var(--border);
  background: var(--surface);
  color: var(--ink-muted);
}

.sk-footer__brand {
  min-width: 0;
}

.sk-footer__tagline {
  max-width: 44ch;
  margin-top: var(--sp-3);
}

/* As drawn: the heads in capitals, the links a quiet list (a nav, read as
   links by where they stand), underlined on hover; focus rings as everywhere. */
.sk-footer--brand .sk-footer__head {
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.sk-footer--brand .sk-footer__list a,
.sk-footer__legal-list a {
  color: var(--ink-muted);
  text-decoration: none;
}

.sk-footer--brand .sk-footer__list a:hover,
.sk-footer__legal-list a:hover {
  color: var(--ink);
  text-decoration: underline;
}

/* The bar under a rule: the copyright, then Privacy and Terms; on one row from
   600px, stacked on a phone, as drawn. */
.sk-footer__bar {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  padding-top: var(--sp-6);
  border-top: 1px solid var(--border);
}

.sk-footer__bar .sk-footer__copy {
  margin: 0;
}

.sk-footer__legal-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0 var(--sp-4);
  margin: 0;
  padding: 0;
  list-style: none;
}

.sk-footer__legal-list a {
  display: inline-flex;
  align-items: center;
  min-height: var(--min-target);
  font-weight: 600;
}

@media (min-width: 600px) {
  /* The brand takes the whole first row; the columns pair up under it. */
  .sk-footer--brand .sk-footer__brand {
    grid-column: 1 / -1;
  }

  .sk-footer__bar {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-2) var(--sp-6);
  }
}

@media (min-width: 1024px) {
  .sk-footer--brand .sk-footer__brand {
    grid-column: auto;
  }

  .sk-footer--brand .sk-footer__cols--4 {
    grid-template-columns: minmax(0, 2fr) repeat(3, minmax(0, 1fr));
  }

  .sk-footer--brand .sk-footer__cols--3 {
    grid-template-columns: minmax(0, 2fr) repeat(2, minmax(0, 1fr));
  }
}

/* ── Legal pages (/terms, /privacy) ───────────────────────── */
.sk-legal__inner {
  max-width: 72ch;
}

.sk-legal__title {
  margin-bottom: var(--sp-2);
}

.sk-legal__banner {
  margin-top: var(--sp-4);
}

.sk-legal__meta {
  margin-top: var(--sp-4);
  color: var(--ink-muted);
  font-size: var(--fs-sm);
  line-height: var(--lh-sm);
}

/* Long reading. */
.sk-legal__body {
  margin-top: var(--sp-6);
  font-size: var(--fs-lg);
  line-height: var(--lh-lg-loose);
  overflow-wrap: anywhere;
}

.sk-legal__body > * + * {
  margin-top: var(--sp-4);
}

.sk-legal__body h2,
.sk-legal__body h3 {
  margin-top: var(--sp-8);
}

.sk-legal__body ul,
.sk-legal__body ol {
  padding-left: var(--sp-6);
}

.sk-legal__body a {
  text-decoration: underline;
}

/* ── Hero ─────────────────────────────────────────────────── */
.sk-hero {
  position: relative;
  padding-block: var(--sp-12) var(--sp-10);
}

.sk-hero::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 4px;
  background: var(--accent-grad);
}

/* Overline. */
.sk-eyebrow {
  margin-bottom: var(--sp-3);
  color: var(--accent-text);
  font-size: var(--fs-xs);
  line-height: var(--lh-xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* THE public headline: one per page, sized by the window (tokens.css). */
.sk-hero__title {
  max-width: 20ch;
  font-size: var(--fs-headline);
  line-height: var(--lh-headline);
  font-weight: 700;
  letter-spacing: -0.02em;
}

/* Long reading. */
.sk-hero__lead {
  max-width: 62ch;
  margin-top: var(--sp-4);
  color: var(--ink-muted);
  font-size: var(--fs-lg);
  line-height: var(--lh-lg-loose);
}

.sk-hero__lead > * + * {
  margin-top: var(--sp-3);
}

.sk-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  margin-top: var(--sp-6);
}

@media (min-width: 600px) {
  .sk-hero {
    padding-block: var(--sp-20) var(--sp-16);
  }
}

/* ── Hero motion (public-surface unit 24, Q41) ───────────────
   BP-1171's hero in motion, shared by every brand's home page:
   an element carrying `data-sk-motion` moves the parts inside it
   that name a `data-sk-motion-part`, and stands still otherwise.

   CSS ALONE, so it needs no script: with JavaScript off the page
   is complete and moves just the same, and its Pause button (a
   switch, components/motion-pause) works too. Every number a part
   draws is already in the HTML — an animation only ever travels
   TO the value the page carries, never computes one.

   THE STILL IS THE DEFAULT. Every animation lives inside
   `prefers-reduced-motion: no-preference`, so with reduced motion
   nothing runs and the parts stand where the page draws them; and
   while the Pause switch is on, every part stands there too.

   The parts, each named by what it does:
     · rise  — lifts into place once, then floats (a decorative
               mark: it fades in, so never put words on it);
     · lift  — rises into place once, never fading (it may carry
               words: they are readable from the first frame);
     · draw  — an SVG stroke with pathLength="100" draws itself
               from nothing to its own stroke-dasharray;
     · fill  — a bar grows from its start to its own length,
               `--sk-motion-i` steps of 90ms after the first;
     · drift — a decorative field whose background drifts up one
               tile (`--sk-drift-tile`) at a time, for ever.
   Nothing moves text, and nothing moves sideways, so no part can
   push the page wider than the screen. */
.sk-motion-pause {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 44px or more everywhere (B1-46, S8A-01: it measured 34 on a computer); a
     default-size control, so 48 on touch. 44 is WCAG 2.5.5's target, and no
     token holds it on a computer (--min-target there is 24). */
  min-height: max(var(--control-h-md), 44px);
  padding: var(--sp-2) var(--sp-4);
  border: 1px solid var(--ink-muted);
  border-radius: var(--r-full);
  background: var(--surface);
  color: var(--ink);
  font-size: var(--fs-sm);
  font-weight: 600;
  line-height: var(--lh-sm);
}

/* The switch lies over the whole pill: the pill is what a finger
   presses and what keyboard focus rings. */
.sk-motion-pause__switch {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  border-radius: inherit;
  appearance: none;
  background: transparent;
  cursor: pointer;
}

/* The button form (B1-46): a real <button>, so it takes the page's font and
   the hand; site.js reveals it (display above would beat the [hidden] it
   ships with). Its words are Pause or Play; " motion" completes its name for a
   screen reader ("Pause motion", "Play motion") and is not drawn. */
.sk-motion-pause--button {
  cursor: pointer;
  font-family: inherit;
}

.sk-motion-pause[hidden] {
  display: none;
}

.sk-motion-pause__noun {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* In site-kit's own hero, below its actions. */
.sk-hero .sk-motion-pause {
  margin-top: var(--sp-6);
}

/* In a split hero, in the top corner of the picture that moves (B1-46, COMMON
   SENSE): beside the motion it stops, never a third pill under the buttons. On
   the surface, with its outline, so it reads over any picture. The picture is
   its containing block (.sk-hero__visual, below). */
.sk-hero__visual .sk-motion-pause {
  position: absolute;
  z-index: 2;
  inset-block-start: var(--sp-3);
  inset-inline-end: var(--sp-3);
  margin: 0;
}

/* On: pressed, drawn as the inverse of off. */
.sk-motion-pause:has(.sk-motion-pause__switch:checked) {
  border-color: var(--ink);
  background: var(--ink);
  color: var(--canvas);
}

@media (prefers-reduced-motion: no-preference) {
  [data-sk-motion] [data-sk-motion-part~="rise"] {
    animation:
      sk-motion-rise 2.4s cubic-bezier(0.16, 1, 0.3, 1) both,
      sk-motion-float 6.5s ease-in-out 2.4s infinite;
  }

  [data-sk-motion] [data-sk-motion-part~="lift"] {
    animation: sk-motion-lift 1.1s cubic-bezier(0.16, 1, 0.3, 1) 0.45s both;
  }

  [data-sk-motion] [data-sk-motion-part~="draw"] {
    animation: sk-motion-draw 1.3s cubic-bezier(0.33, 1, 0.68, 1) 0.9s both;
  }

  [data-sk-motion] [data-sk-motion-part~="fill"] {
    transform-origin: 0 50%;
    animation: sk-motion-fill 0.9s cubic-bezier(0.22, 1, 0.36, 1) calc(1.05s + var(--sk-motion-i, 0) * 90ms) both;
  }

  [data-sk-motion] [data-sk-motion-part~="drift"] {
    animation: sk-motion-drift 14s linear infinite;
  }

  /* Paused: every part at its still, as with motion turned off. The button
     marks its hero data-sk-paused (site.js); the switch is read by :has(). */
  [data-sk-motion][data-sk-paused] [data-sk-motion-part],
  [data-sk-motion]:has(.sk-motion-pause__switch:checked) [data-sk-motion-part] {
    animation: none;
  }
}

/* Nothing moves, so there is nothing to pause. */
@media (prefers-reduced-motion: reduce) {
  .sk-motion-pause {
    display: none;
  }
}

/* A browser without :has() cannot read the switch, so Pause would do
   nothing while the endless parts ran on (WCAG 2.2.2). There the
   switch is not drawn, and the endless parts run once and end on the
   page's own still: no motion lasts past its arrival. */
@supports not selector(:has(*)) {
  .sk-motion-pause {
    display: none;
  }

  [data-sk-motion] [data-sk-motion-part~="rise"],
  [data-sk-motion] [data-sk-motion-part~="drift"] {
    animation-iteration-count: 1;
  }
}

@media print {
  .sk-motion-pause {
    display: none;
  }
}

/* The button form with no script to run it (switched off, or it never
   arrived): the button stays hidden, so the endless parts run once and end on
   the page's own still, as where :has() is missing. With scripting off the
   <noscript> switch is drawn as well and Pause works as it always has. */
html:not(.sk-js) [data-sk-motion]:has([data-sk-motion-pause]) [data-sk-motion-part~="rise"],
html:not(.sk-js) [data-sk-motion]:has([data-sk-motion-pause]) [data-sk-motion-part~="drift"] {
  animation-iteration-count: 1;
}

@keyframes sk-motion-rise {
  from {
    opacity: 0;
    translate: 0 var(--sp-12);
  }
}

@keyframes sk-motion-float {
  50% {
    transform: translateY(calc(-1 * var(--sp-2)));
  }
}

@keyframes sk-motion-lift {
  from {
    translate: 0 var(--sp-12);
  }
}

@keyframes sk-motion-draw {
  from {
    stroke-dasharray: 0 100;
  }
}

@keyframes sk-motion-fill {
  from {
    transform: scaleX(0);
  }
}

@keyframes sk-motion-drift {
  to {
    background-position-y: calc(-1 * var(--sk-drift-tile, 240px));
  }
}

/* ── Buttons ──────────────────────────────────────────────── */
.sk-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* The default (md) control: 40 on a desktop, 48 on touch; its label the
     Label size. */
  min-height: var(--control-h-md);
  padding: var(--sp-2) var(--sp-5);
  border: 1px solid transparent;
  border-radius: var(--r-md);
  background: var(--sk-btn-bg);
  color: var(--sk-btn-fg);
  font: inherit;
  font-size: var(--fs-base);
  line-height: var(--lh-base);
  font-weight: 600;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: box-shadow var(--t-fast) var(--ease);
}

.sk-btn:hover {
  box-shadow: var(--sh-md);
}

.sk-btn--secondary {
  /* The outline is the button's only edge on a surface-coloured fill — the
     same 3:1 case as .sk-input, so the same token. */
  border-color: var(--ink-muted);
  background: var(--surface);
  color: var(--ink);
}

/* ── Sections ─────────────────────────────────────────────── */
.sk-section {
  padding-block: var(--sp-12);
}

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

/* The public title: a section headline, sized by the window (tokens.css). */
.sk-section__title {
  font-size: var(--fs-public-title);
  line-height: var(--lh-public-title);
  font-weight: 700;
}

/* Long reading. */
.sk-section__intro {
  max-width: 62ch;
  margin-top: var(--sp-3);
  color: var(--ink-muted);
  font-size: var(--fs-lg);
  line-height: var(--lh-lg-loose);
}

.sk-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--gutter);
  margin: var(--sp-8) 0 0;
  padding: 0;
  list-style: none;
}

.sk-card {
  padding: var(--sp-6);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
}

.sk-section--alt .sk-card {
  background: var(--canvas);
}

.sk-card__marker {
  display: block;
  width: var(--sp-8);
  height: 4px;
  margin-bottom: var(--sp-4);
  border-radius: var(--r-full);
  background: var(--accent);
}

.sk-card__title {
  font-size: var(--fs-lg);
  line-height: var(--lh-lg);
}

.sk-card__body {
  margin-top: var(--sp-2);
  color: var(--ink-muted);
}

.sk-card__body > * + * {
  margin-top: var(--sp-2);
}

.sk-notice {
  max-width: 62ch;
  margin-top: var(--sp-6);
  padding: var(--sp-4);
  border-left: 4px solid var(--accent);
  border-radius: var(--r-md);
  background: var(--accent-50);
  color: var(--ink);
  font-size: var(--fs-base);
  line-height: var(--lh-base);
}

@media (min-width: 600px) {
  .sk-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1024px) {
  .sk-grid--3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* ── Call to action + early-access form ───────────────────── */
.sk-cta {
  padding-block: var(--sp-12);
}

.sk-cta__panel {
  position: relative;
  overflow: hidden;
  padding: var(--sp-6);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  background: var(--surface);
  box-shadow: var(--sh-md);
}

.sk-cta__panel::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 4px;
  background: var(--accent-grad);
}

/* The public title, as every section headline. */
.sk-cta__title {
  font-size: var(--fs-public-title);
  line-height: var(--lh-public-title);
  font-weight: 700;
}

/* Long reading. */
.sk-cta__body {
  max-width: 62ch;
  margin-top: var(--sp-2);
  color: var(--ink-muted);
  font-size: var(--fs-lg);
  line-height: var(--lh-lg-loose);
}

.sk-form {
  max-width: 560px;
  margin-top: var(--sp-6);
  color: var(--ink);
}

/* Label. */
.sk-form label {
  display: block;
  margin-bottom: var(--sp-2);
  font-size: var(--fs-base);
  line-height: var(--lh-base);
  font-weight: 600;
}

/* One vertical rhythm for stacked fields: a gap above every label but the
   first, and above the submit. */
.sk-form label:not(:first-child) {
  margin-top: var(--sp-4);
}

.sk-form textarea + button,
.sk-form textarea + .sk-btn,
.sk-form input + button,
.sk-form input + .sk-btn,
.sk-form button[type="submit"]:not(:first-child),
.sk-form .sk-btn[type="submit"]:not(:first-child) {
  margin-top: var(--sp-4);
}

.sk-form__row {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}

.sk-input {
  width: 100%;
  /* A default (md) control, the button's height beside it. */
  min-height: var(--control-h-md);
  padding: var(--sp-2) var(--sp-3);
  /* The field's fill is nearly the panel's, so the outline is the only thing
     that shows where the box is, and WCAG 1.4.11 wants 3:1. --border-strong
     measures 1.41:1 light / 1.85:1 dark; --border-input is the token made for
     it (L-09, 2026-10-27). ContrastTest pins it. */
  border: 1px solid var(--border-input);
  border-radius: var(--r-md);
  background: var(--canvas);
  color: var(--ink);
  font: inherit;
  font-size: var(--fs-base);
  line-height: var(--lh-base);
}

.sk-input[aria-invalid="true"] {
  border-color: var(--danger);
}

.sk-hint {
  margin-top: var(--sp-2);
  color: var(--ink-muted);
  font-size: var(--fs-sm);
  line-height: var(--lh-sm);
}

.sk-status {
  margin-bottom: var(--sp-4);
  padding: var(--sp-3) var(--sp-4);
  border-left: 4px solid transparent;
  border-radius: var(--r-md);
  font-weight: 600;
}

.sk-status--ok {
  border-left-color: var(--success);
  background: var(--success-50);
  color: var(--ink);
}

.sk-status--error {
  border-left-color: var(--danger);
  background: var(--danger-50);
  color: var(--ink);
}

/* The honeypot: out of sight and out of the tab order, but still in the form. */
.sk-hp {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

@media (min-width: 600px) {
  .sk-form__row {
    flex-direction: row;
  }

  .sk-form__row .sk-input {
    flex: 1;
  }
}

@media (min-width: 600px) {
  .sk-cta__panel {
    padding: var(--sp-10);
  }
}

/* ── Landing blocks (public-surface unit 24, BP-1171) ──────────
   The approved BP-1171 landing as kit blocks, for fflo, Advisor
   Accelerator and the advisor pages (Q40): the section head, the
   split hero and its browser frame, the steps, the panels behind
   tabs, words beside a picture, the icon tile and the solid closing
   panel. EVERY WORD SITS ON A SOLID TOKEN (Q42): the canvas, the
   surface, or the solid-button pair; a gradient or a pattern only
   ever decorates a field with no words on it. */
.sk-icon {
  flex: none;
  width: 1em;
  height: 1em;
}

.sk-head--center {
  text-align: center;
}

.sk-head--center .sk-section__title,
.sk-head--center .sk-section__intro {
  margin-inline: auto;
}

.sk-head--center .sk-section__title {
  max-width: 24ch;
}

/* Split hero: copy beside a picture; stacked, copy first, on a phone. */
.sk-hero__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-10);
  align-items: center;
}

.sk-hero--split .sk-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-1) var(--sp-3);
  border: 1px solid var(--border);
  border-radius: var(--r-full);
  background: var(--surface);
}

.sk-hero--split .sk-eyebrow::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: var(--r-full);
  background: var(--accent);
}

.sk-hero--split .sk-hero__title {
  max-width: none;
}

/* The title's closing phrase: solid brand text, measured (ContrastTest). */
.sk-hero__accent {
  color: var(--accent-text);
}

.sk-hero__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-5);
  margin: var(--sp-6) 0 0;
  padding: 0;
  color: var(--ink-muted);
  font-size: var(--fs-sm);
  line-height: var(--lh-sm);
  list-style: none;
}

.sk-hero__meta li {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
}

.sk-hero__meta .sk-icon {
  color: var(--accent-text);
}

.sk-hero__visual {
  /* The Pause control's corner (B1-46, "Hero motion" above). */
  position: relative;
  min-width: 0;
}

/* A page in a browser window. */
.sk-browser {
  margin: 0;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  color: var(--ink);
  box-shadow: var(--sh-md);
}

.sk-browser__chrome {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-3);
  border-bottom: 1px solid var(--border);
  background: var(--canvas);
}

.sk-browser__dots {
  display: inline-flex;
  flex: none;
  gap: var(--sp-1);
}

.sk-browser__dots span {
  width: 9px;
  height: 9px;
  border-radius: var(--r-full);
  background: var(--border-strong);
}

.sk-browser__url {
  display: inline-flex;
  flex: 1;
  align-items: center;
  gap: var(--sp-1);
  min-width: 0;
  padding: var(--sp-1) var(--sp-3);
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: var(--r-full);
  background: var(--surface);
  color: var(--ink-muted);
  font-size: var(--fs-xs);
  line-height: var(--lh-xs);
  font-weight: 600;
  white-space: nowrap;
}

.sk-browser__url span {
  overflow: hidden;
  text-overflow: ellipsis;
}

.sk-browser__body {
  padding: var(--sp-6) var(--sp-4);
}

/* Steps: stacked on a phone, a row joined by a line from 600px. */
.sk-steps {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-8);
  margin: var(--sp-10) 0 0;
  padding: 0;
  list-style: none;
}

.sk-step {
  position: relative;
  text-align: center;
}

.sk-step__number {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border: 2px solid var(--accent);
  border-radius: var(--r-full);
  background: var(--surface);
  color: var(--accent-text);
  font-size: var(--fs-xl);
  line-height: var(--lh-xl);
  font-weight: 600;
}

/* A step behind the reader: the solid-button pair, which ContrastTest measures. */
.sk-step--done .sk-step__number {
  border-color: var(--sk-btn-bg);
  background: var(--sk-btn-bg);
  color: var(--sk-btn-fg);
}

.sk-step__title {
  margin-top: var(--sp-4);
  font-size: var(--fs-lg);
  line-height: var(--lh-lg);
}

.sk-step__body {
  max-width: 40ch;
  margin: var(--sp-2) auto 0;
  color: var(--ink-muted);
}

/* Panels behind tabs: a list of sections until site.js makes them tabs. */
.sk-tabs {
  margin-top: var(--sp-8);
}

.sk-tabs__list {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--sp-1);
  margin-bottom: var(--sp-6);
}

/* display: flex above beats the [hidden] attribute: without this the tab row
   would show, and do nothing, with JavaScript off. (No kit-wide [hidden] rule:
   the accordion shows its [hidden] answers on purpose without a script.) */
.sk-tabs__list[hidden] {
  display: none;
}

.sk-tabs__tab {
  display: inline-flex;
  align-items: center;
  /* A default (md) control. */
  min-height: var(--control-h-md);
  padding: var(--sp-2) var(--sp-4);
  border: 0;
  border-radius: var(--r-full);
  background: transparent;
  color: var(--ink-muted);
  font: inherit;
  font-size: var(--fs-base);
  line-height: var(--lh-base);
  font-weight: 600;
  cursor: pointer;
}

.sk-tabs__tab[aria-selected="true"] {
  background: var(--sk-btn-bg);
  color: var(--sk-btn-fg);
}

.sk-tabs__panel + .sk-tabs__panel {
  margin-top: var(--sp-8);
}

.sk-tabs__heading {
  margin-bottom: var(--sp-3);
  font-size: var(--fs-lg);
  line-height: var(--lh-lg);
}

/* With tabs, the tab names the panel; its h3 stays for a screen reader. */
.sk-js .sk-tabs__heading {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.sk-js .sk-tabs__panel + .sk-tabs__panel {
  margin-top: 0;
}

/* A ticked list (BP-1171's check_circle rows). */
.sk-checks {
  display: grid;
  gap: var(--sp-3);
  margin: var(--sp-4) 0 0;
  padding: 0;
  list-style: none;
}

.sk-checks li {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-2);
}

.sk-checks .sk-icon {
  width: 22px;
  height: 22px;
  color: var(--accent-text);
}

/* Words beside a picture. */
.sk-split__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-10);
  align-items: center;
}

/* Long reading. */
.sk-split__body {
  margin-top: var(--sp-4);
  color: var(--ink-muted);
  font-size: var(--fs-lg);
  line-height: var(--lh-lg-loose);
}

.sk-split__body > * + * {
  margin-top: var(--sp-3);
}

.sk-split__visual {
  min-width: 0;
}

/* A feature's icon tile, in place of the plain marker. */
.sk-card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  margin-bottom: var(--sp-4);
  border-radius: var(--r-md);
  background: var(--accent-50);
  color: var(--accent-text);
  /* The icon's size (it is drawn 1em square), not a type role: 24px is the
     Library's large icon, and there is no icon token on the web yet. */
  font-size: 24px;
}

/* The solid closing panel (Q42): the solid-button pair, buttons inside out. */
.sk-cta--solid .sk-cta__panel {
  border-color: var(--sk-btn-bg);
  background: var(--sk-btn-bg);
  color: var(--sk-btn-fg);
  text-align: center;
}

.sk-cta--solid .sk-cta__panel::before {
  display: none;
}

.sk-cta--solid .sk-cta__title,
.sk-cta--solid .sk-cta__body {
  color: var(--sk-btn-fg);
}

.sk-cta--solid .sk-cta__body {
  margin-inline: auto;
}

.sk-cta--solid .sk-actions {
  justify-content: center;
}

.sk-cta--solid .sk-btn {
  border-color: var(--sk-btn-fg);
  background: var(--sk-btn-fg);
  color: var(--sk-btn-bg);
}

.sk-cta--solid .sk-btn--secondary {
  background: transparent;
  color: var(--sk-btn-fg);
}

/* The ring in the panel's own label colour: the accent ring would vanish on it. */
.sk-cta--solid :focus-visible {
  outline-color: var(--sk-btn-fg);
}

@media (min-width: 600px) {
  .sk-steps {
    grid-auto-columns: minmax(0, 1fr);
    grid-auto-flow: column;
  }

  /* Each step after the first draws the line back to the one before it. */
  .sk-step + .sk-step::before {
    content: "";
    position: absolute;
    top: 27px;
    left: calc(-50% - var(--sp-8));
    width: calc(100% + var(--sp-8));
    height: 2px;
    background: var(--border);
  }
}

@media (min-width: 1024px) {
  .sk-hero__grid {
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
    gap: var(--sp-12);
  }

  .sk-split__grid {
    grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
    gap: var(--sp-16);
  }
}

/* ── Accordion (FAQ) ──────────────────────────────────────── */
.sk-acc {
  max-width: 680px;
  margin-top: var(--sp-8);
  border-top: 1px solid var(--border);
}

.sk-acc__item {
  border-bottom: 1px solid var(--border);
}

.sk-acc__heading {
  font-size: inherit;
  font-weight: inherit;
}

.sk-acc__trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  width: 100%;
  min-height: var(--min-target);
  padding: var(--sp-4) 0;
  border: 0;
  background: none;
  color: var(--ink);
  font: inherit;
  /* A question as a card title. */
  font-size: var(--fs-lg);
  line-height: var(--lh-lg);
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}

.sk-acc__icon {
  position: relative;
  flex: none;
  width: 14px;
  height: 14px;
}

.sk-acc__icon::before,
.sk-acc__icon::after {
  content: "";
  position: absolute;
  inset: 6px 0 auto;
  height: 2px;
  border-radius: var(--r-full);
  background: var(--accent-text);
  transition: transform var(--t-fast) var(--ease);
}

.sk-acc__icon::after {
  transform: rotate(90deg);
}

.sk-acc__trigger[aria-expanded="true"] .sk-acc__icon::after {
  transform: rotate(0deg);
}

/* Long reading. */
.sk-acc__body {
  padding-bottom: var(--sp-4);
  color: var(--ink-muted);
  font-size: var(--fs-lg);
  line-height: var(--lh-lg-loose);
}

.sk-acc__body > * + * {
  margin-top: var(--sp-2);
}

/* No JavaScript, no way to open an answer: show them all. */
html:not(.sk-js) .sk-acc__panel[hidden] {
  display: block;
}

html:not(.sk-js) .sk-acc__icon {
  display: none;
}

@media (min-width: 600px) {
  .sk-acc__body {
    padding-right: var(--sp-8);
  }
}

/* ── Reveal on scroll (R049) ──────────────────────────────── */
/* Hidden only once site.js is running AND will be able to reveal it. */
.sk-js .sk-reveal:not(.is-in) {
  opacity: 0;
  transform: translateY(var(--sp-4));
}

.sk-reveal {
  transition:
    opacity var(--t-slow) var(--ease),
    transform var(--t-slow) var(--ease);
}

@media (prefers-reduced-motion: reduce) {
  .sk-btn,
  .sk-header,
  .sk-reveal,
  .sk-acc__icon::before,
  .sk-acc__icon::after {
    transition: none;
  }

  .sk-js .sk-reveal:not(.is-in) {
    opacity: 1;
    transform: none;
  }
}

/* ── Cookie choice banner (PUB-22) ────────────────────────── */
/* A bar along the bottom edge, never an overlay: no backdrop, no scroll lock,
   nothing inert, so the page stays fully usable while it is showing. */
.sk-consent {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: 40;
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding: var(--sp-4) var(--sk-gutter);
  border-top: 1px solid var(--border);
  background: var(--surface);
  color: var(--ink);
  box-shadow: var(--sh-md);
}

.sk-consent[hidden] {
  display: none;
}

/* site.js sets --sk-consent-h while the bar shows and removes it after; with
   no JS the bar stays hidden and the fallback is 0, so nothing changes. */
html {
  scroll-padding-bottom: var(--sk-consent-h, 0px);
}

body {
  padding-bottom: var(--sk-consent-h, 0px);
}

.sk-consent__text {
  max-width: 62ch;
  margin: 0;
  font-size: var(--fs-sm);
  line-height: var(--lh-sm);
}

.sk-consent__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
}

.sk-consent__btn {
  min-height: var(--control-h-md);
  min-width: var(--min-target);
}

.sk-consent__actions {
  align-items: center;
}

/* "Choose" is a link in look, a button in behaviour. */
.sk-consent__link {
  min-height: var(--min-target);
  min-width: var(--min-target);
  padding: 0 var(--sp-2);
  border: 0;
  background: none;
  color: var(--ink);
  font: inherit;
  font-size: var(--fs-sm);
  line-height: var(--lh-sm);
  text-decoration: underline;
  cursor: pointer;
}

/* The footer control is a button (it opens a panel) that looks like its
   neighbours: .sk-footer__list a, same colour, underline and vertical rhythm. */
.sk-footer__consent button {
  display: inline-flex;
  align-items: center;
  min-height: var(--min-target);
  padding: var(--sp-1) 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-decoration: underline;
  cursor: pointer;
}

.sk-footer__consent button[hidden] {
  display: none;
}

.sk-consent__actions [hidden] {
  display: none;
}

.sk-consent {
  flex-wrap: wrap;
}

.sk-consent__panel {
  order: 2;
  flex-basis: 100%;
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  align-items: flex-start;
}

.sk-consent__panel[hidden] {
  display: none;
}

.sk-consent__row {
  margin: 0;
  font-size: var(--fs-sm);
  line-height: var(--lh-sm);
  max-width: 62ch;
}

.sk-consent__switch {
  display: flex;
  gap: var(--sp-2);
  align-items: flex-start;
}

.sk-consent__switch input {
  width: 24px;
  height: 24px;
  flex: none;
}

.sk-footer__consent {
  margin: 0;
}

@media (min-width: 600px) {
  .sk-consent {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }

  /* Panel open: one group, top to bottom: words, the choices, then the buttons. */
  .sk-consent[data-open="true"] {
    flex-direction: column;
    align-items: flex-start;
  }

  .sk-consent[data-open="true"] .sk-consent__actions {
    order: 3;
  }
}
