/*
 * Pillo — the whole site's styles.
 *
 * Generated from the Astro source by tools/collect-css.mjs; the same file is
 * used by all three builds, so a change here shows up in every one of them.
 *
 * Design tokens are at the top: colours, the type scale, spacing, radii and
 * easings, per breakpoint. Recolouring the site is a handful of custom
 * properties in that first block.
 */

/* ============================================================== tokens ============================================================== */

/* ── Pillo design tokens ──────────────────────────────────────────────────
   Transcribed from the Framer project: 34 colour styles and 11 text styles,
   with their real names and their exact light/dark pairs and per-breakpoint
   sizes. Nothing here is an approximation — if a value looks odd, it is the
   value the design uses.

   Breakpoints, as defined in the project:
     Desktop  >= 1200px
     Tablet   810px – 1199.98px
     Phone    <= 809.98px
   ───────────────────────────────────────────────────────────────────────── */

:root {
  /* ── Colour styles — light ──────────────────────────────────────────── */
  --c-background: rgb(255, 255, 255);
  --c-text-primary: rgb(12, 10, 9);
  --c-text-secondary: rgb(91, 79, 75);
  --c-text-tertiary: rgba(91, 79, 75, 0.5);
  --c-border: rgba(12, 10, 9, 0.2);
  --c-border-subtle: rgba(12, 10, 9, 0.05);
  --c-icon-default: rgb(71, 60, 57);
  --c-icon-secondary: rgb(124, 109, 103);
  --c-background-0: rgba(255, 255, 255, 0);
  --c-text-button-primary: rgb(12, 10, 9);
  --c-bg-button-primary: rgb(12, 10, 9);
  --c-secondary-button-bg: rgba(12, 10, 9, 0.05);
  --c-secondary-button-border: rgba(12, 10, 9, 0.1);
  --c-surface-elevated: rgba(12, 10, 9, 0.05);
  --c-surface: rgb(243, 241, 241);
  --c-surface-default: rgb(233, 228, 227);
  --c-bg-inverse: rgb(12, 10, 9);

  /* Fixed constants. Scrims over photography, and anything drawn on top of an
     image, must not flip with the theme — the photograph does not change. */
  --c-ink: rgb(12, 10, 9);
  --c-white: rgb(255, 255, 255);

  /* Fixed — these have no dark counterpart in the project. */
  --c-orange: rgb(232, 98, 44);
  --c-yellow: rgb(245, 166, 35);
  --c-badge-bg: rgb(252, 232, 216);
  --c-badge-text: rgb(217, 70, 29);

  /* "Image:" styles — for content sitting on photography, so they are the
     same in both themes. */
  --c-image-text-primary: rgb(255, 255, 255);
  --c-image-text-secondary: rgb(216, 210, 208);
  --c-image-icon-default: rgb(255, 255, 255);
  --c-image-secondary-button-bg: rgba(253, 252, 251, 0.1);
  --c-image-secondary-button-border: rgba(253, 252, 251, 0.3);

  /* "Card:" styles — the pricing cards keep a light surface in both themes. */
  --c-card-bg: rgb(255, 255, 255);
  --c-card-text-primary: rgb(12, 10, 9);
  --c-card-text-secondary: rgb(124, 109, 103);
  --c-card-button-bg: rgba(12, 10, 9, 0.05);
  --c-card-button-border: rgba(12, 10, 9, 0.1);
  --c-card-button-text: rgb(12, 10, 9);

  /* ── Text styles ─────────────────────────────────────────────────────── */
  --font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
    Helvetica, Arial, sans-serif;

  /* Heading 1 */
  --h1-size: 72px;   --h1-line: 80px;  --h1-track: -1.5px; --h1-weight: 700;
  /* Heading 2 */
  --h2-size: 48px;   --h2-line: 56px;  --h2-track: -1px;   --h2-weight: 700;
  /* Heading 3 */
  --h3-size: 36px;   --h3-line: 44px;  --h3-track: -0.5px; --h3-weight: 700;
  /* Text Large */
  --tl-size: 24px;   --tl-line: 32px;  --tl-track: 0px;    --tl-weight: 600;
  /* Metrics */
  --metrics-size: 48px; --metrics-line: 56px; --metrics-track: -1px; --metrics-weight: 600;

  /* These four do not change across breakpoints. */
  --body-size: 16px; --body-line: 24px; --body-track: 0px;   --body-weight: 400;
  --bodys-size: 14px; --bodys-line: 20px; --bodys-track: 0px; --bodys-weight: 400;
  --button-size: 16px; --button-line: 24px; --button-track: 0px; --button-weight: 600;
  --badge-size: 14px; --badge-line: 20px; --badge-track: 0.1px; --badge-weight: 500;
  --badges-size: 12px; --badges-line: 16px; --badges-track: 0px; --badges-weight: 400;
  --eyebrow-size: 14px; --eyebrow-line: 20px; --eyebrow-track: 0.1px; --eyebrow-weight: 500;

  /* ── Layout ──────────────────────────────────────────────────────────── */
  --container: 1200px;
  --gutter: 20px;
  --nav-h: 76px;

  /* ── Radius ──────────────────────────────────────────────────────────── */
  --radius-sm: 8px;
  --radius: 12px;
  --radius-lg: 20px;
  --radius-xl: 32px;
  --radius-pill: 999px;

  /* ── Space ───────────────────────────────────────────────────────────── */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 40px;
  --space-8: 48px;
  --space-9: 64px;
  --space-10: 80px;
  --space-11: 120px;
  --space-12: 160px;

  /* ── Motion ──────────────────────────────────────────────────────────── */
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --dur-fast: 160ms;
  --dur: 320ms;
  --dur-slow: 640ms;
}

/* Tablet — 810px to 1199.98px. Only the responsive text styles change. */
@media (max-width: 1199.98px) {
  :root {
    --h1-size: 48px;  --h1-line: 56px;  --h1-track: -1.5px;
    --h2-size: 36px;  --h2-line: 44px;  --h2-track: -1px;
    --h3-size: 30px;  --h3-line: 36px;  --h3-track: -0.5px;
    --tl-size: 20px;  --tl-line: 28px;
    --metrics-size: 36px; --metrics-line: 44px;
  }
}

/* Phone — 809.98px and below. */
@media (max-width: 809.98px) {
  :root {
    /* The header collapses to a fixed 64px bar on phone. */
    --nav-h: 64px;

    --h1-size: 40px;  --h1-line: 46px;  --h1-track: -1.5px;
    --h2-size: 30px;  --h2-line: 36px;  --h2-track: -1px;
    --h3-size: 24px;  --h3-line: 32px;  --h3-track: -0.5px;
    --tl-size: 18px;  --tl-line: 28px;
    --metrics-size: 30px; --metrics-line: 36px;
  }
}

/* ── Dark ─────────────────────────────────────────────────────────────────
   Dark is the shipped default (ThemeToggle's DEFAULT_MODE is "dark"), so it
   is applied unless the visitor explicitly picks light. Every value below is
   the project's own dark counterpart for the token above it. */
:root:not([toggle-theme='light']) {
  --c-background: rgb(12, 10, 9);
  --c-text-primary: rgb(255, 255, 255);
  --c-text-secondary: rgb(216, 210, 208);
  --c-text-tertiary: rgba(216, 210, 208, 0.5);
  --c-border: rgba(253, 252, 251, 0.3);
  --c-border-subtle: rgba(253, 252, 251, 0.2);
  --c-icon-default: rgb(232, 228, 227);
  --c-background-0: rgba(12, 10, 9, 0);
  --c-text-button-primary: rgb(12, 10, 9);
  --c-bg-button-primary: rgb(251, 250, 249);
  --c-secondary-button-bg: rgba(253, 252, 251, 0.1);
  --c-secondary-button-border: rgba(253, 252, 251, 0.3);
  --c-surface-elevated: rgba(253, 252, 251, 0.1);
  --c-surface: rgb(29, 24, 22);
  --c-surface-default: rgba(251, 250, 249, 0.1);
  --c-bg-inverse: rgb(255, 255, 255);
}

/* ============================================================== global ============================================================== */

@import './tokens.css';

/* ── Fonts ─────────────────────────────────────────────────────────────── */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/fonts/inter-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
    U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
    U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/fonts/inter-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
    U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F,
    U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F,
    U+A720-A7FF;
}

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

* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  /* Deliberately NOT scroll-behavior: smooth. The smooth-scroll engine drives
     window.scrollTo itself; CSS smoothing would turn each of those calls into
     an animation that the engine's own scroll handler then reads as an
     external jump and cancels — which deadlocks scrolling entirely. */
}

