/* =========================================================================
   Varn - Variants & Swatches AI  |  Marketing site stylesheet
   Built by Enstacked Technologies

   Architecture
   ------------
   @layer reset      normalise + box model
   @layer base       typography, page furniture
   @layer layout     shell, section rhythm, grid primitives
   @layer components purpose-named BEM blocks
   @layer utilities  single-purpose helpers (always last, always wins)

   Conventions
   -----------
   - Mobile-first. Breakpoints use the px scale documented in
     design-tokens.css: 480 / 576 / 768 / 992 / 1200px, plus 360px for the
     tiniest phones.
   - Every size in this file is px. No rem, em or ch: a ratio that used to
     ride on the element's own size (tracking, a 25ch measure) is written as
     calc() against the same font-size the rule declares, so a rule that
     changes a size must restate them.
   - Every repeated value is a token in design-tokens.css, which loads
     first on every page. No magic numbers in rules.
   - Only transform / opacity / filter are animated.
   - prefers-reduced-motion disables every non-essential animation.
   ========================================================================= */

@layer reset, base, layout, components, utilities;

/* =========================================================================
   FONTS  -  Instrument Sans, variable weight 400-700, roman only.

   The @font-face rules are served by the Google Fonts stylesheet linked in
   the <head> of index.html, with display=swap so text paints immediately in
   the fallback and never blocks the largest contentful paint.

   The ROMAN axis is the only one requested. The italic axis is deliberately
   never downloaded and never used anywhere on this page - see the font-style
   guard in @layer reset, which also blocks the browser's synthetic oblique.
   ========================================================================= */

/* =========================================================================
   RESET
   ========================================================================= */
@layer reset {
  *,
  *::before,
  *::after {
    box-sizing: border-box;
  }

  * {
    margin: 0;
  }

  html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
  }

  body {
    min-block-size: 100vh;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
  }

  img,
  svg,
  video,
  canvas {
    display: block;
    max-inline-size: 100%;
  }

  img,
  video {
    block-size: auto;
  }

  input,
  button,
  select,
  textarea {
    font: inherit;
    color: inherit;
  }

  button {
    background: none;
    border: 0;
    cursor: pointer;
  }

  ul,
  ol {
    padding-inline-start: 0;
    list-style: none;
  }

  a {
    color: inherit;
    text-decoration: none;
  }

  /* The 25-character measure that used to live here as max-width: 25ch now
     sits on each rule that owns a heading's size, because a character measure
     resolves against the element's own font-size and cannot survive as one
     shared px value. */
  h1,
  h2,
  h3,
  h4 {
    font-weight: 500;
  }

  p {
    text-wrap: pretty;
  }

  /* No italics anywhere on this page, by request. These are the elements a
     browser slants by default. Emphasis is carried by weight instead, which
     keeps the single roman family and still reads as emphasis. */
  i,
  em,
  cite,
  var,
  dfn,
  address,
  blockquote,
  figcaption {
    font-style: normal;
  }

  i,
  em {
    font-weight: 600;
  }

  :target {
    scroll-margin-block-start: var(--space-4xl);
  }
}

/* =========================================================================
   BASE - page furniture
   ========================================================================= */
@layer base {
  /* Tokens (colour, type, space, radius, shadow, layout, layers, motion)
     live in assets/css/design-tokens.css, linked before this file. */

  html {
    scroll-behavior: smooth;
    scroll-padding-block-start: calc(var(--header-h) + var(--space-sm));
  }

  body {
    position: relative;
    background-color: var(--color-page);
    /* clean SaaS surface - no texture overlay */
    color: var(--color-ink);
    font-family: var(--font-sans);
    font-size: var(--text-body);
    font-weight: 400;
    font-style: normal;
    line-height: var(--leading-normal);
    overflow-x: clip;

    /* Instrument Sans is a variable font: keep the width axis at its default
       and let the optical size axis follow the rendered size. */
    font-optical-sizing: auto;
    font-variation-settings: "wdth" 100;

    /* Inherited by every element. Permits synthetic BOLD (never needed - the
       400-700 range is real) but forbids synthetic OBLIQUE, so nothing on the
       page can slant the roman to fake an italic we never load. */
    font-synthesis: weight;
  }

  ::selection {
    background: var(--color-violet);
    color: var(--color-white);
  }

  :focus-visible {
    outline: 2px solid var(--color-violet-deep);
    outline-offset: 3px;
    border-radius: var(--radius-xs);
  }

  strong,
  b {
    font-weight: 600;
  }
}

/* =========================================================================
   LAYOUT
   ========================================================================= */
@layer layout {
  /* Anchors the absolutely-positioned journey overlay to the full page. */
  main {
    position: relative;
  }

  /* --shell-max is the CONTENT width (1320px); the gutters sit outside it,
     so on a wide screen the text column measures exactly 1320px. */
  .shell {
    inline-size: 100%;
    max-inline-size: calc(var(--shell-max) + 2 * var(--shell-pad));
    margin-inline: auto;
    padding-inline: var(--shell-pad);
  }

  .shell--narrow {
    max-inline-size: var(--shell-narrow);
  }

  .shell--mid {
    max-inline-size: var(--shell-mid);
  }

  /* 64px on phones, 100px from 768px: the step lives in --section-pad. */
  .section {
    position: relative;
    z-index: var(--z-content);
    padding-block: var(--section-pad);
  }

  .section--tight {
    padding-block: var(--section-pad);
  }

  /* This section sits directly under the hero, whose own bottom padding
     already creates separation, so its top is trimmed further to avoid
     stacking two paddings into one oversized gap. */
  .hero + .section--tight {
    padding-block-start: var(--space-lg);
  }

  /* No grey fill and no hairlines (owner, 2026-09-15): the page stays white
     and minimal, and sections are separated by their padding alone. The
     class stays in the markup as a hook for a future tint. */
  .section--sunk {
    background: transparent;
  }

  /* Coloured sections are rounded panels inside the 1320px column, never
     full-bleed bands (owner, 2026-09-15). The panel's outer edge lines up with
     the content edge of every other section, and the content inside gets its
     own, wider inset so it never sits against the rounded edge. */
  .section--ink {
    inline-size: calc(100% - 2 * var(--shell-pad));
    max-inline-size: var(--shell-max);
    margin-inline: auto;
    border-radius: clamp(20px, 3.5vw, 40px);
    background: var(--color-ink);
    color: var(--color-page);
    overflow: clip;
  }

  .section--ink > .shell {
    padding-inline: clamp(20px, 16px + 3vw, 56px);
  }

  /* Headings run the full measure and wrap naturally - no forced breaks,
     no cramped single column. Leads keep a readable measure of their own. */
  .section__head {
    max-inline-size: none;
    margin-block-end: var(--space-2xl);
  }

  /* Kept as a hook, but aligned to the left edge like the header. */
  .section__head--center {
    margin-inline: 0;
    text-align: start;
  }

  .section__head--center .section__lead {
    margin-inline: 0;
  }

  .section__title {
    font-size: var(--text-h2);
    max-width: calc(var(--text-h2) * 16.925);
    line-height: var(--leading-snug);
    letter-spacing: calc(var(--text-h2) * var(--tracking-tight));
    font-weight: 600;
    margin-block-start: var(--space-sm);
  }

  .section__lead {
    max-inline-size: calc(var(--text-lead) * 38.628);
    font-size: var(--text-lead);
    color: var(--color-ink-muted);
    margin-block-start: var(--space-md);
  }

  .section--ink .section__lead {
    color: rgb(var(--color-white-rgb) / 72%);
  }

  .skip-link {
    position: absolute;
    inset-block-start: var(--space-sm);
    inset-inline-start: var(--space-sm);
    z-index: var(--z-skip-link);
    padding: var(--space-2xs) var(--space-sm);
    border-radius: var(--radius-sm);
    background: var(--color-ink);
    color: var(--color-page);
    font-size: var(--text-sm);
    transform: translateY(-160%);
    transition: transform var(--dur-base) var(--ease-out);
  }

  .skip-link:focus-visible {
    transform: translateY(0);
  }
}

/* =========================================================================
   COMPONENTS
   ========================================================================= */
