/*
 * Better Pricing Mothership theme.
 *
 * One stylesheet, built from the bottom up: faces, then tokens, then a handful of
 * primitives (frame, type steps, buttons, surfaces, fields), and only then the pages. No
 * framework underneath it. Every colour on every page comes from the tokens below, which
 * is what lets the whole site change between light and dark by swapping one block.
 *
 * The design language takes its structure from Paygent — an editorial frame that every
 * block runs to the edge of, mono eyebrows, one brand hue, a bloom of light at the top of
 * the page rather than a band, flat square-ish buttons — and its colour from Better
 * Pricing's own mark: the green of the wordmark, and the amber of the money bag as the
 * one warm second hue.
 *
 * Theme. Light unless the visitor's system says dark; a choice made with the toggle in
 * the header is written to <html data-theme> by the inline script in Head.ss before the
 * first paint, and wins over the system either way. The dark tokens are written out twice
 * for that reason — once under the media query for "system, and nothing chosen", once
 * under [data-theme="dark"] — since plain CSS has no way to name a block and reuse it.
 */

/* ---------------------------------------------------------------------------
   Faces

   Self-hosted rather than fetched from Google: a Danish site loading fonts from a
   third party hands every visitor's address to it, which is a GDPR problem in its
   own right. All three are variable fonts under the SIL Open Font License; the
   licences are beside the files.

   Schibsted Grotesk sets the display steps — headings and the big numbers. Geist is
   the reading face, and Geist Mono the eyebrows and anything that is a figure in a
   column, where every digit should be the same width.
--------------------------------------------------------------------------- */

@font-face {
    font-family: "Schibsted Grotesk";
    src: url("../fonts/schibsted-grotesk-latin.woff2") format("woff2");
    font-weight: 400 900;
    font-style: normal;
    font-display: swap;
    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: "Schibsted Grotesk";
    src: url("../fonts/schibsted-grotesk-latin-ext.woff2") format("woff2");
    font-weight: 400 900;
    font-style: normal;
    font-display: swap;
    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;
}

@font-face {
    font-family: "Geist";
    src: url("../fonts/geist-sans.woff2") format("woff2");
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Geist Mono";
    src: url("../fonts/geist-mono.woff2") format("woff2");
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
}

/* ---------------------------------------------------------------------------
   Tokens
--------------------------------------------------------------------------- */

:root {
    color-scheme: light;

    --font-display: "Schibsted Grotesk", "Geist", system-ui, sans-serif;
    --font-sans: "Geist", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    --font-mono: "Geist Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;

    /* The one frame every block on every page runs to the edge of. The gutter is never
       under 16px, so nothing touches the side of a phone. */
    --frame: 76rem;
    --gutter: clamp(1rem, 4vw, 2rem);
    --header-height: 4.25rem;

    --radius-sm: 0.375rem;
    --radius: 0.75rem;
    --radius-lg: 1.25rem;

    --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
    --ease-expo: cubic-bezier(0.16, 1, 0.3, 1);
    --t-press: 140ms;
    --t-hover: 180ms;

    /* Surfaces. `paper` is the page, `card` is something lifted off it, `sunk` is a well
       pressed into a card — a code block, a progress track, the summary's footnote. The
       neutrals lean a fraction cool, toward the blue, so the page reads clean beside the
       green rather than tinted by it — the dark theme especially, where a green-grey ground
       made the whole page look green. */
    --paper: oklch(0.984 0.006 255);
    --card: oklch(1 0 0);
    --sunk: oklch(0.96 0.01 255);
    --elevated: oklch(0.972 0.008 255);

    --foreground: oklch(0.21 0.025 262);
    /* 4.5:1 on paper and on sunk, so it can carry the eyebrow and help text. */
    --muted: oklch(0.49 0.02 262);
    --faint: oklch(0.62 0.016 262);

    /* The green of the wordmark, deepened until white text on it clears 4.5:1. */
    --primary: oklch(0.52 0.14 150);
    --primary-hover: oklch(0.46 0.13 150);
    --primary-foreground: oklch(0.99 0.005 150);
    --primary-text: oklch(0.47 0.13 150);
    --primary-tint: oklch(0.95 0.035 150);
    --primary-tint-strong: oklch(0.9 0.06 150);

    /* The money bag. Warmth, never a second call to action: it lights backgrounds and
       marks the one thing on a card that is "sent" or "counted". */
    --amber: oklch(0.76 0.15 70);
    --amber-text: oklch(0.5 0.11 60);
    --amber-tint: oklch(0.95 0.04 80);

    /* The application's own second hue — the second series on its dashboard charts. Here it
       means "under way": a step being worked on, a link to read, a note to know. Green is
       still what is done and what to press. */
    --blue: oklch(0.56 0.15 255);
    --blue-text: oklch(0.49 0.15 255);
    --blue-tint: oklch(0.95 0.03 255);

    --danger: oklch(0.52 0.19 27);
    --danger-tint: oklch(0.95 0.03 27);
    --warning: oklch(0.52 0.12 70);
    --warning-tint: oklch(0.96 0.04 85);

    /* A hairline groups; a strong border is the edge of something you can operate, which
       WCAG 1.4.11 wants at 3:1 against what it sits on. */
    --border: oklch(0.9 0.012 258);
    --border-strong: oklch(0.66 0.02 258);
    --ring: var(--primary);

    --shadow-hairline: 0 1px 2px oklch(0.2 0.04 262 / 0.06);
    --shadow-card: 0 1px 2px oklch(0.2 0.04 262 / 0.04), 0 12px 32px -12px oklch(0.2 0.04 262 / 0.14);
    --shadow-menu: 0 16px 40px -12px oklch(0.2 0.04 262 / 0.24);
    --shadow-hero: 0 40px 80px -40px color-mix(in oklab, var(--primary) 45%, transparent);

    --bloom-green: oklch(0.8 0.14 150 / 0.26);
    --bloom-blue: oklch(0.74 0.14 252 / 0.42);
    --bloom-amber: oklch(0.86 0.12 75 / 0.26);

    /* Logos are drawn for white paper, and most of them have no dark version. */
    --logo-tile: oklch(1 0 0);
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        color-scheme: dark;

        --paper: oklch(0.155 0.02 265);
        --card: oklch(0.195 0.024 265);
        --sunk: oklch(0.135 0.018 265);
        --elevated: oklch(0.228 0.026 265);

        --foreground: oklch(0.96 0.008 255);
        --muted: oklch(0.74 0.02 260);
        --faint: oklch(0.6 0.02 260);

        --primary: oklch(0.76 0.16 150);
        --primary-hover: oklch(0.82 0.15 150);
        --primary-foreground: oklch(0.18 0.04 150);
        --primary-text: oklch(0.8 0.15 150);
        --primary-tint: oklch(0.27 0.05 150);
        --primary-tint-strong: oklch(0.34 0.07 150);

        --amber: oklch(0.8 0.15 72);
        --amber-text: oklch(0.84 0.13 75);
        --amber-tint: oklch(0.28 0.05 70);

        --blue: oklch(0.72 0.13 252);
        --blue-text: oklch(0.79 0.11 250);
        --blue-tint: oklch(0.28 0.05 258);

        --danger: oklch(0.74 0.16 25);
        --danger-tint: oklch(0.26 0.05 25);
        --warning: oklch(0.83 0.13 80);
        --warning-tint: oklch(0.27 0.05 75);

        --border: oklch(1 0 0 / 0.11);
        --border-strong: oklch(1 0 0 / 0.38);

        --shadow-hairline: 0 1px 2px oklch(0 0 0 / 0.3);
        --shadow-card: 0 1px 2px oklch(0 0 0 / 0.3), 0 16px 40px -16px oklch(0 0 0 / 0.6);
        --shadow-menu: 0 18px 48px -12px oklch(0 0 0 / 0.7);
        --shadow-hero: 0 40px 90px -40px color-mix(in oklab, var(--primary) 30%, transparent);

        --bloom-green: oklch(0.55 0.14 150 / 0.17);
        --bloom-blue: oklch(0.5 0.15 258 / 0.34);
        --bloom-amber: oklch(0.6 0.12 70 / 0.12);

        --logo-tile: oklch(0.96 0.006 255);
    }
}

:root[data-theme="dark"] {
    color-scheme: dark;

    --paper: oklch(0.155 0.02 265);
    --card: oklch(0.195 0.024 265);
    --sunk: oklch(0.135 0.018 265);
    --elevated: oklch(0.228 0.026 265);

    --foreground: oklch(0.96 0.008 255);
    --muted: oklch(0.74 0.02 260);
    --faint: oklch(0.6 0.02 260);

    --primary: oklch(0.76 0.16 150);
    --primary-hover: oklch(0.82 0.15 150);
    --primary-foreground: oklch(0.18 0.04 150);
    --primary-text: oklch(0.8 0.15 150);
    --primary-tint: oklch(0.27 0.05 150);
    --primary-tint-strong: oklch(0.34 0.07 150);

    --amber: oklch(0.8 0.15 72);
    --amber-text: oklch(0.84 0.13 75);
    --amber-tint: oklch(0.28 0.05 70);

    --blue: oklch(0.72 0.13 252);
    --blue-text: oklch(0.79 0.11 250);
    --blue-tint: oklch(0.28 0.05 258);

    --danger: oklch(0.74 0.16 25);
    --danger-tint: oklch(0.26 0.05 25);
    --warning: oklch(0.83 0.13 80);
    --warning-tint: oklch(0.27 0.05 75);

    --border: oklch(1 0 0 / 0.11);
    --border-strong: oklch(1 0 0 / 0.38);

    --shadow-hairline: 0 1px 2px oklch(0 0 0 / 0.3);
    --shadow-card: 0 1px 2px oklch(0 0 0 / 0.3), 0 16px 40px -16px oklch(0 0 0 / 0.6);
    --shadow-menu: 0 18px 48px -12px oklch(0 0 0 / 0.7);
    --shadow-hero: 0 40px 90px -40px color-mix(in oklab, var(--primary) 30%, transparent);

    --bloom-green: oklch(0.55 0.14 150 / 0.17);
    --bloom-blue: oklch(0.5 0.15 258 / 0.34);
    --bloom-amber: oklch(0.6 0.12 70 / 0.12);

    --logo-tile: oklch(0.96 0.006 255);
}

/* ---------------------------------------------------------------------------
   Base
--------------------------------------------------------------------------- */

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

html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
    background-color: var(--paper);
    /* An in-page link lands under the sticky header without this. */
    scroll-padding-top: calc(var(--header-height) + 1rem);
}

@media (prefers-reduced-motion: no-preference) {
    html {
        scroll-behavior: smooth;
    }
}

body {
    position: relative;
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    min-height: 100svh;
    margin: 0;
    background-color: var(--paper);
    color: var(--foreground);
    font-family: var(--font-sans);
    font-size: 1rem;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
}

/* Clipped sideways here rather than on body: overflow on body is handed to the
   viewport, where it stops nothing. clip, not hidden, so the sticky columns inside
   keep sticking — hidden would make main their scroll container. */
main {
    position: relative;
    flex: 1 0 auto;
    overflow-x: clip;
    outline: none;
}

h1,
h2,
h3,
h4,
h5,
h6 {
    margin: 0;
    color: var(--foreground);
    font-family: var(--font-display);
    font-weight: 650;
    line-height: 1.15;
    letter-spacing: -0.015em;
    text-wrap: balance;
}

p,
ul,
ol,
dl,
dd,
figure,
blockquote,
fieldset {
    margin: 0;
}

ul,
ol {
    padding: 0;
}

fieldset {
    min-width: 0;
    padding: 0;
    border: 0;
}

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

img {
    height: auto;
}

a {
    color: inherit;
    text-decoration-thickness: 0.07em;
    text-underline-offset: 0.22em;
}

strong,
b {
    font-weight: 600;
}

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

button {
    cursor: pointer;
}

::selection {
    background-color: color-mix(in oklab, var(--primary) 28%, transparent);
}

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

[hidden] {
    display: none !important;
}

.visually-hidden,
.sr-only {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    padding: 0 !important;
    margin: -1px !important;
    overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important;
    white-space: nowrap !important;
    border: 0 !important;
}

.skip-link {
    position: absolute;
    top: 0.75rem;
    left: 0.75rem;
    z-index: 200;
    padding: 0.6rem 1rem;
    border-radius: var(--radius-sm);
    background-color: var(--foreground);
    color: var(--paper);
    font-weight: 500;
    text-decoration: none;
    transform: translateY(-200%);
}

.skip-link:focus {
    transform: none;
}

/* Font Awesome glyphs that are decoration sit on the text baseline at the text size. */
.fa-solid,
.fas,
.fa-regular,
.far,
.fa-brands,
.fab {
    line-height: 1;
}