body {
  font-family: var(--font);
  font-size: var(--body-size);
  line-height: var(--body-line);
  color: var(--c-text-primary);
  background: var(--c-background);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

img,
picture,
video,
canvas,
svg {
  display: block;
  max-width: 100%;
}

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

h1, h2, h3, h4, h5, h6 { font-weight: var(--h2-weight); }

/* Framer balances every rich-text block that has a width rather than hugging
   its content. It is not a flourish: it decides where every heading and
   paragraph on the site breaks, and without it a dozen blocks wrap a word or
   two later than the original.

   Framer pairs this with `white-space: pre-wrap`, which is safe for markup a
   machine emits with no stray whitespace and is not safe here. Under pre-wrap
   the newlines and indentation in these source files render as line breaks, so
   the layout would depend on the HTML being minified and would come apart the
   moment anyone formatted a component. */
h1, h2, h3, h4, h5, h6, p, blockquote, figcaption, li {
  text-wrap: balance;
}
/* Chips, buttons and nav links hug their content, and Framer gives those
   `nowrap`/`pre` instead. */
button, a.btn, .nav a, [data-nowrap] { text-wrap: nowrap; }

/* The 11 text styles, as named in the project. */
.t-h1 { font-size: var(--h1-size); line-height: var(--h1-line); letter-spacing: var(--h1-track); font-weight: var(--h1-weight); }
.t-h2 { font-size: var(--h2-size); line-height: var(--h2-line); letter-spacing: var(--h2-track); font-weight: var(--h2-weight); }
.t-h3 { font-size: var(--h3-size); line-height: var(--h3-line); letter-spacing: var(--h3-track); font-weight: var(--h3-weight); }
.t-large { font-size: var(--tl-size); line-height: var(--tl-line); font-weight: var(--tl-weight); }
.t-body { font-size: var(--body-size); line-height: var(--body-line); font-weight: var(--body-weight); }
.t-body-s { font-size: var(--bodys-size); line-height: var(--bodys-line); font-weight: var(--bodys-weight); }
.t-button { font-size: var(--button-size); line-height: var(--button-line); font-weight: var(--button-weight); }
.t-badge { font-size: var(--badge-size); line-height: var(--badge-line); letter-spacing: var(--badge-track); font-weight: var(--badge-weight); }
.t-badge-s { font-size: var(--badges-size); line-height: var(--badges-line); font-weight: var(--badges-weight); }
.t-metrics { font-size: var(--metrics-size); line-height: var(--metrics-line); letter-spacing: var(--metrics-track); font-weight: var(--metrics-weight); }

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

ul { padding: 0; list-style: none; }

:focus-visible {
  outline: 2px solid var(--c-orange);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/* ── Layout helpers ────────────────────────────────────────────────────── */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section {
  padding-block: var(--space-10);
}

@media (min-width: 810px) {
  .section { padding-block: var(--space-12); }
}

.eyebrow {
  font-size: var(--eyebrow-size);
  line-height: var(--eyebrow-line);
  letter-spacing: var(--eyebrow-track);
  font-weight: var(--eyebrow-weight);
  text-transform: uppercase;
  color: var(--c-text-secondary);
}

.h1 {
  font-size: var(--h2-size);
  line-height: var(--h2-line);
  letter-spacing: var(--h2-track);
  font-weight: var(--h2-weight);
}

.lead {
  font-size: var(--body-size);
  line-height: var(--body-line);
  color: var(--c-text-secondary);
}

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

/* ── Motion ────────────────────────────────────────────────────────────── */
/* Reveals are scroll-scrubbed in JS (see scripts/reveal.js), which sets
   opacity and transform inline. CSS deliberately leaves them at their settled
   values: if the script never runs — no JS, reduced motion, a thrown error —
   the content is simply visible. A reveal must never be able to hide content. */
.reveal { will-change: opacity, transform; }

@media (prefers-reduced-motion: reduce) {

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

  /* Motion withdrawn, layout intact. */
  .reveal {
    opacity: 1 !important;
    transform: none !important;
  }
}

/* ── Shimmer sweep ─────────────────────────────────────────────────────── */
/* Verbatim from the project's ShimmerTitle component: a duplicate of the text
   drawn from a moving gradient clipped to the glyphs, layered over the real
   text. The real text underneath is untouched, so the sweep is purely
   decorative and removing it costs nothing. */
.shimmer {
  position: relative;
  display: inline-block;
}
.shimmer::before {
  content: attr(data-text);
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image: linear-gradient(
    90deg,
    transparent 0%,
    transparent 40%,
    var(--shimmer-highlight, rgb(255 255 255 / 0.85)) 50%,
    transparent 60%,
    transparent 100%
  );
  background-size: 400% 100%;
  background-repeat: no-repeat;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
  animation: shimmer-sweep var(--shimmer-dur, 2000ms) linear infinite;
}
@keyframes shimmer-sweep {
  0%   { background-position: 100% 0; }
  100% { background-position: 0% 0; }
}

/* ── Avatar group hover ────────────────────────────────────────────────── */
:root {
  --avatar-lift: -4px;
  --avatar-dur: 320ms;
  --avatar-scale: 1.05;
  --avatar-falloff: 0.45;
  --avatar-ease-in: cubic-bezier(0.22, 1, 0.36, 1);
  --avatar-ease-out: cubic-bezier(0.34, 3.85, 0.64, 1);
}

.t-avatar {
  position: absolute;
  top: 0;
  width: 40px;
  height: 40px;
  transform-origin: center;
  transform: translateY(var(--shift, 0px)) scale(var(--scale-active, 1));
  transition: transform var(--avatar-dur) var(--avatar-ease-in);
  will-change: transform;
}

.t-avatar img {
  width: 40px;
  height: 40px;
  border-radius: 9999px;
  border: 1px solid var(--c-border);
  object-fit: cover;
}

@media (prefers-reduced-motion: reduce) {
  .shimmer::before { animation: none !important; }
  .t-avatar { transition: none !important; transform: none !important; }
}

/* ── Custom cursor ─────────────────────────────────────────────────────── */
/* Cursor Hero / Cursor Rest page, from the canvas:
     Normal  8px dot, radius 100px
     Link    32x32 ring, 1.5px border, 8px dot inside
   Colour is Image: Text Primary over the hero, Text Primary elsewhere.
   The native cursor is hidden only under .has-cursor, which the script adds
   after its elements exist, so nothing can leave a visitor without a pointer. */
.has-cursor,
.has-cursor a,
.has-cursor button,
.has-cursor summary {
  cursor: none;
}

/* Hidden until the pointer first moves — see scripts/cursor.js. */
.cursor-dot:not(.is-seen),
.cursor-ring:not(.is-seen) { opacity: 0; }

.cursor-dot,
.cursor-ring {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 200;
  pointer-events: none;
  border-radius: 100px;
  transition: opacity var(--dur-fast) linear;
}

.cursor-dot {
  width: 8px;
  height: 8px;
  background: var(--c-text-primary);
}

.cursor-ring {
  width: 32px;
  height: 32px;
  border: 1.5px solid var(--c-text-primary);
  opacity: 0;
  transition:
    opacity var(--dur) var(--ease-out),
    transform var(--dur) var(--ease-out),
    opacity var(--dur-fast) linear;
}
.cursor-ring.is-active { opacity: 1; }

/* Over the hero photograph both take the fixed on-image colour. */
.cursor-dot.is-on-image { background: var(--c-image-text-primary); }
.cursor-ring.is-on-image { border-color: var(--c-image-text-primary); }

@media (prefers-reduced-motion: reduce) {
  .cursor-dot,
  .cursor-ring { display: none; }
  .has-cursor,
  .has-cursor a,
  .has-cursor button,
  .has-cursor summary { cursor: auto; }
}

/* Group of tabs — used by the pricing hero and by the phone-only plan
   switcher over the comparison table, so it lives here rather than scoped
   to one section. 4px padding, 8px gap, pill, Surface-Elevated + Border
   Subtle; the sliding pill is TabsSlideEffect. */
  /* Group of tabs — 4px padding, 8px gap, pill, Surface-Elevated + Border Subtle. */
  /* Group 48 tall, tabs 40, pill inset 4 — the TabsSlideEffect override. */
  .tabs {
    position: relative;
    display: flex;
    align-items: center;
    gap: 8px;
    height: 48px;
    padding: 4px;
    box-sizing: border-box;
    border-radius: 9999px;
    background: var(--c-surface-elevated);
    border: 1px solid var(--c-border-subtle);
    overflow: clip;
  }
  .tabs__pill {
    position: absolute;
    top: 4px;
    left: 0;
    height: 40px;
    width: 0;
    border-radius: 9999px;
    background: var(--c-bg-inverse);
    transform: translateX(0);
    transition:
      transform 250ms cubic-bezier(0.22, 1, 0.36, 1),
      width 250ms cubic-bezier(0.22, 1, 0.36, 1);
    will-change: transform, width;
    z-index: 0;
    pointer-events: none;
  }

  .tabs__tab {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    height: 40px;
    padding: 8px 16px;
    border: 0;
    border-radius: 9999px;
    background: transparent;
    color: var(--c-text-primary);
    font-size: var(--body-size);
    cursor: pointer;
    transition: color 250ms cubic-bezier(0.22, 1, 0.36, 1);
  }
  .tabs__tab[aria-pressed='true'] { color: var(--c-background); }
  .tabs__tab:last-child { padding: 8px 12px 8px 16px; }
  .tabs__save {
    padding: 2px 8px;
    border-radius: 9999px;
    background: var(--c-badge-bg);
    color: var(--c-badge-text);
    font-size: var(--badges-size);
    line-height: var(--badges-line);
  }

/* ================================================================ Base ================================================================ */

.skip-link {
    position: absolute;
    left: var(--space-4);
    top: -100%;
    z-index: 100;
    padding: var(--space-2) var(--space-4);
    background: var(--c-white);
    color: var(--c-ink);
    border-radius: var(--radius-sm);
    font-size: var(--bodys-size);
    font-weight: var(--button-weight);
  }
  .skip-link:focus-visible { top: var(--space-4); }

/* ================================================================= Nav ================================================================= */

.nav {
    position: fixed;
    inset: 0 0 auto;
    z-index: 50;
    display: flex;
    justify-content: center;
    gap: 32px;
    padding: 16px 20px;
    box-sizing: border-box;
    height: var(--nav-h);
  }

  .nav--on-image { color: var(--c-image-text-primary); }
  .nav--on-page {
    color: var(--c-text-primary);
    background: linear-gradient(180deg, var(--c-background) 0%, var(--c-background-0) 100%);
  }

  .nav__main {
    display: flex;
    align-items: center;
    gap: 32px;
    width: 100%;
    max-width: 1160px;
  }

  .nav__left {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 32px;
    flex: 1 1 0;
    height: 44px;
  }
  .nav__leftinner { display: flex; align-items: center; gap: 32px; }

  .nav__links { display: none; align-items: center; gap: 24px; margin: 0; }
  .nav__link a {
    position: relative;
    display: block;
    height: 20px;
    font-size: var(--bodys-size);
    line-height: var(--bodys-line);
    color: currentColor;
  }
  .nav__underline {
    position: absolute;
    left: 0;
    bottom: -3px;
    height: 1px;
    width: 100%;
    background: currentColor;
    transform: scaleX(0);
    transform-origin: left;
    transition: transform var(--dur) var(--ease-out);
  }
  .nav__link a:hover .nav__underline,
  .nav__link a:focus-visible .nav__underline { transform: scaleX(1); }

  /* ThemeToggleSingle: 18px icon, 36px hit area, radius 999. */
  .nav__theme {
    position: relative;
    display: none;
    place-items: center;
    width: 36px;
    height: 36px;
    padding: 0;
    border: 0;
    border-radius: 999px;
    background: transparent;
    color: currentColor;
    cursor: pointer;
    overflow: hidden;
    transition: transform 0.15s ease;
  }
  /* The component's glass body: a blurred disc with a lit rim, not a flat
     fill. Without it the icon floats on the photograph with no affordance. */
  .nav__glass {
    position: absolute;
    inset: 0;
    border-radius: 999px;
    background: var(--c-background-0);
    backdrop-filter: blur(4px) saturate(150%);
    -webkit-backdrop-filter: blur(4px) saturate(150%);
    box-shadow:
      inset 0 0 0 1px rgb(255 255 255 / 0.16),
      inset 0 1px 0.5px rgb(255 255 255 / 0.45),
      inset 0 -1px 0.5px rgb(255 255 255 / 0.28),
      0 1px 4px rgb(0 0 0 / 0.12);
  }
  .nav__theme svg {
    position: relative;
    z-index: 3;
    grid-area: 1 / 1;
    transition: opacity 0.25s ease, transform 0.25s ease;
  }
  .nav__theme:active { transform: scale(0.92); }

  /* Values straight off ThemeToggle.tsx: the outgoing icon rotates 90deg and
     halves while the incoming one settles, over 250ms. */
  .nav__sun,
  .nav__moon { transition: opacity 0.25s ease, transform 0.25s ease; }
  .nav__moon { transform: rotate(-90deg) scale(0.5); opacity: 0; }
  :root[toggle-theme='light'] .nav__sun { transform: rotate(90deg) scale(0.5); opacity: 0; }
  :root[toggle-theme='light'] .nav__moon { transform: rotate(0deg) scale(1); opacity: 1; }

  @media (prefers-reduced-motion: reduce) {
    .nav__sun,
    .nav__moon,
    .nav__theme { transition: none; }
  }

  /* Hamburger 36×37, Icon Default. */
  .nav__burger {
    display: grid;
    place-content: center;
    gap: 6px;
    width: 36px;
    height: 37px;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
    color: var(--c-icon-default);
  }
  .nav--on-image .nav__burger { color: var(--c-image-icon-default); }
  .nav__burger span[aria-hidden] {
    display: block;
    width: 20px;
    height: 1.5px;
    background: currentColor;
  }

  @media (min-width: 810px) {
    .nav__links { display: flex; }
    .nav__theme { display: grid; }
    .nav__burger { display: none; }
  }

  @media (max-width: 809.98px) {
    /* Mobile header is 64px tall: 32px row + 16px padding each side. */
    .nav__left { height: 32px; }
  }

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

/* ============================================================== Drawer ============================================================== */

.drawer {
    position: fixed;
    inset: 0;
    z-index: 60;
    display: flex;
    flex-direction: column;
    gap: var(--space-8);
    padding: var(--space-4) var(--gutter) var(--space-8);
    background: var(--c-ink);
    /* Closed state is off-canvas rather than display:none so the panel can
       animate; visibility keeps it out of the tab order while closed. */
    transform: translateY(-100%);
    visibility: hidden;
    transition: transform var(--dur) var(--ease-out),
      visibility 0s linear var(--dur);
  }
  .drawer.is-open {
    /* Explicit translateY(0) rather than `none`: interpolating a percentage
       translate to the `none` keyword is not reliable across engines. */
    transform: translateY(0);
    visibility: visible;
    transition: transform var(--dur) var(--ease-out), visibility 0s;
  }

  .drawer__head {
    height: calc(var(--nav-h) - var(--space-4) * 2);
    display: flex;
    align-items: center;
    justify-content: space-between;
  }
  .drawer__close {
    width: 32px;
    height: 32px;
    border: 0;
    background: none;
    color: var(--c-image-text-primary);
    font-size: 28px;
    line-height: 1;
    cursor: pointer;
  }

  .drawer__links { display: grid; gap: var(--space-5); margin: 0; }
  .drawer__links a {
    font-size: var(--h3-size);
    line-height: var(--h3-line);
    letter-spacing: var(--h3-track);
    font-weight: var(--h2-weight);
    color: var(--c-image-text-primary);
  }

  /* No .drawer__cta rule here: the class lands on the Button component's root,
     outside this component's style scope, so a rule here never applied in
     the Astro build and would only apply once the styles are flattened. */

  @media (min-width: 810px) { .drawer { display: none; } }

  @media (prefers-reduced-motion: reduce) {
    .drawer { transition: visibility 0s linear var(--dur); }
    .drawer.is-open { transition: none; }
  }

/* =========================================================== HeroStage =========================================================== */

/* Transparent: the pinned photograph is inside the hero, and below the
     hero (on phone, where the rig collapses) the panels sit on the page
     background exactly as the canvas has them. */
  .stage { position: relative; }

  /* ── hero ─────────────────────────────────────────────────────────────── */
  .stage__hero { position: sticky; top: 0; height: 100svh; }

  .stage__bgclip {
    position: absolute;
    inset: 0;
    overflow: clip;
    will-change: transform;
  }

  /* Main container: 672 tall, bottom-anchored, capped at 1200 with a 20px
     gutter — the same box the rest of the page uses. */
  .stage__copy {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    margin-inline: auto;
    width: 100%;
    max-width: 1200px;
    height: 672px;
    padding-inline: 20px;
    display: flex;
    align-items: center;
  }

  .stage__left {
    flex: 1;
    align-self: stretch;
    padding: 120px 40px 80px 0;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    align-items: flex-start;
    overflow: clip;
  }

  .stage__text {
    width: 100%;
    max-width: 672px;
    display: flex;
    flex-direction: column;
    gap: 32px;
    will-change: transform;
  }
  .stage__proof { will-change: transform; }

  .stage__title {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 14px;
    overflow: clip;
    font-size: var(--h1-size);
    line-height: var(--h1-line);
    letter-spacing: var(--h1-track);
    font-weight: var(--h1-weight);
    color: var(--c-image-text-primary);
  }
  .stage__title-line,
  .stage__rotator { display: block; white-space: nowrap; }
  /* Holds the width of the longest rotating word open. */
  .stage__title-ghost { color: transparent; }

  .stage__rotator span::after {
    content: '';
    display: inline-block;
    width: 2px;
    height: 0.78em;
    margin-left: 2px;
    vertical-align: baseline;
    background: var(--c-orange);
    animation: caret-blink 500ms steps(1, end) infinite;
  }
  @keyframes caret-blink {
    0%, 100% { opacity: 1; }
    50% { opacity: 0; }
  }
  @media (prefers-reduced-motion: reduce) {
    .stage__rotator span::after { animation: none; }
  }

  .stage__lead {
    width: 524px;
    max-width: 100%;
    font-size: var(--body-size);
    line-height: var(--body-line);
    color: var(--c-image-text-secondary);
  }

  .stage__actions { display: flex; gap: 8px; }

  /* ── travelling mockup ────────────────────────────────────────────────── */
  .stage__phone {
    position: absolute;
    inset: 0;
    overflow: visible;
    pointer-events: none;
  }
  .stage__travel {
    position: absolute;
    transform-origin: top left;
    will-change: transform;
    /* Desktop rest pose. --pu is one canvas pixel of the 439x916 device. */
    --pu: 0.913px;
    left: calc(50vw + 98.8px);
    top: calc(0.75 * 100vh - 413.8px);
    width: calc(439 * var(--pu));
  }

  /* ── feature panels ───────────────────────────────────────────────────── */
  .stage__area { position: relative; }

  .stage__panel {
    position: sticky;
    top: 0;
    height: 100svh;
    display: grid;
    align-content: center;
    pointer-events: none;
    opacity: 0;
    will-change: transform, opacity;
  }
  /* Without JS every panel simply stands still and readable. */
  .stage:not([data-stage-live]) .stage__panel { opacity: 1; }

  .stage__panel-inner {
    width: 100%;
    max-width: 1160px;
    margin-inline: auto;
    padding-inline: 20px;
    display: flex;
    align-items: center;
    justify-content: space-between;
  }
  .stage__panel-gap { flex: 1; height: 1px; }
  .stage__panel-text {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 16px;
  }

  /* Adaptive page tokens, not the fixed on-image pair: verified by toggling
     the live build to light, where these headings go near-black even over the
     photograph. The hero copy above does use the fixed pair. */
  .stage__panel-title {
    font-size: var(--h2-size);
    line-height: var(--h2-line);
    letter-spacing: var(--h2-track);
    color: var(--c-text-primary);
  }
  .stage__panel-body {
    font-size: var(--body-size);
    line-height: var(--body-line);
    color: var(--c-text-secondary);
  }

  .stage__spacer { height: 60svh; }

  /* ── tablet: 810-1199.98 ──────────────────────────────────────────────── */
  @media (min-width: 810px) and (max-width: 1199.98px) {
    /* The hero stops being a viewport and becomes a fixed 800px band, while
       the backdrop stays a full viewport tall behind it. */
    .stage__hero { height: 800px; }
    .stage__bgclip { bottom: auto; height: 100vh; }
    .stage__copy { bottom: -48px; }

    /* The canvas stacks the two title lines with no row gap below desktop. */
    .stage__title { row-gap: 0; }

    .stage__travel {
      --pu: 0.7335px;                 /* 322 / 439 */
      left: calc(53.85vw + 34px);
      top: 233px;
      width: calc(439 * var(--pu));
    }

    .stage__panel { height: 50svh; padding: 128px 20px; }
    .stage__panel-inner { padding-inline: 0; }
    .stage__spacer { height: 30svh; }
  }

  /* ── phone: <= 809.98 ─────────────────────────────────────────────────── */
  @media (max-width: 809.98px) {
    /* No rig at all here: the hero is one screen, then the three features
       simply stack under it. The travelling mockup is not rendered. */
    .stage__title { row-gap: 0; }
    .stage__hero { position: relative; height: 100svh; }
    .stage__bgclip { height: 100svh; }
    .stage__copy { height: 672px; }
    .stage__left {
      padding: 80px 0;
      align-items: center;
    }
    .stage__text { align-items: stretch; }
    /* Phone swaps the lead to the primary on-image colour, not the secondary
       one the wider breakpoints use. */
    .stage__lead {
      width: 100%;
      text-align: center;
      color: var(--c-image-text-primary);
    }
    .stage__actions { flex-direction: column; align-self: stretch; }
    .stage__actions > * { width: 100%; }

    .stage__phone { display: none; }

    .stage__panel {
      position: static;
      height: auto;
      opacity: 1;
      padding: 48px 20px 0;
    }
    .stage__area:first-of-type .stage__panel { padding-top: 64px; }
    .stage__area:last-of-type .stage__panel { padding-bottom: 96px; }
    .stage__panel-inner { padding-inline: 0; }
    .stage__panel-gap { display: none; }
    .stage__spacer { display: none; }
  }

/* ========================================================== HowItWorks ========================================================== */

.how {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    background: var(--c-background);
    overflow: clip;
  }

  /* Title block — padding 128px 20px 0 from the canvas. The 672px cap is on
     the *content*, so the padding sits outside it; capping the padded box
     instead leaves 632px and wraps the heading onto a second line. */
  .how__title {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-4);
    width: 100%;
    max-width: calc(672px + var(--gutter) * 2);
    padding: 128px var(--gutter) 0;
    text-align: center;
  }
  .how__title > * { max-width: 672px; margin-inline: auto; width: 100%; }
  .how__heading {
    font-size: var(--h2-size);
    line-height: var(--h2-line);
    letter-spacing: var(--h2-track);
    font-weight: var(--h2-weight);
    color: var(--c-text-primary);
  }

  .how__body { position: relative; width: 100%; padding-top: var(--space-7); }

  /* The stage is 96.667% of the page, capped at 1160, and everything inside
     it is placed in real pixels — the canvas does not scale the composition
     down with the viewport, it re-lays it out per breakpoint. */
  .how__stage {
    --u: 1px;
    position: relative;
    width: min(1160px, 96.667%);
    height: calc(800 * var(--u));
    margin-inline: auto;
  }

  .how__glow {
    position: absolute;
    left: 50%;
    top: 42%;
    width: calc(330 * var(--u));
    height: calc(273 * var(--u));
    transform: translate(-50%, -50%);
    background: var(--c-orange);
    border-radius: 100%;
    filter: blur(calc(60 * var(--u)));
    opacity: 0.55;
  }

  /* Canvas position. The drift against the Framer build at any given scroll
     depth is the withParallax override, applied via data-parallax below —
     not a fixed offset. */
  /* global.css caps every image at its container; this one is deliberately
     wider than the stage and bleeds off the right edge. */
  .how__mockup {
    position: absolute;
    max-width: none;
    right: calc(-20 * var(--u));
    bottom: calc(-50 * var(--u));
    width: calc(859 * var(--u));
    height: auto;
  }

  .how__card {
    position: absolute;
    top: var(--desktop-top);
    right: var(--desktop-right);
    bottom: var(--desktop-bottom);
    left: var(--desktop-left);
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-4);
    width: calc(400 * var(--u));
    padding: var(--space-5);
    border-radius: 24px;
    background: var(--c-surface-elevated);
    border: 1px solid var(--c-border);
    backdrop-filter: blur(12px);
    overflow: clip;
  }
  .how__card-title {
    font-size: var(--tl-size);
    line-height: var(--tl-line);
    letter-spacing: var(--tl-track);
    font-weight: var(--tl-weight);
    color: var(--c-text-primary);
  }
  .how__card-body {
    font-size: var(--bodys-size);
    line-height: var(--bodys-line);
    color: var(--c-text-secondary);
  }

  /* Gradient fades, Background 0% → Background, straight off the canvas. */
  .how__fade { position: absolute; pointer-events: none; }
  /* Measured off the Framer build: a 112x800 strip at the stage's right edge.
     The canvas serialises this frame's width and height the other way round,
     which produced a wide band across the photograph instead. */
  .how__fade--right {
    top: 0;
    left: calc(1069 * var(--u));
    width: calc(112 * var(--u));
    height: calc(800 * var(--u));
    background: linear-gradient(180deg, var(--c-background-0) 0%, var(--c-background) 100%);
  }
  .how__fade--bottom {
    bottom: 0;
    left: 0;
    width: 100%;
    height: 168px;
    background: linear-gradient(180deg, var(--c-background-0) 0%, var(--c-background) 100%);
  }

  /* ── tablet ───────────────────────────────────────────────────────────── */
  @media (min-width: 810px) and (max-width: 1199.98px) {
    .how__card {
      top: var(--tablet-top);
      right: var(--tablet-right);
      bottom: var(--tablet-bottom);
      left: var(--tablet-left);
    }
    .how__mockup {
      right: calc(437 * var(--u) * -1);
      bottom: calc(-63.5 * var(--u));
      width: calc(1007 * var(--u));
      height: 100%;
      object-fit: cover;
      object-position: left center;
    }
  }

  /* ── phone ────────────────────────────────────────────────────────────── */
  @media (max-width: 809.98px) {
    /* Still the absolute composition, just re-stacked: three 350px cards
       bottom-anchored over a 850px photograph in a 1025px stage. */
    .how__title { padding-top: 48px; }
    .how__body { padding-top: 0; }
    .how__stage { height: calc(1025 * var(--u)); }
    /* No left/right on the canvas means centred, which for an absolute box
       needs both edges pinned before margin auto does anything. */
    .how__card {
      top: var(--phone-top);
      bottom: var(--phone-bottom);
      left: 0;
      right: 0;
      width: calc(350 * var(--u));
      margin-inline: auto;
    }
    .how__glow { height: calc(175 * var(--u)); }
    .how__mockup {
      top: calc(113 * var(--u));
      right: auto;
      bottom: auto;
      left: calc(21.5 * var(--u));
      width: calc(768 * var(--u));
      height: 60.2927%;
      object-fit: contain;
      object-position: center;
    }
    .how__fade--right { display: none; }
    .how__fade--bottom { height: 168px; }
  }