@layer components {
  /* ---------- Eyebrow ------------------------------------------------- */
  .eyebrow {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2xs);
    font-size: var(--text-eyebrow);
    font-weight: 600;
    letter-spacing: calc(var(--text-eyebrow) * var(--tracking-wide));
    text-transform: uppercase;
    color: var(--color-ink-subtle);
  }

  .section--ink .eyebrow {
    color: rgb(var(--color-white-rgb) / 62%);
  }

  /* Brand-gradient accent inside display headings. Stops are tuned to
     >= 3:1 on both white and ink so large text stays AA everywhere. */
  /* The gradient only paints inside the element's box, and with tight
     heading line-heights that box stops above the descenders, so the tails
     of p, y, g were cut off. The extra block padding grows the painted area
     to cover them; the matching negative margin keeps line spacing exactly
     as it was. "clone" repeats that padding on every line when a phrase
     wraps, so the second line is covered too.

     The same clipping happened sideways, on the LAST letter of every accent.
     Headings use negative letter-spacing, and letter-spacing is also applied
     after the final character, so the span's box ends a few pixels before
     that letter's ink does (measured up to 3.4px at 45px type, on "k", "e",
     "p", "s", "t"). The gradient stopped painting at the box edge and cut
     the letter off. Inline padding carries the painted area past the ink on
     both sides; the matching negative margin keeps every letter, and the
     punctuation after the accent, exactly where it was. */
  .accent {
    padding-block: 6.8px 13.6px;
    padding-inline: 3.4px 8.16px;
    margin-block: -6.8px -13.6px;
    margin-inline: -3.4px -8.16px;
    -webkit-box-decoration-break: clone;
    box-decoration-break: clone;
    background: var(--grad-accent);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
  }

  /* ---------- Buttons -------------------------------------------------- */
  .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2xs);
    min-block-size: 48px;
    padding: 0 var(--space-md);
    border: 1px solid transparent;
    border-radius: var(--radius-pill);
    font-size: var(--text-sm);
    font-weight: 600;
    letter-spacing: calc(var(--text-sm) * -0.006);
    text-align: center;
    white-space: nowrap;
    transition:
      transform var(--dur-fast) var(--ease-out),
      background-color var(--dur-fast) var(--ease-out),
      border-color var(--dur-fast) var(--ease-out),
      box-shadow var(--dur-base) var(--ease-out),
      color var(--dur-fast) linear;
  }

  .btn:hover {
    transform: translateY(-1px);
  }

  .btn:active {
    transform: translateY(0);
  }

  .btn--primary {
    background: var(--color-violet-deep);
    color: var(--color-white);
    box-shadow: var(--shadow-md);
  }

  .btn--primary:hover {
    background: var(--color-violet-deep-hover);
    box-shadow: var(--shadow-md);
  }

  .btn--secondary {
    background: transparent;
    border-color: var(--color-line-strong);
    color: var(--color-ink);
  }

  .btn--secondary:hover {
    background: rgb(var(--color-ink-rgb) / 5%);
    border-color: var(--color-ink);
  }

  /* The quiet third option. It sits beside a bordered secondary button, so it
     carries no fill and no border of its own, otherwise the pair reads as two
     equally weighted actions and neither leads. */
  .btn--ghost {
    padding: 0 var(--space-2xs);
    background: transparent;
    border-color: transparent;
    color: var(--color-ink-muted);
    text-decoration: underline;
    text-decoration-color: transparent;
    text-underline-offset: 4px;
    transition:
      color var(--dur-fast) var(--ease-out),
      text-decoration-color var(--dur-fast) var(--ease-out);
  }

  .btn--ghost:hover {
    color: var(--color-ink);
    text-decoration-color: currentColor;
    transform: none;
  }

  .btn--inverse {
    background: var(--color-page);
    color: var(--color-ink);
  }

  .btn--inverse:hover {
    background: var(--color-white);
  }

  .btn--outline-inverse {
    border-color: rgb(var(--color-white-rgb) / 34%);
    color: var(--color-page);
  }

  .btn--outline-inverse:hover {
    border-color: var(--color-page);
    background: rgb(var(--color-white-rgb) / 8%);
  }

  /* Tracking is a ratio of the label's size, so a size modifier restates it
     against its own size. With em this followed automatically; in px each
     size has to say it, or a large button keeps the small button's tracking. */
  .btn--sm {
    min-block-size: 40px;
    padding-inline: var(--space-sm);
    font-size: var(--text-xs);
    letter-spacing: calc(var(--text-xs) * -0.006);
  }

  .btn--lg {
    min-block-size: 56px;
    padding-inline: var(--space-lg);
    font-size: 15.04px;
    letter-spacing: calc(15.04px * -0.006);
  }

  .btn--block {
    inline-size: 100%;
  }

  /* Shared action cluster, used wherever a section ends in buttons. */
  .actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs);
    margin-block-start: var(--space-lg);
  }

  /* ---------- Site header ---------------------------------------------- */
  .site-header {
    position: fixed;
    inset-block-start: 0;
    inset-inline: 0;
    z-index: var(--z-header);
    transition:
      transform var(--dur-base) var(--ease-out),
      background-color var(--dur-base) linear,
      box-shadow var(--dur-base) linear;
  }

  .site-header::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: var(--z-local-below);
    background: var(--color-page);
    border-block-end: 1px solid var(--color-line-soft);
    opacity: 1;
    transition: opacity var(--dur-base) linear;
  }

  .site-header.is-stuck::before {
    opacity: 1;
    backdrop-filter: saturate(150%) blur(14px);
    -webkit-backdrop-filter: saturate(150%) blur(14px);
    border-block-end: 1px solid var(--color-line-soft);
  }

  .site-header.is-hidden {
    transform: translateY(-102%);
  }

  .site-header__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-md);
    block-size: var(--header-h);
  }

  .site-header__nav {
    display: none;
  }

  .site-header__links {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
  }

  .site-header__link {
    display: inline-flex;
    align-items: center;
    min-block-size: 44px;
    padding-inline: var(--space-xs);
    border-radius: var(--radius-sm);
    font-size: var(--text-sm);
    font-weight: 500;
    color: var(--color-ink-muted);
    transition: color var(--dur-fast) linear;
  }

  .site-header__link:hover {
    color: var(--color-ink);
  }

  .site-header__actions {
    display: flex;
    align-items: center;
    gap: var(--space-2xs);
  }

  .site-header__cta-secondary {
    display: none;
  }

  /* ---------- Brand lockup --------------------------------------------- */
  .brand {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2xs);
  }

  .brand__mark {
    inline-size: 30px;
    block-size: 30px;
    flex: none;
    border-radius: 7px;
  }

  .brand__name {
    font-size: 18.24px;
    font-weight: 700;
    letter-spacing: -0.5472px;
  }

  .brand__by {
    display: none;
    align-items: center;
    gap: 5px;
    padding-inline-start: var(--space-2xs);
    margin-inline-start: 2px;
    border-inline-start: 1px solid var(--color-line);
    font-size: var(--text-xs);
    color: var(--color-ink-subtle);
    white-space: nowrap;
  }

  .brand__by-mark {
    inline-size: 16px;
    block-size: 16px;
    flex: none;
    color: var(--color-ink);
  }

  /* ---------- Hero ------------------------------------------------------ */
  .hero {
    position: relative;
    z-index: var(--z-content);
    /* Bottom padding is deliberately its own smaller value, not --space-3xl/
       4xl: the hero already ends with the facts row's own margin-block-start,
       and the next section (.section--tight) brings its own top padding, so
       reusing the section scale here double-stacks into a huge dead gap. */
    padding-block: calc(var(--header-h) + var(--space-xl)) var(--space-lg);
    overflow: clip;
  }

  /* Two columns from 992px: pill, headline, lead, actions and the proof
     chips on the left, the live demo on the right, so the demo is in the
     first screen. Below 992px it is one column and the demo follows the
     copy. */
  .hero__grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-2xl);
    align-items: center;
  }

  .hero__copy {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    text-align: start;
  }

  .hero__pill {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2xs);
    padding: 7px 16px;
    border-radius: var(--radius-pill);
    background: var(--color-violet-soft);
    color: var(--color-violet-deep);
    font-size: var(--text-sm);
    font-weight: 600;
  }

  .hero__pill-dot {
    inline-size: 8px;
    block-size: 8px;
    border-radius: 50%;
    background: var(--color-violet);
  }

  /* The headline is the anchor of the left column, so it runs at the display
     step and wraps naturally over as many lines as the column needs. The
     .hero__line spans are inline, so they no longer force a break. */
  .hero__title {
    font-size: var(--text-h2);
    max-width: calc(var(--text-display) * 16.925);
    line-height: 1.06;
    letter-spacing: calc(var(--text-display) * -0.04);
    font-weight: 600;
    margin-block-start: var(--space-md);
    text-wrap: balance;
  }

  .hero__lead {
    max-inline-size: calc(var(--text-lead) * 31.968);
    margin-block-start: var(--space-md);
    font-size: var(--text-lead);
    color: var(--color-ink-muted);
  }

  .hero__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs);
    margin-block-start: var(--space-lg);
  }

  .hero__note {
    display: flex;
    align-items: center;
    text-align: start;
    text-wrap: balance;
    gap: var(--space-2xs);
    margin-block-start: var(--space-sm);
    font-size: var(--text-sm);
    color: var(--color-ink-subtle);
  }

  /* No filled panel behind the demo any more. A soft wash, drawn from the
     brand violet and clay at low alpha, lifts the card off the white page
     without darkening the section. It sits behind the card, is purely
     decorative, and never catches a pointer. */
  .hero__stage {
    position: relative;
    margin-block-start: var(--space-2xl);
  }

  .hero__stage::before {
    content: "";
    position: absolute;
    z-index: var(--z-local-below);
    inset: -8% -6% -10%;
    pointer-events: none;
  }

  .hero__stage .demo {
    max-inline-size: 640px;
    margin-inline: auto;
  }

  .hero__note-icon {
    inline-size: 15px;
    block-size: 15px;
    flex: none;
    color: var(--color-success);
  }

  /* The theme strip closes the hero: its label sits beside the moving row
     rather than above it, under a hairline that separates the strip from the
     copy and the demo. The marquee keeps its own mask and animation. */
  .themes {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-xs) var(--space-md);
    margin-block-start: var(--space-2xl);
    padding-block-start: var(--space-md);
    border-block-start: 1px solid var(--color-line-soft);
  }

  .themes .marquee {
    flex: 1 1 320px;
    min-inline-size: 0;
    padding-block: 0;
  }

  /* ---------- Fact strip ------------------------------------------------ */
  /* Four proof chips under the buttons. A card each, so they read as facts
     rather than a caption. Two by two on phones, one row of four from 768px.
     From 992px the row sits in the hero's left column (about 450px to
     620px wide), so the value size and card padding tighten there to keep
     "Within 24 h" on one line. Grid rows keep paired cards the same height
     when one label wraps. */
  .facts {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-2xs);
    inline-size: 100%;
    margin-block-start: var(--space-xl);
  }

  /* Definition lists must be <dt> then <dd>, but the value reads first.
     column-reverse keeps the markup valid and the reading order visual.
     In column-reverse the main axis runs bottom to top, so flex-end packs
     the pair against the TOP of the stretched grid cell. Load-bearing: with
     the default flex-start the pair sits on the bottom edge instead, and a
     label that wraps to two lines shoves its own value upward, so the row of
     numbers no longer shares a baseline. */
  .facts__item {
    display: flex;
    flex-direction: column-reverse;
    justify-content: flex-end;
    align-items: flex-start;
    min-inline-size: 0;
    /* Side padding eases from 16px to 12px below ~400px so the longest
       value still fits on one line at 320px. */
    padding: var(--space-xs) clamp(12px, 4.8vw - 3px, 16px);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    border: 1px solid var(--color-line);
    box-shadow: var(--shadow-xs);
  }

  .facts__value {
    display: block;
    --facts-value-size: clamp(18.4px, 16px + 0.7vw, 22.4px);

    margin-inline-start: 0;
    font-size: var(--facts-value-size);
    font-weight: 600;
    letter-spacing: calc(var(--facts-value-size) * -0.025);
    line-height: 1.1;
    white-space: nowrap;
  }

  .facts__label {
    display: block;
    margin-block-start: 3px;
    font-size: var(--text-xs);
    line-height: 1.4;
    color: var(--color-ink-subtle);
  }

  /* ---------- Product demo (hero + reused elsewhere) -------------------- */
  .demo {
    --demo-pad: clamp(16px, 6.4px + 2vw, 28px);

    position: relative;
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    border: 1px solid var(--color-line);
    box-shadow: var(--shadow-lg);
  }

  .demo__chrome {
    display: flex;
    align-items: center;
    gap: var(--space-2xs);
    padding: var(--space-xs) var(--demo-pad);
    border-block-end: 1px solid var(--color-line-soft);
  }

  .demo__dots {
    display: flex;
    gap: 5px;
  }

  .demo__dot {
    inline-size: 9px;
    block-size: 9px;
    border-radius: 50%;
    background: var(--color-line-strong);
  }

  .demo__url {
    flex: 1;
    min-inline-size: 0;
    padding: 3px var(--space-2xs);
    border-radius: var(--radius-xs);
    background: var(--color-surface-sunk);
    font-family: var(--font-mono);
    font-size: 10.88px;
    color: var(--color-ink-subtle);
    text-align: center;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .demo__body {
    display: grid;
    gap: var(--space-md);
    padding: var(--demo-pad);
  }

  .demo__media {
    position: relative;
    border-radius: var(--radius-md);
    background: var(--color-surface-sunk);
    overflow: hidden;
  }

  .demo__stage {
    display: block;
    inline-size: 100%;
    block-size: auto;
    aspect-ratio: 4 / 5;
    transition: background-color var(--dur-slow) var(--ease-out);
  }

  .demo__badge {
    position: absolute;
    inset-block-start: var(--space-2xs);
    inset-inline-start: var(--space-2xs);
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 4px 10px;
    border-radius: var(--radius-pill);
    background: var(--color-ink);
    color: var(--color-page);
    font-size: var(--text-xs);
    font-weight: 600;
    opacity: 0;
    transform: translateY(-4px);
    transition:
      opacity var(--dur-base) var(--ease-out),
      transform var(--dur-base) var(--ease-out);
  }

  .demo__badge.is-visible {
    opacity: 1;
    transform: translateY(0);
  }

  .demo__thumbs {
    display: flex;
    gap: var(--space-2xs);
    margin-block-start: var(--space-2xs);
  }

  .demo__thumb {
    inline-size: 46px;
    block-size: 46px;
    flex: none;
    border-radius: var(--radius-xs);
    border: 1px solid var(--color-line);
    background: var(--color-surface-sunk);
    overflow: hidden;
    transition:
      border-color var(--dur-fast) linear,
      opacity var(--dur-base) var(--ease-out);
  }

  .demo__thumb[aria-current="true"] {
    border-color: var(--color-ink);
  }

  .demo__thumb[hidden] {
    display: none;
  }

  .demo__title {
    font-size: var(--text-h4);
    font-weight: 600;
    letter-spacing: calc(var(--text-h4) * -0.02);
  }

  .demo__meta {
    display: flex;
    align-items: baseline;
    gap: var(--space-2xs);
    margin-block-start: 2px;
  }

  .demo__price {
    font-size: 16.8px;
    font-weight: 600;
  }

  .demo__compare {
    font-size: var(--text-sm);
    color: var(--color-ink-subtle);
    text-decoration: line-through;
  }

  .demo__option-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-2xs);
    margin-block-end: var(--space-2xs);
  }

  .demo__option-label {
    font-size: var(--text-sm);
    font-weight: 600;
  }

  .demo__option-value {
    font-size: var(--text-sm);
    color: var(--color-ink-subtle);
  }

  .demo__select {
    inline-size: 100%;
    min-block-size: 46px;
    padding: 0 var(--space-lg) 0 var(--space-xs);
    border: 1px solid var(--color-line-strong);
    border-radius: var(--radius-xs);
    background-color: var(--color-surface);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%234e483a' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right var(--space-xs) center;
    font-size: var(--text-sm);
    appearance: none;
  }

  .demo__stock {
    display: block;
    min-block-size: calc(var(--text-xs) * 1.2);
    margin-block-start: var(--space-2xs);
    font-size: var(--text-xs);
    font-weight: 600;
    color: var(--color-warn);
  }

  .demo__atc {
    margin-block-start: var(--space-2xs);
  }

  .demo__caption {
    margin-block-start: var(--space-xs);
    font-size: var(--text-xs);
    color: var(--color-ink-subtle);
    text-align: center;
  }

  /* Two panels stacked in the same grid cell, cross-faded by the toggle. */
  .demo__picker {
    display: grid;
  }

  .demo__panel {
    grid-area: 1 / 1;
    transition:
      opacity var(--dur-base) var(--ease-out),
      transform var(--dur-base) var(--ease-out);
  }

  .demo__panel[aria-hidden="true"] {
    opacity: 0;
    transform: translateY(6px) scale(0.99);
    pointer-events: none;
    visibility: hidden;
  }

  /* ---------- Swatch row (the product, rendered honestly) -------------- */
  .swatches {
    display: flex;
    flex-wrap: wrap;
    gap: var(--swatch-gap);
    align-items: flex-start;
  }

  .swatch {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 5px;
    inline-size: max(var(--swatch-size), 76px);
    padding: 0;
    background: none;
    border: 0;
    border-radius: var(--radius-xs);
  }

  .swatch__chip {
    position: relative;
    inline-size: var(--swatch-size);
    block-size: var(--swatch-size);
    border-radius: var(--swatch-radius);
    background-color: var(--chip-a, var(--color-surface-sunk));
    box-shadow: inset 0 0 0 var(--swatch-border) rgb(var(--color-ink-rgb) / 22%);
    transition:
      box-shadow var(--dur-base) var(--ease-out),
      transform var(--dur-base) var(--ease-spring);
    overflow: hidden;
  }

  /* Two-tone: hard split. Gradient: blend. Both real product capabilities. */
  .swatch__chip--duo {
    background-image: linear-gradient(
      135deg,
      var(--chip-a) 0 50%,
      var(--chip-b) 50% 100%
    );
  }

  .swatch__chip--gradient {
    background-image: linear-gradient(135deg, var(--chip-a), var(--chip-b));
  }

  .swatch__chip--photo {
    background-size: cover;
    background-position: center;
  }

  .swatch[aria-checked="true"] .swatch__chip {
    box-shadow:
      inset 0 0 0 var(--swatch-border) rgb(var(--color-ink-rgb) / 22%),
      0 0 0 2px var(--color-surface),
      0 0 0 4px var(--swatch-ring);
  }

  .swatch:hover .swatch__chip {
    transform: translateY(-2px);
  }

  .swatch__label {
    max-inline-size: 76px;
    font-size: 11.52px;
    line-height: 1.25;
    color: var(--color-ink-muted);
    text-align: center;
    overflow-wrap: break-word;
    hyphens: auto;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    overflow: hidden;
  }

  .swatches--no-labels .swatch__label {
    display: none;
  }

  .swatches--no-labels .swatch {
    inline-size: max(var(--swatch-size), 44px);
  }

  /* Sold out: diagonal strike, never colour alone (label carries the state). */
  .swatch[data-state="soldout"] .swatch__chip::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(
      to top left,
      transparent calc(50% - 1px),
      rgb(var(--color-ink-rgb) / 55%) calc(50% - 1px) calc(50% + 1px),
      transparent calc(50% + 1px)
    );
  }

  .swatch[data-state="soldout"] {
    opacity: 0.72;
  }

  /* ---------- Before / after toggle ------------------------------------ */
  .toggle {
    display: inline-flex;
    align-items: center;
    padding: 3px;
    border-radius: var(--radius-pill);
    background: var(--color-surface-sunk);
    border: 1px solid var(--color-line-soft);
  }

  .toggle__option {
    position: relative;
    z-index: var(--z-local-raised);
    min-block-size: 38px;
    padding-inline: var(--space-sm);
    border-radius: var(--radius-pill);
    font-size: var(--text-xs);
    font-weight: 600;
    color: var(--color-ink-subtle);
    transition: color var(--dur-base) linear;
  }

  .toggle__option[aria-pressed="true"] {
    color: var(--color-page);
  }

  .toggle__save {
    margin-inline-start: 6px;
    color: var(--color-success);
    font-weight: 700;
  }

  .toggle__option[aria-pressed="true"] .toggle__save {
    color: var(--color-success-soft);
  }

  .toggle__thumb {
    position: absolute;
    inset-block: 3px;
    z-index: var(--z-local-base);
    border-radius: var(--radius-pill);
    background: var(--color-ink);
    transition:
      transform var(--dur-slow) var(--ease-spring),
      inline-size var(--dur-slow) var(--ease-spring);
  }

  .toggle--framed {
    position: relative;
  }

  /* ---------- Marquee --------------------------------------------------- */
  .marquee {
    position: relative;
    overflow: hidden;
    padding-block: var(--space-sm);
    /* A mask reads only the alpha of these stops, so any opaque colour draws
       the same fade. Ink is used so no raw colour is left in the rule. */
    mask-image: linear-gradient(
      to right,
      transparent,
      var(--color-ink) 8%,
      var(--color-ink) 92%,
      transparent
    );
    -webkit-mask-image: linear-gradient(
      to right,
      transparent,
      var(--color-ink) 8%,
      var(--color-ink) 92%,
      transparent
    );
    max-width: var(--shell-max);
    margin-inline: auto;
  }

  .marquee__track {
    display: flex;
    inline-size: max-content;
    gap: var(--space-md);
    animation: marquee-slide 46s linear infinite;
  }

  .marquee:hover .marquee__track,
  .marquee:focus-within .marquee__track {
    animation-play-state: paused;
  }

  .marquee__item {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2xs);
    padding: var(--space-2xs) var(--space-md);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-pill);
    background: var(--color-surface);
    font-size: var(--text-sm);
    font-weight: 500;
    white-space: nowrap;
  }

  .marquee__dot {
    inline-size: 8px;
    block-size: 8px;
    border-radius: 50%;
    flex: none;
  }

  @keyframes marquee-slide {
    to {
      transform: translateX(calc(-50% - var(--space-md) / 2));
    }
  }

  /* ---------- Steps (how it works) -------------------------------------- */
  .steps {
    display: grid;
    gap: var(--space-2xl);
    align-items: start;
  }

  /* Grid items default to their content's width; let both columns shrink
     so the 320px layout never scrolls sideways. */
  .steps > * {
    min-width: 0;
  }

  .steps__list {
    display: grid;
    gap: var(--space-xs);
  }

  .step {
    position: relative;
    padding: var(--space-sm) var(--space-md);
    border-radius: var(--radius-md);
    border: 1px solid transparent;
    transition:
      background-color var(--dur-base) var(--ease-out),
      border-color var(--dur-base) var(--ease-out);
  }

  .step.is-active {
    background: var(--color-surface);
    border-color: var(--color-line);
    box-shadow: var(--shadow-sm);
  }

  .step__head {
    /* No font-size here: this h3 renders at the browser's default heading
       size, so its 25-character measure is that size times 16.775. */
    max-width: 314.03px;
    display: flex;
    align-items: center;
    gap: var(--space-xs);
  }

  .step__index {
    display: grid;
    place-items: center;
    inline-size: 32px;
    block-size: 32px;
    flex: none;
    border-radius: 50%;
    border: 1px solid var(--color-line-strong);
    font-size: var(--text-xs);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    transition:
      background-color var(--dur-base) linear,
      color var(--dur-base) linear,
      border-color var(--dur-base) linear;
  }

  .step.is-active .step__index {
    background: var(--color-ink);
    border-color: var(--color-ink);
    color: var(--color-page);
  }

  .step__title {
    font-size: var(--text-h4);
    font-weight: 600;
    letter-spacing: calc(var(--text-h4) * -0.018);
  }

  .step__body {
    margin-block-start: var(--space-2xs);
    padding-inline-start: calc(32px + var(--space-xs));
    color: var(--color-ink-muted);
    font-size: var(--text-sm);
  }

  .step__meta {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    margin-block-start: var(--space-2xs);
    padding: 3px 9px;
    border-radius: var(--radius-pill);
    background: var(--color-violet-soft);
    color: var(--color-violet-deep);
    font-size: var(--text-xs);
    font-weight: 600;
  }

  .steps__stage {
    position: sticky;
    inset-block-start: calc(var(--header-h) + var(--space-md));
  }

  /* ---------- Admin mock (the stage visual) ----------------------------- */
  .mock {
    border-radius: var(--radius-lg);
    border: 1px solid var(--color-line);
    background: var(--color-surface);
    box-shadow: var(--shadow-lg);
    overflow: hidden;
  }

  .mock__bar {
    display: flex;
    align-items: center;
    gap: var(--space-2xs);
    padding: var(--space-2xs) var(--space-sm);
    border-block-end: 1px solid var(--color-line-soft);
    background: var(--color-surface-sunk);
    font-size: var(--text-xs);
    font-weight: 600;
    color: var(--color-ink-muted);
  }

  .mock__panel {
    display: grid;
    gap: var(--space-sm);
    padding: var(--space-md);
    min-block-size: 330px;
    align-content: start;
  }

  .mock__panel[hidden] {
    display: none;
  }

  .mock__row {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    padding: var(--space-2xs) var(--space-xs);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-sm);
    background: var(--color-well);
    font-size: var(--text-sm);
  }

  .mock__row-chip {
    inline-size: 26px;
    block-size: 26px;
    flex: none;
    border-radius: 50%;
    box-shadow: inset 0 0 0 1px rgb(var(--color-ink-rgb) / 18%);
  }

  .mock__row-name {
    flex: 1;
    min-inline-size: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .mock__row-state {
    font-size: var(--text-xs);
    font-weight: 600;
    color: var(--color-ink-subtle);
    white-space: nowrap;
  }

  .mock__row.is-matched .mock__row-state {
    color: var(--color-success);
  }

  .mock__note {
    font-size: var(--text-xs);
    color: var(--color-ink-subtle);
  }

  .mock__cta {
    justify-self: start;
  }

  /* ---------- Bento ----------------------------------------------------- */
  .bento {
    display: grid;
    gap: var(--space-sm);
    grid-template-columns: 1fr;
  }

  .tile {
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
    padding: var(--space-md);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    box-shadow: var(--shadow-xs);
    transition:
      transform var(--dur-base) var(--ease-out),
      box-shadow var(--dur-base) var(--ease-out);
  }

  .tile:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-md);
  }

  .tile__visual {
    display: grid;
    place-items: center;
    min-block-size: 116px;
    padding: var(--space-sm);
    border-radius: var(--radius-md);
    background: var(--color-well);
    border: 1px solid var(--color-line-soft);
    order: -1;
  }

  .tile__title {
    font-size: var(--text-h4);
    max-width: calc(var(--text-h4) * 16.925);
    font-weight: 600;
    letter-spacing: calc(var(--text-h4) * -0.018);
  }

  .tile__text {
    font-size: var(--text-sm);
    color: var(--color-ink-muted);
  }

  /* Pastel card tints, one per tile (the smile.io feature-grid look).
     Text stays ink on every tint: the softs are all >= 90% luminance, so
     the existing ink/ink-muted pairings keep their AA contrast. */
  .tile--pastel-violet,
  .tile--pastel-blush,
  .tile--pastel-cream,
  .tile--pastel-clay {
    border-color: transparent;
    box-shadow: none;
  }

  .tile--pastel-violet {
    background: var(--color-violet-soft);
  }

  .tile--pastel-blush {
    background: var(--color-blush-soft);
  }

  .tile--pastel-cream {
    background: var(--color-cream-soft);
  }

  .tile--pastel-clay {
    background: var(--color-clay-soft);
  }

  .tile--pastel-violet .tile__visual,
  .tile--pastel-blush .tile__visual,
  .tile--pastel-cream .tile__visual,
  .tile--pastel-clay .tile__visual {
    background: rgb(var(--color-white-rgb) / 62%);
    border-color: transparent;
  }

  .tile__tag {
    align-self: flex-start;
    padding: 3px 9px;
    border-radius: var(--radius-pill);
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: calc(var(--text-xs) * 0.02);
  }

  .tile__tag--free {
    background: var(--color-success-soft);
    color: var(--color-success);
  }

  .tile__tag--advance {
    background: var(--color-clay-soft);
    color: var(--color-clay-deep);
  }

  /* ---------- Style studio ---------------------------------------------- */
  .studio {
    display: grid;
    gap: var(--space-lg);
    padding: var(--space-md);
    border-radius: var(--radius-lg);
    border: 1px solid var(--color-line);
    background: var(--color-surface);
    box-shadow: var(--shadow-md);
  }

  .studio__preview {
    display: grid;
    place-items: center;
    padding: var(--space-lg) var(--space-md);
    border-radius: var(--radius-md);
    background: var(--color-well);
    border: 1px solid var(--color-line-soft);
    min-block-size: 170px;
  }

  .studio__controls {
    display: grid;
    gap: var(--space-md);
  }

  .field {
    display: grid;
    gap: var(--space-2xs);
  }

  .field__label {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-2xs);
    font-size: var(--text-xs);
    font-weight: 600;
    letter-spacing: calc(var(--text-xs) * 0.02);
    text-transform: uppercase;
    color: var(--color-ink-subtle);
  }

  .field__value {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    text-transform: none;
    letter-spacing: 0;
    color: var(--color-ink);
  }

  .segmented {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    padding: 4px;
    border-radius: var(--radius-pill);
    background: var(--color-surface-sunk);
  }

  .segmented__option {
    flex: 1 1 auto;
    min-block-size: 38px;
    padding-inline: var(--space-xs);
    border-radius: var(--radius-pill);
    font-size: var(--text-xs);
    font-weight: 600;
    color: var(--color-ink-muted);
    transition:
      background-color var(--dur-fast) linear,
      color var(--dur-fast) linear;
  }

  .segmented__option[aria-pressed="true"] {
    background: var(--color-surface);
    color: var(--color-ink);
    box-shadow: var(--shadow-xs);
  }

  .slider {
    inline-size: 100%;
    block-size: 24px;
    background: transparent;
    appearance: none;
  }

  .slider::-webkit-slider-runnable-track {
    block-size: 4px;
    border-radius: var(--radius-pill);
    background: var(--color-surface-sunk);
  }

  .slider::-moz-range-track {
    block-size: 4px;
    border-radius: var(--radius-pill);
    background: var(--color-surface-sunk);
  }

  .slider::-webkit-slider-thumb {
    appearance: none;
    inline-size: 20px;
    block-size: 20px;
    margin-block-start: -8px;
    border-radius: 50%;
    background: var(--color-ink);
    border: 3px solid var(--color-surface);
    box-shadow: var(--shadow-sm);
    cursor: pointer;
  }

  .slider::-moz-range-thumb {
    inline-size: 20px;
    block-size: 20px;
    border-radius: 50%;
    background: var(--color-ink);
    border: 3px solid var(--color-surface);
    cursor: pointer;
  }

  .switch {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-xs);
    min-block-size: 44px;
    font-size: var(--text-sm);
    font-weight: 500;
    cursor: pointer;
  }

  .switch__control {
    position: relative;
    inline-size: 44px;
    block-size: 26px;
    flex: none;
    border-radius: var(--radius-pill);
    background: var(--color-surface-sunk);
    box-shadow: inset 0 0 0 1px var(--color-line);
    transition: background-color var(--dur-base) var(--ease-out);
  }

  .switch__control::after {
    content: "";
    position: absolute;
    inset-block-start: 3px;
    inset-inline-start: 3px;
    inline-size: 20px;
    block-size: 20px;
    border-radius: 50%;
    background: var(--color-surface);
    box-shadow: var(--shadow-sm);
    transition: transform var(--dur-base) var(--ease-spring);
  }

  .switch__input {
    position: absolute;
    opacity: 0;
    inline-size: 1px;
    block-size: 1px;
  }

  .switch__input:checked + .switch__control {
    background: var(--color-ink);
  }

  .switch__input:checked + .switch__control::after {
    transform: translateX(18px);
  }

  .switch__input:focus-visible + .switch__control {
    outline: 2px solid var(--color-violet-deep);
    outline-offset: 3px;
  }

  /* ---------- Surface cards (where swatches appear) --------------------- */
  .surfaces {
    display: grid;
    gap: var(--space-sm);
  }

  .surface-card {
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
    padding: var(--space-md);
    border-radius: var(--radius-md);
    border: 1px solid var(--color-line);
    background: var(--color-surface);
  }

  .surface-card__grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-2xs);
  }

  .product-card {
    display: grid;
    gap: 6px;
    padding: 7px;
    border-radius: var(--radius-sm);
    background: var(--color-well);
    border: 1px solid var(--color-line-soft);
  }

  .product-card__media {
    aspect-ratio: 4 / 5;
    border-radius: var(--radius-xs);
    overflow: hidden;
    background: var(--color-surface-sunk);
  }

  .product-card__name {
    font-size: 11.2px;
    font-weight: 600;
    line-height: 1.3;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .product-card__swatches {
    display: flex;
    gap: 5px;
  }

  .product-card__chip {
    inline-size: 15px;
    block-size: 15px;
    border-radius: 50%;
    box-shadow: inset 0 0 0 1px rgb(var(--color-ink-rgb) / 18%);
  }

  .surface-card__title {
    font-size: var(--text-h4);
    max-width: calc(var(--text-h4) * 16.925);
    font-weight: 600;
    letter-spacing: calc(var(--text-h4) * -0.018);
  }

  .surface-card__text {
    font-size: var(--text-sm);
    color: var(--color-ink-muted);
  }

  /* ---------- Proof pillars --------------------------------------------- */
  .pillars {
    display: grid;
    gap: var(--space-sm);
  }

  .pillar {
    display: grid;
    align-content: start;
    gap: var(--space-xs);
    padding: var(--space-md);
    border-radius: var(--radius-md);
    border: 1px solid rgb(var(--color-white-rgb) / 14%);
    background: rgb(var(--color-white-rgb) / 4%);
  }

  .pillar__icon {
    inline-size: 30px;
    block-size: 30px;
    color: var(--color-blush);
  }

  .pillar__title {
    font-size: var(--text-h4);
    max-width: calc(var(--text-h4) * 16.925);
    font-weight: 600;
    letter-spacing: calc(var(--text-h4) * -0.018);
  }

  .pillar__text {
    font-size: var(--text-sm);
    color: rgb(var(--color-white-rgb) / 70%);
  }

  /* Cards in a row share row tracks, so the titles, the body copy and the
     stat line each start on one line across the row however long the text
     above them is. Browsers without subgrid keep the stacked layout. */
  @supports (grid-template-rows: subgrid) {
    .pillar {
      grid-row: span 4;
      grid-template-rows: subgrid;
    }
  }

  .pillar__stat {
    align-self: end;
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    color: var(--color-blush);
  }

  /* ---------- Split feature rows ---------------------------------------- */
  .split {
    display: grid;
    gap: var(--space-lg);
    align-items: center;
  }

  .split + .split {
    margin-block-start: var(--space-3xl);
  }

  /* Section headings sit above the split, not inside a column, so the copy
     column opens with its text, which needs no gap above. */
  .split__copy > .split__text:first-child {
    margin-block-start: 0;
  }

  .split__title {
    font-size: var(--text-h3);
    font-weight: 600;
    letter-spacing: calc(var(--text-h3) * -0.024);
    margin-block-start: var(--space-2xs);
  }

  .split__text {
    margin-block-start: var(--space-xs);
    color: var(--color-ink-muted);
  }

  .split__list {
    display: grid;
    gap: var(--space-2xs);
    margin-block-start: var(--space-md);
  }

  .split__list-item {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2xs);
    font-size: var(--text-sm);
  }

  .split__list-icon {
    inline-size: 17px;
    block-size: 17px;
    flex: none;
    margin-block-start: 4px;
    color: var(--color-violet-deep);
  }

  .section--ink .split__text {
    color: rgb(var(--color-white-rgb) / 72%);
  }

  .section--ink .split__list-icon {
    color: var(--color-blush);
  }

  /* ---------- Agent readiness scorecard --------------------------------- */
  .scorecard {
    display: grid;
    gap: var(--space-md);
    padding: var(--space-md);
    border-radius: var(--radius-lg);
    border: 1px solid var(--color-line);
    background: var(--color-surface);
    box-shadow: var(--shadow-md);
  }

  .scorecard__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-sm);
  }

  .scorecard__score {
    font-size: clamp(33.6px, 28.8px + 1.3vw, 44px);
    font-weight: 600;
    letter-spacing: calc(clamp(33.6px, 28.8px + 1.3vw, 44px) * -0.04);
    line-height: 1;
    font-variant-numeric: tabular-nums;
  }

  .scorecard__grade {
    display: grid;
    place-items: center;
    inline-size: 46px;
    block-size: 46px;
    border-radius: var(--radius-sm);
    background: var(--color-success-soft);
    color: var(--color-success);
    font-size: 20px;
    font-weight: 700;
  }

  .scorecard__signals {
    display: grid;
    gap: var(--space-2xs);
  }

  .signal {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 4px var(--space-xs);
    align-items: center;
    font-size: var(--text-sm);
  }

  .signal__bar {
    grid-column: 1 / -1;
    block-size: 6px;
    border-radius: var(--radius-pill);
    background: var(--color-surface-sunk);
    overflow: hidden;
  }

  .signal__fill {
    display: block;
    block-size: 100%;
    border-radius: inherit;
    background: var(--color-violet);
    inline-size: var(--fill, 0%);
    transform-origin: left;
  }

  /* Hatched TRACK marks the shortfall; the fill stays at 0 so the bar
     reads as empty rather than complete. */
  .signal__bar--missing {
    background: repeating-linear-gradient(
      45deg,
      var(--color-clay-soft) 0 5px,
      var(--color-clay-hatch) 5px 10px
    );
    box-shadow: inset 0 0 0 1px rgb(var(--color-clay-rgb) / 35%);
  }

  .signal__points {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    color: var(--color-ink-subtle);
  }

  /* Marks the analytics illustration as sample data. App Store listing rules
     bar stats and data in images, so the invented figures have to read as an
     example, not as a reported result. */
  .dash__note {
    margin-top: var(--space-2xs);
    font-size: var(--text-xs);
    color: var(--color-ink-subtle);
  }

  .scorecard__note {
    font-size: var(--text-xs);
    color: var(--color-ink-subtle);
  }

  /* ---------- Variants gallery mock ------------------------------------- */
  .vgal {
    padding: var(--space-sm);
  }

  .vgal__chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2xs);
  }

  .vgal__chip {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 7px 14px;
    border: 1px solid var(--color-line);
    border-radius: var(--radius-pill);
    background: var(--color-surface);
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--color-ink-muted);
    transition:
      border-color var(--dur-fast) var(--ease-out),
      color var(--dur-fast) var(--ease-out),
      background-color var(--dur-fast) var(--ease-out);
  }

  .vgal__chip:hover {
    border-color: var(--color-line-strong);
    color: var(--color-ink);
  }

  .vgal__chip[aria-pressed="true"] {
    border-color: var(--color-ink);
    background: var(--color-surface-sunk);
    color: var(--color-ink);
  }

  .vgal__dot {
    inline-size: 12px;
    block-size: 12px;
    border-radius: 50%;
    box-shadow: inset 0 0 0 1px rgb(var(--color-ink-rgb) / 12%);
  }

  .vgal__grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-2xs);
    margin-block-start: var(--space-sm);
  }

  .vgal__photo {
    position: relative;
    border-radius: var(--radius-sm);
    overflow: clip;
    border: 1px solid var(--color-line-soft);
  }

  /* [hidden] on a list item would normally win, but be explicit so the
     filter can never be undone by a display rule elsewhere. */
  .vgal__photo[hidden] {
    display: none;
  }

  .vgal__photo svg {
    display: block;
    inline-size: 100%;
    block-size: auto;
  }

  .vgal__badge {
    position: absolute;
    inset-block-start: 6px;
    inset-inline-start: 6px;
    padding: 2px 8px;
    border-radius: var(--radius-pill);
    background: var(--color-ink);
    color: var(--color-page);
    font-size: 10.56px;
    font-weight: 700;
    letter-spacing: 0.2112px;
  }

  .vgal__badge--n {
    background: rgb(var(--color-white-rgb) / 88%);
    color: var(--color-ink);
  }

  /* ---------- Product groups mock --------------------------------------- */
  .gjoin {
    padding: var(--space-sm);
    display: grid;
    gap: var(--space-xs);
  }

  .gjoin__kicker {
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: calc(var(--text-xs) * 0.06);
    text-transform: uppercase;
    color: var(--color-ink-subtle);
  }

  .gjoin__caption {
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--color-ink-muted);
  }

  .gjoin__chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2xs);
  }

  .gjoin__chip {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 7px 14px;
    border: 1px solid var(--color-line);
    border-radius: var(--radius-pill);
    background: var(--color-surface);
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--color-ink-muted);
  }

  .gjoin__chip.is-current {
    border-color: var(--color-ink);
    background: var(--color-surface-sunk);
    color: var(--color-ink);
  }

  .gjoin__dot {
    inline-size: 12px;
    block-size: 12px;
    border-radius: 50%;
    box-shadow: inset 0 0 0 1px rgb(var(--color-ink-rgb) / 12%);
  }

  .gjoin__members {
    display: grid;
    gap: 6px;
    margin: 0;
    padding: 0;
    list-style: none;
  }

  .gjoin__member {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    border: 1px solid var(--color-line-soft);
    border-radius: var(--radius-sm);
    background: var(--color-surface);
  }

  .gjoin__member.is-here {
    border-color: var(--color-line);
    background: var(--color-surface-sunk);
  }

  .gjoin__grip {
    inline-size: 8px;
    block-size: 14px;
    flex: none;
    background: radial-gradient(
        circle,
        var(--color-ink-subtle) 1.1px,
        transparent 1.2px
      )
      0 0 / 4px 5px;
    opacity: 0.55;
  }

  .gjoin__thumb {
    inline-size: 28px;
    block-size: 28px;
    flex: none;
    border-radius: 8px;
    box-shadow: inset 0 0 0 1px rgb(var(--color-ink-rgb) / 10%);
  }

  .gjoin__meta {
    display: grid;
    gap: 1px;
    min-inline-size: 0;
  }

  .gjoin__title {
    font-size: var(--text-sm);
    font-weight: 600;
    letter-spacing: calc(var(--text-sm) * -0.01);
  }

  .gjoin__sub {
    font-size: var(--text-xs);
    color: var(--color-ink-subtle);
  }

  /* ---------- Analytics dashboard mock ---------------------------------- */
  .dash {
    padding: var(--space-md);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    box-shadow: var(--shadow-md);
  }

  .dash__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-sm);
  }

  .dash__range {
    padding: 3px 10px;
    border: 1px solid var(--color-line);
    border-radius: var(--radius-pill);
    font-size: var(--text-xs);
    color: var(--color-ink-subtle);
  }

  .dash__tiles {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-2xs);
    margin-block-start: var(--space-sm);
  }

  .dash__tile {
    display: flex;
    flex-direction: column;
    padding: var(--space-xs);
    border-radius: var(--radius-md);
    background: var(--color-well);
  }

  .dash__tile--warn {
    background: var(--color-warn-soft);
  }

  .dash__num {
    font-size: clamp(17.6px, 16px + 0.55vw, 22.4px);
    font-weight: 600;
    letter-spacing: calc(clamp(17.6px, 16px + 0.55vw, 22.4px) * -0.02);
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
  }

  .dash__tile--warn .dash__num {
    color: var(--color-warn);
  }

  .dash__lab {
    margin-block-start: 2px;
    font-size: var(--text-xs);
    color: var(--color-ink-subtle);
  }

  .dash__sub {
    margin-block-start: var(--space-md);
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: calc(var(--text-xs) * 0.08);
    text-transform: uppercase;
    color: var(--color-ink-subtle);
  }

  .dash__signals {
    display: grid;
    gap: var(--space-2xs);
    margin-block-start: var(--space-xs);
  }

  .dash__advice {
    margin-block-start: var(--space-md);
    padding: var(--space-xs) var(--space-sm);
    border-radius: var(--radius-sm);
    background: var(--color-clay-soft);
    color: var(--color-clay-deep);
    font-size: var(--text-sm);
  }

  /* ---------- Pricing ---------------------------------------------------- */
  /* The heading and the billing switch share one row from 992px (see that
     media block), so the switch sits beside the prices it changes instead of
     on a line of its own above them. */
  .pricing__head {
    display: grid;
    gap: var(--space-md);
    align-items: end;
    margin-block-end: var(--space-xl);
  }

  /* The head's own bottom margin belongs to the grid here. */
  .pricing__head .section__head {
    margin-block-end: 0;
  }

  .pricing__switch {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: var(--space-xs);
  }

  .pricing__trial-line {
    font-size: var(--text-sm);
    color: var(--color-ink-subtle);
    text-align: start;
  }

  /* One strip under the cards rather than a block: the title labels the row
     and the shared features wrap along it, so the section ends on a line
     instead of a second card of lists. */
  .pricing__includes {
    display: grid;
    gap: var(--space-sm);
    align-items: center;
    margin-block-start: var(--space-md);
    padding: var(--space-md);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
  }

  .pricing__includes-title {
    font-size: var(--text-h4);
    max-width: calc(var(--text-h4) * 16.925);
    font-weight: 600;
    letter-spacing: calc(var(--text-h4) * -0.018);
  }

  .pricing__includes-list {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2xs) var(--space-lg);
    margin: 0;
    padding: 0;
    list-style: none;
  }

  .pricing__includes .plan__feature-icon {
    color: var(--color-success);
  }

  .pricing__grid {
    display: grid;
    gap: var(--space-md);
    align-items: stretch;
  }

  .plan {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
    padding: var(--space-lg) var(--space-md) var(--space-md);
    border-radius: var(--radius-lg);
    border: 1px solid var(--color-line);
    background: var(--color-surface);
    box-shadow: var(--shadow-xs);
    overflow: hidden;
    transition:
      transform var(--dur-base) var(--ease-out),
      box-shadow var(--dur-base) var(--ease-out),
      border-color var(--dur-base) linear;
  }

  /* Every card has the same six parts (name, price, billing note, tagline,
     trial line, feature list), so the cards share the grid's rows: each part
     starts on one line across a row of cards however long any one card's copy
     runs, and the feature dividers line up. The row gap here only spaces the
     parts inside a card; the grid's own gap still separates the cards.
     Browsers without subgrid keep the stacked flex layout above. */
  @supports (grid-template-rows: subgrid) {
    .plan {
      display: grid;
      grid-row: span 6;
      grid-template-rows: subgrid;
      row-gap: var(--space-sm);
      align-content: start;
    }
  }

  .plan:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-md);
    border-color: var(--color-line-strong);
  }

  /* Every card carries a slim brand crown; only the highlighted plan's is lit. */
  .plan::before {
    content: "";
    position: absolute;
    inset-block-start: 0;
    inset-inline: 0;
    block-size: 4px;
    background: var(--color-line-soft);
  }

  /* The chosen plan is ringed in the brand gradient. A border cannot carry a
     gradient directly, so the card's own surface fills the padding box and
     the gradient fills the border box behind it. */
  .plan--highlight {
    border-color: transparent;
    background:
      linear-gradient(var(--color-surface), var(--color-surface)) padding-box,
      var(--grad-accent) border-box;
    box-shadow: var(--shadow-lg);
  }

  /* The crown would draw a second gradient inside the ring. */
  .plan--highlight::before {
    display: none;
  }

  .plan--highlight:hover {
    border-color: transparent;
    box-shadow: var(--shadow-lg);
  }

  .plan__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2xs);
  }

  .plan__name {
    font-size: var(--text-h4);
    max-width: calc(var(--text-h4) * 16.925);
    font-weight: 600;
    letter-spacing: calc(var(--text-h4) * -0.02);
  }

  .plan__flag {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 9px;
    border-radius: var(--radius-pill);
    border: 1px solid var(--color-violet);
    background: var(--color-violet-soft);
    color: var(--color-violet-deep);
    font-size: var(--text-xs);
    font-weight: 700;
    white-space: nowrap;
  }

  .plan__flag-icon {
    inline-size: 13px;
    block-size: 13px;
    flex: none;
  }

  .plan__price {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 5px var(--space-2xs);
  }

  .plan__amount {
    font-size: clamp(30.4px, 25.6px + 1.2vw, 38.4px);
    font-weight: 600;
    letter-spacing: calc(clamp(30.4px, 25.6px + 1.2vw, 38.4px) * -0.04);
    line-height: 1;
    font-variant-numeric: tabular-nums;
  }

  /* The yearly discount is the crossed-out price of twelve monthly payments,
     never a percentage, so the card reads the same way as the plan cards in
     the app. Hidden on the monthly view by the `hidden` attribute. */
  .plan__strike {
    font-size: var(--text-lead);
    font-weight: 600;
    color: var(--color-ink-subtle);
    /* Same line-height as the amount beside it: the default leading on a
       smaller baseline-aligned flex item grew the price row by 3px, which put
       the Free card's button above Grow's on the yearly view. */
    line-height: 1;
    text-decoration-line: line-through;
    text-decoration-thickness: 1.5px;
    font-variant-numeric: tabular-nums;
  }

  .plan__period {
    font-size: var(--text-sm);
    color: var(--color-ink-subtle);
  }

  .plan__note {
    font-size: var(--text-sm);
    color: var(--color-ink-subtle);
  }

  .plan__tagline {
    font-size: var(--text-sm);
    color: var(--color-ink-muted);
  }

  /* The trial line under the tagline: same quiet weight on every card so the
     four cards keep one rhythm whether the line says "trial" or "no limit". */
  .plan__trial {
    font-size: var(--text-xs);
    font-weight: 600;
    color: var(--color-ink-subtle);
  }

  /* Starter has no trial, but it keeps the line's height so its feature
     list starts level with Grow's beside it. */
  .plan__trial--placeholder {
    visibility: hidden;
  }

  /* The feature list is the last thing in the card and the lists differ in
     length, so the divider hangs off the list rather than the card edge. */
  .plan__features {
    padding-block-start: var(--space-sm);
    border-block-start: 1px solid var(--color-line-soft);
  }

  .plan__features {
    display: grid;
    gap: var(--space-2xs);
    /* The list fills its shared row (so every divider lines up), and a shorter
       list beside a longer one would otherwise spread its items over the extra
       height. Packed to the top, every list keeps the same spacing. */
    align-content: start;
    font-size: var(--text-sm);
  }

  .plan__feature {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2xs);
  }

  .plan__feature-icon {
    inline-size: 16px;
    block-size: 16px;
    flex: none;
    margin-block-start: 4px;
    color: var(--color-violet-deep);
  }

  .plan--advance .plan__feature-icon,
  .plan--premium .plan__feature-icon {
    color: var(--color-clay-deep);
  }

  .plan--free .plan__feature-icon {
    color: var(--color-success);
  }

  .plan__cta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2xs) var(--space-xs);
    padding-block-start: var(--space-2xs);
  }

  .pricing__note {
    margin-block-start: var(--space-lg);
    max-inline-size: calc(var(--text-sm) * 47.952);
    text-align: start;
    font-size: var(--text-sm);
    color: var(--color-ink-subtle);
  }

  /* ---------- Enstacked ------------------------------------------------- */
  /* The maker band closes the ink proof panel (revamp, 2026-09-15). It was a
     white section of its own between pricing and the FAQ; "why trust this
     app" and "who built it" now read as one moment right before pricing.

     The band reuses the pillar card surface, so it reads as the last card of
     the same panel, and every colour here is one the ink panel already uses.
     This supersedes the earlier "Enstacked keeps its earlier design" scale:
     inside a card the heading steps down to the h3 size and the wordmark
     becomes a lockup beside the logo. The eyebrow keeps its short rule. */
  .maker {
    display: grid;
    gap: var(--space-xl);
    align-items: center;
    margin-block-start: var(--space-sm); /* the same seam as between pillars */
    padding: var(--space-md);
    border-radius: var(--radius-md);
    border: 1px solid rgb(var(--color-white-rgb) / 14%);
    background: rgb(var(--color-white-rgb) / 4%);
  }

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

  .maker__copy .eyebrow::before {
    content: "";
    inline-size: 20px;
    block-size: 1px;
    background: currentcolor;
    opacity: 0.5;
  }

  /* Inline SVG: the dark strokes are currentColor, so they turn white on
     ink. The orange strokes stay the maker's own orange. */
  .maker__logo {
    flex: none;
    inline-size: clamp(52px, 4.5vw, 64px);
    block-size: auto;
    aspect-ratio: 1;
    color: var(--color-white);
  }

  .maker__logo-accent {
    fill: var(--color-enstacked);
  }

  .maker__wordmark {
    font-size: clamp(17.6px, 16px + 0.4vw, 20.8px);
    font-weight: 700;
    letter-spacing: calc(clamp(17.6px, 16px + 0.4vw, 20.8px) * -0.035);
    line-height: 1.05;
  }

  /* Enstacked orange on ink: 4.69:1, AA at any size. */
  .maker__wordmark span {
    color: var(--color-enstacked);
  }

  .maker__tagline {
    margin-block-start: var(--space-2xs);
    font-size: var(--text-xs);
    letter-spacing: calc(var(--text-xs) * 0.1);
    text-transform: uppercase;
    color: rgb(var(--color-white-rgb) / 62%);
  }

  .maker__title {
    margin-block-start: var(--space-xs);
    font-size: var(--text-h3);
    max-width: calc(var(--text-h3) * 16.925);
    font-weight: 600;
    line-height: var(--leading-snug);
    letter-spacing: calc(var(--text-h3) * -0.025);
  }

  .maker__text {
    margin-block-start: var(--space-xs);
    font-size: var(--text-sm);
    color: rgb(var(--color-white-rgb) / 70%);
  }

  .maker__stats {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-md);
  }

  /* Same shared-baseline rule as .facts__item, see the note there. */
  .maker__stats > div {
    display: flex;
    flex-direction: column-reverse;
    justify-content: flex-end;
  }

  .maker__stat-value {
    display: block;
    margin-inline-start: 0;
    font-size: clamp(20.8px, 17.6px + 0.9vw, 27.2px);
    font-weight: 600;
    letter-spacing: calc(clamp(20.8px, 17.6px + 0.9vw, 27.2px) * -0.03);
  }

  .maker__stat-label {
    display: block;
    margin-block-start: 2px;
    font-size: var(--text-xs);
    color: rgb(var(--color-white-rgb) / 62%);
  }

  /* ---------- FAQ -------------------------------------------------------- */
  /* Two columns from 992px (see that media block): the heading, the support
     path and the live status strip on the left, the questions on the right.
     One column below it, heading first. */
  .faq-grid {
    display: grid;
    gap: var(--space-xl);
    align-items: start;
  }

  /* A measure is a ratio of the text it holds, so a rule that changes the
     size restates it. With ch this followed the element on its own. */
  .faq-side .section__lead {
    font-size: var(--text-body);
    max-inline-size: calc(var(--text-body) * 38.628);
  }

  .faq-side .actions {
    margin-block-start: var(--space-md);
  }

  /* In the side column the strip is a narrow two-row box, so it keeps the
     card radius instead of the pill the full-width strip takes from 768px.
     The compound selector beats that rule wherever it sits in the file. */
  .status-strip.status-strip--side {
    margin-block-start: var(--space-lg);
    border-radius: var(--radius-lg);
  }

  .faq {
    display: grid;
    gap: var(--space-2xs);
  }

  .faq__item {
    border: 1px solid var(--color-line);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    overflow: hidden;
  }

  .faq__item[open] {
    border-color: var(--color-line-strong);
  }

  .faq__question {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-sm);
    min-block-size: 60px;
    padding: var(--space-sm) var(--space-md);
    font-size: var(--text-h4);
    font-weight: 500;
    letter-spacing: calc(var(--text-h4) * -0.015);
    cursor: pointer;
    list-style: none;
  }

  .faq__question::-webkit-details-marker {
    display: none;
  }

  /* .faq__item clips its rounded corners with overflow: hidden and the
     question fills it edge to edge, so the site-wide focus outline, drawn
     3px OUTSIDE the element, was cut away on three sides and a keyboard
     user saw no ring at all. Drawn 3px inside instead, it stays whole; the
     radius follows the item's inner curve (its 16px less the 1px border). */
  .faq__question:focus-visible {
    outline-offset: -3px;
    border-radius: calc(var(--radius-md) - 1px);
  }

  .faq__icon {
    inline-size: 18px;
    block-size: 18px;
    flex: none;
    color: var(--color-ink-subtle);
    transition: transform var(--dur-base) var(--ease-out);
  }

  .faq__item[open] .faq__icon {
    transform: rotate(45deg);
  }

  .faq__answer {
    padding: 0 var(--space-md) var(--space-md);
    max-inline-size: calc(var(--text-sm) * 45.288);
    color: var(--color-ink-muted);
    font-size: var(--text-sm);
  }

  /* ---------- Closing CTA ------------------------------------------------ */
  /* The paper-dart tour that needed a large seam above this band is switched
     off, so the closing band now sits directly under the previous section.
     If the tour comes back, restore clamp(128px, 64px + 9vw, 224px) here and
     keep it in step with FINISH_GAP in main.js. */
  .closer {
    position: relative;
    overflow: clip;
    text-align: start;
    margin-block-start: 0;
    /* A panel now, so it needs air before the footer's top rule. */
    margin-block-end: var(--space-2xl);
  }

  .closer__title {
    font-size: var(--text-display);
    max-width: calc(var(--text-display) * 16.775);
    line-height: var(--leading-tight);
    letter-spacing: calc(var(--text-display) * var(--tracking-tight));
    font-weight: 500;
  }

  .closer__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-start;
    gap: var(--space-xs);
    margin-block-start: var(--space-lg);
  }

  .closer__swatches {
    display: flex;
    justify-content: flex-start;
    gap: var(--space-xs);
    margin-block-end: var(--space-lg);
  }

  .closer__swatch {
    inline-size: clamp(30px, 6vw, 44px);
    block-size: clamp(30px, 6vw, 44px);
    border-radius: 50%;
    animation: float-chip 5s var(--ease-in-out) infinite;
  }

  .closer__swatch:nth-child(2) {
    animation-delay: 0.4s;
  }

  .closer__swatch:nth-child(3) {
    animation-delay: 0.8s;
  }

  .closer__swatch:nth-child(4) {
    animation-delay: 1.2s;
  }

  @keyframes float-chip {
    0%,
    100% {
      transform: translateY(0);
    }

    50% {
      transform: translateY(-9px);
    }
  }

  /* ---------- Footer ----------------------------------------------------- */
  .site-footer {
    position: relative;
    z-index: var(--z-content);
    padding-block: var(--space-2xl) var(--space-xl);
    border-block-start: 1px solid var(--color-line);
  }

  .site-footer__grid {
    display: grid;
    gap: var(--space-xl);
  }

  .site-footer__blurb {
    max-inline-size: calc(var(--text-sm) * 26.64);
    margin-block-start: var(--space-sm);
    font-size: var(--text-sm);
    color: var(--color-ink-muted);
  }

  .site-footer__nav-title {
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: calc(var(--text-xs) * 0.1);
    text-transform: uppercase;
    color: var(--color-ink-subtle);
    margin-block-end: var(--space-2xs);
  }

  .site-footer__link {
    display: inline-flex;
    align-items: center;
    min-block-size: 34px;
    font-size: var(--text-sm);
    color: var(--color-ink-muted);
    transition: color var(--dur-fast) linear;
  }

  .site-footer__link:hover {
    color: var(--color-ink);
  }

  .site-footer__bottom {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-sm);
    margin-block-start: var(--space-2xl);
    padding-block-start: var(--space-md);
    border-block-start: 1px solid var(--color-line-soft);
    font-size: var(--text-xs);
    color: var(--color-ink-subtle);
  }

  .site-footer__made {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2xs);
  }

  .site-footer__made-mark {
    inline-size: 22px;
    block-size: 22px;
    flex: none;
    color: var(--color-ink);
  }

  /* ---------- Mobile sticky CTA ------------------------------------------ */
  .mobile-cta {
    position: fixed;
    inset-block-end: 0;
    inset-inline: 0;
    z-index: var(--z-sticky-cta);
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    padding: var(--space-2xs) var(--space-sm)
      calc(var(--space-2xs) + env(safe-area-inset-bottom, 0px));
    background: rgb(var(--color-white-rgb) / 92%);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    border-block-start: 1px solid var(--color-line);
    transform: translateY(110%);
    transition: transform var(--dur-base) var(--ease-out);
  }

  .mobile-cta.is-visible {
    transform: translateY(0);
  }

  .mobile-cta__copy {
    flex: 1;
    min-inline-size: 0;
    font-size: var(--text-xs);
    line-height: 1.35;
    color: var(--color-ink-muted);
  }

  .mobile-cta__copy b {
    display: block;
    color: var(--color-ink);
    font-size: var(--text-sm);
  }

  /* ---------- Journey path ----------------------------------------------- */
  /* A scroll-driven SVG route down the whole page: a faint dotted track
     shows where the tour goes, a gradient line draws itself as far as the
     visitor has scrolled, and a swatch-chip traveler rides the line from
     section to section. Markup is generated by main.js; desktop only, and
     the module never runs under prefers-reduced-motion.

     --z-route keeps the whole route UNDER the sections (--z-content),
     so the line dives behind every sunk / ink panel and card and re-emerges
     in the seams between them, instead of drawing over content. That is the
     fallback: on a viewport narrow enough that the outer margin cannot hold
     the dart, the route has nowhere safe to fly and this is what it does. */
  .journey {
    position: absolute;
    inset: 0;
    z-index: var(--z-route);
    pointer-events: none;
    display: none;
  }

  /* Wide viewports get the route LIFTED above the panels (main.js adds the
     class once it has measured a margin the dart fits in). The route is
     confined to that margin and every left-to-right crossing happens in the
     empty band between two sections, so nothing is ever drawn over content -
     it only crosses the blank edge of a panel, which is what keeps the trail
     and the plane in view for the whole page instead of half of it. */
  .journey--over {
    z-index: var(--z-route-over);
  }

  @media (min-width: 992px) {
    .journey {
      display: block;
    }
  }

  .journey svg {
    inline-size: 100%;
    block-size: 100%;
    overflow: visible;
  }

  /* The trail the mark leaves BEHIND it. There is deliberately no preview
     of the route ahead: the page reveals itself as you travel it. Round
     caps on a zero-length dash render the stroke as a row of dots. */
  .journey__trail {
    fill: none;
    stroke: var(--color-ink);
    stroke-width: 6;
    stroke-linecap: round;
    stroke-dasharray: 0.1 18;
  }

  /* The same route drawn once more UNDER the ink dots, in the page colour
     and a little larger. On white it is invisible; over a tinted or ink
     panel it is what carries the trail, so one route reads on every
     background the page has without the JS knowing what it is flying over. */
  .journey__trail-halo {
    fill: none;
    stroke: var(--color-page);
    stroke-width: 12;
    stroke-linecap: round;
    stroke-dasharray: 0.1 18;
  }

  /* Checkpoints share the trail's clip, so one is only ever visible once
     the mark has reached it: it is always in its reached state. */
  .journey__node {
    fill: var(--color-violet);
    stroke: var(--color-ink);
    stroke-width: 2;
  }

  /* The traveler is the Varn brand mark riding the route. The shadow lifts
     it off the line; JS keeps it upright and only leans it into curves.
     The idle bob runs on the image INSIDE the group, so it composes with
     the group's own translate/rotate instead of fighting it. The whole
     journey module never runs under prefers-reduced-motion, so this
     animation cannot reach a reduced-motion visitor. */
  .journey__traveler {
    filter: drop-shadow(0 3px 10px rgb(var(--color-ink-rgb) / 30%));
    will-change: transform;
  }

  /* The traveler is a paper plane in a black-and-white sketch style: white
     near wing, a shaded far wing, a darker keel for the underside fold, all
     in an ink outline. JS rotates it to follow the path tangent.

     Every fill is OPAQUE, and that is the whole point: the shading used to
     be a transparent wash of ink, which reads as grey on the white page but
     dissolves into an ink panel, leaving nothing but the white near wing -
     a sliver, not a plane. Solid paper greys read against white AND against
     the dark panels the route now flies over. The ink outline is the part
     allowed to disappear on ink: by then the light fills carry the shape. */
  .journey__plane-top,
  .journey__plane-bot,
  .journey__plane-keel {
    stroke: var(--color-ink);
    stroke-width: 2;
    stroke-linejoin: round;
    stroke-linecap: round;
  }

  .journey__plane-top {
    fill: var(--color-surface);
  }

  .journey__plane-bot {
    fill: var(--color-plane-shade);
  }

  .journey__plane-keel {
    fill: var(--color-plane-keel);
  }

  .journey__logo {
    animation: journey-bob 3.2s var(--ease-in-out) infinite;
  }

  @keyframes journey-bob {
    0%,
    100% {
      transform: translateY(0);
    }

    50% {
      transform: translateY(-5px);
    }
  }

  /* The notification layer rides ABOVE the sections AND above the route, so
     a bubble is never swallowed by a panel or crossed by the trail. */
  .journey--top {
    z-index: var(--z-route-notes);
  }

  .jtoast {
    position: absolute;
    display: flex;
    align-items: center;
    gap: var(--space-2xs);
    padding: 7.2px 14.4px;
    background: var(--color-surface);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-pill);
    box-shadow: var(--shadow-md);
    font-size: var(--text-xs);
    font-weight: 600;
    color: var(--color-ink);
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    transition:
      opacity var(--dur-base) var(--ease-out),
      transform var(--dur-base) var(--ease-spring);
  }

  .jtoast[data-side="left"] {
    transform: translate(24px, -50%) scale(0.86);
    transform-origin: left center;
  }

  .jtoast[data-side="right"] {
    transform: translate(calc(-100% - 24px), -50%) scale(0.86);
    transform-origin: right center;
  }

  /* Only the finish uses this side, and there the dart has levelled out and
     points STRAIGHT DOWN - its nose reaches 34px past the point the pill is
     measured from, so 28px would have put the pill through the nose. */
  .jtoast[data-side="center"] {
    transform: translate(-50%, 46px) scale(0.86);
    transform-origin: center top;
  }

  .jtoast.is-on {
    opacity: 1;
    pointer-events: auto;
  }

  .jtoast[data-side="left"].is-on {
    transform: translate(24px, -50%) scale(1);
  }

  .jtoast[data-side="right"].is-on {
    transform: translate(calc(-100% - 24px), -50%) scale(1);
  }

  .jtoast[data-side="center"].is-on {
    transform: translate(-50%, 46px) scale(1);
  }

  .jtoast__dot {
    inline-size: 8px;
    block-size: 8px;
    border-radius: 50%;
    flex: none;
  }

  .jtoast__cta {
    color: var(--color-violet-deep);
    font-weight: 700;
  }

  .jtoast__cta:hover {
    text-decoration: underline;
  }
}