/* ---------------------------------------------------------------------------
   The bloom

   Light at the top of every page, behind the header, instead of a coloured band
   for each section: green to the left, blue across the right, and a touch of the
   money bag's amber in the far corner. The header is transparent over it, so they
   read as one field rather than a bar laid on a glow.
--------------------------------------------------------------------------- */

.bloom {
    position: absolute;
    inset: 0 0 auto;
    z-index: 0;
    height: min(62rem, 120vh);
    overflow: hidden;
    pointer-events: none;
}

.bloom::before,
.bloom::after {
    content: "";
    position: absolute;
    border-radius: 50%;
    filter: blur(20px);
}

/* The blue and the amber share one element: two gradients on the same field. */

.bloom::before {
    top: -18rem;
    left: 50%;
    width: min(70rem, 140vw);
    height: 46rem;
    background: radial-gradient(closest-side, var(--bloom-green), transparent);
    transform: translateX(-72%);
}

.bloom::after {
    top: -16rem;
    left: 50%;
    width: min(64rem, 120vw);
    height: 44rem;
    background:
        radial-gradient(closest-side at 45% 55%, var(--bloom-blue), transparent),
        radial-gradient(closest-side at 88% 28%, var(--bloom-amber), transparent 70%);
    transform: translateX(-12%);
}

main > *,
.site-footer {
    position: relative;
    z-index: 1;
}

/* ---------------------------------------------------------------------------
   Frame and rhythm
--------------------------------------------------------------------------- */

.frame {
    width: 100%;
    max-width: calc(var(--frame) + 2 * var(--gutter));
    margin-inline: auto;
    padding-inline: var(--gutter);
}

.frame--narrow {
    max-width: calc(48rem + 2 * var(--gutter));
}

.section {
    padding-block: clamp(5rem, 4rem + 6vw, 10rem) 0;
}

.section--last {
    padding-bottom: clamp(5rem, 4rem + 6vw, 9rem);
}

/* A heading on the left and a sentence on the right, both on one baseline — every
   section on the front page opens this way. */
.section-head {
    display: grid;
    gap: 1.25rem;
    margin-bottom: clamp(2.5rem, 2rem + 2vw, 4rem);
}

@media (min-width: 64rem) {
    .section-head {
        grid-template-columns: minmax(0, 6fr) minmax(0, 5fr);
        align-items: end;
        gap: 2rem;
    }

    .section-head__lead {
        justify-self: end;
        text-align: right;
    }
}

/* ---------------------------------------------------------------------------
   Type steps

   Five steps carry the whole site, plus the eyebrow. Anything that wants to be a
   size in between is one of these.
--------------------------------------------------------------------------- */

.display {
    font-family: var(--font-display);
    font-size: clamp(2.5rem, 1.35rem + 4.6vw, 5.25rem);
    font-weight: 700;
    line-height: 0.98;
    letter-spacing: -0.04em;
    text-wrap: balance;
}

.heading {
    font-family: var(--font-display);
    font-size: clamp(1.9rem, 1.4rem + 1.8vw, 3rem);
    font-weight: 650;
    line-height: 1.04;
    letter-spacing: -0.03em;
    text-wrap: balance;
}

/* A title that steps back so what is under it leads. */
.heading--quiet {
    color: var(--muted);
}

.heading--quiet strong,
.heading--quiet em {
    color: var(--foreground);
    font-style: normal;
}

.statement {
    font-size: clamp(1.2rem, 1.05rem + 0.5vw, 1.5rem);
    line-height: 1.4;
    letter-spacing: -0.01em;
}

.lead {
    max-width: 46ch;
    color: var(--muted);
    font-size: clamp(1.05rem, 1rem + 0.25vw, 1.2rem);
    line-height: 1.6;
    text-wrap: pretty;
}

.small {
    font-size: 0.9375rem;
    line-height: 1.55;
}

.muted {
    color: var(--muted);
}

.tnum {
    font-variant-numeric: tabular-nums;
}

/* Mono, small caps-ish, with a green dot in front of it. */
.eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    margin-bottom: 1.25rem;
    color: var(--muted);
    font-family: var(--font-mono);
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.08em;
    line-height: 1.2;
    text-transform: uppercase;
}

.eyebrow::before {
    content: "";
    flex: none;
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    background-color: var(--primary);
}

.eyebrow--plain::before {
    display: none;
}

/* ---------------------------------------------------------------------------
   Buttons and links

   One button shape for the whole site: square-ish, flat, one fill. Secondary is an
   outline in the operable-border weight; quiet is text that behaves like a button.
--------------------------------------------------------------------------- */

.button,
.btn-toolbar .action,
.btn-toolbar button[type="submit"] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.55rem;
    min-height: 2.875rem;
    padding: 0.65rem 1.25rem;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    background-color: var(--primary);
    color: var(--primary-foreground);
    font-family: var(--font-sans);
    font-size: 0.9375rem;
    font-weight: 550;
    line-height: 1.2;
    text-align: center;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    transition:
        transform var(--t-press) var(--ease-out),
        background-color var(--t-hover) ease,
        border-color var(--t-hover) ease,
        color var(--t-hover) ease;
    -webkit-appearance: none;
    appearance: none;
}

.button:active,
.btn-toolbar .action:active {
    transform: scale(0.97);
}

@media (hover: hover) and (pointer: fine) {
    .button:hover,
    .btn-toolbar .action:hover {
        background-color: var(--primary-hover);
    }
}

.button i {
    font-size: 0.85em;
}

.button--secondary {
    border-color: var(--border-strong);
    background-color: transparent;
    color: var(--foreground);
}

@media (hover: hover) and (pointer: fine) {
    .button--secondary:hover {
        border-color: var(--foreground);
        background-color: color-mix(in oklab, var(--foreground) 4%, transparent);
    }
}

.button--quiet {
    padding-inline: 0.75rem;
    background-color: transparent;
    color: var(--foreground);
}

@media (hover: hover) and (pointer: fine) {
    .button--quiet:hover {
        background-color: color-mix(in oklab, var(--foreground) 6%, transparent);
    }
}

.button--sm {
    min-height: 2.25rem;
    padding: 0.4rem 0.9rem;
    font-size: 0.875rem;
}

.button--block {
    width: 100%;
}

.button[disabled],
.button[aria-disabled="true"] {
    border-color: var(--border);
    background-color: var(--sunk);
    color: var(--faint);
    cursor: not-allowed;
    transform: none;
}

/* The arrow moves, not the button. */
.button__arrow {
    transition: transform var(--t-hover) var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
    .button:hover .button__arrow,
    .link:hover .button__arrow {
        transform: translateX(3px);
    }
}

/* Plain text links: the underline arrives on hover, never the weight. */
.link {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    color: var(--foreground);
    font-weight: 500;
    text-decoration: underline;
    text-decoration-color: transparent;
    transition: text-decoration-color var(--t-hover) ease, color var(--t-hover) ease;
}

@media (hover: hover) and (pointer: fine) {
    .link:hover {
        text-decoration-color: currentColor;
    }
}

.link--muted {
    color: var(--muted);
}

.link--muted:hover {
    color: var(--foreground);
}

/* A check in a ring, for every "what you get" list on the site. */
.checks {
    display: grid;
    gap: 0.7rem;
    list-style: none;
}

.checks li {
    display: flex;
    align-items: flex-start;
    gap: 0.7rem;
    line-height: 1.45;
}

.checks i {
    display: inline-grid;
    place-items: center;
    flex: none;
    width: 1.25rem;
    height: 1.25rem;
    margin-top: 0.05rem;
    border-radius: 50%;
    background-color: var(--primary-tint);
    color: var(--primary-text);
    font-size: 0.65rem;
}

/* A small rounded pill with a dot, for "most popular", "ready" and the like. */
.pill {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.25rem 0.65rem;
    border-radius: 999px;
    background-color: var(--primary-tint);
    color: var(--primary-text);
    font-size: 0.75rem;
    font-weight: 600;
    line-height: 1.4;
    white-space: nowrap;
}

.pill--amber {
    background-color: var(--amber-tint);
    color: var(--amber-text);
}

.pill--blue {
    background-color: var(--blue-tint);
    color: var(--blue-text);
}

.pill--neutral {
    background-color: var(--sunk);
    color: var(--muted);
}

/* ---------------------------------------------------------------------------
   Surfaces
--------------------------------------------------------------------------- */

.surface {
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background-color: var(--card);
    box-shadow: var(--shadow-card);
}

/* A square tile with an icon in it, tinted with the brand. */
.icon-tile {
    display: inline-grid;
    place-items: center;
    flex: none;
    width: 2.5rem;
    height: 2.5rem;
    border: 1px solid color-mix(in oklab, var(--primary) 22%, transparent);
    border-radius: 0.6rem;
    background-color: var(--primary-tint);
    color: var(--primary-text);
    font-size: 1rem;
}

/* ---------------------------------------------------------------------------
   Header

   A plain bar: wordmark, the menu, and the way in. No fill of its own while it sits
   over the bloom; once the page scrolls under it, it takes a translucent page ground
   with a light blur. site.js sets data-scrolled.
--------------------------------------------------------------------------- */

/* The notice across the top of every page – Includes/SiteNotice.ss, switched on in the
   settings. The brand green, so it reads as ours rather than as an error, and above the
   sticky header so it scrolls away once read. Lifted over the bloom, which is absolute. */
.site-notice {
    position: relative;
    z-index: 1;
    padding-block: 0.6rem;
    background-color: var(--primary);
    color: var(--primary-foreground);
    font-size: 0.9375rem;
    line-height: 1.45;
}

.site-notice__inner {
    display: flex;
    gap: 0.5rem;
    align-items: baseline;
    justify-content: center;
    text-align: center;
}

.site-notice a {
    color: inherit;
    text-decoration: underline;
    text-underline-offset: 0.2em;
}

.site-header {
    position: sticky;
    top: 0;
    z-index: 100;
    height: var(--header-height);
    border-bottom: 1px solid transparent;
    transition: background-color 300ms ease, border-color 300ms ease, -webkit-backdrop-filter 300ms ease, backdrop-filter 300ms ease;
}

.site-header[data-scrolled],
.site-header[data-open] {
    border-bottom-color: var(--border);
    background-color: color-mix(in oklab, var(--paper) 78%, transparent);
    -webkit-backdrop-filter: blur(14px) saturate(1.4);
    backdrop-filter: blur(14px) saturate(1.4);
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .site-header[data-scrolled],
    .site-header[data-open] {
        background-color: var(--paper);
    }
}

.site-header__inner {
    display: flex;
    align-items: center;
    gap: 2rem;
    height: 100%;
}

.brand {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    flex: none;
    color: var(--foreground);
    font-family: var(--font-display);
    font-size: 1.125rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    text-decoration: none;
}

/* The money bag on a card, so it holds its shape on both grounds. */
.brand__mark {
    display: grid;
    place-items: center;
    width: 2rem;
    height: 2rem;
    border: 1px solid var(--border);
    border-radius: 0.55rem;
    background-color: var(--card);
    box-shadow: var(--shadow-hairline);
}

.brand__mark img {
    width: 1.3rem;
    height: 1.3rem;
}

.site-nav {
    display: flex;
    flex: 1;
    align-items: center;
    gap: 1.75rem;
}

.site-nav__list {
    display: flex;
    align-items: center;
    gap: 1.75rem;
    list-style: none;
}

.site-nav__link {
    position: relative;
    color: var(--muted);
    font-size: 0.9375rem;
    font-weight: 500;
    text-decoration: none;
    transition: color var(--t-hover) ease;
}

.site-nav__link:hover,
.site-nav__link[aria-current="page"] {
    color: var(--foreground);
}

/* The current page, marked by something other than a shade of grey. */
.site-nav__link[aria-current="page"]::after {
    content: "";
    position: absolute;
    right: 0;
    bottom: -0.4rem;
    left: 0;
    height: 2px;
    border-radius: 2px;
    background-color: var(--primary);
}

/* The language chooser sits at the far end of the menu on the wide layout. */
.site-nav .locale {
    margin-left: auto;
}

.site-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-left: auto;
}

/* An icon-sized quiet button: the theme toggle and the menu. */
.icon-button {
    display: inline-grid;
    place-items: center;
    width: 2.375rem;
    height: 2.375rem;
    padding: 0;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--foreground);
    transition: background-color var(--t-hover) ease, border-color var(--t-hover) ease;
}

.icon-button:hover {
    background-color: color-mix(in oklab, var(--foreground) 6%, transparent);
}

/* The theme toggle needs the script to do anything, so it is only drawn with it. */
html:not(.js) .theme-toggle {
    display: none;
}

/* Sun while dark, moon while light: the icon is what pressing it gives you. */
.theme-toggle__light,
.theme-toggle__dark {
    display: none;
}