/* ============================================================= Metrics ============================================================= */

.metrics {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 32px;
    height: 670px;
    padding: 200px 20px 128px;
    box-sizing: border-box;
    background: var(--c-background);
    overflow: clip;
  }

  .metrics__tilt {
    display: flex;
    flex-direction: column;
    gap: 32px;
  }

  /* The canvas tilts each row about its own centre, not the pair as a block —
     which puts the two rows on slightly different axes. */
  .metrics__row {
    overflow: clip;
    border-radius: 10px;
    transform: rotate(-2deg);
  }

  .metrics__track {
    display: flex;
    align-items: center;
    gap: 24px;
    width: max-content;
    animation: metrics-marquee 46s linear infinite;
  }
  .metrics__row--reverse .metrics__track { animation-direction: reverse; }

  .metrics__item { display: flex; align-items: center; gap: 24px; }

  .metrics__item img {
    flex: none;
    width: 310px;
    height: 155px;
    border-radius: 16px;
    object-fit: cover;
  }

  .metrics__value {
    font-size: var(--metrics-size);
    line-height: var(--metrics-line);
    letter-spacing: var(--metrics-track);
    font-weight: var(--metrics-weight);
    color: var(--c-text-primary);
    white-space: nowrap;
  }

  @keyframes metrics-marquee {
    from { transform: translate3d(0, 0, 0); }
    to   { transform: translate3d(calc(-100% / 3), 0, 0); }
  }

  .metrics:hover .metrics__track { animation-play-state: paused; }

  .metrics__stack { display: none; }

  @media (max-width: 809.98px) {
    .metrics { height: auto; padding: 96px 20px; }
    .metrics__tilt { display: none; }
    .metrics__stack {
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 40px;
    }
    .metrics__item--stacked { flex-direction: column; gap: 24px; }
    .metrics__item img { max-width: 100%; }
  }

  @media (prefers-reduced-motion: reduce) {
    /* Motion withdrawn: the rows stop and can be scrolled by hand, and the
       tilt goes with it so nothing reads as broken while static. */
    .metrics__row { overflow-x: auto; }
    .metrics__track { animation: none; }
    .metrics__row { transform: none; }
  }