/* =========================================================================
   UTILITIES
   ========================================================================= */
@layer utilities {
  /* The headline used to run the full page width as exactly two unbreakable
     lines, so it carried a viewport-tied size cap here and .hero__line was a
     nowrap block. It now sits in the hero's left column and wraps to fit, so
     both rules are gone and the size comes from --text-display in the
     components layer. .hero__line stays in the markup as an inline span.

     Keeps a hyphenated phrase ("Single-Click") on one line. */
  .nowrap {
    white-space: nowrap;
  }

  .visually-hidden {
    position: absolute !important;
    inline-size: 1px;
    block-size: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }

  /* Scroll reveal. Default state is VISIBLE, the animation only starts it
     lower, so a browser without scroll timelines still shows every section. */
  .reveal {
    opacity: 1;
  }

  @supports (animation-timeline: view()) {
    .reveal {
      animation: reveal-rise linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 20%;
    }
  }

  @keyframes reveal-rise {
    from {
      opacity: 0;
      transform: translateY(22px);
    }

    to {
      opacity: 1;
      transform: translateY(0);
    }
  }

  .stack-sm > * + * {
    margin-block-start: var(--space-sm);
  }
}

/* =========================================================================
   RESPONSIVE  -  one block per breakpoint, mobile-first
   ========================================================================= */