:root[data-theme-resolved="light"] .theme-toggle__dark,
:root[data-theme-resolved="dark"] .theme-toggle__light {
    display: inline;
}

/* The language chooser. A <details>, so it opens without a line of script; site.js
   only closes it on Escape and on a click elsewhere. */
.locale {
    position: relative;
}

.locale__toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    min-height: 2.375rem;
    padding: 0.35rem 0.7rem;
    border-radius: var(--radius-sm);
    color: var(--muted);
    font-size: 0.875rem;
    font-weight: 500;
    list-style: none;
    cursor: pointer;
    transition: color var(--t-hover) ease, background-color var(--t-hover) ease;
}

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

.locale__toggle:hover,
.locale[open] .locale__toggle {
    background-color: color-mix(in oklab, var(--foreground) 6%, transparent);
    color: var(--foreground);
}

.locale__chevron {
    font-size: 0.65rem;
    transition: transform var(--t-hover) var(--ease-out);
}

.locale[open] .locale__chevron {
    transform: rotate(180deg);
}

.locale__menu {
    position: absolute;
    top: calc(100% + 0.4rem);
    right: 0;
    z-index: 10;
    min-width: 11rem;
    padding: 0.35rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background-color: var(--card);
    box-shadow: var(--shadow-menu);
    list-style: none;
}

.locale__item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.55rem 0.7rem;
    border-radius: calc(var(--radius) - 0.35rem);
    color: var(--foreground);
    font-size: 0.9375rem;
    text-decoration: none;
}

.locale__item:hover {
    background-color: var(--sunk);
}

.locale__item[aria-current] {
    font-weight: 600;
}

.locale__check {
    color: var(--primary-text);
    font-size: 0.8rem;
}

.menu-toggle {
    display: none;
}

/* Under the wide layout the menu folds into a panel under the bar. Only when the
   script is there to open it: without it the links stay in the bar and wrap. */
@media (max-width: 63.99rem) {
    .site-header__inner {
        gap: 1rem;
    }

    .js .menu-toggle {
        display: inline-grid;
    }

    .js .site-nav {
        position: absolute;
        top: var(--header-height);
        right: 0;
        left: 0;
        display: none;
        flex-direction: column;
        align-items: stretch;
        gap: 1.25rem;
        max-height: calc(100svh - var(--header-height));
        padding: 1.25rem var(--gutter) 1.75rem;
        overflow-y: auto;
        border-bottom: 1px solid var(--border);
        background-color: var(--paper);
        box-shadow: var(--shadow-menu);
    }

    .js .site-header[data-open] .site-nav {
        display: flex;
    }

    .js .site-nav__list {
        flex-direction: column;
        align-items: stretch;
        gap: 0;
    }

    .js .site-nav__link {
        display: block;
        padding: 0.8rem 0;
        border-bottom: 1px solid var(--border);
        color: var(--foreground);
        font-size: 1.125rem;
    }

    .js .site-nav__link[aria-current="page"]::after {
        top: 50%;
        right: auto;
        bottom: auto;
        left: -0.9rem;
        width: 0.35rem;
        height: 0.35rem;
        border-radius: 50%;
        transform: translateY(-50%);
    }

    .js .site-nav .locale {
        align-self: flex-start;
        margin-left: 0;
    }

    .js .site-nav .locale__menu {
        right: auto;
        left: 0;
    }

    html:not(.js) .site-header {
        height: auto;
        min-height: var(--header-height);
    }

    html:not(.js) .site-header__inner {
        flex-wrap: wrap;
        padding-block: 0.75rem;
    }

    html:not(.js) .site-nav,
    html:not(.js) .site-nav__list {
        flex-wrap: wrap;
        gap: 1rem;
    }
}

/* The bar on its own, for pages that are not ContentController pages and have no
   menu to draw. */
.site-header--bare .site-header__inner {
    justify-content: space-between;
}

/* ---------------------------------------------------------------------------
   Footer
--------------------------------------------------------------------------- */

.site-footer {
    flex: none;
    margin-top: auto;
    border-top: 1px solid var(--border);
    background-color: var(--paper);
}

.site-footer__inner {
    display: grid;
    gap: 2.5rem;
    padding-block: clamp(3rem, 2.5rem + 2vw, 4.5rem) 2.5rem;
}

@media (min-width: 48rem) {
    .site-footer__inner {
        grid-template-columns: minmax(0, 5fr) repeat(3, minmax(0, 2fr));
        gap: 2rem;
    }
}

.site-footer__tagline {
    max-width: 32ch;
    margin-top: 1rem;
    color: var(--muted);
    font-size: 0.9375rem;
}

.site-footer__heading {
    margin-bottom: 1rem;
    color: var(--muted);
    font-family: var(--font-mono);
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.site-footer__links {
    display: grid;
    gap: 0.55rem;
    list-style: none;
}

.site-footer__links a {
    color: var(--foreground);
    font-size: 0.9375rem;
    text-decoration: underline;
    text-decoration-color: transparent;
    transition: text-decoration-color var(--t-hover) ease;
}

.site-footer__links a:hover {
    text-decoration-color: currentColor;
}

.site-footer__links a[aria-current] {
    color: var(--primary-text);
    font-weight: 500;
}

.site-footer__bottom {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem 1.5rem;
    padding-block: 1.5rem;
    border-top: 1px solid var(--border);
    color: var(--muted);
    font-size: 0.875rem;
}

.site-footer__bottom p {
    margin: 0;
}

/* ---------------------------------------------------------------------------
   Reveal

   site.js marks only the elements that start below the fold as pending, so
   nothing already on screen ever blinks out, and nothing stays hidden without the
   script. Elements in the first screen rise once on load instead.
--------------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
    [data-reveal].is-pending {
        opacity: 0;
        transform: translateY(24px);
    }

    [data-reveal].is-in {
        opacity: 1;
        transform: none;
        transition: opacity 700ms var(--ease-out), transform 900ms var(--ease-expo);
        transition-delay: calc(var(--r, 0) * 80ms);
    }

    [data-load] {
        opacity: 0;
        transform: translateY(14px);
        animation: rise 640ms var(--ease-out) forwards;
        animation-delay: var(--d, 120ms);
    }
}

@keyframes rise {
    to {
        opacity: 1;
        transform: none;
    }
}

/* ---------------------------------------------------------------------------
   Front page: hero
--------------------------------------------------------------------------- */

.hero {
    padding-block: clamp(2.5rem, 1.5rem + 4vw, 4.5rem) 0;
}

.hero__grid {
    display: grid;
    gap: clamp(3rem, 2rem + 4vw, 5rem);
    align-items: center;
}

@media (min-width: 64rem) {
    .hero__grid {
        grid-template-columns: minmax(0, 6fr) minmax(0, 5fr);
        gap: 3rem;
        min-height: min(calc(100svh - var(--header-height) - 6rem), 40rem);
    }
}

.hero__badge {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    max-width: 100%;
    margin-bottom: 1.75rem;
    padding: 0.35rem 0.85rem 0.35rem 0.4rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    background-color: color-mix(in oklab, var(--card) 70%, transparent);
    color: var(--muted);
    font-size: 0.8125rem;
    line-height: 1.35;
    box-shadow: var(--shadow-hairline);
}

.hero__badge-mark {
    display: inline-grid;
    place-items: center;
    flex: none;
    width: 1.4rem;
    height: 1.4rem;
    border-radius: 50%;
    background-color: var(--primary-tint);
    color: var(--primary-text);
    font-size: 0.65rem;
}

.hero__title {
    max-width: 14ch;
}

.hero__lead {
    margin-top: 1.75rem;
}

.hero__content {
    max-width: 52ch;
    margin-top: 1rem;
    color: var(--muted);
}

.hero__content p + p {
    margin-top: 0.75rem;
}

.hero__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem 1.5rem;
    margin-top: 2.25rem;
}

.hero__facts {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem 1.5rem;
    margin-top: 2.75rem;
    color: var(--muted);
    font-size: 0.9rem;
    list-style: none;
}

.hero__facts li {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
}

.hero__facts i {
    color: var(--primary-text);
    font-size: 0.8rem;
}

.hero__visual {
    position: relative;
    justify-self: center;
    width: 100%;
    max-width: 30rem;
}

@media (min-width: 64rem) {
    .hero__visual {
        justify-self: end;
    }
}

/* Light behind the card, in place of a panel. */
.hero__visual::before {
    content: "";
    position: absolute;
    inset: -4rem;
    z-index: -1;
    background:
        radial-gradient(closest-side at 62% 38%, color-mix(in oklab, var(--primary) 22%, transparent), transparent),
        radial-gradient(closest-side at 28% 82%, color-mix(in oklab, var(--blue) 26%, transparent), transparent);
    pointer-events: none;
}

/* ---------------------------------------------------------------------------
   The application, drawn small

   The hero's picture of Better Pricing is a copy of its calculator, in the
   application's own palette — the --app-* tokens, which are the same in both of
   this site's themes because the application is dark whichever theme this site is
   read in. Sizes are in em off one font size on .app-shot, so the whole screen
   scales as one picture rather than reflowing like a page.
--------------------------------------------------------------------------- */

.app-shot {
    --app-page: oklch(0.13 0.02 275);
    --app-bar: oklch(0.17 0.025 275);
    --app-card: oklch(0.2 0.03 278);
    --app-field: oklch(0.235 0.04 278);
    --app-rule: oklch(1 0 0 / 0.08);
    --app-green: oklch(0.62 0.16 150);
    --app-green-dark: oklch(0.52 0.13 150);
    --app-text: oklch(1 0 0);
    --app-label: oklch(0.8 0 0);

    position: relative;
    overflow: hidden;
    border: 1px solid oklch(1 0 0 / 0.1);
    border-radius: var(--radius-lg);
    background: linear-gradient(180deg, var(--app-page), oklch(0.08 0.01 275));
    box-shadow: var(--shadow-card), var(--shadow-hero);
    color: var(--app-text);
    font-family: Roboto, "Segoe UI", system-ui, sans-serif;
    font-size: clamp(0.64rem, 0.5rem + 0.45vw, 0.78rem);
    line-height: 1.3;
}

.app-shot__bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.9em 1.4em;
    background-color: var(--app-bar);
    box-shadow: 0 0.5em 1.5em oklch(0 0 0 / 0.35);
}

.app-shot__brand {
    display: inline-flex;
    align-items: center;
    gap: 0.35em;
    color: var(--app-green);
    font-size: 1.15em;
    font-weight: 700;
    letter-spacing: -0.03em;
}

.app-shot__brand img {
    width: 1.1em;
    height: 1.1em;
}

.app-shot__bar-icons {
    display: inline-flex;
    gap: 1.6em;
    font-size: 1.05em;
}

.app-shot__card {
    margin: 1.4em;
    border: 1px solid var(--app-rule);
    border-radius: 0.6em;
    background-color: var(--app-card);
}

.app-shot__head {
    display: flex;
    align-items: center;
    gap: 0.75em;
    padding: 1em 1.2em;
    border-bottom: 1px solid var(--app-rule);
}

.app-shot__back,
.app-shot__save {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5em;
    height: 2.5em;
    padding: 0 1.1em;
    border-radius: 0.3em;
    background-color: var(--app-green);
    font-size: 0.9em;
    font-weight: 500;
    text-transform: uppercase;
}

.app-shot__title {
    font-size: 1.25em;
    font-weight: 700;
}

.app-shot__save {
    margin-left: auto;
}

.app-shot__body {
    padding: 1.3em 1.2em 1.2em;
}

/* The notched field: a green outline with its label sitting in a gap in the top
   edge, which is what MDB's outline inputs look like in the application. */
.app-field {
    position: relative;
    display: block;
    min-width: 0;
    padding: 0.85em 0.75em 0.5em;
    border: 1px solid var(--app-green);
    border-radius: 0.3em;
    background-color: var(--app-field);
    font-size: 1.05em;
}

/* Truncated here rather than on the field, which would clip the label sitting on its
   top edge. */
.app-field__value {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.app-field__label {
    position: absolute;
    top: -0.1em;
    left: 0.6em;
    padding: 0 0.25em;
    background-color: var(--app-card);
    color: var(--app-text);
    font-size: 0.78em;
    line-height: 1;
    white-space: nowrap;
    transform: translateY(-45%);
}

/* Room for the label above the border. */
.app-shot__form,
.app-shot__lines {
    padding-top: 0.45em;
}

.app-field--select::after {
    content: "";
    position: absolute;
    top: 50%;
    right: 0.75em;
    border: 0.3em solid transparent;
    border-top-color: var(--app-label);
    transform: translateY(-15%);
}

.app-shot__form {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1.05em 0.6em;
}

.app-field--wide {
    grid-column: 1 / -1;
    padding-right: 2em;
}

.app-shot__lines {
    display: grid;
    gap: 0.95em;
    margin-top: 1.4em;
    padding-top: 1.4em;
    border-top: 1px solid var(--app-rule);
    list-style: none;
}

.app-line {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 6.5em;
    gap: 0.6em;
}

.app-field--price {
    text-align: right;
}

.app-shot__total {
    display: flex;
    align-items: baseline;
    justify-content: flex-end;
    gap: 1.2em;
    margin-top: 1.1em;
    padding-bottom: 1em;
    border-bottom: 1px solid var(--app-rule);
    font-size: 1.2em;
    font-weight: 700;
}

.app-shot__total strong {
    font-weight: 700;
}

.app-shot__additions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5em;
    margin-top: 1.1em;
}