/* ======================================================== Testimonials ======================================================== */

.tst { position: relative; width: 100%; background: var(--c-background); }

  .tst__pin {
    position: sticky;
    top: 0;
    width: 100%;
    height: 100svh;
    overflow: hidden;
  }

  .tst__track {
    display: flex;
    height: 100%;
    will-change: transform;
  }

  .tst-panel {
    flex: 0 0 100vw;
    height: 100%;
    display: flex;
    box-sizing: border-box;
    align-items: center;
    justify-content: center;
    padding: 0 48px;
  }

  .tst__intro {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 32px;
    max-width: 672px;
    text-align: center;
  }
  .tst__intro-head { display: flex; flex-direction: column; align-items: center; gap: 16px; }
  .tst__subtitle {
    max-width: 524px;
    font-size: var(--body-size);
    line-height: var(--body-line);
    color: var(--c-text-secondary);
  }

  .tst-h2 {
    font-size: 48px;
    letter-spacing: -1px;
    line-height: 56px;
    font-weight: var(--h2-weight);
    color: var(--c-text-primary);
  }
  .tst-h3 {
    margin: 0;
    font-size: 36px;
    letter-spacing: -0.5px;
    line-height: 44px;
    font-weight: var(--h3-weight);
    color: var(--c-text-primary);
  }

  .tst-row {
    display: flex;
    align-items: center;
    gap: 48px;
    width: 100%;
    max-width: 1160px;
  }
  /* Basis 500, not 0: the photo is capped at 384, and with a zero basis the
     space that cap frees never comes back to the quote. */
  .tst-text { flex: 1 1 500px; display: flex; flex-direction: column; gap: 32px; }
  .tst__by { font-size: 14px; color: var(--c-text-secondary); }
  .tst__by strong { color: var(--c-text-primary); font-weight: var(--h2-weight); }

  .tst-photo {
    position: relative;
    flex: 1 1 384px;
    max-width: 384px;
    aspect-ratio: 1;
    border-radius: 16px;
    overflow: hidden;
  }
  /* Oversized so the parallax's -20%..+20% travel never exposes an edge. */
  .tst-photo img {
    position: absolute;
    left: 0;
    top: -20%;
    width: 100%;
    height: 140%;
    object-fit: cover;
  }

  @media (max-width: 1199px) {
    .tst-h2 { font-size: 36px; line-height: 44px; }
    .tst-h3 { font-size: 30px; line-height: 36px; }
  }

  /* Below 810 the canvas hides this outright and shows the stacked
     MobileTestimonials section instead. */
  @media (max-width: 809.98px) {
    .tst { display: none; }
  }

  @media (max-width: 809px) {
    /* Content docks to the bottom so every review photo lands the same
       distance from the viewport bottom whatever the quote length; the top
       padding clears the fixed navbar. Both notes are the component's own. */
    .tst-panel {
      align-items: flex-end;
      justify-content: flex-end;
      padding: 70px 20px 96px 20px;
    }
    .tst-h2 { font-size: 30px; line-height: 36px; }
    .tst-h3 { font-size: 24px; line-height: 32px; }
    .tst-row { flex-direction: column; }
    .tst-text { flex: none; width: 100%; }
    .tst-photo { flex: none; width: 100%; max-width: 100%; }
  }

  @media (prefers-reduced-motion: reduce) {
    /* Motion withdrawn: an ordinary horizontal scroller, every quote reachable. */
    .tst { height: auto !important; }
    .tst__pin { position: static; height: auto; overflow-x: auto; }
    .tst__track { transform: none !important; }
    .tst-panel { flex: 0 0 min(100vw, 900px); height: auto; padding-block: 80px; }
  }