/* ---- 576px -------------------------------------------------------- */
@media (min-width: 576px) {
  @layer components {
    .demo__body {
      grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
      align-items: start;
    }

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

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

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

/* ---- 768px -------------------------------------------------------- */
@media (min-width: 768px) {
  @layer components {
    .brand__by {
      display: inline-flex;
    }

    .site-header__cta-secondary {
      display: inline-flex;
    }

    .studio {
      grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
      align-items: center;
      padding: var(--space-lg);
    }

    .studio__preview {
      min-block-size: 230px;
    }

    /* The band is still stacked here, so the four stats fit in one row. */
    .maker {
      padding: var(--space-lg);
    }

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

    /* Hero copy is still full width, so the proof cards fit four across. */
    .facts {
      grid-template-columns: repeat(4, minmax(0, 1fr));
    }

    /* Plans pair up two across on tablets and small laptops, and sit in one
       row of four from 1200px (see that block), where every card still has
       room for its name, the badge and the price on one line. */
    .pricing__grid {
      grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .site-footer__grid {
      grid-template-columns: minmax(0, 1.6fr) repeat(2, minmax(0, 1fr));
    }
  }
}

/* ---- 992px -------------------------------------------------------- */
@media (min-width: 992px) {
  @layer components {
    .site-header__nav {
      display: block;
    }

    .hero {
      padding-block: calc(var(--header-h) + var(--space-2xl)) var(--space-lg);
    }

    /* The demo column is a touch wider than the copy: the card carries the
       product image, the swatch row and the button. */
    .hero__grid {
      grid-template-columns: minmax(0, 1fr) minmax(0, 1.04fr);
      gap: var(--space-3xl);
    }

    /* The grid's column gap is the seam now, so the stacked spacing goes. */
    .hero__stage {
      margin-block-start: 0;
    }

    /* Still four across, now inside the narrower left column: the value
       scales with the column (about 15px at 992px up to 22.4px once the
       shell stops growing) and the side padding drops to 12px. */
    .facts__item {
      padding-inline: var(--space-xs);
    }

    .facts__value {
      --facts-value-size: clamp(14.4px, 2.2vw - 7.2px, 22.4px);
    }

    .pricing__head {
      grid-template-columns: minmax(0, 1fr) auto;
    }

    .pricing__switch {
      align-items: flex-end;
    }

    .faq-grid {
      grid-template-columns: minmax(0, 0.82fr) minmax(0, 1.4fr);
      gap: var(--space-3xl);
    }

    /* Support and live status stay on screen while the list is read. */
    .faq-side {
      position: sticky;
      inset-block-start: calc(var(--header-h) + var(--space-md));
    }

    .steps {
      grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr);
      gap: var(--space-3xl);
    }

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

    /* Size carries hierarchy: two double-width anchor cells, one per row. */
    .bento__item--wide {
      grid-column: span 2;
    }

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

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

    .split {
      grid-template-columns: repeat(2, minmax(0, 1fr));
      gap: var(--space-3xl);
    }

    .split--reverse .split__media {
      order: -1;
    }

    /* Two columns: logo lockup over the copy on the left, stats and buttons
       on the right. Three columns would squeeze the copy to about 290px at
       992px, so that waits for 1200px. */
    .maker {
      grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
      column-gap: var(--space-2xl);
    }

    .maker__identity,
    .maker__copy {
      grid-column: 1;
    }

    .maker__aside {
      grid-column: 2;
      grid-row: 1 / span 2;
    }

    /* Beside the copy the aside is too narrow for four stats at their size
       ("WCAG AA" ran into "Direct" at 1024px), so they pair up from here on. */
    .maker__stats {
      grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .mobile-cta {
      display: none;
    }
  }
}

/* ---- 1200px ------------------------------------------------------- */
@media (min-width: 1200px) {
  @layer components {
    /* Logo lockup, copy, then stats and buttons, all in one row. The stats
       stay two by two: the aside column is still too narrow for four. */
    .maker {
      grid-template-columns: auto minmax(0, 1.2fr) minmax(0, 1fr);
    }

    .maker__identity,
    .maker__copy,
    .maker__aside {
      grid-column: auto;
      grid-row: auto;
    }

    /* All four plans in one row. */
    .pricing__grid {
      grid-template-columns: repeat(4, minmax(0, 1fr));
    }

    /* The label and the wrapped feature row sit side by side. */
    .pricing__includes {
      grid-template-columns: auto minmax(0, 1fr);
      gap: var(--space-lg);
    }

    .demo {
      --demo-pad: 28px;
    }

    .site-header__links {
      gap: var(--space-sm);
    }

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

/* =========================================================================
   MOTION PREFERENCES
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }

  @layer utilities {
    .reveal {
      animation: none;
      opacity: 1;
      transform: none;
    }
  }
}

/* =========================================================================
   PRINT
   ========================================================================= */
@media print {
  .site-header,
  .mobile-cta,
  .marquee {
    display: none !important;
  }

  body {
    background: var(--color-white);
  }
}

/* =========================================================================
   LEGAL  -  privacy.html and any future policy page
   =========================================================================
   A long document nobody reads front to back. The layout answers "is the
   part I care about in here", so the contents list is a real control on
   desktop and a native <details> on small screens, and every section owns
   an anchor a merchant can paste into a compliance form.
   ========================================================================= */
@layer components {
  .legal-page {
    padding-block: calc(var(--header-h) + var(--space-2xl)) var(--space-3xl);
  }

  .legal-hero {
    display: grid;
    gap: var(--space-sm);
    padding-block-end: var(--space-lg);
    border-block-end: 1px solid var(--color-line);
  }

  .legal-hero__title {
    margin: 0;
    font-size: clamp(29.6px, 20.8px + 2.2vw, 44.8px);
    max-width: calc(clamp(29.6px, 20.8px + 2.2vw, 44.8px) * 16.925);
    line-height: var(--leading-snug);
    letter-spacing: calc(clamp(29.6px, 20.8px + 2.2vw, 44.8px) * var(--tracking-tight));
    font-weight: 600;
    color: var(--color-ink);
  }

  .legal-hero__meta {
    margin: 0;
    max-width: calc(var(--text-body) * 41.292);
    font-size: var(--text-body);
    line-height: var(--leading-normal);
    color: var(--color-ink-muted);
  }

  .legal-hero__stamp {
    display: inline-flex;
    align-items: center;
    gap: 7.2px;
    padding: 4.8px 11.2px;
    border-radius: var(--radius-pill);
    background: var(--color-surface-sunk);
    border: 1px solid var(--color-line);
    font-size: var(--text-xs);
    font-weight: 500;
    color: var(--color-ink-muted);
    /* fit-content, capped: the longer effective/updated date line wraps on a
       phone instead of widening the page. */
    width: fit-content;
    max-width: 100%;
  }

  /* ---- At a glance ---------------------------------------------------- */
  .legal-glance {
    display: grid;
    gap: var(--space-sm);
    margin-block: var(--space-xl);
  }

  @media (min-width: 768px) {
    .legal-glance {
      grid-template-columns: repeat(2, 1fr);
    }
  }

  .legal-glance__item {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 12px;
    align-items: start;
    padding: var(--space-sm) var(--space-md);
    border-radius: var(--radius-md);
    background: var(--color-surface-sunk);
    border: 1px solid var(--color-line-soft);
  }

  .legal-glance__icon {
    display: grid;
    place-items: center;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: var(--color-white);
    border: 1px solid var(--color-line);
    color: var(--color-violet-deep);
  }

  .legal-glance__title {
    margin: 0 0 2.4px;
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--color-ink);
  }

  .legal-glance__copy {
    margin: 0;
    font-size: var(--text-xs);
    line-height: 1.6;
    color: var(--color-ink-muted);
  }

  /* ---- Two column shell ----------------------------------------------- */
  .legal-body {
    display: grid;
    gap: var(--space-xl);
    align-items: start;
  }

  /* A grid item's automatic minimum is its content's width, so the policy
     tables would otherwise widen the whole column past a phone screen. */
  .legal-body > * {
    min-width: 0;
  }

  @media (min-width: 992px) {
    .legal-body {
      grid-template-columns: 240px minmax(0, 1fr);
      gap: var(--space-2xl);
    }
  }

  .legal-toc__summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-sm);
    min-height: 48px;
    padding-inline: var(--space-md);
    border-radius: var(--radius-sm);
    background: var(--color-surface-sunk);
    border: 1px solid var(--color-line);
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--color-ink);
    cursor: pointer;
    list-style: none;
  }

  .legal-toc__summary::-webkit-details-marker {
    display: none;
  }

  .legal-toc__summary svg {
    transition: transform var(--dur-base) var(--ease-out);
  }

  .legal-toc[open] .legal-toc__summary svg {
    transform: rotate(180deg);
  }

  .legal-toc__title {
    display: none;
    margin: 0 0 var(--space-2xs);
    font-size: var(--text-eyebrow);
    font-weight: 600;
    letter-spacing: calc(var(--text-eyebrow) * var(--tracking-wide));
    text-transform: uppercase;
    color: var(--color-ink-subtle);
  }

  .legal-toc__list {
    margin: var(--space-2xs) 0 0;
    padding: 0;
    list-style: none;
    display: grid;
    gap: 1px;
  }

  .legal-toc__link {
    display: block;
    padding: 8px 11.2px;
    border-radius: var(--radius-xs);
    border-inline-start: 2px solid transparent;
    font-size: var(--text-sm);
    line-height: 1.4;
    color: var(--color-ink-muted);
    text-decoration: none;
    transition:
      color var(--dur-fast) var(--ease-out),
      background var(--dur-fast) var(--ease-out);
  }

  .legal-toc__link:hover {
    background: var(--color-surface-sunk);
    color: var(--color-ink);
  }

  .legal-toc__link[aria-current="true"] {
    border-inline-start-color: var(--color-violet);
    background: var(--color-violet-soft);
    color: var(--color-violet-deep);
    font-weight: 600;
  }

  @media (min-width: 992px) {
    .legal-toc {
      position: sticky;
      top: calc(var(--header-h) + var(--space-md));
      max-height: calc(100svh - var(--header-h) - var(--space-xl));
      overflow-y: auto;
    }

    /* On desktop the list is always open and the disclosure control is not
       a control at all, so it is replaced by a plain heading. */
    .legal-toc__summary {
      display: none;
    }

    .legal-toc__title {
      display: block;
    }

    /* The list scrolls here (overflow-y: auto clips both axes) and every
       link spans its full width, so the outline's left and right edges
       were cut off. Inside the link, the whole ring shows. */
    .legal-toc__link:focus-visible {
      outline-offset: -2px;
    }
  }

  /* ---- The document ---------------------------------------------------- */
  .legal-doc {
    max-width: calc(var(--text-body) * 45.288);
    font-size: var(--text-body);
    line-height: var(--leading-normal);
    color: var(--color-ink-muted);
  }

  .legal-doc > section + section {
    margin-block-start: var(--space-xl);
    padding-block-start: var(--space-lg);
    border-block-start: 1px solid var(--color-line-soft);
  }

  .legal-doc h2 {
    /* Anchor jumps must clear the fixed header. */
    scroll-margin-top: calc(var(--header-h) + var(--space-md));
    margin: 0 0 var(--space-xs);
    font-size: var(--text-h3);
    max-width: calc(var(--text-h3) * 16.925);
    line-height: 1.25;
    letter-spacing: calc(var(--text-h3) * -0.015);
    font-weight: 600;
    color: var(--color-ink);
  }

  .legal-doc h3 {
    margin: var(--space-md) 0 var(--space-2xs);
    font-size: var(--text-h4);
    max-width: calc(var(--text-h4) * 16.925);
    line-height: 1.3;
    font-weight: 600;
    color: var(--color-ink);
  }

  /* Policy tables (legal basis, retention): hairlines only, and they scroll
     inside their own box on a narrow phone rather than widening the page. */
  .legal-table-wrap {
    margin: 0 0 var(--space-sm);
    overflow-x: auto;
  }

  .legal-table {
    inline-size: 100%;
    min-inline-size: 480px;
    border-collapse: collapse;
    font-size: var(--text-sm);
  }

  .legal-table th,
  .legal-table td {
    padding: 9.6px 12px 9.6px 0;
    border-block-end: 1px solid var(--color-line);
    text-align: start;
    vertical-align: top;
  }

  .legal-table th {
    color: var(--color-ink);
    font-weight: 600;
  }

  .legal-doc p {
    margin: 0 0 var(--space-sm);
  }

  .legal-doc p:last-child {
    margin-bottom: 0;
  }

  .legal-doc ul {
    margin: 0 0 var(--space-sm);
    padding-inline-start: 18.4px;
    display: grid;
    gap: 9.6px;
  }

  .legal-doc li {
    padding-inline-start: 3.2px;
  }

  .legal-doc li::marker {
    color: var(--color-violet);
  }

  .legal-doc strong {
    color: var(--color-ink);
    font-weight: 600;
  }

  .legal-doc a {
    color: var(--color-violet-deep);
    text-decoration: underline;
    text-underline-offset: 2px;
  }

  .legal-doc a:hover {
    color: var(--color-ink);
  }

  .legal-callout {
    display: grid;
    gap: 6.4px;
    padding: var(--space-md);
    margin-block: 0 var(--space-sm);
    border-radius: var(--radius-md);
    background: var(--color-violet-soft);
    border: 1px solid rgb(var(--color-violet-rgb) / 22%);
    color: var(--color-ink-muted);
  }

  .legal-callout__title {
    margin: 0;
    display: flex;
    align-items: center;
    gap: 7.2px;
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--color-violet-deep);
  }

  .legal-doc__end {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2xs);
    margin-block-start: var(--space-xl);
    padding-block-start: var(--space-lg);
    border-block-start: 1px solid var(--color-line);
  }
}