.app-chip {
    padding: 0.45em 0.7em;
    border: 1px solid var(--app-green);
    border-radius: 0.25em;
    color: var(--app-green);
    font-size: 0.78em;
    font-weight: 500;
    text-transform: uppercase;
}

.app-chip--on {
    background-color: var(--app-green);
    color: var(--app-text);
}

/* The calculation happening: the lines arrive one at a time and the total last, as
   they do in the application once width and height are in. */
@media (prefers-reduced-motion: no-preference) {
    .app-line,
    .app-shot__total,
    .app-chip {
        opacity: 0;
        transform: translateY(8px);
        animation: rise 520ms var(--ease-out) forwards;
    }

    .app-line:nth-child(1) { animation-delay: 700ms; }
    .app-line:nth-child(2) { animation-delay: 850ms; }
    .app-line:nth-child(3) { animation-delay: 1000ms; }
    .app-line:nth-child(4) { animation-delay: 1150ms; }
    .app-shot__total { animation-delay: 1350ms; }
    .app-chip { animation-delay: 1500ms; }

    .app-shot__total strong {
        animation: total-land 1200ms 1350ms var(--ease-out) both;
    }
}

@keyframes total-land {
    0% { color: var(--app-green); }
    100% { color: var(--app-text); }
}

/* ---------------------------------------------------------------------------
   Front page: benefits
--------------------------------------------------------------------------- */

.features {
    display: grid;
    gap: 0.5rem;
    margin-top: clamp(1.5rem, 1rem + 2vw, 3rem);
    list-style: none;
}

@media (min-width: 40rem) {
    .features {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (min-width: 64rem) {
    .features {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

/* A cell with light rising out of one corner, the corner alternating side to side and
   the colour cycling green, blue, amber — and a screenshot of the product docked to that side
   and running out of frame, so the grid reads as pieces of the application rather than
   as a list of claims with pictures beside it. */
.feature {
    position: relative;
    isolation: isolate;
    display: flex;
    flex-direction: column;
    gap: 1.75rem;
    min-height: 15rem;
    overflow: hidden;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background-color: var(--card);
}

.feature::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background:
        radial-gradient(110% 80% at var(--gx, 100%) 0%, color-mix(in oklab, var(--gc, var(--primary)) 26%, transparent), transparent 65%),
        linear-gradient(160deg, color-mix(in oklab, var(--foreground) 3%, transparent), transparent 45%);
    opacity: 0.85;
    transition: opacity 500ms var(--ease-out);
}

.feature:nth-child(even) {
    --gx: 0%;
}

.feature:nth-child(3n + 2) {
    --gc: var(--blue);
}

.feature:nth-child(3n) {
    --gc: var(--amber);
}

@media (hover: hover) and (pointer: fine) {
    .feature:hover::before {
        opacity: 1;
    }
}

.feature__text {
    display: grid;
    gap: 0.6rem;
    justify-items: start;
    padding: 1.75rem 1.75rem 0;
}

.feature:not(.feature--shot) .feature__text {
    padding-bottom: 1.75rem;
}

.feature__text .icon-tile {
    margin-bottom: 0.5rem;
}

.feature__title {
    font-family: var(--font-sans);
    font-size: 1.0625rem;
    font-weight: 600;
    letter-spacing: -0.005em;
}

.feature__description {
    max-width: 38ch;
    color: var(--muted);
    font-size: 0.9375rem;
    line-height: 1.55;
}

/* Flush with the bottom and one side of the cell, inset from the other, with only the
   inner corner rounded: a window onto the application that carries on past the edge.
   The crop's top left is what stays in view whichever side the cell docks to, so that
   is where a screenshot should put the thing it is about. */
.feature__shot {
    position: relative;
    height: clamp(13rem, 10rem + 8vw, 17rem);
    margin-top: auto;
    margin-left: 1.75rem;
    overflow: hidden;
    border: 1px solid var(--border);
    border-right: 0;
    border-bottom: 0;
    border-top-left-radius: var(--radius);
    background-color: var(--elevated);
    box-shadow: var(--shadow-card);
}

.feature__shot img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: left top;
    transition: transform 700ms var(--ease-out);
}

.feature:nth-child(even) .feature__shot {
    margin-right: 1.75rem;
    margin-left: 0;
    border-right: 1px solid var(--border);
    border-left: 0;
    border-top-left-radius: 0;
    border-top-right-radius: var(--radius);
}

@media (hover: hover) and (pointer: fine) {
    .feature:hover .feature__shot img {
        transform: scale(1.03);
    }
}

/* ---------------------------------------------------------------------------
   Front page: plans
--------------------------------------------------------------------------- */

.plans__head-end {
    display: grid;
    gap: 1.25rem;
    justify-items: start;
}

@media (min-width: 64rem) {
    .plans__head-end {
        justify-items: end;
    }
}

/* Two radios and a :has() rule, not script. */
.billing-toggle {
    display: inline-flex;
    padding: 0.25rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    background-color: var(--sunk);
}

.billing-toggle__input {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

.billing-toggle__option {
    padding: 0.4rem 1.1rem;
    border-radius: 999px;
    color: var(--muted);
    font-size: 0.875rem;
    font-weight: 500;
    cursor: pointer;
    transition: background-color var(--t-hover) ease, color var(--t-hover) ease;
}

.billing-toggle__input:checked + .billing-toggle__option {
    background-color: var(--card);
    color: var(--foreground);
    box-shadow: var(--shadow-hairline);
}

.billing-toggle__input:focus-visible + .billing-toggle__option {
    outline: 2px solid var(--ring);
    outline-offset: 2px;
}

.plans__group--year {
    display: none;
}

.plans:has(#plans-interval-year:checked) .plans__group--month {
    display: none;
}

.plans:has(#plans-interval-year:checked) .plans__group--year {
    display: block;
}

.plan-grid {
    display: grid;
    gap: 1rem;
    list-style: none;
}

@media (min-width: 48rem) {
    .plan-grid {
        grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
    }
}

.plan {
    position: relative;
    display: flex;
    flex-direction: column;
    padding: 1.75rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background-color: var(--card);
    box-shadow: var(--shadow-hairline);
}

.plan--featured {
    border-color: color-mix(in oklab, var(--primary) 55%, transparent);
    box-shadow: var(--shadow-card), var(--shadow-hero);
}

.plan--featured::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    border-radius: inherit;
    background: radial-gradient(120% 60% at 50% 0%, color-mix(in oklab, var(--primary) 9%, transparent), transparent 70%);
    pointer-events: none;
}

.plan > * {
    position: relative;
}

.plan__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    min-height: 1.75rem;
}

.plan__name {
    font-family: var(--font-sans);
    font-size: 1.0625rem;
    font-weight: 600;
    letter-spacing: 0;
}

.plan__users {
    margin-top: 0.35rem;
    color: var(--blue-text);
    font-family: var(--font-mono);
    font-size: 0.8rem;
}

.plan__price {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.25rem 0.5rem;
    margin-top: 1.75rem;
}

.plan__amount {
    font-family: var(--font-display);
    font-size: clamp(2.25rem, 1.9rem + 1.2vw, 2.85rem);
    font-weight: 700;
    letter-spacing: -0.04em;
    line-height: 1;
    font-variant-numeric: lining-nums proportional-nums;
}

.plan__period {
    color: var(--muted);
    font-size: 0.9rem;
}

.plan__desc {
    margin-top: 1rem;
    color: var(--muted);
    font-size: 0.9375rem;
}

.plan__features {
    margin-top: 1.5rem;
    padding-top: 1.5rem;
    border-top: 1px solid var(--border);
    font-size: 0.9375rem;
}

.plan__action {
    margin-top: auto;
    padding-top: 2rem;
}

.plans__note {
    max-width: 70ch;
    margin-top: 1.75rem;
    color: var(--muted);
    font-size: 0.875rem;
}

/* ---------------------------------------------------------------------------
   Front page: accounting systems
--------------------------------------------------------------------------- */

.logo-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.5rem;
    list-style: none;
}

@media (min-width: 40rem) {
    .logo-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

@media (min-width: 64rem) {
    .logo-grid {
        grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
    }
}

.logo-tile {
    display: grid;
    place-items: center;
    height: 100%;
    min-height: 6.5rem;
    padding: 1.25rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background-color: var(--logo-tile);
    color: oklch(0.25 0.025 262);
    text-decoration: none;
    transition: transform var(--t-hover) var(--ease-out), box-shadow var(--t-hover) ease;
}

a.logo-tile:hover {
    box-shadow: var(--shadow-card);
    transform: translateY(-2px);
}

.logo-tile__logo {
    max-width: 100%;
    max-height: 3rem;
    object-fit: contain;
}

.logo-tile__name {
    font-family: var(--font-display);
    font-size: 1.125rem;
    font-weight: 650;
    text-align: center;
}

/* ---------------------------------------------------------------------------
   Front page: questions

   The heading pinned on the left while the questions run down the right. Each one
   is a <details>, named into one group, so the browser itself keeps a single
   answer open; a dot in front fills green on the open one.
--------------------------------------------------------------------------- */

.faq__grid {
    display: grid;
    gap: 2.5rem;
}

@media (min-width: 64rem) {
    .faq__grid {
        grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
        gap: 3rem;
        align-items: start;
    }

    .faq__intro {
        position: sticky;
        top: calc(var(--header-height) + 2rem);
    }
}

.faq__lead {
    margin-top: 1.25rem;
}

.faq__list {
    border-top: 1px solid var(--border);
}

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

.faq__question {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    padding: 1.35rem 0;
    color: var(--muted);
    font-size: clamp(1.05rem, 1rem + 0.3vw, 1.2rem);
    font-weight: 500;
    line-height: 1.4;
    list-style: none;
    cursor: pointer;
    transition: color var(--t-hover) ease;
}

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

.faq__question:hover,
.faq__item[open] .faq__question {
    color: var(--foreground);
}

.faq__dot {
    flex: none;
    width: 0.55rem;
    height: 0.55rem;
    margin-top: 0.55em;
    border-radius: 50%;
    background-color: color-mix(in oklab, var(--muted) 40%, transparent);
    transition: background-color 300ms ease, transform 300ms var(--ease-out);
}

.faq__item[open] .faq__dot {
    background-color: var(--blue);
    transform: scale(1.25);
}

.faq__plus {
    flex: none;
    margin-left: auto;
    margin-top: 0.3em;
    color: var(--faint);
    font-size: 0.85rem;
    transition: transform 300ms var(--ease-out);
}

.faq__item[open] .faq__plus {
    transform: rotate(45deg);
    color: var(--foreground);
}

.faq__answer {
    max-width: 62ch;
    padding: 0 2rem 1.75rem 1.55rem;
    color: var(--foreground);
    font-size: 1.0625rem;
    line-height: 1.65;
}

.faq__answer > * + * {
    margin-top: 0.85rem;
}

.faq__answer ul,
.faq__answer ol {
    padding-left: 1.25rem;
}

@media (prefers-reduced-motion: no-preference) {
    .faq__item[open] .faq__answer {
        animation: rise 420ms var(--ease-out);
    }
}

/* ---------------------------------------------------------------------------
   Front page: the close
--------------------------------------------------------------------------- */

.closing {
    position: relative;
    overflow: hidden;
    padding: clamp(2.5rem, 2rem + 3vw, 4.5rem);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background-color: var(--card);
}

.closing::before {
    content: "";
    position: absolute;
    inset: 0;
    background:
        radial-gradient(60% 120% at 100% 100%, color-mix(in oklab, var(--primary) 16%, transparent), transparent 70%),
        radial-gradient(45% 100% at 80% 0%, color-mix(in oklab, var(--blue) 16%, transparent), transparent 70%);
    pointer-events: none;
}

.closing__inner {
    position: relative;
    display: grid;
    gap: 2rem;
}

@media (min-width: 64rem) {
    .closing__inner {
        grid-template-columns: minmax(0, 7fr) minmax(0, 4fr);
        align-items: end;
    }

    .closing__actions {
        justify-self: end;
    }
}

.closing__title {
    max-width: 22ch;
    font-family: var(--font-display);
    font-size: clamp(1.75rem, 1.3rem + 1.6vw, 2.6rem);
    font-weight: 650;
    letter-spacing: -0.03em;
    line-height: 1.1;
}

.closing__lead {
    margin-top: 1rem;
}

.closing__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem 1.5rem;
}