/* ============================================================= Pricing ============================================================= */

.zoom {
    position: relative;
    width: 100%;
    background: var(--c-background);
    /* PricingRevealCards' own padding. The desktop component uses 96/40. */
    padding-block: 48px;
  }

  .zoom__pin { display: grid; }

  .zoom__inner {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
    width: 100%;
    max-width: 1160px;
    margin-inline: auto;
    padding-inline: 20px;
  }

  .zoom__headline {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0 0.3em;
    text-align: center;
    font-size: var(--h2-size);
    line-height: var(--h2-line);
    letter-spacing: var(--h2-track);
    font-weight: var(--h2-weight);
    color: var(--c-text-primary);
  }
  .zoom__half { display: inline-block; }

  .zoom__cards {
    display: grid;
    gap: 16px;
    margin-top: 32px;
    width: 100%;
  }
  .zoom__card { display: flex; }

  /* Tablet: side by side, each capped at 377px, as the reveal component does. */
  @media (min-width: 650px) {
    .zoom__cards {
      grid-template-columns: repeat(2, minmax(0, 377px));
      justify-content: center;
    }
  }

  @media (min-width: 1200px) {
    /* appear 90 + split 70 + hold 40 = 200vh */
    .zoom { height: 200svh; padding-block: 0; }
    .zoom__pin {
      position: sticky;
      top: 0;
      min-height: 100svh;
      overflow: hidden;
      box-sizing: border-box;
      padding: 96px 20px 40px;
      align-content: start;
    }
    .zoom__inner { padding-inline: 0; }
    .zoom__cards { grid-template-columns: 1fr 1fr; }
    .zoom__half { will-change: transform; }
    .zoom__card { will-change: transform; }
  }

  /* Below the desktop breakpoint nothing is posed, so CSS guarantees the
     resting layout even if a stale inline transform survives a resize. */
  @media (max-width: 1199.98px) {
    .zoom__half,
    .zoom__card,
    .zoom__compare { transform: none !important; }
  }

  @media (prefers-reduced-motion: reduce) {
    .zoom { height: auto !important; padding-block: 48px; }
    .zoom__pin { position: static; min-height: 0; }
    .zoom__half,
    .zoom__card,
    .zoom__compare { transform: none !important; opacity: 1 !important; }
  }