/* =========================================================================
   MOTION PREFERENCES  -  waitlist + legal blocks
   Everything lands on its final state; nothing is left mid-transition.
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {
  .wl__flow {
    transition: none;
  }

  .wl__pill,
  .wl__title,
  .wl__lead,
  .wl__by,
  .wl__panel,
  .wl__perk,
  .wl__done-swatch {
    animation: none !important;
    opacity: 1;
    transform: none;
  }

  .wl__pill-dot::after,
  .wl__spinner {
    animation: none;
  }

  /* The spinner is the only signal that a submit is in flight, so with
     motion off it becomes a static ring rather than nothing at all. */
  .wl__spinner {
    border-top-color: rgb(var(--color-white-rgb) / 55%);
  }

  .wl__submit:hover svg,
  .legal-toc[open] .legal-toc__summary svg {
    transition: none;
  }

  .wl__view.is-leaving {
    transition: none;
  }
}

/* =========================================================================
   PRINT  -  the policy is the one page people actually print or file.
   ========================================================================= */
@media print {
  .legal-toc,
  .legal-doc__end,
  .legal-glance__icon {
    display: none;
  }

  .legal-page {
    padding-block: 0;
  }

  .legal-body {
    display: block;
  }

  .legal-doc {
    max-width: none;
    /* Pure black on paper only, on purpose: see --color-print-ink. */
    color: var(--color-print-ink);
  }

  .legal-doc > section + section {
    break-inside: avoid;
  }

  .legal-doc a::after {
    content: " (" attr(href) ")";
    font-size: calc(var(--text-body) * 0.85);
    word-break: break-all;
  }
}