/* ---------------------------------------------------------------------------
   Standard pages and prose
--------------------------------------------------------------------------- */

.page-head {
    padding-block: clamp(3rem, 2rem + 4vw, 6rem) clamp(2.5rem, 2rem + 2vw, 4rem);
}

.page-head__title {
    max-width: 20ch;
}

.page-head__lead {
    margin-top: 1.5rem;
}

.page-body {
    padding-bottom: clamp(5rem, 4rem + 4vw, 8rem);
}

.prose {
    max-width: 68ch;
    font-size: 1.0625rem;
    line-height: 1.7;
}

.prose > * + * {
    margin-top: 1.1em;
}

.prose h2 {
    margin-top: 2.2em;
    font-size: clamp(1.45rem, 1.25rem + 0.7vw, 1.85rem);
    letter-spacing: -0.02em;
}

.prose h3 {
    margin-top: 1.8em;
    font-size: 1.25rem;
}

.prose h4 {
    margin-top: 1.6em;
    font-size: 1.0625rem;
}

.prose h2 + *,
.prose h3 + *,
.prose h4 + * {
    margin-top: 0.6em;
}

.prose > :first-child {
    margin-top: 0;
}

/* Blue: a link in a paragraph is something to read next, not the thing to press. */
.prose a {
    color: var(--blue-text);
    font-weight: 500;
}

.prose a:hover {
    text-decoration-thickness: 0.12em;
}

.prose ul,
.prose ol {
    padding-left: 1.4rem;
}

.prose li + li {
    margin-top: 0.4em;
}

.prose li::marker {
    color: var(--faint);
}

.prose ol li::marker {
    font-family: var(--font-mono);
    font-size: 0.9em;
}

.prose blockquote {
    padding-left: 1.25rem;
    border-left: 3px solid var(--primary);
    color: var(--muted);
}

.prose hr {
    margin-block: 2.5em;
    border: 0;
    border-top: 1px solid var(--border);
}

.prose img {
    border-radius: var(--radius);
}

.prose code {
    padding: 0.1em 0.35em;
    border-radius: 0.3rem;
    background-color: var(--sunk);
    font-family: var(--font-mono);
    font-size: 0.88em;
}

.prose pre {
    padding: 1rem 1.25rem;
    overflow-x: auto;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background-color: var(--sunk);
}

.prose pre code {
    padding: 0;
    background: none;
}

.prose table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.9375rem;
}

.prose th,
.prose td {
    padding: 0.65rem 0.75rem;
    border-bottom: 1px solid var(--border);
    text-align: left;
    vertical-align: top;
}

.prose th {
    color: var(--muted);
    font-family: var(--font-mono);
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

/* The CMS editor's own alignment classes. */
.prose .text-center,
.prose .center {
    text-align: center;
}

.prose .text-right {
    text-align: right;
}

.prose img.left {
    float: left;
    max-width: 50%;
    margin: 0.25rem 1.5rem 1rem 0;
}

.prose img.right {
    float: right;
    max-width: 50%;
    margin: 0.25rem 0 1rem 1.5rem;
}

.prose img.center,
.prose img.leftAlone {
    margin-inline: auto;
}

/* ---------------------------------------------------------------------------
   Forms

   Labels above, never floating: the label is what the field is for, and a label
   that moves out of the way as you type is one you can no longer read. Styled by
   element inside a form, so the framework's own forms at /Security need no class
   of ours added to their inputs.
--------------------------------------------------------------------------- */

form .field {
    margin-bottom: 1.35rem;
}

.field__label,
form .field > label:not(.field__check-label),
form .field legend {
    display: block;
    margin-bottom: 0.45rem;
    color: var(--foreground);
    font-size: 0.9rem;
    font-weight: 550;
    line-height: 1.35;
}

form input:where([type="text"], [type="email"], [type="password"], [type="tel"], [type="url"], [type="number"], [type="search"], [type="date"]),
form input.text,
form select,
form textarea {
    display: block;
    width: 100%;
    min-height: 2.875rem;
    padding: 0.6rem 0.85rem;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    background-color: var(--card);
    color: var(--foreground);
    font-size: 1rem;
    line-height: 1.4;
    box-shadow: var(--shadow-hairline);
    transition: border-color var(--t-hover) ease, box-shadow var(--t-hover) ease;
    -webkit-appearance: none;
    appearance: none;
}

form textarea {
    min-height: 7rem;
    resize: vertical;
}

form select {
    padding-right: 2.5rem;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23808a85' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.85rem center;
    background-size: 1rem;
}

form input::placeholder,
form textarea::placeholder {
    color: var(--faint);
}

form input:hover,
form select:hover,
form textarea:hover {
    border-color: color-mix(in oklab, var(--foreground) 60%, var(--border-strong));
}

form input:focus,
form select:focus,
form textarea:focus {
    border-color: var(--primary);
    outline: none;
    box-shadow: 0 0 0 3px color-mix(in oklab, var(--primary) 22%, transparent);
}

form input:disabled,
form select:disabled,
form textarea:disabled {
    background-color: var(--sunk);
    color: var(--faint);
    cursor: not-allowed;
}

/* A field the server sent back. */
form .field.error input,
form .field.error select,
form .field.error textarea,
form .holder-error input,
form .holder-error select {
    border-color: var(--danger);
}

.field__help,
form .field .description,
form .field .right-title {
    margin-top: 0.45rem;
    color: var(--muted);
    font-size: 0.85rem;
    line-height: 1.5;
}

.field__help i {
    margin-right: 0.3rem;
}

/* Messages. The framework renders `message $MessageType` on the form and on each
   field, with good, bad, required, validation and warning as the types. */
.message {
    display: flex;
    gap: 0.65rem;
    align-items: flex-start;
    margin-bottom: 1.25rem;
    padding: 0.8rem 1rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background-color: var(--sunk);
    color: var(--foreground);
    font-size: 0.9rem;
    line-height: 1.5;
}

.message:empty {
    display: none;
}

.message.good {
    border-color: color-mix(in oklab, var(--primary) 35%, transparent);
    background-color: var(--primary-tint);
}

.message.bad,
.message.error,
.message.required,
.message.validation {
    border-color: color-mix(in oklab, var(--danger) 35%, transparent);
    background-color: var(--danger-tint);
}

.message.warning {
    border-color: color-mix(in oklab, var(--warning) 35%, transparent);
    background-color: var(--warning-tint);
}

.message.notice,
.message.info {
    border-color: color-mix(in oklab, var(--blue) 35%, transparent);
    background-color: var(--blue-tint);
}

/* The same, but under a single field, where a box would be heavier than the field. */
.field__message {
    margin-top: 0.45rem;
    color: var(--danger);
    font-size: 0.85rem;
    font-weight: 500;
}

.field__message.good {
    color: var(--primary-text);
}

.field__message.warning {
    color: var(--warning);
}

/* A single checkbox with its label beside it. */
.field--check {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 0.65rem;
}

.field--check .field__help,
.field--check .field__message {
    flex-basis: 100%;
    margin-left: 1.9rem;
}

form input[type="checkbox"],
form input[type="radio"] {
    display: inline-grid;
    place-content: center;
    flex: none;
    width: 1.25rem;
    height: 1.25rem;
    margin: 0.1rem 0 0;
    border: 1px solid var(--border-strong);
    border-radius: 0.3rem;
    background-color: var(--card);
    cursor: pointer;
    transition: background-color var(--t-hover) ease, border-color var(--t-hover) ease;
    -webkit-appearance: none;
    appearance: none;
}

form input[type="radio"] {
    border-radius: 50%;
}

form input[type="checkbox"]::before {
    content: "";
    width: 0.65rem;
    height: 0.65rem;
    background-color: var(--primary-foreground);
    clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
    transform: scale(0);
    transition: transform 120ms var(--ease-out);
}

form input[type="radio"]::before {
    content: "";
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    background-color: var(--primary-foreground);
    transform: scale(0);
    transition: transform 120ms var(--ease-out);
}

form input[type="checkbox"]:checked,
form input[type="radio"]:checked {
    border-color: var(--primary);
    background-color: var(--primary);
}

form input[type="checkbox"]:checked::before,
form input[type="radio"]:checked::before {
    transform: scale(1);
}

form input[type="checkbox"]:focus-visible,
form input[type="radio"]:focus-visible {
    outline: 2px solid var(--ring);
    outline-offset: 2px;
}

.field__check-label {
    flex: 1;
    min-width: 0;
    font-size: 0.9375rem;
    line-height: 1.45;
    cursor: pointer;
}

/* Radio options as selectable cards. The label covers the whole card, which is what
   makes the card clickable without a line of JavaScript. */
.choices {
    display: grid;
    gap: 0.6rem;
}

@media (min-width: 36rem) {
    .choices {
        grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
    }
}

.choice {
    position: relative;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    min-height: 3.25rem;
    padding: 0.75rem 1rem;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    background-color: var(--card);
    transition: border-color var(--t-hover) ease, background-color var(--t-hover) ease, box-shadow var(--t-hover) ease;
}

.choice:hover {
    border-color: color-mix(in oklab, var(--foreground) 60%, var(--border-strong));
}

.choice:has(input:checked) {
    border-color: var(--primary);
    background-color: color-mix(in oklab, var(--primary-tint) 60%, var(--card));
    box-shadow: 0 0 0 1px var(--primary);
}

.choice:has(input:disabled) {
    opacity: 0.6;
}

.choice__label {
    flex: 1;
    font-size: 0.9375rem;
    font-weight: 500;
    cursor: pointer;
}

/* Stretched over the whole card. */
.choice__label::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
}

/* Two fields side by side on wider screens. */
.field-row {
    display: grid;
    gap: 0 1rem;
}

@media (min-width: 36rem) {
    .field-row {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* The address field: the input and the base domain as one box, so the customer can
   see the whole address they are choosing. */
.subdomain {
    display: flex;
    align-items: stretch;
    overflow: hidden;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    background-color: var(--card);
    box-shadow: var(--shadow-hairline);
    transition: border-color var(--t-hover) ease, box-shadow var(--t-hover) ease;
}

.subdomain:focus-within {
    border-color: var(--primary);
    box-shadow: 0 0 0 3px color-mix(in oklab, var(--primary) 22%, transparent);
}

form .subdomain input.text,
form .subdomain input {
    flex: 1;
    min-width: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
    font-family: var(--font-mono);
    font-size: 0.95rem;
}

form .subdomain input:focus {
    box-shadow: none;
}

.subdomain__base {
    display: flex;
    align-items: center;
    padding: 0 0.85rem;
    border-left: 1px solid var(--border);
    background-color: var(--sunk);
    color: var(--muted);
    font-family: var(--font-mono);
    font-size: 0.9rem;
    white-space: nowrap;
}

@media (max-width: 24rem) {
    .subdomain {
        flex-direction: column;
    }

    .subdomain__base {
        padding-block: 0.4rem;
        border-top: 1px solid var(--border);
        border-left: 0;
    }
}

.field__lock {
    display: flex;
    gap: 0.45rem;
    align-items: baseline;
    color: var(--amber-text);
}

/* The submit row. The framework wraps its actions in .btn-toolbar. */
.btn-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem 1.25rem;
    margin-top: 0.5rem;
}

.btn-toolbar #ForgotPassword {
    margin: 0;
    font-size: 0.9rem;
}

.btn-toolbar #ForgotPassword a {
    color: var(--muted);
    text-decoration: underline;
    text-decoration-color: transparent;
}

.btn-toolbar #ForgotPassword a:hover {
    color: var(--foreground);
    text-decoration-color: currentColor;
}

form .clear {
    display: none;
}

/* The password strength meter the framework leaves an empty div for. */
.passwordstrength:empty {
    display: none;
}

/* ---------------------------------------------------------------------------
   Waiting on a submit — see auth.js
--------------------------------------------------------------------------- */

.btn-toolbar .action.is-busy {
    opacity: 0.6;
    cursor: progress;
}

.auth__busy {
    display: flex;
    flex-basis: 100%;
    align-items: center;
    gap: 0.6rem;
    margin: 0;
    color: var(--muted);
    font-size: 0.9rem;
}

.auth__spinner {
    width: 1rem;
    height: 1rem;
    border: 2px solid var(--border);
    border-top-color: var(--primary);
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
}

@keyframes spin {
    to {
        transform: rotate(360deg);
    }
}

/* ---------------------------------------------------------------------------
   Login, password and message pages

   The claim on the left and the card on the right on a wide screen, stacked on a
   narrow one — Paygent's sign-in, with our own lead and note in the left column.
--------------------------------------------------------------------------- */