/* ========================================================= PricingHero ========================================================= */

.pricehero {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 48px;
    /* The header is in flow in the Framer build, so the section's 80px top
       padding sits below it. Ours is fixed, so the nav height is added here
       rather than letting the content slide underneath. */
    padding: calc(80px + var(--nav-h)) 20px 128px;
    background: var(--c-background);
    overflow: clip;
  }

  /* The /pricing sections drop to 48/96 below desktop; phone opens with 96
     above rather than 48 so the h1 clears the collapsed header. */
  @media (min-width: 810px) and (max-width: 1199.98px) {
    .pricehero { padding: calc(48px + var(--nav-h)) 20px 96px; }
  }

  @media (max-width: 809.98px) {
    .pricehero { padding: calc(96px + var(--nav-h)) 20px 96px; }
  }

  .pricehero__main {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 48px;
    width: 100%;
    max-width: 1160px;
  }

  .pricehero__title {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 32px;
    max-width: 672px;
    text-align: center;
  }
  .pricehero__h1 {
    font-size: var(--h1-size);
    line-height: var(--h1-line);
    letter-spacing: var(--h1-track);
    font-weight: var(--h1-weight);
    color: var(--c-text-primary);
  }
  .pricehero__sub {
    max-width: 524px;
    font-size: var(--body-size);
    line-height: var(--body-line);
    color: var(--c-text-secondary);
  }

  /* Tab group styles are in global.css: the comparison table reuses them. */

  .pricehero__cards {
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-items: start;
    gap: 16px;
    width: 100%;
  }

  @media (max-width: 809.98px) {
    /* Gaps stay 48 on the canvas at every breakpoint; only the padding moves.
       The rule that set them to 32 here also outranked the padding above. */
    .pricehero__cards { grid-template-columns: 1fr; }
  }

  @media (prefers-reduced-motion: reduce) {
    .tabs__pill,
    .tabs__tab { transition: none !important; }
  }

/* ============================================================= Compare ============================================================= */

.compare {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 48px;
    padding: 80px 20px 128px;
    background: var(--c-background);
    overflow: clip;
  }
  .compare .container { max-width: 1160px; padding-inline: 0; }
  .compare__title {
    max-width: 672px;
    margin-inline: auto;
    margin-bottom: 48px;
    text-align: center;
    color: var(--c-text-primary);
  }

  /* Wide table scrolls inside its own box; the page never scrolls sideways. */
  .compare__scroll { overflow-x: auto; }

  .compare__table {
    width: 100%;
    min-width: 34rem;
    border-collapse: collapse;
    text-align: left;
  }

  .compare__table th,
  .compare__table td {
    padding: var(--space-4) var(--space-3);
    border-bottom: 1px solid var(--c-surface-elevated);
    font-size: var(--body-size);
    line-height: var(--body-line);
    font-weight: var(--body-weight);
    color: var(--c-text-secondary);
    vertical-align: middle;
  }

  .compare__table thead th { color: var(--c-text-primary); font-weight: var(--body-weight); }
  .compare__table tbody th { color: var(--c-text-primary); }
  .compare__table tfoot td { border-bottom: 0; padding-top: var(--space-6); }

  .tick {
    display: inline-block;
    width: 14px;
    height: 8px;
    border-left: 1.5px solid var(--c-orange);
    border-bottom: 1.5px solid var(--c-orange);
    transform: rotate(-45deg) translateY(-2px);
  }
  .dash {
    display: inline-block;
    width: 14px;
    height: 1.5px;
    background: var(--c-border);
  }

  @media (min-width: 810px) {
    .compare__table th,
    .compare__table td { padding: 24px 16px; }
  }

  /* The switcher only exists on phone. */
  .compare__tabs { display: none; }

  @media (max-width: 1199.98px) {
    .compare { padding: 48px 20px 96px; }
  }

  @media (max-width: 809.98px) {
    .compare__tabs { display: flex; margin-inline: auto; }
    .compare__title { margin-bottom: 48px; }

    /* One plan column at a time, chosen by the switcher. */
    .compare[data-plan='plus'] [data-plan-col='free'],
    .compare[data-plan='free'] [data-plan-col='plus'] { display: none; }

    .compare__scroll { overflow-x: visible; }
    .compare__table { min-width: 0; }
    .compare__table th,
    .compare__table td { padding: 24px; height: 96px; box-sizing: border-box; }
    .compare__table tbody th {
      position: sticky;
      left: 0;
      width: 157px;
      background: var(--c-background);
    }
    .compare__table tfoot td { height: auto; }
  }

/* ================================================================= Faq ================================================================= */

.faq {
    display: flex;
    justify-content: center;
    padding: 80px var(--gutter) 128px;
    background: var(--c-background);
    overflow: clip;
  }

  .faq__container {
    display: flex;
    align-items: flex-start;
    gap: 40px;
    width: 100%;
    max-width: 1160px;
  }

  .faq__title {
    display: flex;
    flex-direction: column;
    gap: 32px;
    flex: 1 1 0;
    max-width: 672px;
  }
  .faq__title-head { display: flex; flex-direction: column; gap: 16px; }
  .faq__heading {
    font-size: var(--h2-size);
    line-height: var(--h2-line);
    letter-spacing: var(--h2-track);
    font-weight: var(--h2-weight);
    color: var(--c-text-primary);
  }
  .faq__subtitle {
    max-width: 524px;
    font-size: var(--body-size);
    line-height: var(--body-line);
    color: var(--c-text-secondary);
  }

  .faq__list { display: flex; flex-direction: column; flex: 1 1 0; gap: 16px; }

  /* FAQItem: 24px padding all round, 16px gap, no fill, no rule. Measured on
     the live build, where a collapsed item is 560x112 and the items are 128
     apart — padding plus the accordion's own 16px gap. */
  .faq__item {
    padding: 24px;
    overflow: clip;
  }

  .faq__question {
    display: flex;
    align-items: flex-start;
    gap: 16px;
    cursor: pointer;
    list-style: none;
    font-size: var(--tl-size);
    line-height: var(--tl-line);
    font-weight: var(--tl-weight);
    color: var(--c-text-primary);
  }
  .faq__question::-webkit-details-marker { display: none; }
  /* 1fr of the padded card. The earlier 310px cap was compensating for the
     missing `text-wrap: balance`, which now lives in global.css. */
  .faq__question > span:first-child { flex: 1 1 0; }

  /* 24px icon column, plus sign drawn from two rules — no icon request. */
  .faq__icon {
    position: relative;
    flex: none;
    width: 24px;
    height: 40px;
    color: var(--c-icon-default);
  }
  .faq__icon::before,
  .faq__icon::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 3px;
    width: 18px;
    height: 1.5px;
    background: currentColor;
    transition: transform var(--dur) var(--ease-out);
  }
  .faq__icon::after { transform: rotate(90deg); }
  .faq__item[open] .faq__icon::after { transform: rotate(0deg); }

  .faq__answer {
    max-width: 532px;
    margin-top: 16px;
    font-size: var(--body-size);
    line-height: var(--body-line);
    color: var(--c-text-secondary);
  }

  @media (min-width: 810px) and (max-width: 1199.98px) {
    .faq__container { gap: 24px; }
    .faq--compact { padding: 48px var(--gutter) 96px; }
  }

  @media (max-width: 809.98px) {
    .faq { padding: 48px var(--gutter) 96px; }
    .faq__container { flex-direction: column; gap: 24px; }
    .faq__title { max-width: none; }
  }

  @media (prefers-reduced-motion: reduce) {
    .faq__icon::before,
    .faq__icon::after { transition: none; }
  }

/* ================================================== MobileTestimonials ================================================== */

/* Phone only: above 810 the scroll track takes over. */
  .mtst { display: none; }

  @media (max-width: 809.98px) {
    .mtst {
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 48px;
      padding: 48px 20px 96px;
      background: var(--c-background);
      overflow: clip;
    }

    .mtst__inner {
      width: 100%;
      max-width: 1160px;
      display: flex;
      flex-direction: column;
      gap: 80px;
    }

    .mtst__title {
      width: 100%;
      max-width: 672px;
      margin-inline: auto;
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 32px;
      text-align: center;
    }
    .mtst__head { display: flex; flex-direction: column; align-items: center; gap: 16px; }
    .mtst__h2 {
      font-size: var(--h2-size);
      line-height: var(--h2-line);
      letter-spacing: var(--h2-track);
      color: var(--c-text-primary);
    }
    .mtst__subtitle {
      max-width: 524px;
      font-size: var(--body-size);
      line-height: var(--body-line);
      color: var(--c-text-secondary);
    }

    .mtst__review {
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 40px;
    }
    /* 350x350 window over a 406px-tall image, so the parallax has 28px of
       travel at either end without ever showing an edge. */
    .mtst__photo {
      position: relative;
      width: 350px;
      max-width: 100%;
      aspect-ratio: 1;
      border-radius: 16px;
      overflow: clip;
    }
    .mtst__photo img {
      position: absolute;
      top: -28px;
      left: 50%;
      translate: -50% 0;
      width: 116%;
      height: calc(100% + 56px);
      object-fit: cover;
    }

    .mtst__quote {
      width: 100%;
      max-width: 672px;
      padding-inline: 8px;
      display: flex;
      flex-direction: column;
      gap: 32px;
    }
    /* Text Large, not Heading 3 — measured at 18/28 on the live build. */
    .mtst__h3 {
      font-size: var(--tl-size);
      line-height: var(--tl-line);
      letter-spacing: var(--tl-track);
      font-weight: var(--tl-weight);
      color: var(--c-text-primary);
    }
    .mtst__by {
      font-size: var(--body-size);
      line-height: var(--body-line);
      color: var(--c-text-secondary);
    }
    .mtst__by strong { color: var(--c-text-primary); font-weight: 600; }
  }