/* =========================================================================
   FIXES verified in the browser at 390 / 768 / 1440
   ========================================================================= */
@layer components {
  /* Both waitlist views are display:grid, which OUTRANKS the user agent's
     [hidden] rule, so the form stayed on screen underneath the thank-you.
     Caught by rendering the success state, not by reading the markup. */
  .wl [hidden] {
    display: none !important;
  }

  /* The honeypot's input inherits no width, so it reported a box wider than
     a phone. It is clipped either way; this keeps the geometry honest. */
  .wl__trap input {
    width: 1px;
    height: 1px;
    padding: 0;
    border: 0;
  }

  /* 44px minimum on every target, the rule the rest of the site follows. */
  .wl__brand {
    min-height: 44px;
  }

  .wl__foot a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  .legal-toc__link {
    display: flex;
    align-items: center;
    min-height: 44px;
  }

  .brand {
    min-height: 44px;
  }
}

/* =========================================================================
   REFINEMENTS after inspecting the render
   ========================================================================= */
@layer components {
  /* The field is a moving image, so contrast over it cannot be measured or
     promised. Everything outside the main card now carries its own light
     ground instead of borrowing the shader's. */
  .wl__brand {
    padding-inline: 12px 14.4px;
    border-radius: var(--radius-pill);
    background: rgb(var(--color-white-rgb) / 72%);
    border: 1px solid var(--color-line);
    backdrop-filter: blur(8px);
  }

  .wl__foot {
    padding: 9.6px var(--space-md);
    border-radius: var(--radius-md);
    background: rgb(var(--color-white-rgb) / 78%);
    border: 1px solid rgb(var(--color-white-rgb) / 60%);
    backdrop-filter: blur(10px);
    color: var(--color-ink-muted);
  }

  .wl__shell {
    padding-block-end: var(--space-lg);
  }

  /* On a phone the top row has to stay one row, and "Built by Enstacked
     Technologies" is already spelled out inside the card. */
  @media (max-width: 479.84px) {
    .wl__brand-by {
      display: none;
    }

    .wl__back {
      padding-inline: 12px;
    }
  }

  /* The policy's three blocks (title, summary, document) shared a 1280px
     shell while the prose itself is capped at 68ch, which left the right
     edge ragged. One measure for all three. */
  /* Same 1320px column and gutter as the header; the policy text keeps its
     own readable measure (.legal-doc max-width). */
  .legal-page {
    max-width: calc(var(--shell-max) + 2 * var(--shell-pad));
  }
}

@layer components {
  /* The 44px hit area made the border-bottom sit at the base of the box
     rather than under the words. Underline the text, keep the target. */
  .wl__foot a {
    border-bottom: 0;
    text-decoration: underline;
    text-decoration-color: var(--color-line-strong);
    text-underline-offset: 3px;
  }

  .wl__foot a:hover {
    text-decoration-color: currentcolor;
  }
}

/* =========================================================================
   STATUS  -  status.html, plus the strip on index.html
   =========================================================================
   The --st-* tone palette lives in design-tokens.css (Status tones), with
   the reasoning for each colour and its AA text pair.
   ========================================================================= */