.auth {
    padding-block: clamp(2.5rem, 1.5rem + 5vw, 7rem) clamp(4rem, 3rem + 4vw, 7rem);
}

.auth__grid {
    display: grid;
    gap: 2.5rem;
    align-items: center;
}

@media (min-width: 60rem) {
    .auth__grid {
        grid-template-columns: minmax(0, 6fr) minmax(0, 5fr);
        gap: 4rem;
        min-height: min(calc(100svh - var(--header-height) - 14rem), 36rem);
    }
}

.auth__grid--single {
    max-width: 32rem;
    margin-inline: auto;
}

@media (min-width: 60rem) {
    .auth__grid--single {
        grid-template-columns: 1fr;
        min-height: 0;
    }
}

.auth__title {
    font-family: var(--font-display);
    font-size: clamp(2.2rem, 1.5rem + 2.8vw, 3.75rem);
    font-weight: 700;
    letter-spacing: -0.035em;
    line-height: 1.02;
}

.auth__lead {
    margin-top: 1.25rem;
}

.auth__note {
    display: flex;
    gap: 0.75rem;
    align-items: flex-start;
    max-width: 46ch;
    margin-top: 2rem;
    padding-top: 1.5rem;
    border-top: 1px solid var(--border);
    color: var(--muted);
    font-size: 0.9375rem;
}

.auth__note i {
    margin-top: 0.3rem;
    color: var(--primary-text);
}

.auth__note .fa-circle-info {
    color: var(--blue-text);
}

.auth__panel {
    width: 100%;
}

.auth__card {
    padding: clamp(1.5rem, 1.2rem + 1.5vw, 2.25rem);
}

.auth__card-title {
    margin-bottom: 1.5rem;
    font-family: var(--font-sans);
    font-size: 1.25rem;
    font-weight: 600;
    letter-spacing: -0.01em;
}

.auth__content {
    margin-bottom: 1.25rem;
    color: var(--muted);
}

.auth__content > * + * {
    margin-top: 0.75rem;
}

.auth__content a {
    color: var(--primary-text);
    font-weight: 500;
}

.auth__card .btn-toolbar .action {
    width: 100%;
}

.auth__card .btn-toolbar #ForgotPassword {
    flex-basis: 100%;
    text-align: center;
}

.auth__list {
    margin-bottom: 1.75rem;
}

.auth__alt {
    margin-top: 1.25rem;
    color: var(--muted);
    font-size: 0.9375rem;
    text-align: center;
}

.auth__alt a {
    color: var(--foreground);
    font-weight: 600;
}

/* /login's question for somebody with more than one installation (LoginChooser.ss): one
   full-width row per installation, the company on top and its address under it, so two
   companies with similar names are still told apart by where they live. */
.auth__choices {
    display: grid;
    gap: 0.75rem;
    margin-top: 1.75rem;
    padding: 0;
    list-style: none;
}

.auth__choice {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.9rem 1.1rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background-color: var(--card);
    color: var(--foreground);
    text-decoration: none;
    transition: border-color var(--t-hover) ease, background-color var(--t-hover) ease;
}

a.auth__choice:hover,
a.auth__choice:focus-visible {
    border-color: var(--primary);
    background-color: var(--primary-tint);
}

.auth__choice-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.auth__choice-title {
    font-weight: 600;
    overflow-wrap: anywhere;
}

.auth__choice-domain {
    color: var(--muted);
    font-size: 0.875rem;
    overflow-wrap: anywhere;
}

.auth__choice i {
    color: var(--primary-text);
}

.auth__choice--disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

/* ---------------------------------------------------------------------------
   Signup
--------------------------------------------------------------------------- */

.signup {
    padding-block: clamp(3rem, 2rem + 4vw, 6rem) clamp(5rem, 4rem + 4vw, 8rem);
}

.signup__head {
    margin-bottom: clamp(2.5rem, 2rem + 2vw, 3.5rem);
}

.signup__grid {
    display: grid;
    gap: 2rem;
    align-items: start;
}

@media (min-width: 64rem) {
    .signup__grid {
        grid-template-columns: minmax(0, 7fr) minmax(0, 4fr);
        gap: 3rem;
    }

    .signup__aside {
        position: sticky;
        top: calc(var(--header-height) + 1.5rem);
        order: 2;
    }
}

/* One numbered step. The number is a CSS counter, so adding or reordering steps
   cannot leave it wrong. */
.signup__grid form > fieldset {
    counter-reset: signup-step;
}

.form-step {
    margin-bottom: 1rem;
    padding: clamp(1.35rem, 1rem + 1.5vw, 2rem);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background-color: var(--card);
    box-shadow: var(--shadow-hairline);
    counter-increment: signup-step;
}

.form-step__head {
    display: flex;
    gap: 1rem;
    align-items: flex-start;
    margin-bottom: 1.5rem;
    padding-bottom: 1.25rem;
    border-bottom: 1px solid var(--border);
}

.form-step__number {
    display: inline-grid;
    place-items: center;
    flex: none;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 0.6rem;
    background-color: var(--primary-tint);
    color: var(--primary-text);
    font-family: var(--font-mono);
    font-size: 0.85rem;
    font-weight: 600;
}

.form-step__number::before {
    content: counter(signup-step, decimal-leading-zero);
}

.form-step__title {
    font-family: var(--font-sans);
    font-size: 1.125rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    line-height: 1.3;
}

.form-step__desc {
    margin-top: 0.25rem;
    color: var(--muted);
    font-size: 0.9rem;
}

.form-step .field:last-child {
    margin-bottom: 0;
}

.signup__grid form > .btn-toolbar {
    margin-top: 1.5rem;
}

.signup__grid form > .btn-toolbar .action {
    min-height: 3.25rem;
    padding-inline: 2rem;
    font-size: 1rem;
}

/* The order summary. */
.summary {
    padding: 1.75rem;
}

.summary--chosen {
    border-color: color-mix(in oklab, var(--primary) 45%, transparent);
}

.summary__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}

.summary__name {
    font-family: var(--font-sans);
    font-size: 1.25rem;
    font-weight: 600;
    letter-spacing: -0.01em;
}

.summary__users {
    margin-top: 0.35rem;
    color: var(--blue-text);
    font-family: var(--font-mono);
    font-size: 0.8rem;
}

.summary__price {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.25rem 0.5rem;
    margin-block: 1.5rem;
    padding-block: 1.25rem;
    border-block: 1px solid var(--border);
}

.summary__amount {
    font-family: var(--font-display);
    font-size: 2.25rem;
    font-weight: 700;
    letter-spacing: -0.04em;
    line-height: 1;
    font-variant-numeric: lining-nums proportional-nums;
}

.summary__period {
    color: var(--muted);
    font-size: 0.9rem;
}

.summary__list {
    font-size: 0.9375rem;
}

.summary__change {
    margin-top: 1.5rem;
    font-size: 0.9rem;
}

/* In place of the form, for a plan that cannot be bought yet. */
.signup__closed {
    padding: clamp(1.35rem, 1rem + 1.5vw, 2rem);
}

.summary__note {
    display: flex;
    gap: 0.65rem;
    align-items: flex-start;
    margin-top: 1rem;
    padding-inline: 0.5rem;
    color: var(--muted);
    font-size: 0.875rem;
}

.summary__note i {
    margin-top: 0.25rem;
    color: var(--primary-text);
}

/* ---------------------------------------------------------------------------
   The manual
--------------------------------------------------------------------------- */

.docs-intro {
    max-width: 58ch;
    margin-top: 1.5rem;
    color: var(--muted);
    font-size: 1.125rem;
}

.docs-intro > * + * {
    margin-top: 0.75rem;
}

.docs-contents__head {
    margin-bottom: 2rem;
}

.docs-contents__title {
    font-size: 1.5rem;
}

.docs-contents__lead {
    margin-top: 0.5rem;
}

.docs-contents__list {
    display: grid;
    gap: 0.75rem;
    list-style: none;
}