/* ================================================================= Cta ================================================================= */

.cta {
    display: flex;
    justify-content: center;
    padding-inline: var(--gutter);
    background: var(--c-background);
  }

  .cta__container {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 48px;
    width: 100%;
    max-width: 1160px;
    padding: 228px 0 64px;
    overflow: clip;
  }

  .cta__text {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 32px;
    width: 100%;
    max-width: 672px;
    text-align: center;
  }

  /* Shimmer speed 2.5s, sweeping the Text Primary colour across Text
     Secondary — both straight off the component's controls. */
  .cta__title,
  .cta__subtitle {
    --shimmer-dur: 2500ms;
    --shimmer-highlight: var(--c-text-primary);
    color: var(--c-text-secondary);
  }

  .cta__title {
    font-size: var(--h2-size);
    line-height: var(--h2-line);
    letter-spacing: var(--h2-track);
    font-weight: var(--h2-weight);
  }

  .cta__subtitle {
    max-width: 524px;
    font-size: var(--body-size);
    line-height: var(--body-line);
    font-weight: var(--body-weight);
  }

  .cta__buttons { display: flex; gap: 8px; }

  /* Only the container's top padding changes across breakpoints: 228 / 128 /
     80, all with 64 below and a 48 gap. */
  @media (min-width: 810px) and (max-width: 1199.98px) {
    .cta__container { padding-top: 128px; }
  }

  @media (max-width: 809.98px) {
    .cta__container { padding-top: 80px; }
    .cta__buttons { flex-direction: column; align-self: stretch; }
    .cta__buttons > * { width: 100%; }
  }

/* ============================================================== Footer ============================================================== */