@layer components {
  /* ---- tone plumbing: one attribute drives dot, tick and badge ------- */
  [data-status="operational"] {
    --st-tone: var(--st-operational);
    --st-tone-ink: var(--st-operational-ink);
  }
  [data-status="degraded"] {
    --st-tone: var(--st-degraded);
    --st-tone-ink: var(--st-degraded-ink);
  }
  [data-status="partial"] {
    --st-tone: var(--st-partial);
    --st-tone-ink: var(--st-partial-ink);
  }
  [data-status="major"] {
    --st-tone: var(--st-major);
    --st-tone-ink: var(--st-major-ink);
  }
  [data-status="maintenance"] {
    --st-tone: var(--st-maintenance);
    --st-tone-ink: var(--st-maintenance-ink);
  }

  .st-dot {
    position: relative;
    display: inline-block;
    flex: none;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--st-tone, var(--st-operational));
  }

  .st-dot--live::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: inherit;
    animation: st-ping 2.6s var(--ease-out) infinite;
  }

  @keyframes st-ping {
    0% {
      transform: scale(1);
      opacity: 0.5;
    }
    70%,
    100% {
      transform: scale(2.8);
      opacity: 0;
    }
  }

  /* ---- page shell ---------------------------------------------------- */
  .st-page {
    max-width: calc(var(--shell-max) + 2 * var(--shell-pad));
    padding-block: calc(var(--header-h) + var(--space-2xl)) var(--space-3xl);
  }

  .st-note {
    margin: 0 0 var(--space-lg);
    padding: var(--space-sm) var(--space-md);
    border-radius: var(--radius-md);
    font-size: var(--text-sm);
    line-height: 1.55;
  }

  .st-note[data-kind="preview"] {
    background: var(--color-warn-soft);
    border: 1px solid rgb(var(--color-warn-rgb) / 22%);
    color: var(--color-warn);
  }

  .st-note[data-kind="error"] {
    background: var(--color-clay-soft);
    border: 1px solid rgb(var(--color-clay-deep-rgb) / 22%);
    color: var(--color-clay-deep);
  }

  /* ---- hero ----------------------------------------------------------- */
  .st-hero {
    padding-block-end: var(--space-xl);
    border-block-end: 1px solid var(--color-line);
  }

  .st-pill {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 var(--space-md);
    padding: 6.72px 14.4px;
    border-radius: var(--radius-pill);
    background: var(--color-surface-sunk);
    border: 1px solid var(--color-line);
    font-size: var(--text-sm);
    color: var(--color-ink-subtle);
  }

  .st-pill__label {
    font-weight: 600;
    color: var(--color-ink);
  }

  .st-pill__checked {
    font-variant-numeric: tabular-nums;
  }

  .st-pill__checked:empty {
    display: none;
  }

  .st-title {
    margin: 0;
    max-width: calc(clamp(30.4px, 20.8px + 2.6vw, 49.6px) * 13.54);
    font-size: clamp(30.4px, 20.8px + 2.6vw, 49.6px);
    line-height: var(--leading-snug);
    letter-spacing: calc(clamp(30.4px, 20.8px + 2.6vw, 49.6px) * var(--tracking-tight));
    font-weight: 600;
    color: var(--color-ink);
    text-wrap: balance;
  }

  .st-lead {
    margin: var(--space-sm) 0 0;
    max-width: calc(var(--text-lead) * 35.964);
    font-size: var(--text-lead);
    line-height: 1.55;
    color: var(--color-ink-muted);
    font-variant-numeric: tabular-nums;
  }

  .st-hero__actions {
    margin: var(--space-md) 0 0;
  }

  .st-hero__actions:has(button[hidden]) {
    margin: 0;
  }

  /* ---- sections -------------------------------------------------------- */
  .st-section {
    margin-block-start: var(--space-2xl);
  }

  .st-section__title {
    margin: 0;
    font-size: var(--text-h3);
    max-width: calc(var(--text-h3) * 16.925);
    line-height: 1.25;
    letter-spacing: calc(var(--text-h3) * -0.015);
    font-weight: 600;
    color: var(--color-ink);
  }

  .st-section__sub {
    margin: 5.6px 0 0;
    font-size: var(--text-sm);
    line-height: 1.55;
    color: var(--color-ink-subtle);
  }

  .st-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: end;
    justify-content: space-between;
    gap: var(--space-sm);
    margin-block-end: var(--space-lg);
  }

  /* ---- component groups ------------------------------------------------ */
  .st-groups {
    display: grid;
    gap: var(--space-lg);
  }

  .st-group {
    display: grid;
    gap: var(--space-md);
    padding: var(--space-md);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    border: 1px solid var(--color-line-soft);
  }

  .st-group__title {
    margin: 0;
    font-size: var(--text-eyebrow);
    max-width: calc(var(--text-eyebrow) * 16.925);
    font-weight: 600;
    letter-spacing: calc(var(--text-eyebrow) * var(--tracking-wide));
    text-transform: uppercase;
    color: var(--color-ink-subtle);
  }

  .st-svc {
    display: grid;
    gap: 9.6px;
    padding: var(--space-sm) var(--space-md) var(--space-md);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    border: 1px solid var(--color-line-soft);
  }

  .st-svc__head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 5.6px var(--space-md);
  }

  .st-svc__name {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    font-size: var(--text-body);
    font-weight: 600;
    color: var(--color-ink);
  }

  .st-svc__desc {
    margin: 2.4px 0 0;
    padding-inline-start: 16.8px;
    font-size: var(--text-xs);
    line-height: 1.5;
    color: var(--color-ink-subtle);
  }

  .st-svc__meta {
    display: flex;
    align-items: baseline;
    gap: var(--space-sm);
    font-size: var(--text-sm);
    white-space: nowrap;
  }

  .st-svc__state {
    color: var(--color-ink-muted);
  }

  .st-svc__uptime {
    font-weight: 600;
    color: var(--color-ink);
    font-variant-numeric: tabular-nums;
  }

  .st-svc__latency {
    color: var(--color-ink-muted);
    font-variant-numeric: tabular-nums;
  }

  /* ---- the uptime bar --------------------------------------------------- */
  .st-bar-wrap {
    /* 90 thin ticks squeeze fine down to a phone, but if a longer range is
       ever served this scrolls rather than shrinking to invisible. */
    overflow-x: auto;
    overscroll-behavior-x: contain;
    /* A scrolling box clips BOTH axes and each tick fills the bar's full
       height, so a focused tick lost the top and bottom of its outline
       (only a 2px sliver was left on a phone), and the first and last tick
       lost their outer edge as well. The outline (2px, drawn 2px out) with
       the 1.12 focus lift reaches about 7px past the bar vertically and 4px
       sideways, so the padding makes that room and the negative margin
       hands it straight back: nothing around the bar moves. */
    padding-block: 8px;
    padding-inline: 4px;
    margin-block: -8px;
    margin-inline: -4px;
  }

  .st-bar {
    display: flex;
    align-items: stretch;
    gap: 1px;
    height: 44px;
    min-width: 100%;
  }

  .st-tick {
    flex: 1 1 0;
    min-width: 3px;
    padding: 0;
    border: 0;
    border-radius: var(--st-tick-radius);
    background: var(--st-tone, var(--st-operational));
    cursor: pointer;
    transition:
      transform var(--dur-fast) var(--ease-out),
      opacity var(--dur-fast) var(--ease-out);
  }

  .st-tick:hover,
  .st-tick:focus-visible {
    transform: scaleY(1.12);
    opacity: 1;
  }

  .st-tick:focus-visible {
    outline: 2px solid var(--color-ink);
    outline-offset: 2px;
  }

  .st-tick[data-dim="true"] {
    opacity: 0.32;
  }

  .st-tick[aria-pressed="true"] {
    transform: scaleY(1.12);
    outline: 2px solid var(--color-ink);
    outline-offset: 2px;
  }

  .st-axis {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-block-start: 7.2px;
    font-size: var(--text-xs);
    color: var(--color-ink-subtle);
  }

  .st-axis__mid {
    display: none;
  }

  @media (min-width: 480px) {
    .st-axis__mid {
      display: inline;
    }
  }

  .st-bar-none {
    margin: 0;
    padding-block: var(--space-2xs);
    font-size: var(--text-xs);
    color: var(--color-ink-subtle);
  }

  /* ---- tooltip ----------------------------------------------------------- */
  .st-tip {
    position: fixed;
    z-index: var(--z-tooltip);
    transform: translate(-50%, -100%);
    padding: 7.2px 10.4px;
    border-radius: var(--radius-xs);
    background: var(--color-ink);
    color: var(--color-white);
    pointer-events: none;
    box-shadow: var(--shadow-md);
  }

  .st-tip__title {
    margin: 0;
    font-size: var(--text-xs);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
  }

  .st-tip__body {
    margin: 1.6px 0 0;
    font-size: var(--text-xs);
    color: rgb(var(--color-white-rgb) / 72%);
  }

  /* ---- legend -------------------------------------------------------------- */
  .st-legend {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2xs) var(--space-md);
    margin: var(--space-md) 0 0;
    padding: 0;
    list-style: none;
    font-size: var(--text-xs);
    color: var(--color-ink-muted);
  }

  .st-legend__item {
    display: inline-flex;
    align-items: center;
    gap: 6.4px;
  }

  /* ---- incidents ----------------------------------------------------------- */
  .st-incidents,
  .st-mnt-list {
    display: grid;
    gap: var(--space-md);
    margin-block-start: var(--space-lg);
  }

  .st-inc,
  .st-mnt {
    padding: var(--space-md);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    border: 1px solid var(--color-line);
    box-shadow: var(--shadow-xs);
  }

  .st-inc__head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px var(--space-md);
  }

  .st-inc__title,
  .st-mnt__title {
    margin: 0;
    font-size: var(--text-h4);
    line-height: 1.3;
    font-weight: 600;
    color: var(--color-ink);
  }

  .st-inc__badges {
    display: flex;
    gap: 5.6px;
    margin: 0;
  }

  .st-inc__badge {
    display: inline-flex;
    align-items: center;
    padding: 2.4px 8.8px;
    border-radius: var(--radius-pill);
    background: var(--color-surface-sunk);
    border: 1px solid var(--color-line);
    font-size: var(--text-xs);
    font-weight: 600;
    color: var(--color-ink-muted);
  }

  .st-inc__badge[data-state="resolved"] {
    background: var(--color-success-soft);
    border-color: rgb(var(--color-success-rgb) / 22%);
    color: var(--color-success);
  }

  .st-inc__badge[data-state="investigating"],
  .st-inc__badge[data-state="identified"],
  .st-inc__badge[data-state="monitoring"] {
    background: var(--color-warn-soft);
    border-color: rgb(var(--color-warn-rgb) / 22%);
    color: var(--color-warn);
  }

  .st-inc__meta {
    margin: 8px 0 0;
    font-size: var(--text-xs);
    color: var(--color-ink-subtle);
    font-variant-numeric: tabular-nums;
  }

  .st-inc__summary {
    margin: var(--space-2xs) 0 0;
    font-size: var(--text-sm);
    line-height: var(--leading-normal);
    color: var(--color-ink-muted);
  }

  .st-inc__updates {
    display: grid;
    gap: var(--space-sm);
    margin: var(--space-md) 0 0;
    padding: 0 0 0 var(--space-md);
    list-style: none;
    border-inline-start: 2px solid var(--color-line);
  }

  .st-inc__update {
    position: relative;
  }

  .st-inc__update::before {
    content: "";
    position: absolute;
    inset-inline-start: calc(var(--space-md) * -1 - 5px);
    top: 6.72px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--color-line-strong);
  }

  .st-inc__update:first-child::before {
    background: var(--color-violet);
  }

  .st-inc__update-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 8px;
    margin: 0;
  }

  .st-inc__update-state {
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--color-ink);
  }

  .st-inc__update-at {
    font-size: var(--text-xs);
    color: var(--color-ink-subtle);
    font-variant-numeric: tabular-nums;
  }

  .st-inc__update-body {
    margin: 2.4px 0 0;
    font-size: var(--text-sm);
    line-height: var(--leading-normal);
    color: var(--color-ink-muted);
  }

  /* ---- empty, filter, skeleton ---------------------------------------------- */
  .st-empty {
    padding: var(--space-lg) var(--space-md);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    border: 1px dashed var(--color-line-strong);
    text-align: start;
  }

  .st-empty__title {
    margin: 0;
    font-size: var(--text-body);
    font-weight: 600;
    color: var(--color-ink);
  }

  .st-empty__copy {
    margin: 4.8px 0 0;
    max-width: calc(var(--text-sm) * 34.632);
    margin-inline: auto;
    font-size: var(--text-sm);
    line-height: 1.55;
    color: var(--color-ink-subtle);
  }

  .st-filter {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2xs);
    padding: 8px 9.6px 8px var(--space-md);
    border-radius: var(--radius-pill);
    background: var(--color-violet-soft);
    font-size: var(--text-sm);
    font-weight: 500;
    color: var(--color-violet-deep);
  }

  .st-skel {
    display: grid;
    gap: 9.6px;
    padding: var(--space-md);
    border-radius: var(--radius-md);
    background: var(--color-surface-sunk);
  }

  .st-skel__line,
  .st-skel__bar {
    display: block;
    border-radius: var(--radius-xs);
    background: linear-gradient(
      90deg,
      var(--color-line-soft) 25%,
      var(--color-line) 37%,
      var(--color-line-soft) 63%
    );
    background-size: 400% 100%;
    animation: st-shimmer 1.4s linear infinite;
  }

  .st-skel__line {
    width: 40%;
    height: 14px;
  }
  .st-skel__bar {
    width: 100%;
    height: 44px;
  }

  @keyframes st-shimmer {
    from {
      background-position: 100% 0;
    }
    to {
      background-position: 0 0;
    }
  }

  /* ---- about --------------------------------------------------------------- */
  .st-about__grid {
    display: grid;
    gap: var(--space-md);
    margin-block-start: var(--space-md);
    font-size: var(--text-sm);
    line-height: var(--leading-normal);
    color: var(--color-ink-muted);
  }

  @media (min-width: 768px) {
    .st-about__grid {
      grid-template-columns: 1fr 1fr;
      gap: var(--space-lg);
    }
  }

  .st-about__grid p {
    margin: 0;
  }

  .st-about__grid a {
    color: var(--color-violet-deep);
    text-decoration: underline;
    text-underline-offset: 2px;
  }

  /* =======================================================================
     THE STRIP  -  index.html
     A live line, not a badge: it says the state, the number behind it, and
     where to go for the detail. It reserves its own height so arriving data
     never shifts the page.
     ===================================================================== */
  .status-strip {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-sm) var(--space-md);
    min-height: 64px;
    padding: var(--space-sm) var(--space-md);
    /* Below 768px the strip wraps to two rows, and a pill radius on a
       two-row box draws a capsule. The old 640px switch sat inside that
       band (at 640px the strip is still two rows), so the pill now starts
       at 768px, the same step that pulls the service pips back up. */
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    border: 1px solid var(--color-line);
    box-shadow: var(--shadow-xs);
  }

  @media (min-width: 768px) {
    .status-strip {
      border-radius: var(--radius-pill);
    }
  }

  .status-strip__state {
    display: flex;
    align-items: center;
    gap: 8.8px;
    min-width: 0;
  }

  .status-strip__label {
    font-size: var(--text-body);
    font-weight: 600;
    color: var(--color-ink);
  }

  .status-strip__detail {
    font-size: var(--text-sm);
    color: var(--color-ink-subtle);
    font-variant-numeric: tabular-nums;
  }

  .status-strip__services {
    display: flex;
    gap: 3px;
  }

  @media (min-width: 768px) {
    .status-strip__services {
      margin-inline-start: auto;
    }
  }

  .status-strip__pip {
    width: 8px;
    height: 22px;
    border-radius: var(--st-tick-radius);
    background: var(--st-tone, var(--st-operational));
  }

  .status-strip__link {
    display: inline-flex;
    align-items: center;
    gap: 5.6px;
    min-height: 44px;
    padding-inline: 14.4px;
    border-radius: var(--radius-pill);
    border: 1px solid var(--color-line);
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--color-ink);
    text-decoration: none;
    transition: background var(--dur-fast) var(--ease-out);
  }

  .status-strip__link:hover {
    background: var(--color-surface-sunk);
  }

  /* Until the fetch lands there is nothing true to show but the shape. */
  .status-strip[data-state="loading"] .status-strip__label {
    color: var(--color-ink-subtle);
  }

  .status-strip[data-state="loading"] .st-dot {
    background: var(--color-line-strong);
  }
}

@media (prefers-reduced-motion: reduce) {
  .st-dot--live::after,
  .st-skel__line,
  .st-skel__bar {
    animation: none;
  }

  .st-skel__line,
  .st-skel__bar {
    background: var(--color-line-soft);
  }

  .st-tick {
    transition: none;
  }
}

@media print {
  .st-tip,
  .segmented,
  .st-hero__actions {
    display: none;
  }
}

@layer components {
  /* .btn sets display: inline-flex, which outranks the user agent's
     [hidden] rule, so a hidden button stayed on screen. Caught by seeing
     "Try again" sitting under a healthy status board. */
  .btn[hidden],
  .st-page [hidden] {
    display: none !important;
  }
}

@layer components {
  /* Open incidents, above the grid. Marked by the clay edge rather than a
     shouting background: it has to read as urgent without making the rest
     of a mostly-healthy page feel broken. */
  .st-active {
    margin-block-start: var(--space-xl);
    padding: var(--space-md);
    border-radius: var(--radius-lg);
    background: var(--color-clay-soft);
    border: 1px solid rgb(var(--color-clay-rgb) / 22%);
    border-inline-start: 3px solid var(--color-clay);
  }

  .st-active .st-incidents {
    margin-block-start: var(--space-sm);
  }

  /* Smaller here, so the measure and the tracking are restated against this
     size; with ch and em both followed the element automatically. */
  .st-active .st-section__title {
    font-size: var(--text-h4);
    max-width: calc(var(--text-h4) * 16.925);
    letter-spacing: calc(var(--text-h4) * -0.015);
    color: var(--color-clay-deep);
  }
}

@layer components {
  /* At 390 the 90 ticks needed 359px and the bar scrolled, which puts
     today off screen on the page where today matters most. Thinner ticks
     fit the whole window; the row stays 44px tall, so the target only
     narrows, it does not shrink.

     A 2px floor still did not fit: 90 ticks at 2px plus 89 1px gaps need
     269px, and the bar is about 266px wide at 390, narrower still at 360.
     The bar kept scrolling, with the last days (today included) under the
     edge behind a scrollbar. With a 1px floor the ticks flex to fill the
     bar instead, a fraction under 2px each, and every day is on screen. */
  @media (max-width: 479.84px) {
    .st-tick {
      min-width: 1px;
      border-radius: 2px;
    }
  }

  /* The range switcher is a real control on a page people use on a phone. */
  .segmented__option {
    min-height: 44px;
  }
}