@media (min-width: 48rem) {
    .docs-contents__list {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

.chapter {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background-color: var(--card);
    transition: border-color var(--t-hover) ease, box-shadow var(--t-hover) ease;
}

.chapter:hover {
    border-color: color-mix(in oklab, var(--primary) 40%, var(--border));
    box-shadow: var(--shadow-card);
}

.chapter__head {
    display: flex;
    gap: 1rem;
    align-items: flex-start;
    padding: 1.35rem 1.5rem;
    color: inherit;
    text-decoration: none;
}

.chapter__number {
    flex: none;
    min-width: 1.75rem;
    padding-top: 0.15rem;
    color: var(--faint);
    font-family: var(--font-mono);
    font-size: 0.85rem;
    font-variant-numeric: tabular-nums;
}

.chapter__text {
    display: grid;
    flex: 1;
    gap: 0.3rem;
}

.chapter__title {
    display: flex;
    gap: 0.6rem;
    align-items: center;
    font-family: var(--font-display);
    font-size: 1.15rem;
    font-weight: 650;
    letter-spacing: -0.015em;
}

.chapter__icon {
    color: var(--blue-text);
    font-size: 0.95rem;
}

.chapter__summary {
    color: var(--muted);
    font-size: 0.9375rem;
    line-height: 1.5;
}

.chapter__arrow {
    flex: none;
    padding-top: 0.25rem;
    color: var(--faint);
    font-size: 0.8rem;
    transition: transform var(--t-hover) var(--ease-out), color var(--t-hover) ease;
}

.chapter__head:hover .chapter__arrow {
    color: var(--primary-text);
    transform: translateX(3px);
}

.chapter__articles {
    margin: 0 1.5rem 1.25rem 4.25rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--border);
    list-style: none;
}

.chapter__articles a {
    display: block;
    padding: 0.35rem 0;
    color: var(--foreground);
    font-size: 0.9375rem;
    text-decoration: none;
}

.chapter__articles a:hover .chapter__article-title {
    text-decoration: underline;
}

.chapter__article-summary {
    display: block;
    color: var(--muted);
    font-size: 0.85rem;
}

.docs-contents__empty {
    color: var(--muted);
}

/* A page of the manual: the manual on the left, the page in the middle, and on the
   widest screens the page's own headings on the right. */
.docs-layout {
    display: grid;
    gap: 2.5rem;
    padding-bottom: clamp(5rem, 4rem + 4vw, 8rem);
}

@media (min-width: 64rem) {
    .docs-layout {
        grid-template-columns: 15rem minmax(0, 1fr);
        gap: 3.5rem;
        align-items: start;
    }
}

@media (min-width: 80rem) {
    .docs-layout--toc {
        grid-template-columns: 15rem minmax(0, 1fr) 13rem;
    }
}

.docs-nav {
    font-size: 0.9375rem;
}

@media (min-width: 64rem) {
    .docs-nav,
    .docs-toc {
        position: sticky;
        top: calc(var(--header-height) + 1.5rem);
        max-height: calc(100vh - var(--header-height) - 3rem);
        overflow-y: auto;
        overscroll-behavior: contain;
        scrollbar-width: thin;
    }
}

/* Under the wide layout the manual's contents fold into one <details>, so the
   article is not pushed a screen down by a dozen links. */
.docs-nav__fold {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background-color: var(--card);
}

.docs-nav__summary {
    display: flex;
    gap: 0.6rem;
    align-items: center;
    padding: 0.85rem 1rem;
    font-weight: 600;
    list-style: none;
    cursor: pointer;
}

.docs-nav__summary::-webkit-details-marker {
    display: none;
}

.docs-nav__summary i:last-child {
    margin-left: auto;
    color: var(--faint);
    font-size: 0.7rem;
    transition: transform var(--t-hover) var(--ease-out);
}

.docs-nav__fold[open] .docs-nav__summary i:last-child {
    transform: rotate(180deg);
}

.docs-nav__body {
    padding: 0 1rem 1rem;
}

@media (min-width: 64rem) {
    .docs-nav__fold {
        border: 0;
        background: none;
    }

    .docs-nav__summary {
        display: none;
    }

    .docs-nav__body {
        padding: 0;
    }

}

.docs-nav__heading {
    display: flex;
    gap: 0.6rem;
    align-items: center;
    margin-bottom: 1rem;
    color: var(--muted);
    font-family: var(--font-mono);
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.08em;
    text-decoration: none;
    text-transform: uppercase;
}

.docs-nav__heading:hover {
    color: var(--foreground);
}

.docs-nav__chapters,
.docs-nav__articles {
    display: grid;
    gap: 0.1rem;
    list-style: none;
}

.docs-nav__articles {
    margin: 0.15rem 0 0.5rem 0.75rem;
    padding-left: 0.75rem;
    border-left: 1px solid var(--border);
}

.docs-nav__link {
    display: block;
    padding: 0.4rem 0.65rem;
    border-radius: var(--radius-sm);
    color: var(--muted);
    line-height: 1.35;
    text-decoration: none;
    transition: background-color var(--t-hover) ease, color var(--t-hover) ease;
}

.docs-nav__link:hover {
    background-color: color-mix(in oklab, var(--foreground) 5%, transparent);
    color: var(--foreground);
}

.docs-nav__link[aria-current] {
    background-color: var(--primary-tint);
    color: var(--primary-text);
    font-weight: 600;
}

.docs-nav__chapter--open > .docs-nav__link:not([aria-current]) {
    color: var(--foreground);
    font-weight: 500;
}

.docs-main {
    min-width: 0;
}

.docs-toc {
    font-size: 0.875rem;
}

.docs-toc__heading {
    margin-bottom: 0.85rem;
    color: var(--muted);
    font-family: var(--font-mono);
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.docs-toc__list {
    display: grid;
    gap: 0.1rem;
    border-left: 1px solid var(--border);
    list-style: none;
}

.docs-toc__list a {
    display: block;
    margin-left: -1px;
    padding: 0.3rem 0 0.3rem 0.9rem;
    border-left: 2px solid transparent;
    color: var(--muted);
    line-height: 1.4;
    text-decoration: none;
    transition: color var(--t-hover) ease, border-color var(--t-hover) ease;
}

.docs-toc__list a:hover {
    color: var(--foreground);
}

.docs-toc__list a[aria-current] {
    border-left-color: var(--blue);
    color: var(--foreground);
    font-weight: 500;
}

/* On screens without the third column, the page's contents sits above the body as a
   compact card. */
.docs-toc--inline {
    margin-bottom: 2.5rem;
    padding: 1.25rem 1.35rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background-color: var(--card);
}

.docs-toc--inline .docs-toc__list {
    border-left: 0;
}

.docs-toc--inline .docs-toc__list a {
    padding-left: 0;
    border-left: 0;
}

@media (min-width: 80rem) {
    .docs-toc--inline {
        display: none;
    }
}

.docs-toc--side {
    display: none;
}

@media (min-width: 80rem) {
    .docs-toc--side {
        display: block;
    }
}

.docs-body h2 {
    scroll-margin-top: calc(var(--header-height) + 1.5rem);
}

.docs-children {
    margin-top: 3.5rem;
}

.docs-children__heading {
    margin-bottom: 1rem;
    font-size: 1.25rem;
}

.docs-children__list {
    display: grid;
    gap: 0.6rem;
    list-style: none;
}

@media (min-width: 40rem) {
    .docs-children__list {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

.docs-children__item {
    display: grid;
    gap: 0.3rem;
    height: 100%;
    padding: 1.1rem 1.25rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background-color: var(--card);
    color: inherit;
    text-decoration: none;
    transition: border-color var(--t-hover) ease, box-shadow var(--t-hover) ease;
}

.docs-children__item:hover {
    border-color: color-mix(in oklab, var(--primary) 40%, var(--border));
    box-shadow: var(--shadow-card);
}

.docs-children__title {
    display: flex;
    gap: 0.55rem;
    align-items: center;
    font-weight: 600;
}

.docs-children__icon {
    color: var(--blue-text);
    font-size: 0.85rem;
}

.docs-children__summary {
    color: var(--muted);
    font-size: 0.9rem;
}

.docs-pager {
    display: grid;
    gap: 0.75rem;
    margin-top: 4rem;
    padding-top: 2rem;
    border-top: 1px solid var(--border);
}

@media (min-width: 40rem) {
    .docs-pager {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

.docs-pager__link {
    display: grid;
    gap: 0.3rem;
    padding: 1.1rem 1.25rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background-color: var(--card);
    color: inherit;
    text-decoration: none;
    transition: border-color var(--t-hover) ease, box-shadow var(--t-hover) ease;
}

.docs-pager__link:hover {
    border-color: color-mix(in oklab, var(--primary) 40%, var(--border));
    box-shadow: var(--shadow-card);
}

.docs-pager__link--next {
    text-align: right;
}

.docs-pager__label {
    color: var(--muted);
    font-family: var(--font-mono);
    font-size: 0.75rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.docs-pager__label i {
    font-size: 0.7rem;
}

.docs-pager__title {
    font-family: var(--font-display);
    font-size: 1.1rem;
    font-weight: 650;
}

/* ---------------------------------------------------------------------------
   Thanks, after paying
--------------------------------------------------------------------------- */

.thanks__address {
    margin-block: 1.5rem;
    padding: 1rem 1.25rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background-color: var(--sunk);
}

.thanks__address-label {
    color: var(--muted);
    font-family: var(--font-mono);
    font-size: 0.75rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.thanks__address-value {
    margin-top: 0.25rem;
    font-family: var(--font-mono);
    font-size: 1.0625rem;
    font-weight: 600;
    word-break: break-all;
}

.thanks__body > * + * {
    margin-top: 1rem;
}

.thanks__body .button {
    margin-top: 1.5rem;
}

/* ---------------------------------------------------------------------------
   The deployment status page

   The colour of the whole page follows the state: grey while waiting, blue while
   building, green when done, amber when stopped. --deploy-accent carries it into the
   badge and the light behind the scene.
--------------------------------------------------------------------------- */

.deploy {
    --deploy-accent: var(--faint);
    --deploy-progress: 0;
    padding-block: clamp(2.5rem, 1.5rem + 4vw, 5.5rem) clamp(5rem, 4rem + 4vw, 8rem);
}

.deploy[data-state="running"] {
    --deploy-accent: var(--blue);
}

.deploy[data-state="ready"] {
    --deploy-accent: var(--primary);
}

.deploy[data-state="failed"] {
    --deploy-accent: var(--amber);
}

.deploy__grid {
    display: grid;
    gap: 2.5rem;
    align-items: start;
}

@media (min-width: 64rem) {
    .deploy__grid {
        grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
        gap: 4rem;
    }

    .deploy__intro {
        position: sticky;
        top: calc(var(--header-height) + 3rem);
        padding-top: 2rem;
    }
}

.deploy__title {
    font-family: var(--font-display);
    font-size: clamp(2.2rem, 1.5rem + 2.8vw, 3.75rem);
    font-weight: 700;
    letter-spacing: -0.035em;
    line-height: 1.02;
}

.deploy__lead {
    margin-top: 1.25rem;
}

.deploy__note {
    max-width: 52ch;
    margin-top: 2rem;
    padding-top: 1.5rem;
    border-top: 1px solid var(--border);
    color: var(--muted);
    font-size: 0.9375rem;
}

.deploy__note > * + * {
    margin-top: 0.75rem;
}

.deploy__note a {
    color: var(--primary-text);
}

.deploy__noscript {
    margin-top: 1.5rem;
    color: var(--muted);
    font-size: 0.9rem;
}

.deploy-card {
    padding: clamp(1.25rem, 1rem + 1.5vw, 2rem);
}

.deploy-card__head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    margin-bottom: 0.85rem;
}

.deploy-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.35rem 0.8rem 0.35rem 0.65rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    background-color: var(--sunk);
    font-size: 0.82rem;
    font-weight: 600;
}

.deploy-badge__dot {
    width: 0.55rem;
    height: 0.55rem;
    border-radius: 50%;
    background-color: var(--deploy-accent);
    box-shadow: 0 0 0 4px color-mix(in oklab, var(--deploy-accent) 20%, transparent);
}

.deploy[data-state="running"] .deploy-badge__dot,
.deploy[data-state="queued"] .deploy-badge__dot,
.deploy[data-state="pending"] .deploy-badge__dot {
    animation: blink 1.4s ease-in-out infinite;
}

@keyframes blink {
    50% {
        opacity: 0.35;
    }
}

/* A ring leaving the marker, once a beat: something is happening here. */
@keyframes step-ping {
    70%,
    100% {
        box-shadow: 0 0 0 8px color-mix(in oklab, var(--blue) 0%, transparent);
    }
}

.deploy-card__count {
    display: flex;
    gap: 0.65rem;
    align-items: baseline;
    color: var(--muted);
    font-size: 0.875rem;
}

.deploy-card__count strong {
    color: var(--foreground);
    font-family: var(--font-mono);
    font-size: 0.95rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.deploy-bar {
    height: 0.65rem;
    overflow: hidden;
    border-radius: 999px;
    background-color: var(--sunk);
    box-shadow: inset 0 0 0 1px var(--border);
}

.deploy-bar__fill {
    position: relative;
    width: calc(var(--deploy-progress) * 1%);
    height: 100%;
    overflow: hidden;
    border-radius: inherit;
    background-image: linear-gradient(90deg, var(--primary), var(--blue));
    transition: width 600ms var(--ease-out);
}

.deploy[data-state="failed"] .deploy-bar__fill {
    background-image: none;
    background-color: var(--amber);
}

.deploy-bar__shine {
    position: absolute;
    inset: 0;
    background-image: linear-gradient(100deg, transparent 15%, oklch(1 0 0 / 0.45) 48%, transparent 82%);
    transform: translateX(-120%);
}

.deploy[data-state="running"] .deploy-bar__shine {
    animation: bar-shine 2.2s ease-in-out infinite;
}

.deploy[data-state="queued"] .deploy-bar__fill,
.deploy[data-state="pending"] .deploy-bar__fill {
    width: 38%;
    background-image: linear-gradient(90deg, transparent, color-mix(in oklab, var(--foreground) 22%, transparent), transparent);
    animation: bar-waiting 1.8s ease-in-out infinite;
}

@keyframes bar-shine {
    55%,
    100% {
        transform: translateX(120%);
    }
}

@keyframes bar-waiting {
    from {
        transform: translateX(-115%);
    }

    to {
        transform: translateX(300%);
    }
}

.deploy-card__steps-title {
    margin-top: 1.75rem;
    margin-bottom: 0.75rem;
    color: var(--muted);
    font-family: var(--font-mono);
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.deploy-steps {
    display: grid;
    gap: 0 1.5rem;
    list-style: none;
}

@media (min-width: 36rem) {
    .deploy-steps {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

.deploy-step {
    display: flex;
    gap: 0.8rem;
    align-items: flex-start;
    min-width: 0;
    padding: 0.75rem 0;
    border-top: 1px solid var(--border);
    transition: opacity 300ms ease;
}

.deploy-step[data-step-state="waiting"] {
    opacity: 0.55;
}

.deploy-step__marker {
    position: relative;
    display: inline-grid;
    place-items: center;
    flex: none;
    width: 2.1rem;
    height: 2.1rem;
    border: 1px solid var(--border);
    border-radius: 0.6rem;
    background-color: var(--sunk);
    color: var(--muted);
    font-size: 0.8rem;
    transition: background-color 300ms ease, color 300ms ease, border-color 300ms ease;
}

.deploy-step__dot {
    width: 0.45rem;
    height: 0.45rem;
    border-radius: 50%;
    background-color: currentColor;
}

.deploy-step[data-step-state="done"] .deploy-step__marker {
    border-color: transparent;
    background-color: var(--primary);
    color: var(--primary-foreground);
    animation: build-pop 420ms cubic-bezier(0.34, 1.56, 0.64, 1) both;
}

/* A done step trades its icon for a tick. */
.deploy-step[data-step-state="done"] .deploy-step__marker > * {
    visibility: hidden;
}

.deploy-step[data-step-state="done"] .deploy-step__marker::after {
    content: "";
    position: absolute;
    width: 0.8rem;
    height: 0.8rem;
    background-color: currentColor;
    clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
}

.deploy-step[data-step-state="active"] .deploy-step__marker {
    border-color: color-mix(in oklab, var(--blue) 55%, transparent);
    background-color: var(--blue-tint);
    color: var(--blue-text);
    box-shadow: 0 0 0 0 color-mix(in oklab, var(--blue) 40%, transparent);
    animation: step-ping 1.6s ease-out infinite;
}

.deploy-step[data-step-state="active"] .deploy-step__title {
    color: var(--blue-text);
}

.deploy-step[data-step-state="stopped"] .deploy-step__marker {
    border-color: color-mix(in oklab, var(--amber) 50%, transparent);
    background-color: var(--amber-tint);
    color: var(--amber-text);
}

.deploy-step__body {
    display: grid;
    gap: 0.1rem;
    min-width: 0;
}

.deploy-step__title {
    font-size: 0.9375rem;
    font-weight: 600;
    line-height: 1.35;
}

.deploy-step__description {
    color: var(--muted);
    font-size: 0.85rem;
    line-height: 1.45;
}

.deploy-card__address {
    display: grid;
    gap: 0.2rem;
    margin-top: 1.5rem;
    padding: 1rem 1.15rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background-color: var(--sunk);
}

.deploy-card__address-label {
    color: var(--muted);
    font-family: var(--font-mono);
    font-size: 0.72rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.deploy-card__address-value {
    font-family: var(--font-mono);
    font-size: 1rem;
    font-weight: 600;
    word-break: break-all;
}

/* Rendered in every state and uncovered in the one where it works. A button drawn in
   by a script is a button that is missing when the script fails. */
.deploy-card__actions {
    display: grid;
    gap: 0.6rem;
    margin-top: 1.5rem;
}

.deploy-card__cta,
.deploy-card__login {
    display: none;
}

.deploy[data-state="ready"] .deploy-card__cta,
.deploy[data-state="unknown"] .deploy-card__login {
    display: inline-flex;
}

.deploy[data-state="unknown"] .deploy-card__progress,
.deploy[data-state="unknown"] .deploy-card__address {
    display: none;
}

.deploy[data-state="unknown"] .deploy-card__actions {
    margin-top: 0;
}

/* The scene: the customer's Better Pricing putting itself together, one part per
   step. See Includes/DeployScene.ss. */
.deploy-scene {
    margin: -0.25rem -0.25rem 1.25rem;
    padding: clamp(0.9rem, 0.6rem + 1.2vw, 1.5rem);
    overflow: hidden;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background:
        radial-gradient(70% 90% at 30% 100%, color-mix(in oklab, var(--deploy-accent) 14%, transparent), transparent 70%),
        radial-gradient(50% 70% at 90% 0%, color-mix(in oklab, var(--blue) 10%, transparent), transparent 70%),
        var(--sunk);
}

.build {
    --cell: 0.62rem;
    position: relative;
    font-family: var(--font-mono);
}

.build__window {
    position: relative;
    overflow: hidden;
    border: 1px dashed var(--border-strong);
    border-radius: 0.6rem;
    background-color: color-mix(in oklab, var(--card) 40%, transparent);
    transition: border-color 600ms ease, background-color 600ms ease, box-shadow 600ms ease, transform 600ms var(--ease-out);
}

.build__bar {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.5rem 0.75rem;
    border-bottom: 1px solid var(--border);
    background-color: var(--elevated);
}

.build__dots {
    display: inline-flex;
    gap: 0.3rem;
}

.build__dots span {
    width: 0.45rem;
    height: 0.45rem;
    border-radius: 50%;
    background-color: var(--border-strong);
    opacity: 0.6;
}

.build__address {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    flex: 0 1 17rem;
    min-width: 0;
    margin-inline: auto;
    padding: 0.2rem 0.65rem;
    overflow: hidden;
    border-radius: 999px;
    background-color: var(--sunk);
    color: var(--muted);
    font-size: var(--cell);
}

.build__lock {
    flex: none;
    color: var(--faint);
    font-size: 0.85em;
    transition: color 400ms ease, transform 400ms var(--ease-out);
}

.build__domain {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.build__domain--blank {
    flex: 1;
    height: 0.5em;
    border-radius: 999px;
    background-color: var(--border);
}

.build__app {
    display: grid;
    grid-template-columns: 4.25rem minmax(0, 1fr);
    min-height: 9.5rem;
}

.build__nav {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
    padding: 0.7rem 0.6rem;
    overflow: hidden;
    border-right: 1px solid var(--border);
    background-color: color-mix(in oklab, var(--sunk) 70%, transparent);
}

.build__brand {
    display: grid;
    place-items: center;
    width: 1.5rem;
    height: 1.5rem;
    margin-bottom: 0.2rem;
    border: 1px solid var(--border);
    border-radius: 0.4rem;
    background-color: var(--card);
}

.build__brand img {
    width: 0.9rem;
    height: 0.9rem;
}

.build__nav-line {
    height: 0.35rem;
    border-radius: 999px;
    background-color: var(--border);
}

.build__nav-line--on {
    background-color: var(--primary);
    opacity: 0.75;
}

.build__nav-line--short {
    width: 60%;
}

.build__main {
    display: grid;
    align-content: start;
    gap: 0.7rem;
    min-width: 0;
    padding: 0.7rem 0.8rem 0.8rem;
}

.build__head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.build__title {
    width: 38%;
    height: 0.5rem;
    border-radius: 999px;
    background-color: color-mix(in oklab, var(--foreground) 22%, transparent);
}

.build__action {
    width: 2.2rem;
    height: 0.9rem;
    margin-left: auto;
    border-radius: 0.2rem;
    background-color: var(--primary);
    opacity: 0.8;
}

.build__avatar {
    position: relative;
    display: inline-grid;
    place-items: center;
    width: 1.35rem;
    height: 1.35rem;
    overflow: hidden;
    border-radius: 50%;
    background-color: var(--border);
    color: var(--card);
    font-size: 0.55rem;
    transition: background-color 400ms ease, color 400ms ease;
}

.build__table {
    position: relative;
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 0.25rem;
    overflow: hidden;
    border-radius: 0.3rem;
}

.build__cell {
    display: grid;
    place-items: center;
    min-width: 0;
    height: 1.35rem;
    overflow: hidden;
    border: 1px solid color-mix(in oklab, var(--primary) 40%, transparent);
    border-radius: 0.2rem;
    background-color: var(--card);
    color: var(--foreground);
    font-size: var(--cell);
    font-variant-numeric: tabular-nums;
}

.build__cell--size {
    border-color: transparent;
    background-color: var(--blue-tint);
    color: var(--blue-text);
}

.build__cell--corner {
    border-color: transparent;
    background: none;
}

/* Ready and stopped, pinned to the window's corner. */
.build__badge {
    position: absolute;
    top: -0.55rem;
    right: -0.55rem;
    display: grid;
    place-items: center;
    width: 2.1rem;
    height: 2.1rem;
    border: 3px solid var(--sunk);
    border-radius: 50%;
    font-size: 0.8rem;
    opacity: 0;
    transform: scale(0.4);
}

.build__badge--ready {
    background-color: var(--primary);
    color: var(--primary-foreground);
}

.build__badge--stopped {
    background-color: var(--amber);
    color: oklch(0.25 0.05 70);
}

/* Layers. Every part of the window starts as a ghost of itself. */
.build__nav,
.build__address,
.build__table,
.build__avatar {
    opacity: 0.32;
    filter: saturate(0);
    transition: opacity 600ms ease, filter 600ms ease, box-shadow 400ms ease;
}

/* Being worked on: present, in blue, with light passing over it. */
.deploy:has([data-step="composer"][data-step-state="active"]) .build__nav,
.deploy:has([data-step="env"][data-step-state="active"]) .build__address,
.deploy:has([data-step="build"][data-step-state="active"]) .build__table,
.deploy:has([data-step="user"][data-step-state="active"]) .build__avatar {
    opacity: 1;
    filter: none;
    box-shadow: 0 0 0 1px var(--blue), 0 0 0 4px color-mix(in oklab, var(--blue) 18%, transparent);
}

.deploy:has([data-step="composer"][data-step-state="active"]) .build__nav::after,
.deploy:has([data-step="env"][data-step-state="active"]) .build__address::after,
.deploy:has([data-step="build"][data-step-state="active"]) .build__table::after,
.deploy:has([data-step="user"][data-step-state="active"]) .build__avatar::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(100deg, transparent 20%, color-mix(in oklab, var(--blue) 30%, transparent) 50%, transparent 80%);
    transform: translateX(-100%);
    animation: build-shimmer 1.4s ease-in-out infinite;
}

.deploy:has([data-step="build"][data-step-state="active"]) .build__cell:not(.build__cell--size, .build__cell--corner) {
    color: transparent;
}

/* Done: settled, in colour. */
.deploy:has([data-step="composer"][data-step-state="done"]) .build__nav,
.deploy:has([data-step="env"][data-step-state="done"]) .build__address,
.deploy:has([data-step="build"][data-step-state="done"]) .build__table,
.deploy:has([data-step="user"][data-step-state="done"]) .build__avatar,
.deploy[data-state="ready"] .build__nav,
.deploy[data-state="ready"] .build__address,
.deploy[data-state="ready"] .build__table,
.deploy[data-state="ready"] .build__avatar,
.deploy[data-state="unknown"] .build__nav,
.deploy[data-state="unknown"] .build__address,
.deploy[data-state="unknown"] .build__table,
.deploy[data-state="unknown"] .build__avatar {
    opacity: 1;
    filter: none;
}

/* The prices arrive cell by cell as the database step finishes. */
.deploy:has([data-step="build"][data-step-state="done"]) .build__cell,
.deploy[data-state="ready"] .build__cell {
    animation: build-cell 420ms var(--ease-out) both;
    animation-delay: calc(var(--i, 0) * 55ms);
}

.deploy:has([data-step="user"][data-step-state="done"]) .build__avatar,
.deploy[data-state="ready"] .build__avatar {
    background-color: var(--primary);
    color: var(--primary-foreground);
    animation: build-pop 500ms cubic-bezier(0.34, 1.56, 0.64, 1) both;
}

/* The window itself is the clone: drawn in dashes until there is a copy to stand in. */
.deploy:has([data-step="clone"][data-step-state="active"]) .build__window {
    border-color: var(--blue);
    animation: build-breathe 1.6s ease-in-out infinite;
}

.deploy:has([data-step="clone"][data-step-state="done"]) .build__window,
.deploy[data-state="ready"] .build__window,
.deploy[data-state="unknown"] .build__window {
    border-style: solid;
    border-color: var(--border);
    background-color: var(--card);
    box-shadow: var(--shadow-card);
}

/* The certificate: the lock turns green, the way a browser's does. */
.deploy:has([data-step="ssl"][data-step-state="active"]) .build__lock {
    color: var(--blue);
    animation: build-blink 1s ease-in-out infinite;
}

.deploy:has([data-step="ssl"][data-step-state="done"]) .build__lock,
.deploy[data-state="ready"] .build__lock {
    color: var(--primary-text);
    animation: build-pop 500ms cubic-bezier(0.34, 1.56, 0.64, 1) both;
}

/* Stopped: the part that stopped goes amber, and so does the corner. */
.deploy:has([data-step="clone"][data-step-state="stopped"]) .build__window,
.deploy:has([data-step="composer"][data-step-state="stopped"]) .build__nav,
.deploy:has([data-step="env"][data-step-state="stopped"]) .build__address,
.deploy:has([data-step="build"][data-step-state="stopped"]) .build__table,
.deploy:has([data-step="ssl"][data-step-state="stopped"]) .build__address,
.deploy:has([data-step="user"][data-step-state="stopped"]) .build__avatar {
    opacity: 1;
    filter: none;
    box-shadow: 0 0 0 1px var(--amber), 0 0 0 4px color-mix(in oklab, var(--amber) 20%, transparent);
}

.deploy[data-state="failed"] .build__badge--stopped {
    opacity: 1;
    transform: none;
    transition: opacity 300ms ease, transform 500ms cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* Ready: the window lifts and the corner gets its tick. */
.deploy[data-state="ready"] .build__window {
    transform: translateY(-2px);
    box-shadow: var(--shadow-card), 0 18px 40px -18px color-mix(in oklab, var(--primary) 55%, transparent);
}

.deploy[data-state="ready"] .build__badge--ready {
    animation: build-pop 600ms 500ms cubic-bezier(0.34, 1.56, 0.64, 1) both;
}

/* Waiting to start: the outline of a window, breathing. */
.deploy[data-state="queued"] .build__window,
.deploy[data-state="pending"] .build__window {
    animation: build-breathe 2.4s ease-in-out infinite;
}

/* Nothing to show yet but the way in: the finished picture, quietly. */
.deploy[data-state="unknown"] .build {
    opacity: 0.6;
}

@keyframes build-shimmer {
    to {
        transform: translateX(100%);
    }
}

@keyframes build-breathe {
    50% {
        opacity: 0.6;
    }
}

@keyframes build-blink {
    50% {
        opacity: 0.35;
    }
}

@keyframes build-cell {
    from {
        opacity: 0;
        transform: translateY(4px) scale(0.92);
    }
}

@keyframes build-pop {
    from {
        opacity: 0;
        transform: scale(0.4);
    }

    to {
        opacity: 1;
        transform: none;
    }
}

/* ---------------------------------------------------------------------------
   Reduced motion
--------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }

    /* Without the pop, the tick still has to arrive. */
    .deploy[data-state="ready"] .build__badge--ready {
        opacity: 1;
        transform: none;
    }

    .build [data-layer]::after {
        display: none;
    }

    .deploy[data-state="queued"] .deploy-bar__fill,
    .deploy[data-state="pending"] .deploy-bar__fill {
        width: 100%;
        transform: none;
        opacity: 0.35;
    }
}

/* ---------------------------------------------------------------------------
   Print
--------------------------------------------------------------------------- */

@media print {
    .site-header,
    .site-footer,
    .bloom,
    .docs-nav,
    .docs-toc,
    .docs-pager {
        display: none !important;
    }

    body {
        background: #fff;
        color: #000;
    }
}