.footer {
    position: relative;
    isolation: isolate;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 120px;
    padding: 200px 0 20px;
    height: 827px;
    overflow: clip;
    box-sizing: border-box;
  }

  .footer__bg {
    position: absolute;
    inset: 0;
    z-index: -2;
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

  .footer__fade {
    position: absolute;
    top: 0;
    left: 0;
    z-index: -1;
    width: 100%;
    background: linear-gradient(180deg, var(--c-background) 0%, var(--c-background-0) 100%);
    pointer-events: none;
  }
  .footer__fade { height: 481px; }

  .footer__info {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 48px;
    width: 100%;
    max-width: 1200px;
    padding: 0 20px;
    box-sizing: border-box;
  }

  .footer__links { display: flex; align-items: center; gap: 24px; margin: 0; }
  .footer__links a,
  .footer__credit {
    font-size: var(--bodys-size);
    line-height: var(--bodys-line);
    color: var(--c-text-secondary);
  }
  .footer__links a { display: block; height: 20px; }
  .footer__links a:hover,
  .footer__credit a:hover { color: var(--c-text-primary); }
  .footer__credit a { text-decoration: underline; text-underline-offset: 2px; }

  .footer__logo {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 1;
    width: 100%;
    max-width: 1200px;
    min-height: 0;
    padding: 20px;
    box-sizing: border-box;
  }
  .footer__logo { position: relative; }

  .footer__wordmark {
    width: 100%;
    max-width: 1160px;
    height: auto;
  }
  /* Once the shader is live the flat wordmark steps aside. */
  .footer__logo.is-glass .footer__wordmark { visibility: hidden; }

  /* The shader's canvas is created in JS, so the sizing lives on this stage
     and not on the canvas. The filter finishes the copper: the shader's tint
     is a colour burn over chrome, so its highlights are white until sepia
     warms them and the hue turn pulls the gold back towards orange. */
  .footer__liquid {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 100%;
    max-width: 1160px;
    aspect-ratio: 1160 / 451;
    pointer-events: none;
    filter: sepia(0.55) saturate(1.7) brightness(0.96) hue-rotate(-14deg);
  }
  .footer__liquid canvas { display: block; width: 100%; height: 100%; }

  @media (min-width: 810px) and (max-width: 1199.98px) {
    .footer { height: 604px; padding-top: 128px; }
  }

  @media (max-width: 809.98px) {
    .footer {
      height: 408px;
      gap: 80px;
      padding-top: 80px;
    }
    .footer__info { flex-direction: column; align-items: center; gap: 32px; }
    .footer__links { flex-wrap: wrap; justify-content: center; gap: 16px 24px; }
    .footer__fade { height: 350px; }
  }

/* ============================================================== Button ============================================================== */

.btn {
    position: relative;
    display: inline-flex;
    align-items: center;
    height: 44px;
    border-radius: 9999px;
    overflow: clip;
    font-size: var(--button-size);
    line-height: var(--button-line);
    letter-spacing: var(--button-track);
    font-weight: var(--button-weight);
    white-space: nowrap;
  }

  /* flex: 1 so the fill and the label follow the button when it is stretched
     to the full column width, as it is on phone. Without it the pill stayed
     content-sized and sat left-aligned inside a full-width border. */
  .btn__inner {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    height: 44px;
    padding: 8px 24px;
    border-radius: 999px;
    transition: transform var(--dur) var(--ease-out);
  }
  /* The second label sits exactly on top of the first and is revealed by the
     pair sliding one height. The hit area never changes size. */
  .btn__inner:not(.btn__inner--fill) {
    position: absolute;
    inset: 0;
    transform: translateY(100%);
  }
  .btn:hover .btn__inner--fill { transform: translateY(-100%); }
  .btn:hover .btn__inner:not(.btn__inner--fill) { transform: translateY(0); }

  /* ── primary ─────────────────────────────────────────────────────────── */
  /* The project's "Text Button Primary" is rgb(12,10,9) in both themes, which
     only works against the dark theme's near-white fill — in the light theme
     it would be ink on ink. Dark is the shipped default, so that combination
     never renders there; here the label simply takes the contrast of its own
     fill, which is what the dark theme already produces. */
  .btn--primary { border: 1px solid var(--c-bg-button-primary); }
  .btn--primary .btn__inner--fill {
    background: var(--c-bg-button-primary);
    color: var(--c-background);
  }
  .btn--primary .btn__inner:not(.btn__inner--fill) {
    color: var(--c-text-primary);
  }
  .btn--primary.btn--on-image { border-color: var(--c-image-text-primary); }
  .btn--primary.btn--on-image .btn__inner--fill {
    background: var(--c-image-text-primary);
    color: var(--c-text-button-primary);
  }
  .btn--primary.btn--on-image .btn__inner:not(.btn__inner--fill) {
    color: var(--c-image-text-primary);
  }

  /* ── secondary ───────────────────────────────────────────────────────── */
  .btn--secondary {
    border: 1px solid var(--c-secondary-button-border);
    color: var(--c-text-primary);
  }
  .btn--secondary .btn__inner--fill { background: var(--c-secondary-button-bg); }
  .btn--secondary.btn--on-image {
    border-color: var(--c-image-secondary-button-border);
    color: var(--c-image-text-primary);
  }
  .btn--secondary.btn--on-image .btn__inner--fill {
    background: var(--c-image-secondary-button-bg);
  }

  @media (prefers-reduced-motion: reduce) {
    /* Motion withdrawn: hide the duplicate rather than sliding it. */
    .btn__inner:not(.btn__inner--fill) { display: none; }
    .btn:hover .btn__inner--fill { transform: none; }
  }

/* ================================================================ Logo ================================================================ */

.logo {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    gap: 5px;
    font-size: var(--bodys-size);
    font-weight: var(--button-weight);
    line-height: 1;
    color: currentColor;
  }
  .logo img { width: 16px; height: 16px; border-radius: 4px; }

/* ========================================================= LiquidImage ========================================================= */

.liquid { position: absolute; inset: 0; overflow: clip; }
  .liquid__content,
  .liquid__content img,
  .liquid__output {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
  }
  .liquid__content img { object-fit: cover; }
  .liquid__output { pointer-events: none; }
  .liquid__source { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
  .liquid.is-liquid .liquid__content { opacity: 0; }

/* ========================================================= PhoneMockup ========================================================= */

/* --pu is one canvas pixel of the 439×916 device. */
  .phone {
    position: relative;
    width: calc(439 * var(--pu, 1px));
    height: calc(916 * var(--pu, 1px));
    flex: none;
  }

  .phone__window {
    position: absolute;
    top: calc(18 * var(--pu, 1px));
    left: calc(18 * var(--pu, 1px));
    right: calc(16 * var(--pu, 1px));
    bottom: calc(17 * var(--pu, 1px));
    border-radius: calc(57 * var(--pu, 1px));
    overflow: clip;
  }

  .phone__screen {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: top center;
    /* Screens below the active one wait underneath; the active one sits at 0
       and the ones already shown slide up out of the window. */
    transform: translateY(100%);
    transition: transform 620ms var(--ease-out);
  }
  /* The welcome screen is a wide 740x626 render, not a full-bleed photo. The
     canvas anchors its centre at 46.68% of the 881px window and lets it keep
     its own aspect, which lands it 240 canvas px down — top-aligning it, as
     this did before, floated the wordmark ~215px too high. */
  .phone__screen[data-screen-index='0'] {
    inset: auto 0 auto 0;
    top: calc(240 * var(--pu, 1px));
    height: auto;
    object-fit: contain;
  }

  .phone[data-screen='0'] .phone__screen[data-screen-index='0'],
  .phone[data-screen='1'] .phone__screen[data-screen-index='1'],
  .phone[data-screen='2'] .phone__screen[data-screen-index='2'],
  .phone[data-screen='3'] .phone__screen[data-screen-index='3'] {
    transform: translateY(0);
  }

  .phone[data-screen='1'] .phone__screen[data-screen-index='0'],
  .phone[data-screen='2'] .phone__screen[data-screen-index='0'],
  .phone[data-screen='2'] .phone__screen[data-screen-index='1'],
  .phone[data-screen='3'] .phone__screen[data-screen-index='0'],
  .phone[data-screen='3'] .phone__screen[data-screen-index='1'],
  .phone[data-screen='3'] .phone__screen[data-screen-index='2'] {
    transform: translateY(-100%);
  }

  /* The welcome screen is shorter than the window, so -100% would leave it
     half visible. The canvas parks it at top:-354, which is 594 canvas px up. */
  .phone[data-screen='1'] .phone__screen[data-screen-index='0'],
  .phone[data-screen='2'] .phone__screen[data-screen-index='0'],
  .phone[data-screen='3'] .phone__screen[data-screen-index='0'] {
    transform: translateY(calc(-594 * var(--pu, 1px)));
  }

  .phone__frame {
    position: relative;
    width: 100%;
    height: 100%;
    pointer-events: none;
  }

  @media (prefers-reduced-motion: reduce) {
    /* Motion withdrawn: the screens still change, they just cut rather than slide. */
    .phone__screen { transition: none; }
  }

/* ============================================================ PlanCard ============================================================ */

.pcard {
    width: 100%;
    border-radius: 16px;
    overflow: hidden;
    padding: 8px 8px 0 8px;
    box-sizing: border-box;
    background: var(--c-surface);
    border: 1px solid var(--c-border-subtle);
  }
  /* Feature text on this card is white ("Text on image Primary"), so the
     colour behind it must never fall back to the white card surface — if the
     photograph fails to load the warm orange underneath still carries it. */
  .pcard--popular {
    background: var(--c-orange) url('/assets/pricing-plus-bg.jpg') center / cover no-repeat;
    border: 0;
  }

  .pcard__inner {
    background: var(--c-card-bg);
    border-radius: 12px;
    padding: 24px;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    gap: 48px;
  }

  .pcard__head { display: flex; flex-direction: column; gap: 24px; }
  .pcard__labels {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 28px;
  }
  .pcard__label {
    font-size: 14px;
    line-height: 20px;
    font-weight: 400;
    color: var(--c-card-text-secondary);
  }
  .pcard__badge {
    padding: 4px 16px;
    border-radius: 9999px;
    background: var(--c-badge-bg);
    color: var(--c-badge-text);
    font-size: 14px;
    line-height: 20px;
    font-weight: 600;
  }
  .pcard__headline {
    font-size: 24px;
    line-height: 32px;
    font-weight: 600;
    color: var(--c-card-text-primary);
  }

  .pcard__buy { display: flex; flex-direction: column; gap: 24px; }
  .pcard__price { display: flex; align-items: flex-end; gap: 8px; }
  .pcard__amount {
    font-size: 48px;
    line-height: 56px;
    font-weight: 700;
    color: var(--c-card-text-primary);
  }
  .pcard__freq {
    font-size: 16px;
    padding-bottom: 4px;
    color: var(--c-card-text-secondary);
  }

  .pcard__button {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 44px;
    border-radius: 9999px;
    font-size: 16px;
    font-weight: 600;
    color: var(--c-card-button-text);
    background: var(--c-card-button-bg);
    border: 1px solid var(--c-card-button-border);
  }

  .pcard__features {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
    padding: 16px 8px;
  }
  .pcard__column { display: flex; flex-direction: column; gap: 12px; }
  .pcard__feature {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 14px;
    line-height: 20px;
    color: var(--c-text-primary);
  }
  .pcard--popular .pcard__feature { color: var(--c-image-text-primary); }

  /* Orange on the free card, "Icon on image" white on the popular one. */
  .pcard__check { flex: none; color: var(--c-orange); }
  .pcard--popular .pcard__check { color: var(--c-image-icon-default); }

  /* The card's type is set by which pricing component is on screen, and the
     reveal one switches tier on its own width at 650 — not at the project's
     810 breakpoint. Headline is Text Large, price is Heading 2, both per tier. */
  @media (min-width: 650px) and (max-width: 1199.98px) {
    .pcard__headline { font-size: 20px; line-height: 28px; }
    .pcard__amount { font-size: 36px; line-height: 44px; }
  }

  @media (max-width: 649.98px) {
    .pcard__headline { font-size: 18px; line-height: 28px; }
    .pcard__amount { font-size: 30px; line-height: 36px; }
    /* One column: the row gap has to match the in-column gap or the two
       halves read as two separate lists. */
    .pcard__features { grid-template-columns: 1fr; gap: 12px; }
  }

/* ========================================================= SocialProof ========================================================= */

.proof { display: flex; align-items: center; gap: 16px; }

  .proof__avatars {
    position: relative;
    width: 112px;
    height: 40px;
    margin: 0;
    flex: none;
  }
  /* .t-avatar lives in global.css, beside the hover transform that
     scripts/avatars.js drives. */

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

  .proof__stars { display: flex; gap: 4px; }
  .proof__stars span {
    width: 15px;
    height: 15px;
    background: var(--c-yellow);
    /* Five-point star, drawn rather than loaded. */
    clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
  }

  .proof__text {
    font-size: var(--bodys-size);
    line-height: var(--bodys-line);
    color: var(--c-text-secondary);
  }
  .proof--on-image .proof__text { color: var(--c-image-text-secondary); }

/* ========================================================== StoreBadge ========================================================== */

.getpillo {
    position: fixed;
    right: 24px;
    bottom: 24px;
    z-index: 40;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 4px 10px 4px 4px;
    border-radius: 13px;
    background: var(--c-bg-button-primary);
    color: var(--c-background);
    box-shadow: 0 8px 24px rgb(12 10 9 / 0.28);
    transition: transform var(--dur) var(--ease-out);
  }
  .getpillo:hover { transform: translateY(-2px); }

  .getpillo__icon { width: 30px; height: 29px; border-radius: 7px; }

  .getpillo__label {
    font-size: var(--bodys-size);
    line-height: var(--bodys-line);
    font-weight: var(--button-weight);
  }

  @media (prefers-reduced-motion: reduce) {
    .getpillo { transition: none; }
    .getpillo:hover { transform: none; }
  }

/* ================================================================= 404 ================================================================= */

.nf {
    position: relative;
    isolation: isolate;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100svh;
    padding: var(--nav-h) 20px 0;
    overflow: clip;
  }

  /* The liquid canvas is an absolutely-positioned sibling, so static content
     after it would paint underneath. Lift the copy into its own layer. */
  .nf__text {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: flex-start;
    width: 100%;
    max-width: 1160px;
  }
  .nf__title {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 32px;
    max-width: 672px;
  }
  .nf__h1 {
    /* Framer breaks after "Page"; its box is narrower than the 672 column. */
    max-width: 520px;
    font-size: var(--h1-size);
    line-height: var(--h1-line);
    letter-spacing: var(--h1-track);
    font-weight: var(--h1-weight);
    color: var(--c-image-text-primary);
  }
  .nf__body {
    max-width: 524px;
    font-size: var(--body-size);
    line-height: var(--body-line);
    color: var(--c-image-text-secondary);
  }