@layer components {
  /* Third time this has bitten on this site: a component with its own
     `display` (.btn inline-flex, .segmented flex, the waitlist views grid)
     outranks the user agent's [hidden] rule, so hiding it in JavaScript does
     nothing. Anything inside the status page that sets [hidden] means it. */
  .st-page [hidden] {
    display: none !important;
  }
}

@layer components {
  /* "We do not know" is a real status and needs its own tone. Grey, not
     green: the failure screenshot had a green dot beside a headline saying
     the check could not be reached. */
  [data-status="unknown"] {
    --st-tone: var(--color-ink-subtle);
    --st-tone-ink: var(--color-ink-muted);
  }

  /* The separator sits BEFORE the timestamp, so `:empty + *` pointed at the
     wrong element and left a dangling "·" whenever there was no time to
     print. Ask the pill about its own contents instead. */
  .st-pill:has(.st-pill__checked:empty) .st-pill__sep {
    display: none;
  }
}

@layer components {
  /* Where an incident was written. Quiet: it is provenance, not a call to
     action, and it must not compete with the update timeline above it. */
  .st-inc__source {
    margin: var(--space-sm) 0 0;
  }

  .st-inc__source a,
  .st-inc__all a {
    display: inline-flex;
    align-items: center;
    gap: 5.6px;
    min-height: 44px;
    font-size: var(--text-sm);
    font-weight: 500;
    color: var(--color-ink-muted);
    text-decoration: none;
  }

  .st-inc__source a:hover,
  .st-inc__all a:hover {
    color: var(--color-ink);
    text-decoration: underline;
    text-underline-offset: 3px;
  }

  .st-inc__source svg,
  .st-inc__all svg {
    flex: none;
  }

  .st-inc__all {
    margin: 0;
    text-align: center;
  }
}

/* =========================================================================
   LAUNCH  -  "Now live" hero pill + the launch moment surprise
   =========================================================================
   The surprise is earned, never pushed: explore a few colors in the hero
   demo and Add to cart gets a gentle nudge; press it and the swatches burst
   out as confetti and a small receipt card rises from the bottom. Built by
   initLaunchMoment in main.js. Every motion is off under reduced motion.
   ========================================================================= */
@layer components {
  /* ---- Hero pill, now a link to the live listing --------------------- */
  .hero__pill--live {
    color: var(--color-violet-deep);
    text-decoration: none;
    box-shadow: inset 0 0 0 1px rgb(var(--color-violet-rgb) / 22%);
    transition:
      background-color var(--dur-fast) linear,
      box-shadow var(--dur-fast) linear,
      transform var(--dur-base) var(--ease-out);
  }

  .hero__pill--live:hover {
    background: var(--color-violet-soft-hover);
    box-shadow: inset 0 0 0 1px rgb(var(--color-violet-rgb) / 45%);
  }

  .hero__pill--live:focus-visible {
    outline: none;
    box-shadow: var(--shadow-focus);
  }

  .hero__pill--live .hero__pill-dot {
    position: relative;
    background: var(--color-success);
  }

  .hero__pill--live .hero__pill-dot::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: var(--color-success);
    animation: launch-ping 1.8s var(--ease-out) infinite;
  }

  .hero__pill-tag {
    padding: 1px 8px;
    border-radius: var(--radius-pill);
    background: var(--color-ink);
    color: var(--color-white);
    font-size: var(--text-xs);
    letter-spacing: calc(var(--text-xs) * 0.02);
  }

  .hero__pill-arrow {
    flex: none;
    transition: transform var(--dur-base) var(--ease-out);
  }

  .hero__pill--live:hover .hero__pill-arrow {
    transform: translateX(3px);
  }

  @keyframes launch-ping {
    0% {
      transform: scale(1);
      opacity: 0.55;
    }
    80%,
    100% {
      transform: scale(2.6);
      opacity: 0;
    }
  }

  /* ---- Add to cart nudge, after a few colors were explored ----------- */
  .demo__atc .btn.is-nudging {
    animation: launch-nudge 1.4s var(--ease-out) 3;
  }

  @keyframes launch-nudge {
    0% {
      box-shadow: 0 0 0 0 rgb(var(--color-violet-rgb) / 55%);
      transform: translateY(0);
    }
    30% {
      transform: translateY(-2px);
    }
    60% {
      box-shadow: 0 0 0 12px rgb(var(--color-violet-rgb) / 0%);
      transform: translateY(0);
    }
    100% {
      box-shadow: 0 0 0 0 rgb(var(--color-violet-rgb) / 0%);
    }
  }

  /* ---- Confetti: swatch chips, positioned by JS, animated by WAAPI --- */
  .confetti-layer {
    position: fixed;
    inset: 0;
    z-index: var(--z-confetti);
    overflow: hidden;
    pointer-events: none;
  }

  .confetti-bit {
    position: absolute;
    border-radius: 3px;
    box-shadow: inset 0 0 0 1px rgb(var(--color-ink-rgb) / 12%);
    will-change: transform, opacity;
  }

  .confetti-bit--round {
    border-radius: 50%;
  }

  .confetti-bit--pill {
    border-radius: var(--radius-pill);
  }

  /* ---- The card ------------------------------------------------------- */
  .launch-moment {
    position: fixed;
    inset-inline: 0;
    inset-block-end: calc(var(--space-md) + env(safe-area-inset-bottom, 0px));
    z-index: var(--z-modal);
    display: flex;
    justify-content: center;
    padding-inline: var(--space-sm);
    pointer-events: none;
  }

  .launch-moment[hidden] {
    display: none !important;
  }

  .launch-moment__card {
    position: relative;
    inline-size: min(100%, 440px);
    padding: var(--space-md);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    box-shadow:
      0 0 0 1px var(--color-line),
      0 24px 60px rgb(var(--color-ink-rgb) / 22%),
      0 4px 12px rgb(var(--color-ink-rgb) / 8%);
    pointer-events: auto;
    opacity: 0;
    transform: translateY(24px) scale(0.97);
    transition:
      opacity var(--dur-base) var(--ease-out),
      transform var(--dur-slow) var(--ease-spring);
  }

  /* Brand rule across the top: the four Varn colors as one stripe. */
  .launch-moment__card::before {
    content: "";
    position: absolute;
    inset-block-start: 0;
    inset-inline: var(--space-md);
    block-size: 4px;
    border-radius: 0 0 4px 4px;
    background: linear-gradient(
      90deg,
      var(--color-violet) 0 25%,
      var(--color-blush) 25% 50%,
      var(--color-clay) 50% 75%,
      var(--color-ink) 75% 100%
    );
  }

  .launch-moment.is-open .launch-moment__card {
    opacity: 1;
    transform: translateY(0) scale(1);
  }

  .launch-moment__close {
    position: absolute;
    inset-block-start: var(--space-xs);
    inset-inline-end: var(--space-xs);
    display: grid;
    place-items: center;
    inline-size: 44px;
    block-size: 44px;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--color-ink-subtle);
    cursor: pointer;
  }

  .launch-moment__close:hover {
    background: var(--color-surface-sunk);
    color: var(--color-ink);
  }

  .launch-moment__close:focus-visible {
    outline: none;
    box-shadow: var(--shadow-focus);
  }

  .launch-moment__receipt {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    margin-inline-end: 44px;
    padding: var(--space-2xs) var(--space-xs);
    border-radius: var(--radius-md);
    background: var(--color-well);
  }

  .launch-moment__receipt-chip {
    flex: none;
    inline-size: 36px;
    block-size: 36px;
    border-radius: 50%;
    background-size: cover;
    box-shadow:
      inset 0 0 0 1px rgb(var(--color-ink-rgb) / 14%),
      0 0 0 2px var(--color-white),
      0 0 0 3.5px var(--color-ink);
  }

  .launch-moment__receipt-lines {
    display: grid;
    min-inline-size: 0;
    line-height: 1.3;
  }

  .launch-moment__receipt-name {
    overflow: hidden;
    font-size: var(--text-sm);
    font-weight: 600;
    white-space: nowrap;
    text-overflow: ellipsis;
  }

  .launch-moment__receipt-meta {
    font-size: var(--text-xs);
    color: var(--color-ink-subtle);
  }

  .launch-moment__receipt-tick {
    display: grid;
    flex: none;
    place-items: center;
    inline-size: 26px;
    block-size: 26px;
    margin-inline-start: auto;
    border-radius: 50%;
    background: var(--color-success);
    color: var(--color-white);
  }

  .launch-moment.is-open .launch-moment__receipt-tick {
    animation: launch-tick var(--dur-slow) var(--ease-spring) 0.18s both;
  }

  @keyframes launch-tick {
    from {
      transform: scale(0);
    }
    to {
      transform: scale(1);
    }
  }

  .launch-moment__eyebrow {
    margin-block-start: var(--space-sm);
    font-size: var(--text-eyebrow);
    font-weight: 600;
    letter-spacing: calc(var(--text-eyebrow) * var(--tracking-wide));
    text-transform: uppercase;
    color: var(--color-clay-deep);
  }

  .launch-moment__title {
    margin-block-start: var(--space-3xs);
    font-size: var(--text-h4);
    max-width: calc(var(--text-h4) * 16.925);
    line-height: var(--leading-snug);
    letter-spacing: calc(var(--text-h4) * -0.015);
    font-weight: 600;
  }

  .launch-moment__text {
    margin-block-start: var(--space-2xs);
    font-size: var(--text-sm);
    line-height: 1.55;
    color: var(--color-ink-muted);
  }

  .launch-moment__live {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2xs);
    margin-block-start: var(--space-sm);
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--color-success);
  }

  .launch-moment__live-dot {
    flex: none;
    margin-block-start: calc(var(--text-sm) * 0.45);
    inline-size: 8px;
    block-size: 8px;
    border-radius: 50%;
    background: var(--color-success);
    box-shadow: 0 0 0 4px var(--color-success-soft);
  }

  .launch-moment__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2xs);
    margin-block-start: var(--space-sm);
  }

  .launch-moment__actions .btn {
    flex: 1 1 160px;
    justify-content: center;
  }

  /* Phones: sit above the sticky call to action bar. */
  @media (max-width: 767.84px) {
    .launch-moment {
      inset-block-end: calc(76px + env(safe-area-inset-bottom, 0px));
    }
  }

  /* Small phones: the receipt, headline and CTA carry the moment; the
     longer sentence is the first thing to go so the card stays short. */
  @media (max-width: 479.84px) {
    .launch-moment__card {
      padding: var(--space-sm);
    }

    .launch-moment__text {
      display: none;
    }
  }
}

@media (prefers-reduced-motion: reduce) {
  .hero__pill--live .hero__pill-dot::after,
  .demo__atc .btn.is-nudging,
  .launch-moment.is-open .launch-moment__receipt-tick {
    animation: none !important;
  }

  .launch-moment__card {
    transform: none;
    transition: opacity var(--dur-fast) linear;
  }

  .hero__pill--live .hero__pill-arrow {
    transition: none;
  }
}

/* =========================================================================
   SITE HEADER  -  shared by every page (index, status, privacy)
   =========================================================================
   Behaviour lives in assets/js/nav.js. Below 992px the link row is hidden,
   so a menu button opens a panel with the same links and both calls to
   action. The header takes its solid background while the menu is open so
   the panel never floats over page text.
   ========================================================================= */
@layer components {
  .site-header__link[aria-current="page"] {
    color: var(--color-ink);
    font-weight: 600;
  }

  .site-header.is-menu-open::before {
    opacity: 1;
    border-block-end: 1px solid var(--color-line-soft);
  }

  .site-header__menu-btn {
    display: inline-grid;
    place-items: center;
    inline-size: 44px;
    block-size: 44px;
    margin-inline-end: calc(var(--space-2xs) * -1);
    border: 0;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--color-ink);
    cursor: pointer;
    transition: background-color var(--dur-fast) linear;
  }

  .site-header__menu-btn:hover {
    background: var(--color-surface-sunk);
  }

  .site-header__menu-btn:focus-visible {
    outline: none;
    box-shadow: var(--shadow-focus);
  }

  .site-header__menu-close,
  .site-header.is-menu-open .site-header__menu-open {
    display: none;
  }

  .site-header.is-menu-open .site-header__menu-close {
    display: block;
  }

  .site-header__panel {
    position: absolute;
    inset-block-start: 100%;
    inset-inline: 0;
    max-block-size: calc(100dvh - var(--header-h));
    overflow-y: auto;
    padding-block: var(--space-2xs) var(--space-md);
    background: var(--color-surface);
    border-block-end: 1px solid var(--color-line);
    box-shadow: 0 18px 40px rgb(var(--color-ink-rgb) / 12%);
  }

  .site-header__panel[hidden] {
    display: none !important;
  }

  .site-header__panel-links {
    display: grid;
  }

  .site-header__panel-link {
    display: flex;
    align-items: center;
    min-block-size: 48px;
    border-block-end: 1px solid var(--color-line-soft);
    font-size: var(--text-body);
    font-weight: 500;
    color: var(--color-ink);
  }

  .site-header__panel-link[aria-current="page"] {
    font-weight: 600;
    color: var(--color-violet-deep);
  }

  .site-header__panel-actions {
    display: grid;
    gap: var(--space-2xs);
    margin-block-start: var(--space-md);
  }

  /* Tiny phones: the brand, primary button and menu button must share one
     row, so the primary button tightens rather than wrapping. Inclusive of
     360px on purpose (no 0.16px step back): 360 is the phone it is for. */
  @media (max-width: 360px) {
    .site-header__cta {
      padding-inline: var(--space-xs);
    }
  }

  @media (min-width: 992px) {
    .site-header__menu-btn,
    .site-header__panel {
      display: none !important;
    }
  }
}

@media (prefers-reduced-motion: reduce) {
  .site-header__menu-btn {
    transition: none;
  }
}

/* =========================================================================
   TOUCH TARGETS  -  44px on coarse pointers
   =========================================================================
   Every control a thumb can reach gets a 44 x 44px hit area on a touch
   screen, the rule the rest of the site already follows (.btn, header links,
   the menu button, the FAQ). Keyed to (pointer: coarse) rather than a width:
   an iPad at 1024px is a touch screen and a narrow desktop window is not.

   Where a control has empty space around it, the hit area grows through an
   invisible ::before, so nothing on screen moves. Where neighbours sit
   closer than 44px (the footer links are stacked 34px apart) an invisible
   overlay would only steal taps from the next link, so the link itself
   grows instead, and that list gets taller on touch screens.

   Left as they are, on purpose:
   - .st-tick: 90 days have to fit one row on a phone. The row is already
     44px tall, and every tick is reachable by keyboard.
   - Links inside running text: WCAG 2.5.8 exempts inline links, and padding
     them would break the line spacing of the policy.
   - .skip-link: it only appears for keyboard focus.
   ========================================================================= */
@media (pointer: coarse) {
  @layer components {
    .hero__pill--live,
    .toggle__option,
    .vgal__chip,
    .btn--sm {
      position: relative;
    }

    /* min() never shrinks a box that is already large enough: 50% - 22px is
       only negative when that side is under 44px. */
    .hero__pill--live::before,
    .toggle__option::before,
    .vgal__chip::before,
    .btn--sm::before {
      content: "";
      position: absolute;
      inset-block: min(0px, calc(50% - 22px));
      inset-inline: min(0px, calc(50% - 22px));
    }

    /* A range input cannot carry a pseudo-element, so the input itself
       becomes 44px tall and the negative margins give the extra 20px back to
       the layout: the track, the thumb and the spacing around them stay put. */
    .slider {
      block-size: 44px;
      margin-block: -10px;
    }

    /* Traced around the taller box, the focus ring ran into the field label
       above. Drawn 7px inside, it is the same 30px-tall ring the 24px
       slider had; the radius grows by the same 7px so the inset ring keeps
       the site's 6px corner instead of going square. */
    .slider:focus-visible {
      outline-offset: -7px;
      border-radius: calc(var(--radius-xs) + 7px);
    }

    .site-footer__link {
      min-block-size: 44px;
      min-inline-size: 44px; /* the shortest labels are narrower than that */
    }
  }
}
