@font-face { font-family: "Inter"; font-style: normal; font-weight: 100 900; font-display: swap; src: url("/fonts/InterVariable.woff2") format("woff2"); }
@font-face { font-family: "Inter"; font-style: italic; font-weight: 100 900; font-display: swap; src: url("/fonts/InterVariable-Italic.woff2") format("woff2"); }
@font-face { font-family: "JetBrains Mono"; font-style: normal; font-weight: 400 700; font-display: swap; src: url("/fonts/jetbrains-mono-latin.woff2") format("woff2"); }
@font-face { font-family: "JetBrains Mono"; font-style: normal; font-weight: 400 700; font-display: swap; src: url("/fonts/jetbrains-mono-latin-ext.woff2") format("woff2"); unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }

/* Three theming layers, and rules below may only reference the second one.
   1. RAMP    absolute palette values. --ink-1000 is the near-black in every theme.
   2. ROLES   what a colour is for. A theme redeclares this layer and nothing else.
   3. THEMES  :root (light) · [data-theme="dark"] · [data-theme="auto"] · forced colours.
   A raw ramp reference inside a component rule is a colour that cannot be themed. The values are the
   design system's tokens.json; this file declares the roles its rules use, under the design system's names. */
:root {
    --font-sans: "Inter", system-ui, -apple-system, sans-serif; --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, monospace;

    /* Layer 1 · ramp */
    --blue-100: #e2eaf6; --blue-400: #5f88c4; --blue-500: #2959aa; --blue-600: #204a90; --blue-700: #0f4b6e;
    --ink-1000: #1a1b26; --ink-750: #363c4d; --ink-650: #4a5272; --ink-600: #565a6e; --ink-590: #575d79; --ink-580: #5a607b; --ink-570: #5e647e; --ink-400: #979db8;
    --line-strong: #c1c2c7; --line-600: #c7c9d3; --line-450: #d2d4dd; --line-400: #d6d8df; --line-300: #dcdee3; --line-250: #e0e2e8; --line-200: #e1e2e8; --line-150: #e4e5eb; --line-100: #e6e7ed; --line-75: #eaebf0;
    --white: #ffffff; --grey-50: #f7f8fb; --grey-100: #f2f3f7; --grey-150: #eceef3; --grey-200: #e1e2e8; --grey-300: #d6d8df;
    --green-100: #e0ead2; --green-500: #4f7c17; --green-700: #385f0d;
    --amber-100: #f4e7cd; --amber-500: #a87016; --amber-600: #96631a; --amber-700: #8f5e15; --amber-750: #875812;
    --red-50: #faf1f1; --red-100: #f0dada; --red-200: #e3c9c9; --red-500: #a83838; --red-600: #942f2f;

    /* Layer 2 · roles (light) */
    --text-strong: var(--ink-1000); --text-body: var(--ink-750); --text-secondary: var(--ink-650); --text-detail: var(--ink-600);
    --text-label: var(--ink-590); --text-muted: var(--ink-580); --text-faint: var(--ink-570); --text-separator: var(--line-600);
    --text-link: var(--blue-500); --text-link-hover: var(--blue-700); --text-eyebrow: var(--ink-580); --text-on-accent: var(--white); --text-on-inverse: var(--white); --text-on-active: var(--blue-500); --text-invalid: var(--amber-750);
    --surface-page: var(--grey-300); --surface-app: var(--line-100); --surface-card: var(--white); --surface-rail: var(--grey-100); --surface-subtle: var(--grey-50); --surface-panel: var(--line-75);
    --surface-hover: var(--grey-200); --surface-active: var(--blue-100); --surface-inverse: var(--ink-1000); --surface-strong: var(--line-400);
    --surface-control: var(--white); --surface-control-disabled: var(--grey-150); --surface-track: var(--grey-200); --surface-danger-subtle: var(--red-50);
    --border-card: var(--line-150); --border-frame: var(--line-400); --border-divider: var(--line-100); --border-divider-strong: var(--line-300); --border-row: var(--line-75); --border-rail: var(--line-200); --border-control: var(--line-250);
    --border-control-hover: var(--line-strong); --border-control-strong: var(--line-strong); --border-dashed: var(--line-450); --border-emphasis: var(--ink-1000); --border-danger: var(--red-200); --border-invalid: var(--amber-500);
    --accent: var(--blue-500); --accent-hover: var(--blue-600); --accent-quiet: var(--blue-100); --accent-rule: var(--blue-400);
    --focus-ring: var(--blue-400); --focus-halo: var(--blue-100);
    --status-ok-bg: var(--green-100); --status-ok-fg: var(--green-700);
    --status-warn-bg: var(--amber-100); --status-warn-fg: var(--amber-700);
    --status-danger-bg: var(--red-100); --status-danger-fg: var(--red-600); --status-danger-strong: var(--red-500);
    --status-neutral-bg: var(--line-75); --status-neutral-fg: var(--ink-650);
    --dot-ok: var(--green-500); --dot-warn: var(--amber-500); --dot-danger: var(--red-500); --dot-idle: var(--line-strong);
    --chart-1: var(--ink-1000); --chart-2: var(--ink-600); --chart-3: var(--ink-400); --chart-4: var(--line-strong); --chart-track: var(--grey-200);
    --shadow-frame: 0 1px 3px rgba(18,18,26,.06), 0 12px 32px -18px rgba(18,18,26,.18);
    --shadow-popover: 0 2px 6px rgba(18,18,26,.06), 0 14px 34px -16px rgba(18,18,26,.22);
    --shadow-modal: 0 8px 20px rgba(18,18,26,.10), 0 40px 80px -32px rgba(18,18,26,.32);
    --shadow-knob: 0 1px 2px rgba(18,18,26,.2);
    --scrim: rgba(18,18,26,.34);

    --radius-xs: 3px; --radius-badge: 4px; --radius-control: 6px; --radius-input: 7px; --radius-card: 9px; --radius-frame: 12px; --radius-pill: 999px;
    --duration-instant: 90ms; --duration-fast: 120ms; --duration-normal: 180ms; --ease-standard: cubic-bezier(.2,0,.2,1); --ease-out: cubic-bezier(0,0,.2,1); --transition-control: background-color var(--duration-fast) var(--ease-standard), border-color var(--duration-fast) var(--ease-standard), color var(--duration-fast) var(--ease-standard);
}

/* Type: the design system's half-point scale and weights, which every text style below names rather than a literal
   (README "Type in an application"). The wordmark's sizes and an Avatar's initials are the one exception: they are
   the logo's and the component's own metrics, not steps of the type scale.
   Control heights: one height per size, which every control of that size draws to, so a field and the button that
   acts on it line up when they share a line (README "Control heights"). */
:root {
    --text-2xs: 9.5px; --text-xs: 10.5px; --text-sm: 11px; --text-base: 11.5px; --text-md: 12px; --text-lg: 12.5px;
    --text-xl: 13px; --text-2xl: 14px; --text-3xl: 16px; --text-4xl: 17px; --text-5xl: 19px; --text-6xl: 26px;
    --weight-regular: 450; --weight-medium: 500; --weight-book: 550; --weight-semibold: 600; --weight-strong: 650; --weight-bold: 700;
    --tracking-tight: -.01em; --tracking-mono: .03em; --tracking-label: .08em;
    --control-height-sm: 28px; --control-height-md: 32px; --control-height-lg: 40px;
}

/* Layer 3 · dark. Only the role layer is redeclared. Wrapped in @media screen so a dark surface still
   prints as ink on paper, which the design system's print.css reaches by restoring the light roles. */
@media screen {
    [data-theme="dark"] {
        --text-strong: #c0caf5; --text-body: #a9b1d6; --text-secondary: #9ba3c6; --text-detail: #99a1cb;
        --text-label: #949cc5; --text-muted: #8f98c1; --text-faint: #8c94bc; --text-separator: #414868;
        --text-link: #7aa2f7; --text-link-hover: #9ab8ff; --text-eyebrow: #8f98c1; --text-on-accent: #16161e; --text-on-inverse: #16161e; --text-on-active: #c0caf5; --text-invalid: #e0af68;
        --surface-page: #16161e; --surface-app: #1a1b26; --surface-card: #1f2335; --surface-rail: #16161e; --surface-subtle: #24283b; --surface-panel: #24283b;
        --surface-hover: #292e42; --surface-active: #283457; --surface-inverse: #c0caf5; --surface-strong: #414868;
        --surface-control: #1f2335; --surface-control-disabled: #22263a; --surface-track: #292e42; --surface-danger-subtle: #2b1f28;
        --border-card: #2b3049; --border-frame: #292e42; --border-divider: #24283b; --border-divider-strong: #2f334d; --border-row: #232739; --border-rail: #24283b; --border-control: #343a54;
        --border-control-hover: #414868; --border-control-strong: #414868; --border-dashed: #3b4261; --border-emphasis: #c0caf5; --border-danger: #5c3140; --border-invalid: #e0af68;
        --accent: #7aa2f7; --accent-hover: #9ab8ff; --accent-quiet: #283457; --accent-rule: #3d59a1;
        --focus-ring: #7aa2f7; --focus-halo: rgba(122,162,247,.28);
        --status-ok-bg: #22301f; --status-ok-fg: #9ece6a;
        --status-warn-bg: #322a1c; --status-warn-fg: #e0af68;
        --status-danger-bg: #331f26; --status-danger-fg: #f7768e; --status-danger-strong: #f7768e;
        --status-neutral-bg: #292e42; --status-neutral-fg: #a9b1d6;
        --dot-ok: #9ece6a; --dot-warn: #e0af68; --dot-danger: #f7768e; --dot-idle: #414868;
        --chart-1: #c0caf5; --chart-2: #8e97bd; --chart-3: #565f89; --chart-4: #3b4261; --chart-track: #292e42;
        --shadow-frame: 0 1px 3px rgba(0,0,0,.40), 0 12px 32px -18px rgba(0,0,0,.70);
        --shadow-popover: 0 2px 6px rgba(0,0,0,.40), 0 14px 34px -16px rgba(0,0,0,.75);
        --shadow-modal: 0 8px 20px rgba(0,0,0,.45), 0 40px 80px -32px rgba(0,0,0,.80);
        --shadow-knob: 0 1px 2px rgba(0,0,0,.5);
        --scrim: rgba(0,0,0,.58);
    }

    /* The OS preference is opt-in: "dark" is absolute, "auto" defers. */
    [data-theme="auto"] { color-scheme: light dark; }
    @media (prefers-color-scheme: dark) {
        [data-theme="auto"] {
            --text-strong: #c0caf5; --text-body: #a9b1d6; --text-secondary: #9ba3c6; --text-detail: #99a1cb;
            --text-label: #949cc5; --text-muted: #8f98c1; --text-faint: #8c94bc; --text-separator: #414868;
            --text-link: #7aa2f7; --text-link-hover: #9ab8ff; --text-eyebrow: #8f98c1; --text-on-accent: #16161e; --text-on-inverse: #16161e; --text-on-active: #c0caf5; --text-invalid: #e0af68;
            --surface-page: #16161e; --surface-app: #1a1b26; --surface-card: #1f2335; --surface-rail: #16161e; --surface-subtle: #24283b; --surface-panel: #24283b;
            --surface-hover: #292e42; --surface-active: #283457; --surface-inverse: #c0caf5; --surface-strong: #414868;
            --surface-control: #1f2335; --surface-control-disabled: #22263a; --surface-track: #292e42; --surface-danger-subtle: #2b1f28;
            --border-card: #2b3049; --border-frame: #292e42; --border-divider: #24283b; --border-divider-strong: #2f334d; --border-row: #232739; --border-rail: #24283b; --border-control: #343a54;
            --border-control-hover: #414868; --border-control-strong: #414868; --border-dashed: #3b4261; --border-emphasis: #c0caf5; --border-danger: #5c3140; --border-invalid: #e0af68;
            --accent: #7aa2f7; --accent-hover: #9ab8ff; --accent-quiet: #283457; --accent-rule: #3d59a1;
            --focus-ring: #7aa2f7; --focus-halo: rgba(122,162,247,.28);
            --status-ok-bg: #22301f; --status-ok-fg: #9ece6a;
            --status-warn-bg: #322a1c; --status-warn-fg: #e0af68;
            --status-danger-bg: #331f26; --status-danger-fg: #f7768e; --status-danger-strong: #f7768e;
            --status-neutral-bg: #292e42; --status-neutral-fg: #a9b1d6;
            --dot-ok: #9ece6a; --dot-warn: #e0af68; --dot-danger: #f7768e; --dot-idle: #414868;
            --chart-1: #c0caf5; --chart-2: #8e97bd; --chart-3: #565f89; --chart-4: #3b4261; --chart-track: #292e42;
            --shadow-frame: 0 1px 3px rgba(0,0,0,.40), 0 12px 32px -18px rgba(0,0,0,.70);
            --shadow-popover: 0 2px 6px rgba(0,0,0,.40), 0 14px 34px -16px rgba(0,0,0,.75);
            --shadow-modal: 0 8px 20px rgba(0,0,0,.45), 0 40px 80px -32px rgba(0,0,0,.80);
            --shadow-knob: 0 1px 2px rgba(0,0,0,.5);
            --scrim: rgba(0,0,0,.58);
        }
    }
}

/* Layer 3 · forced colours, as the design system's components/bundle.css maps them. The OS replaces colour
   wholesale; every border role keeps an edge, because the 2px emphasis border is how an irreversible action
   is marked, and the disabled control's dashed border takes GrayText, the system colour for unavailable. A
   subtree marked data-theme="light" is mapped as well as the page. */
@media (forced-colors: active) {
    :root, [data-theme="light"], [data-theme="dark"], [data-theme="auto"] {
        forced-color-adjust: none;
        --text-strong: CanvasText; --text-body: CanvasText; --text-secondary: CanvasText; --text-detail: CanvasText;
        --text-label: CanvasText; --text-muted: CanvasText; --text-faint: GrayText; --text-separator: CanvasText;
        --text-link: LinkText; --text-link-hover: LinkText; --text-eyebrow: CanvasText; --text-on-accent: HighlightText; --text-on-inverse: Canvas; --text-on-active: HighlightText; --text-invalid: CanvasText;
        --surface-page: Canvas; --surface-app: Canvas; --surface-card: Canvas; --surface-rail: Canvas; --surface-subtle: Canvas; --surface-panel: Canvas;
        --surface-hover: Canvas; --surface-active: Highlight; --surface-inverse: CanvasText; --surface-strong: Canvas;
        --surface-control: Field; --surface-control-disabled: Canvas; --surface-track: Canvas; --surface-danger-subtle: Canvas;
        --border-card: CanvasText; --border-frame: CanvasText; --border-divider: CanvasText; --border-divider-strong: CanvasText; --border-row: CanvasText; --border-rail: CanvasText; --border-control: CanvasText;
        --border-control-hover: Highlight; --border-control-strong: CanvasText; --border-dashed: GrayText; --border-emphasis: CanvasText; --border-danger: CanvasText; --border-invalid: CanvasText;
        --accent: Highlight; --accent-hover: Highlight; --accent-quiet: Canvas; --accent-rule: CanvasText;
        --focus-ring: Highlight; --focus-halo: transparent;
        --status-ok-bg: Canvas; --status-ok-fg: CanvasText;
        --status-warn-bg: Canvas; --status-warn-fg: CanvasText;
        --status-danger-bg: Canvas; --status-danger-fg: CanvasText; --status-danger-strong: CanvasText;
        --status-neutral-bg: Canvas; --status-neutral-fg: CanvasText;
        --dot-ok: CanvasText; --dot-warn: CanvasText; --dot-danger: CanvasText; --dot-idle: GrayText;
        --chart-1: CanvasText; --chart-2: CanvasText; --chart-3: CanvasText; --chart-4: CanvasText; --chart-track: Canvas;
        --shadow-frame: none; --shadow-popover: none; --shadow-modal: none; --shadow-knob: none; --scrim: Canvas;
    }
    /* A status badge loses its tint here, so it gets the edge that was doing the work; anything whose entire
       signal was a fill -- a checked box, the switch, a bar, a selected row -- keeps an outline. */
    [data-status] { border: 1px solid CanvasText !important; }
    [data-fill] { outline: 1px solid CanvasText; }
}


/* Base. This file is served as committed (ADR 0031), so it carries its own reset: each rule below replaces one the
   Tailwind preflight used to supply, for the elements these pages render. StylesheetResetTest keeps both halves true:
   a reset rule that goes missing fails it, and so does a page that renders an element the reset does not account for.
   The rest is the design system's base: the page desk, body type, links, the focus ring and the selection. */
*, *::before, *::after, ::backdrop, ::file-selector-button { box-sizing: border-box; margin: 0; padding: 0; border: 0 solid; }
html { -webkit-text-size-adjust: 100%; tab-size: 4; font-family: var(--font-sans); line-height: 1.5; }
body { margin: 0; background: var(--surface-page); color: var(--text-body); font-family: var(--font-sans); font-size: var(--text-base); font-weight: var(--weight-regular); line-height: 1.55; -webkit-font-smoothing: antialiased; }
h1, h2, h3, h4, h5, h6 { font-size: inherit; font-weight: inherit; }
ul, ol, menu { list-style: none; }
b, strong { font-weight: bolder; }
small { font-size: 80%; }
code, pre { font-family: var(--font-mono); font-size: 1em; }
table { text-indent: 0; border-color: inherit; border-collapse: collapse; }
th { font-weight: inherit; text-align: inherit; }
fieldset { min-width: 0; }
summary { display: list-item; }
img, svg, canvas { display: block; vertical-align: middle; }
img { max-width: 100%; height: auto; }
button, input, select, optgroup, textarea, ::file-selector-button { font: inherit; letter-spacing: inherit; color: inherit; opacity: 1; background-color: transparent; border-radius: 0; }
button, input[type="button"], input[type="reset"], input[type="submit"], ::file-selector-button { appearance: button; }
::placeholder { opacity: 1; color: color-mix(in oklab, currentcolor 50%, transparent); }
textarea { resize: vertical; }
::-webkit-date-and-time-value { min-height: 1lh; text-align: inherit; }
::-webkit-datetime-edit { display: inline-flex; }
::-webkit-datetime-edit-fields-wrapper { padding: 0; }
::-webkit-inner-spin-button, ::-webkit-outer-spin-button { height: auto; }
/* Mono means the string is exact, so it reads left to right and is isolated from the text around it in any direction. */
code, pre, .mono, .machine, .badge-mono, .state-badge, .pager-button, .report-count, .dialog-selection span { direction: ltr; unicode-bidi: isolate; }
.mono, .machine { font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: var(--tracking-mono); }
/* A link is underlined, not only coloured: the link blue is about 1.6:1 against body text, below the 3:1 WCAG 1.4.1
   asks for when colour alone marks a link in running text. 1px at rest, 2px on hover. Navigation chrome that draws its
   own treatment -- the lockups, rail rows, the breadcrumb, a link drawn as a button -- sets text-decoration: none. */
a { color: var(--text-link); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--text-link-hover); text-decoration-thickness: 2px; }
.brand-lockup, .signin-lockup, .rail-nav a, .breadcrumb a, a.button, a.menu-row, .skip-link { text-decoration: none; }
:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 1px; }
::selection { background: var(--accent-quiet); color: var(--text-strong); }
/* In forced colours that selection would be Canvas behind CanvasText, so it takes the system's pair. */
@media (forced-colors: active) {
    ::selection { background: Highlight; color: HighlightText; }
}
[hidden], .hidden { display: none !important; }
/* WCAG 2.4.1: the rail repeats on every route, so the keyboard can step past it. Out of sight until it is focused,
   and then the first thing on the page. */
.skip-link { position: absolute; inset-inline-start: 8px; top: -48px; z-index: 90; border-radius: var(--radius-input); background: var(--surface-card); padding: 8px 12px; color: var(--text-strong); font-size: var(--text-md); font-weight: var(--weight-semibold); box-shadow: var(--shadow-modal); }
.skip-link:focus { top: 8px; }
.app-main:focus { outline: none; }
/* Text only assistive technology reads: it names a view the visual design titles through its own layout. */
.visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
h1, h2, h3, p { margin-top: 0; }
/* The type roles of an application page (README "Type in an application"): the page title, type-title, 19/700/-0.025em;
   a card title, type-card-heading, 12.5/650, unless its component draws its own. Nothing sits between them. */
h1 { margin-bottom: 5px; color: var(--text-strong); font-size: var(--text-5xl); line-height: 1.2; letter-spacing: -.025em; font-weight: var(--weight-bold); }
h2, h3 { margin-bottom: 4px; color: var(--text-strong); font-size: var(--text-lg); line-height: 1.35; font-weight: var(--weight-strong); }
h3 { margin-bottom: 8px; }

/* The in-app lockup: the wordmark, a hairline rule, then the product name in Inter at regular weight. */
.brand-lockup { display: inline-flex; align-items: center; gap: 8px; color: var(--text-strong); }
.brand-lockup:hover { color: var(--text-strong); }
/* The wordmark's size is the logo's, 15px in the rail and 20px on the standalone screens, not a step of the type scale. */
.wordmark { color: var(--text-strong); font: var(--weight-bold) 15px/1 var(--font-mono); letter-spacing: 0; white-space: nowrap; }
.wordmark-accent { color: var(--text-link); }
.brand-divider { width: 1px; height: 13px; flex: none; background: var(--surface-strong); }
.product-name { color: var(--text-detail); font-size: var(--text-lg); font-weight: var(--weight-regular); letter-spacing: var(--tracking-tight); white-space: nowrap; }
/* The design system's Eyebrow at its default, sans 9.5px at 700, uppercase and tracked 0.08em, opening a section inside
   a card -- a secret's "Secret · shown once". A page title and a card title have none above them: the breadcrumb
   already says where the page is, and a kicker over a card's title would only repeat it. */
.eyebrow { margin-bottom: 5px; color: var(--text-eyebrow); font-family: var(--font-sans); font-size: var(--text-2xs); font-weight: var(--weight-bold); letter-spacing: var(--tracking-label); text-transform: uppercase; }
.supporting-copy { margin-bottom: 0; color: var(--text-secondary); font-size: var(--text-base); font-weight: var(--weight-regular); }
/* A page head's lede, under the title: 11.5px at 450 in --text-detail. */
.page-head p { max-width: 900px; margin-bottom: 0; color: var(--text-detail); font-size: var(--text-base); line-height: 1.55; text-wrap: pretty; }
/* The design system's Link: the link colour and its underline, from the base rule above. */
.text-link { display: inline-block; margin-top: 14px; font-size: var(--text-base); transition: var(--transition-control); }
.supporting-copy .text-link { display: inline; margin-top: 0; font-size: inherit; }
/* A link drawn as a button that only reads as one, such as Account help's "Back to sign in", is a button element. */
.link-button { border: 0; padding: 0; background: none; color: var(--text-link); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 2px; cursor: pointer; }
.link-button:hover { color: var(--text-link-hover); text-decoration-thickness: 2px; }

/* The design system's Button, secondary by default. Each size is one height, which every control of that size shares:
   md 32px at 11px/600, sm (.button-compact) 28px at 550, and lg (.button-large) 40px at 12px/650, the single action
   of a standalone screen. A field and the button beside it are the same size, so they line up. */
.button { display: inline-flex; align-items: center; justify-content: center; gap: 6px; height: var(--control-height-md); flex: none; border: 1px solid var(--border-control); border-radius: var(--radius-control); padding: 0 12px; background: var(--surface-control); color: var(--text-body); font-family: var(--font-sans); font-size: var(--text-sm); font-weight: var(--weight-semibold); letter-spacing: var(--tracking-tight); line-height: 1; white-space: nowrap; cursor: pointer; transition: var(--transition-control); }
.button-primary { border-color: var(--accent); background: var(--accent); color: var(--text-on-accent); }
.button-inverse { border-color: var(--border-emphasis); background: var(--surface-inverse); color: var(--text-on-inverse); }
.button-danger { border-color: var(--border-danger); color: var(--status-danger-fg); }
/* Hover is one step, and a disabled or pending button does not react: a secondary button takes the subtle tint
   and one border step, a danger one the tint alone, a primary one darkens to the accent hover, and an inverse
   one keeps its fill. There is no press state and nothing scales. */
.button:not(:disabled):not([aria-busy="true"]):hover { border-color: var(--border-control-hover); background: var(--surface-subtle); }
.button-danger:not(:disabled):not([aria-busy="true"]):hover { border-color: var(--border-danger); }
.button-primary:not(:disabled):not([aria-busy="true"]):hover { border-color: var(--accent-hover); background: var(--accent-hover); }
.button-inverse:not(:disabled):not([aria-busy="true"]):hover { border-color: var(--border-emphasis); background: var(--surface-inverse); }
/* Unavailable is dashed, faint and explained; it says "you cannot do this, and here is why". */
.button:disabled { border-color: var(--border-dashed); border-style: dashed; background: var(--surface-control-disabled); color: var(--text-faint); cursor: default; }
/* A pending action keeps its colours, names its operation and draws a 2px indeterminate rule along its foot. It is
   not disabled: the dashed treatment is for unavailable, and this is under way. */
.button[aria-busy="true"], .workspace-trigger[aria-busy="true"] { position: relative; overflow: hidden; cursor: progress; }
.button[aria-busy="true"]::after, .workspace-trigger[aria-busy="true"]::after { content: ""; position: absolute; inset-inline: 0; inset-block-end: 0; height: 2px; background: currentColor; opacity: .55; transform-origin: center; animation: snaphop-pending 1.1s var(--ease-standard) infinite; }
.button-compact { height: var(--control-height-sm); padding: 0 10px; font-size: var(--text-sm); font-weight: var(--weight-book); }
.button-large { height: var(--control-height-lg); border-radius: var(--radius-input); padding: 0 16px; font-size: var(--text-md); font-weight: var(--weight-strong); }
.button-block { display: flex; width: 100%; }
.button-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.button-row > .form-status { flex-basis: 100%; margin: 0; }
.button-row-spaced { margin-top: 12px; }

/* The design system's Field: a label, the control, then its hint or, in its place, its error. A required control is
   marked by a muted asterisk after its label, kept on the label's last word by the no-break space it starts with; it
   is aria-hidden, and the control's required and aria-required are what a screen reader announces. Never the word
   "required". */
.field { display: grid; align-content: start; gap: 5px; min-width: 0; color: var(--text-label); font-size: var(--text-sm); font-weight: var(--weight-book); letter-spacing: var(--tracking-tight); }
.field > label, .field > legend { color: var(--text-label); font-size: var(--text-sm); font-weight: var(--weight-book); }
.field-required { color: var(--text-muted); font-weight: var(--weight-regular); white-space: nowrap; }
.field-hint, .field-help, .form-hint { color: var(--text-muted); font-size: var(--text-xs); font-weight: var(--weight-regular); line-height: 1.55; letter-spacing: 0; }
.field-error { color: var(--text-invalid); font-size: var(--text-xs); font-weight: var(--weight-regular); line-height: 1.55; letter-spacing: 0; }
/* An empty error and an empty status line take no room and stay in the accessibility tree, so each live region is in
   place before its text arrives and is announced with it (SnapHop Web's DESIGN.md section 4). Absolutely positioned it
   takes no grid row, gap or margin, and a 1px box with no padding, border or minimum height, clipped to nothing at its
   static position, neither shows nor overflows. */
:is(.field-error, .form-status, .signin-status, .signup-sent):empty {
    position: absolute; width: 1px; height: 1px; min-height: 0; margin: 0; border: 0; padding: 0; overflow: hidden;
    clip-path: inset(50%);
}
/* The error replaces the hint rather than stacking under it, as the design system's Field does. */
.field[data-invalid] .field-hint { display: none; }
.field-inline { display: flex; align-items: center; gap: 8px; }
/* Fields side by side share three rows -- label, control, hint -- through subgrid, so a label that wraps or a hint
   under one field never moves its neighbour's control, and an action in the row lines up with the controls rather
   than the labels. --field-row sets the columns, two equal ones by default. This is the design system's
   [data-field-row] rule as components/bundle.css writes it, with this application's .field in place of [data-field],
   An error stands in its field's hint row. Below --bp-sm, 600,
   the row stacks. */
[data-field-row] { display: grid; grid-template-columns: var(--field-row, repeat(2, minmax(0, 1fr))); column-gap: 12px; row-gap: 0; align-items: start; }
[data-field-row] > .field, [data-field-row] > [data-field-action] { display: grid; grid-row: span 3; grid-template-rows: subgrid; grid-template-columns: minmax(0, 1fr); row-gap: 5px; min-width: 0; }
[data-field-row] > [data-field-action] > * { grid-row: 2; }
[data-field-row] > .field > :is(.field-hint, .field-help, .field-error) { grid-row: 3; }
/* A control keeps its own height when its neighbour's is taller -- a select beside a list of checkboxes. */
[data-field-row] > .field > *, [data-field-row] > [data-field-action] > * { align-self: start; }
/* Rows stacked in a card, outside a stack that spaces them, keep its 10px between them. */
:not(.form-stack) > [data-field-row] + [data-field-row] { margin-top: 10px; }
.field-row-action { --field-row: minmax(0, 1fr) auto; }
.field-row-three { --field-row: repeat(3, minmax(0, 1fr)); }
.field-row-four { --field-row: repeat(4, minmax(0, 1fr)); }
.field-row-invite { --field-row: minmax(0, 1fr) 180px auto; }
.field-row-help { --field-row: minmax(0, 1fr) 140px; }
/* Input, Select and Textarea at their md size. A field's edge says its state, in upstream's order -- invalid (amber),
   focused (the accent and a 3px halo), disabled (dashed), hovered (one border step, never a tint), rest -- so each
   rule below outranks the one before it. */
input, select, textarea { min-width: 0; border: 1px solid var(--border-control); border-radius: var(--radius-input); padding: 0 11px; background: var(--surface-control); color: var(--text-strong); font-size: var(--text-base); font-weight: var(--weight-regular); letter-spacing: -.01em; transition: var(--transition-control); }
/* An input and a select are 32px, the md height a button beside them shares; a textarea grows with its rows. */
input:not([type="checkbox"]):not([type="radio"]), select { height: var(--control-height-md); }
textarea { min-height: calc(var(--control-height-md) * 2); padding: 8px 11px; line-height: 1.55; }
input:hover, select:hover, textarea:hover { border-color: var(--border-control-hover); }
input:disabled, select:disabled, textarea:disabled { border-style: dashed; border-color: var(--border-dashed); background: var(--surface-control-disabled); color: var(--text-faint); }
input:focus, select:focus, textarea:focus { border-style: solid; border-color: var(--accent); outline: none; box-shadow: 0 0 0 3px var(--focus-halo); }
/* Input that is wrong is amber, in the design system's invalid roles, and stays amber while it has focus; red is
   kept for a system that failed. */
input[aria-invalid="true"], select[aria-invalid="true"], textarea[aria-invalid="true"] { border-color: var(--border-invalid); }
/* A file field states what it accepts in its hint before a file is chosen; its picker is a small secondary button. */
input[type="file"] { padding: 0 11px 0 3px; line-height: calc(var(--control-height-md) - 2px); color: var(--text-secondary); font-size: var(--text-sm); cursor: pointer; }
input[type="file"]::file-selector-button { height: var(--control-height-sm); margin-block: 1px; margin-inline-end: 10px; border: 1px solid var(--border-control); border-radius: var(--radius-control); padding: 0 10px; background: var(--surface-control); color: var(--text-body); font-size: var(--text-sm); font-weight: var(--weight-book); cursor: pointer; }
input[type="color"] { width: 56px; padding: 3px; cursor: pointer; }
/* Select: the design system's caret at its reading end, a 7px chevron of two 1.5px borders in the muted text, 12px
   from the reading end. The borders are physical on purpose: rotated, they point down in either writing direction, and
   the chevron is symmetric, so it needs no mirroring. The select sits in a .select wrapper whose ::after draws it,
   since a select cannot draw generated content of its own. Every dropdown and menu trigger -- the organization and
   workspace switchers and the narrow screen's Menu -- ends in the same chevron (.caret), never the character. */
select { appearance: none; padding-inline-end: 32px; cursor: pointer; }
.select { position: relative; display: grid; min-width: 0; }
.select > select { width: 100%; }
.select-inline { display: inline-grid; vertical-align: middle; }
.select::after, .caret { content: ""; width: 7px; height: 7px; flex: none; border-right: 1.5px solid var(--text-muted); border-bottom: 1.5px solid var(--text-muted); pointer-events: none; }
.select::after { position: absolute; inset-inline-end: 12px; top: 50%; transform: translateY(-70%) rotate(45deg); }
.select:has(> select:disabled)::after { border-color: var(--text-faint); }
.caret { display: inline-block; transform: translateY(-2px) rotate(45deg); }
/* Select at its sm size: 28px, 11px, the 6px radius. */
.select-compact select, select.select-compact { height: var(--control-height-sm); border-radius: var(--radius-control); padding-inline: 9px 30px; font-size: var(--text-sm); }
/* The design system's Checkbox: a 14px box, filled with the accent and a check when chosen. */
input[type="checkbox"] { appearance: none; position: relative; width: 14px; height: 14px; flex: none; margin-top: 1px; border: 1px solid var(--border-control-strong); border-radius: var(--radius-badge); padding: 0; background: var(--surface-control); cursor: pointer; }
input[type="checkbox"]:checked { border-color: var(--accent); background: var(--accent); }
input[type="checkbox"]:checked::after { content: "\2713" / ""; position: absolute; inset: 0; display: grid; place-items: center; color: var(--text-on-accent); font-size: var(--text-2xs); line-height: 1; }
input[type="checkbox"]:disabled, input[type="checkbox"]:checked:disabled { border-style: dashed; border-color: var(--border-dashed); background: var(--surface-control-disabled); cursor: default; }
input[type="checkbox"]:checked:disabled::after { color: var(--text-faint); }
/* The design system's Radio: a 14px circle, its chosen dot in the accent. */
input[type="radio"] { appearance: none; position: relative; width: 14px; height: 14px; flex: none; border: 1px solid var(--border-control-strong); border-radius: 50%; padding: 0; background: var(--surface-control); cursor: pointer; }
input[type="radio"]:checked { border-color: var(--accent); }
input[type="radio"]:checked::after { content: ""; position: absolute; inset: 3px; border-radius: 50%; background: var(--accent); }
input[type="checkbox"]:focus, input[type="radio"]:focus { box-shadow: none; }
input[type="checkbox"]:focus-visible, input[type="radio"]:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 1px; }
legend { display: block; width: 100%; margin-bottom: 5px; }
/* A group of checkboxes under one label: the design system's labelledGroup. */
.choices { display: grid; gap: 8px; }
.choice { display: flex; align-items: flex-start; gap: 8px; color: var(--text-strong); font-size: var(--text-base); font-weight: var(--weight-regular); letter-spacing: -.01em; cursor: pointer; }
.form-stack { display: grid; gap: 14px; max-width: 720px; margin-top: 14px; }
/* A button is a grid item here, so it hugs its label like every other button; .button-block asks for a full one. */
.form-stack > .button { justify-self: start; }
.form-stack-compact { gap: 10px; margin-top: 12px; }
.embed { max-height: 240px; overflow: auto; margin: 0; border-radius: var(--radius-input); padding: 12px; background: var(--surface-panel); color: var(--text-strong); }
.embed code { display: block; font: var(--text-sm)/1.75 var(--font-mono); white-space: pre-wrap; overflow-wrap: anywhere; }
.form-status { min-height: 18px; margin: 8px 0 0; color: var(--text-secondary); font-size: var(--text-base); overflow-wrap: anywhere; }

/* The design system's StatusDot: 6px, always beside its written state. */
.status-dot { width: 6px; height: 6px; display: inline-block; margin-inline-end: 7px; border-radius: 50%; background: var(--dot-idle); }
.status-dot-ok { background: var(--dot-ok); }
.status-dot-warn { background: var(--dot-warn); }
.status-dot-danger { background: var(--dot-danger); }

/* The standalone screens -- sign in, sign up, an account link, the second factor and the recipient's own pages -- are
   the design system's: no shell, a 340px column centred on the subtle surface. Each opens with the lockup on one line --
   the wordmark at 20px with no cursor, an 18px hairline, "Sign" at 17px in Inter 450 -- then its title, type-title,
   28px below. The wordmark never stands on its own line above the product name. */
.signin-page, .auth-page { min-height: 100vh; background: var(--surface-subtle); }
.signin-layout { width: min(100% - 32px, 340px); min-height: 100vh; display: flex; flex-direction: column; justify-content: center; margin: 0 auto; padding: 40px 0; }
/* A page that reads a paragraph of terms or a list, such as the verifier or a suspended account's findings, keeps the
   same column and lockup at the reading measure. */
.signin-layout-wide { width: min(100% - 32px, 560px); }
.signin-lockup { display: flex; align-items: center; gap: 11px; color: var(--text-strong); }
.signin-lockup:hover { color: var(--text-strong); }
.signin-lockup .wordmark { font-size: 20px; }
.signin-lockup-rule { width: 1px; height: 18px; flex: none; background: var(--surface-strong); }
.signin-product { color: var(--text-detail); font-size: var(--text-4xl); font-weight: var(--weight-regular); letter-spacing: var(--tracking-tight); white-space: nowrap; }
/* A standalone screen's title is type-title, as a page title is: "Sign in", "Create your account", "Account help". */
.signin-title { margin: 28px 0 0; color: var(--text-strong); font-size: var(--text-5xl); font-weight: var(--weight-bold); line-height: 1.35; letter-spacing: -.025em; }
/* The one sentence under a screen's title, in the secondary text, 6px below it. */
.signin-lede { margin: 6px 0 0; color: var(--text-secondary); font-size: var(--text-base); line-height: 1.55; }
.signin-lede:has(> span:empty:only-child) { display: none; }
/* A link in a sentence is part of it: inline, at the sentence's size, with no space above it. */
:is(.signin-lede, .signin-help, .signin-layout .error-row) .text-link { display: inline; margin-top: 0; font-size: inherit; }
/* SnapHop Web's code page says its one sentence under the title as .supporting-copy, type-body; it stands where the
   lede does. */
.signin-layout > .supporting-copy { margin: 6px 0 0; color: var(--text-body); line-height: 1.55; }
/* SnapHop Web's pages put each refusal's sentence in the design system's error row, .error-row > p (its DESIGN.md
   section 4). On a standalone screen it is the plain danger-tinted row: no bar, the danger text colour, 9px 11px, one
   sentence. */
.signin-layout .error-row { display: block; margin: 16px 0 0; padding: 9px 11px; color: var(--status-danger-fg); }
.signin-layout .error-row::before { content: none; }
.signin-layout .error-row > p { margin: 0; color: inherit; overflow-wrap: anywhere; }
/* A refusal is the design system's plain danger-tinted row: no bar, the
   danger text colour, 9px 11px, one sentence. */
.signin-refusal { margin: 16px 0 0; border: 1px solid var(--border-danger); border-radius: var(--radius-input); padding: 9px 11px; background: var(--surface-danger-subtle); color: var(--status-danger-fg); font-size: var(--text-base); line-height: 1.55; }
.signin-layout .form-stack { margin-top: 18px; }
/* The code an authenticator app scans, drawn on the server at its own pixel size. */
.two-factor-qr { display: block; width: 176px; height: 176px; margin: 10px 0; image-rendering: pixelated; }
/* Ten recovery codes in two columns, room left for "10." beside each code. */
.recovery-codes { display: grid; grid-template-columns: repeat(2, max-content); gap: 4px calc(28px + 5ch); margin: 10px 0 0; padding-inline-start: 5ch; list-style: decimal; font-family: var(--font-mono); font-size: var(--text-base); }
@media (max-width: 599px) { .recovery-codes { grid-template-columns: max-content; } }
/* Google and Microsoft: plain secondary buttons under the form's, worded, without the providers' marks. */
.signin-providers { display: grid; gap: 8px; margin-top: 10px; }
/* A passkey is the other way in: a secondary button under the form's, the same width. */
.signin-passkey { margin-top: 10px; }
/* Sign-up's footnote, faint and xs, 14px under its button. */
.signin-footnote { margin: 14px 0 0; color: var(--text-faint); font-size: var(--text-xs); line-height: 1.55; }
/* What sign-up and an account link say in the form's place once it is done, the kit's card-edged status; a refusal is
   the danger row. SnapHop Web's sign-up says its accepted sentence as .signup-sent, the same row. */
.signin-status, .signup-sent { margin: 18px 0 0; outline: none; border: 1px solid var(--border-card); border-radius: var(--radius-input); padding: 9px 11px; background: var(--surface-card); color: var(--text-body); font-size: var(--text-base); line-height: 1.55; overflow-wrap: anywhere; }
.signin-status[role="alert"] { border-color: var(--border-danger); background: var(--surface-danger-subtle); color: var(--status-danger-fg); }
/* The kit's AuthLinks: under a hairline in --border-divider-strong, which keeps an edge on the subtle surface in dark,
   where --border-divider is that surface's own colour. The other way in, in plain text. */
.auth-links { display: grid; gap: 8px; margin-top: 16px; border-top: 1px solid var(--border-divider-strong); padding-top: 14px; color: var(--text-secondary); font-size: var(--text-base); line-height: 1.55; }
.auth-links p { margin: 0; }
.auth-links form { margin: 0; }
/* The same, SnapHop Web's .signin-help, with logical properties, and then the help only this product needs, said once:
   the note for agents in --text-detail at 10.5px, and Account help's own line in the faint text at 11px. */
.signin-help { display: grid; gap: 8px; margin-block-start: 16px; border-block-start: 1px solid var(--border-divider-strong); padding-block-start: 14px; color: var(--text-secondary); font-size: var(--text-base); line-height: 1.55; }
.signin-help p { margin: 0; }
.signin-help .signin-agents { color: var(--text-detail); font-size: var(--text-xs); }
.signin-help .account-help-note { color: var(--text-faint); font-size: var(--text-sm); }
/* The sign-up screen is sign-in's twin in two columns: the same lockup, then a 745px grid of two 340px columns with a
   hairline between, so "Create your account" and "Account help" start on the same line. Below --bp-md, 880, the
   second column moves below the first, after a divider. */
.signup-layout { width: min(100% - 32px, 745px); }
.signup-columns { display: grid; grid-template-columns: 340px 1px 340px; column-gap: 32px; align-items: start; }
.signup-column { min-width: 0; }
.signup-rule { align-self: stretch; margin-top: 28px; background: var(--border-divider-strong); }
/* Account help: two field rows, each an email field with its md secondary action beside it at the same height and a
   shared width, and each answering in a status row under it. */
.account-help-form { margin-top: 18px; }
.account-help-form + .account-help-form { margin-top: 14px; }
.account-help .form-status { min-height: 0; margin: 6px 0 0; }
.account-help .error-row { margin-top: 6px; }
@media (width < 880px) {
    .signup-layout { width: min(100% - 32px, 340px); }
    .signup-columns { grid-template-columns: minmax(0, 1fr); }
    .signup-rule { height: 1px; margin-top: 24px; }
}
/* A page that could not be shown, SnapHop Web's: the lockup over the design system's ErrorState, its status code in
   mono, in the library's .auth-page, .auth-layout and .error-page-state. Its column is .signin-layout's, 340px, and the
   state stands 28px under the lockup, where a title would. */
.auth-layout { width: min(100% - 32px, 340px); min-height: 100vh; display: grid; align-content: center; gap: 28px; margin: 0 auto; padding: 40px 0; }
.error-page-state h1 { margin: 0; color: var(--status-danger-fg); font-size: var(--text-2xl); line-height: 1.35; letter-spacing: -.02em; font-weight: var(--weight-strong); }
.error-code { margin: 0; color: var(--text-muted); }
/* A notice on sign-in that is neither irreversible nor a failure -- a sign-out, an ended session -- is a line of text,
   SnapHop Web's .form-status. */
.signin-layout > .form-status { min-height: 0; margin: 16px 0 0; color: var(--text-body); line-height: 1.55; }
/* The same on Sign's own standalone pages. */
.notice { margin: 16px 0 0; color: var(--text-body); font-size: var(--text-base); line-height: 1.55; }
/* A standalone page that carries a list -- an app's scopes, a suspended account's findings -- draws it on the card
   surface, ruled like any data list. */
.signin-layout .data-list { margin-top: 14px; border: 1px solid var(--border-card); border-radius: var(--radius-card); padding: 0 14px; background: var(--surface-card); }
.signin-layout .data-list:empty { display: none; }
/* The design system's Callout: a 2px emphasis border on the card's surface, an optional ink label and a title. It marks
   what cannot be taken back -- a secret shown once, a test agreement, a support window open on this organization. */
.callout { display: flex; align-items: flex-start; gap: 13px; margin: 14px 0 0; border: 2px solid var(--border-emphasis); border-radius: var(--radius-card); padding: 13px 15px; background: var(--surface-card); color: var(--text-body); font-size: var(--text-base); line-height: 1.55; overflow-wrap: anywhere; }
.callout-stack { display: grid; gap: 6px; }
.callout-stack > p { margin: 0; }
.callout-label { flex: none; margin-top: 1px; border-radius: var(--radius-badge); padding: 3px 7px; background: var(--surface-inverse); color: var(--text-on-inverse); font: var(--weight-bold) var(--text-2xs)/1.35 var(--font-sans); letter-spacing: var(--tracking-label); text-transform: uppercase; white-space: nowrap; }
.callout-body { min-width: 0; flex: 1; }
.callout-body > p { margin: 0; }
.callout-title { margin: 0; color: var(--text-strong); font-size: var(--text-xl); line-height: 1.35; letter-spacing: 0; font-weight: var(--weight-bold); }
.callout-title + p { margin: 3px 0 0; }
.callout pre, .callout code { white-space: pre-wrap; overflow-wrap: anywhere; }

/* The application shell: a 236px rail, a 46px top bar and the canvas, inside a frame at most 1440px wide. The frame is
   the only elevated application container. */
.app-page { min-height: 100vh; padding: 18px; background: var(--surface-page); }
.app-frame { position: relative; width: min(100%, 1440px); min-height: calc(100vh - 36px); display: grid; grid-template-columns: 236px minmax(0, 1fr); margin: 0 auto; overflow: hidden; border: 1px solid var(--border-frame); border-radius: var(--radius-frame); background: var(--surface-card); box-shadow: var(--shadow-frame); }
/* The rail, as the console kit's: the lockup, the organization switcher, a workspace switcher where the organization has
   workspaces, the SidebarNav rows and a footer. */
.app-rail { min-width: 0; min-height: 100%; display: flex; flex-direction: column; border-inline-end: 1px solid var(--border-rail); background: var(--surface-rail); }
.rail-wordmark { padding: 14px 14px 12px; }
/* The organization switcher, as the console kit's workspace switcher: a Menu whose trigger holds the organization's
   square ink Avatar, its name over "Organization · {role}", and the chevron. Its Menu lists every organization, the
   active one marked "active", then New organization. The workspace switcher under it is the same Menu for the second
   scope, as the design system's "A second switcher" sets it out. */
.menu { position: relative; }
.workspace-menu { padding: 0 10px 12px; }
.workspace-menu + .workspace-menu { margin-top: -6px; }
.workspace-trigger { width: 100%; display: flex; align-items: center; gap: 8px; border: 1px solid var(--border-frame); border-radius: var(--radius-input); padding: 7px 9px; background: var(--surface-card); color: var(--text-strong); text-align: start; cursor: pointer; transition: var(--transition-control); }
.workspace-trigger:hover { border-color: var(--border-control-hover); }
.workspace-trigger-text { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.workspace-trigger-name { overflow: hidden; color: var(--text-strong); font-size: var(--text-base); font-weight: var(--weight-semibold); letter-spacing: var(--tracking-tight); text-overflow: ellipsis; white-space: nowrap; }
.workspace-trigger-meta { overflow: hidden; color: var(--text-faint); font-size: var(--text-2xs); text-overflow: ellipsis; white-space: nowrap; }
.workspace-trigger-caret { margin-inline: auto 2px; }
/* An address that identifies a person is never cut off with an ellipsis, since a truncated address can read as someone
   else's: it wraps. */
.rail-user-meta { color: var(--text-faint); font-size: var(--text-2xs); overflow-wrap: anywhere; }
/* The design system's Avatar: initials, round for a person in --text-strong on --surface-strong, square in ink for an
   organization. Its initials are the component's own 8px, not a step of the type scale. */
.avatar { width: 20px; height: 20px; flex: none; display: flex; align-items: center; justify-content: center; overflow: hidden; border-radius: 50%; background: var(--surface-strong); color: var(--text-strong); font-size: 8px; font-weight: var(--weight-bold); letter-spacing: -.02em; }
.avatar-square { width: 18px; height: 18px; border-radius: var(--radius-control); background: var(--surface-inverse); color: var(--text-on-inverse); }
/* The design system's Menu: a 4px panel on the popover layer, in the frame's border at the input radius, 5px under its
   trigger, rising over --duration-instant. Rows are 11.5px at 6px 8px, the keyboard-active one on the hover surface; a
   header is the table-header and eyebrow style, uppercase by the stylesheet over sentence-case words in the muted text;
   a separator is a divider rule. Headers, separators and a disabled row are skipped by the arrow keys; a disabled row
   stays visible with its reason in its label. */
.menu-panel { position: absolute; inset-block-start: calc(100% + 5px); inset-inline-start: 0; z-index: 80; width: 216px; display: flex; flex-direction: column; gap: 1px; border: 1px solid var(--border-frame); border-radius: var(--radius-input); padding: 4px; background: var(--surface-card); box-shadow: var(--shadow-popover); animation: snaphop-rise var(--duration-instant) var(--ease-out); }
.workspace-menu > .menu-panel { inset-block-start: calc(100% - 7px); inset-inline-start: 10px; }
.menu-group { display: flex; flex-direction: column; gap: 1px; }
.menu-header { padding: 6px 8px 3px; color: var(--text-muted); font-size: var(--text-2xs); font-weight: var(--weight-bold); letter-spacing: var(--tracking-label); text-transform: uppercase; }
.menu-separator { height: 1px; margin: 4px 0; background: var(--border-divider); }
.menu-row { width: 100%; display: flex; align-items: center; gap: 8px; border: 0; border-radius: var(--radius-control); padding: 6px 8px; outline: none; background: transparent; color: var(--text-body); font-size: var(--text-base); letter-spacing: var(--tracking-tight); text-align: start; cursor: pointer; transition: var(--transition-control); }
.menu-row:hover:not(:disabled), .menu-row:focus { background: var(--surface-hover); }
.menu-row:disabled { color: var(--text-faint); cursor: default; }
.menu-row[aria-busy="true"] { cursor: progress; }
a.menu-row, a.menu-row:hover { color: var(--text-body); }
/* A row's meta -- "active", "current" -- is a word, not a machine value, so it is in Inter, as SnapHop Maps has it. */
.menu-row-meta { flex: none; margin-inline-start: auto; color: var(--text-faint); font-size: var(--text-2xs); }
.menu-row-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.menu-form { display: contents; }
/* Below 600px the top bar's first control is "Menu", a small secondary button ending in the chevron, and its menu is
   the design system's Menu: a dropdown under it, aligned to its start, as wide as its longest row -- at least 240px,
   never wider than the screen less 32px -- and never a sheet. It is never taller than the window below the trigger
   less 16px -- the 46px top bar centres the 28px trigger, so its foot is 37px down and the panel starts 5px under it --
   and scrolls inside itself, so Account settings and Sign out are always reachable. dvh follows a phone's toolbars
   where vh would not. */
#rail-toggle .caret { margin-inline-start: 2px; }
.menu-panel-narrow { width: max-content; min-width: 240px; max-width: calc(100vw - 32px); max-height: calc(100vh - 58px); max-height: calc(100dvh - 58px); overflow-y: auto; overscroll-behavior: contain; }
.menu-panel-narrow .menu-row { white-space: normal; }
/* A panel that scrolls must not squeeze its parts to fit: a flex item shrinks by default, so every row, header, group
   and separator keeps its own height and the panel scrolls instead. */
.menu-panel :is(.menu-header, .menu-group, .menu-separator, .menu-row, .menu-theme, .menu-person) { flex-shrink: 0; }
/* The theme in the Menu is the rail's small button group across the menu, its segments menu items the arrows move
   through as through any row; the focused one is ringed inside its edge, as the group clips anything outside it. */
.menu-theme { margin: 2px 8px; }
.menu-theme button:not([aria-checked="true"]):is(:hover, :focus) { background: var(--surface-hover); }
.menu-theme button:focus { outline: 2px solid var(--focus-ring); outline-offset: -2px; }
/* Who is signed in, as the rail shows them, on a line the arrows pass over. */
.menu-person { display: flex; align-items: center; gap: 8px; padding: 4px 8px 6px; }
/* The design system's SidebarNav rows: 12.5px at 5.5px 9px, the current one in the active pair at 650. */
.rail-nav { display: grid; gap: 1px; padding: 0 10px; }
.rail-nav a { overflow: hidden; border-radius: var(--radius-control); padding: 5.5px 9px; color: var(--text-secondary); font-size: var(--text-lg); font-weight: var(--weight-regular); letter-spacing: var(--tracking-tight); text-overflow: ellipsis; white-space: nowrap; transition: var(--transition-control); }
.rail-nav a:hover { background: var(--surface-hover); color: var(--text-secondary); }
.rail-nav a[aria-current="page"] { background: var(--surface-active); color: var(--text-on-active); font-weight: var(--weight-strong); }
/* The footer, in the order the design system's "Shared application elements" gives: Account settings as a quiet link at
   lg, the person signed in, the theme switch and Sign out last. */
.rail-footer { display: grid; gap: 8px; margin-top: auto; border-top: 1px solid var(--border-divider); padding: 12px 10px; }
.rail-settings { margin: 0; padding: 0 9px; }
/* Link (quiet, lg): the muted text, underlined like every link, turning the link hover colour. */
.link-quiet { color: var(--text-muted); font-size: var(--text-lg); }
.link-quiet[aria-current="page"] { color: var(--text-strong); font-weight: var(--weight-strong); }
.rail-user { display: flex; align-items: center; gap: 8px; min-width: 0; padding: 0 9px; }
.rail-user-text { min-width: 0; }
.rail-user-text p { margin: 0; }
.rail-user-name { color: var(--text-body); font-size: var(--text-sm); font-weight: var(--weight-book); overflow-wrap: anywhere; }
/* The theme switch is the design system's ButtonGroup at its sm size: a radiogroup whose chosen segment takes the ink
   treatment. Its three segments, "Light", "Dark" and "Auto", are equal and on one line across the rail, 28px as every
   sm control is, and no word names the group on screen: its accessible name, "Theme", is the group's alone. The
   signature dialog's method choice is the same group. */
.theme-switch, .button-group { display: grid; grid-template-columns: repeat(var(--segments, 3), minmax(0, 1fr)); height: var(--control-height-sm); overflow: hidden; border: 1px solid var(--border-control); border-radius: var(--radius-control); background: var(--surface-control); }
.theme-switch button, .button-group button { min-width: 0; border: 0; padding: 0 9px; background: transparent; color: var(--text-secondary); font-size: var(--text-sm); font-weight: var(--weight-book); letter-spacing: var(--tracking-tight); white-space: nowrap; cursor: pointer; transition: var(--transition-control); }
.theme-switch button + button, .button-group button + button { border-inline-start: 1px solid var(--border-control); }
.theme-switch button[aria-checked="true"], .button-group button[aria-checked="true"] { background: var(--surface-inverse); color: var(--text-on-inverse); font-weight: var(--weight-semibold); }
.theme-switch button:focus-visible, .button-group button:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: -2px; }
.app-main { min-width: 0; background: var(--surface-app); }
/* The top bar: the narrow Menu, then the breadcrumb, "{organization} / {page}". */
.topbar { height: 46px; display: flex; align-items: center; gap: 9px; border-bottom: 1px solid var(--border-divider); padding: 0 18px; background: var(--surface-card); }
.breadcrumb { min-width: 0; margin: 0; overflow: hidden; color: var(--text-secondary); font-size: var(--text-base); text-overflow: ellipsis; white-space: nowrap; }
.breadcrumb a { color: var(--text-secondary); }
.breadcrumb-separator { margin: 0 8px; color: var(--text-separator); }
.breadcrumb-current { color: var(--text-strong); }
.canvas { padding: 16px 18px; }
/* Below 600px the rail is replaced by the top bar's Menu; above it the Menu is not shown. */
.rail-toggle { display: none; flex: none; }
/* A paper sheet names what it shows and who printed it, since the rail that carries that on screen is gone. */
[data-print="only"] { display: none; }

/* The page header pattern: the title, then a lede of a sentence or two, and no eyebrow above the title -- the breadcrumb
   already says where the page is. A page's own actions sit at the head's reading end. */
.page-head { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.page-head > div:first-child { min-width: 0; flex: 1 1 360px; }
.page-head h1 { margin-bottom: 3px; }
.page-head .button-row { flex: none; }
/* The design system's Card: flat, white, a hairline and the 9px radius, no shadow. */
.card { min-width: 0; overflow: hidden; border: 1px solid var(--border-card); border-radius: var(--radius-card); padding: 13px 14px; background: var(--surface-card); }
/* The Card header: a strip with its title at the card-heading size, meta beside it and an action at its end, ruled off
   from the body. It sits on the card's own padding, as the footnote strip does. */
.card-header { display: flex; align-items: center; flex-wrap: wrap; gap: 9px; margin: -13px -14px 13px; border-bottom: 1px solid var(--border-divider); padding: 11px 14px; }
.table-card > .card-header { margin: 0; }
.card-header + .table-scroll { border-top: 0; }
.card-header > div { min-width: 0; }
.card-title { margin: 0; color: var(--text-strong); font-size: var(--text-lg); line-height: 1.35; letter-spacing: 0; font-weight: var(--weight-strong); }
.card-meta { margin: 2px 0 0; color: var(--text-muted); font-size: var(--text-xs); }
.card-action { flex: none; display: flex; align-items: center; gap: 8px; margin-inline-start: auto; }
/* A section inside a card, ruled off from what is above it, with a heading at the card-heading size. */
.card-section { margin-top: 14px; border-top: 1px solid var(--border-divider); padding-top: 12px; }
.card-section > h3 { margin-bottom: 4px; }
/* A card's footnote is type-meta: a full-sentence constraint, 10.5px in the muted text, on the subtle strip at its foot. */
.card-footnote { margin: 13px -14px -13px; padding: 10px 14px; background: var(--surface-subtle); color: var(--text-muted); font-size: var(--text-xs); line-height: 1.55; }
/* Cards on a page stack with the 12px gap the canvas uses, whether a page is one column of them or a grid. */
.stack { display: grid; gap: 12px; }
[data-route-view] > * + * { margin-top: 12px; }
[data-route-view] > .page-head + * { margin-top: 0; }
/* Content columns are a flexible main column beside a fixed aside -- 340px, 372px from 1440px -- never a symmetric grid.
   Below 1180px the aside moves under main. */
.main-aside { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 12px; align-items: start; }
.main-aside > div { display: grid; gap: 12px; min-width: 0; }
.data-list { margin: 8px 0 0; padding: 0; list-style: none; }
.data-list > * + * { border-top: 1px solid var(--border-row); }
.data-list:empty { display: none; }
/* Row padding belongs to the light DOM. Declared on :host it loses to this stylesheet's reset `*{padding:0}`, because
   the outer tree wins for the host element. */
snaphop-list-item { display: block; padding: 11px 0; }
/* A row's actions, slotted from the light DOM: small buttons in a wrapping row. */
snaphop-list-item > .button, snaphop-list-item > a.button, snaphop-list-item > .select, snaphop-list-item > .choice, snaphop-list-item > .state-badge { margin-block: 2px; margin-inline-end: 6px; vertical-align: middle; }
snaphop-list-item > .choice { display: inline-flex; }
snaphop-list-item > .data-list, snaphop-list-item > .form-status, snaphop-list-item > .field-row-controls { margin-top: 8px; }
.scroll-list { max-height: 228px; overflow-y: auto; }
/* A machine-readable answer shown back to a member: bounded, scrollable, and wrapped, because it carries whatever the
   record holds. */
.data-dump { max-height: 20rem; overflow: auto; margin: 12px 0 0; border-radius: var(--radius-input); padding: 12px; background: var(--surface-panel); color: var(--text-strong); font: var(--text-sm)/1.75 var(--font-mono); white-space: pre-wrap; overflow-wrap: anywhere; }
/* Native tables drawn as the design system's DataTable. */
.table-card { min-width: 0; overflow: hidden; border: 1px solid var(--border-card); border-radius: var(--radius-card); background: var(--surface-card); }
.table-scroll { overflow-x: auto; border-top: 1px solid var(--border-card); }
.table-card table { width: 100%; }
.table-card th { padding: 9px 15px; border-bottom: 1px solid var(--border-divider); background: var(--surface-subtle); color: var(--text-muted); font: var(--weight-bold) var(--text-2xs)/1.55 var(--font-sans); letter-spacing: var(--tracking-label); text-align: start; text-transform: uppercase; white-space: nowrap; }
.table-card td { padding: 11px 15px; border-bottom: 1px solid var(--border-row); color: var(--text-body); vertical-align: middle; }
.table-card tbody tr:last-child td { border-bottom: 0; }
.table-card tbody tr:hover { background: var(--surface-subtle); }
.table-card td.empty-cell { padding: 0; }
.table-card td.empty-cell:hover, .table-card tr:has(> td.empty-cell):hover { background: transparent; }
/* A table row's first line is type-row-primary, 12px at 600; its second line, a time or a meta, is type-meta in the
   muted sans. */
.row-primary { margin: 0; color: var(--text-strong); font-size: var(--text-md); font-weight: var(--weight-semibold); overflow-wrap: anywhere; }
.row-secondary { margin: 2px 0 0; color: var(--text-muted); font-size: var(--text-xs); line-height: 1.4; overflow-wrap: anywhere; }
.row-actions { display: flex; flex-wrap: wrap; gap: 6px; justify-content: end; }
/* Where an action can never apply to a row, because of what the row is, the row says so in muted body-small text in
   place of the button: "The owner cannot be removed". */
.row-note { color: var(--text-muted); font-size: var(--text-sm); }
/* The design system's EmptyState at its compact size: a dashed frame, a title and, when there is more to say, a
   sentence. */
.empty-state { display: flex; flex-direction: column; align-items: center; gap: 7px; margin: 14px; border: 1px dashed var(--border-dashed); border-radius: var(--radius-card); padding: 26px 18px; background: var(--surface-card); text-align: center; }
.data-list > .empty-state, .card > .empty-state { margin: 8px 0 0; }
.data-list > .empty-state + * { border-top: 0; }
.empty-state p { max-width: 420px; margin: 0; color: var(--text-detail); font-size: var(--text-base); line-height: 1.55; text-wrap: pretty; }
.empty-state .empty-state-title { color: var(--text-strong); font-size: var(--text-2xl); font-weight: var(--weight-strong); letter-spacing: -.02em; }
/* A list read a page at a time by cursor: the count of what is shown, then the button that reads more, on the subtle
   strip at the card's foot, as the design system's Pagination sits in a data surface's footer. */
.pagination { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; margin: 13px -14px -13px; padding: 11px 15px; background: var(--surface-subtle); }
.pagination-range { margin: 0; color: var(--text-muted); font-size: var(--text-xs); white-space: nowrap; }
.pagination .button { margin-inline-start: auto; }
#dashboard-status:empty { display: none; }

/* The metric strip of MetricCards opening a page: five-up, three-up below 1180px and two-up below 880px. */
.delivery-metrics { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 12px; }
.delivery-metrics-six { grid-template-columns: repeat(6, minmax(0, 1fr)); }
/* The design system's MetricCard. */
.metric { display: flex; flex-direction: column; gap: 4px; padding: 12px 13px; }
.metric p { margin: 0; }
.metric-label { color: var(--text-label); font-size: var(--text-xs); font-weight: var(--weight-semibold); letter-spacing: .02em; }
.metric-value { color: var(--text-strong); font-size: var(--text-6xl); line-height: 1; letter-spacing: -.03em; font-weight: var(--weight-bold); }
.metric-note { color: var(--text-muted); font-size: var(--text-xs); }
/* The design system's outline Badge: bordered text that survives greyscale, in Inter -- a role is a word -- or, for a
   machine value such as an activity's action, in mono. */
.badge { display: inline-block; border: 1px solid var(--border-control-strong); border-radius: var(--radius-badge); padding: 2px 6px; background: transparent; color: var(--text-strong); font: var(--weight-bold) var(--text-2xs)/1.35 var(--font-sans); letter-spacing: .02em; white-space: nowrap; }
.badge-mono { font-family: var(--font-mono); letter-spacing: var(--tracking-mono); }
/* The design system's Badge in a status tone: the state spelled out on its tint. */
.state-badge { display: inline-block; justify-self: start; border: 1px solid transparent; border-radius: var(--radius-badge); padding: 2px 6px; background: var(--status-neutral-bg); color: var(--status-neutral-fg); font: var(--weight-bold) var(--text-2xs)/1.35 var(--font-mono); letter-spacing: .03em; white-space: nowrap; vertical-align: middle; }
.state-badge-ok { background: var(--status-ok-bg); color: var(--status-ok-fg); }
.state-badge-warn { background: var(--status-warn-bg); color: var(--status-warn-fg); }
.state-badge-danger { background: var(--status-danger-bg); color: var(--status-danger-fg); }
/* An annotation: the 2px accent rule beside the text it marks -- a disclosure, a converted document's note. */
.annotation { border-inline-start: 2px solid var(--accent-rule); padding: 9px 11px; background: var(--surface-subtle); color: var(--text-body); font-size: var(--text-base); line-height: 1.55; }
/* A filter states its effect: how many are shown, under which filter. */
.filter-effect { margin: 4px 0 0; color: var(--text-muted); font-size: var(--text-xs); }
/* Filters and bulk actions are a form of many labelled fields: a grid whose fields share their rows, then the actions
   on a line of their own. */
.filter-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(176px, 1fr)); gap: 10px 12px; align-items: start; margin-top: 12px; }
.filter-grid > .button-row, .filter-grid > .form-status { grid-column: 1 / -1; margin: 0; }
.brand-logo-preview { display: block; max-height: 60px; margin-top: 10px; }

/* The design system's Dialog: a scrim, and over it a panel with its title and a close control, its body, and its
   actions on the subtle strip at its foot. Fixed to the viewport, not the frame, and scrolled within the layer, so a
   dialog taller than the window keeps its top reachable. */
.dialog-layer { position: fixed; inset: 0; z-index: 60; display: grid; justify-items: center; align-content: start; overflow-y: auto; padding: 56px 24px; }
.dialog-scrim { position: fixed; inset: 0; background: var(--scrim); }
.dialog { position: relative; width: min(100%, 520px); overflow: hidden; outline: none; border: 1px solid var(--border-frame); border-radius: var(--radius-frame); background: var(--surface-card); box-shadow: var(--shadow-modal); }
.dialog-wide { width: min(100%, 640px); }
.dialog-head { display: flex; align-items: baseline; gap: 9px; border-bottom: 1px solid var(--border-divider); padding: 13px 16px; }
.dialog-head h2 { margin: 0; color: var(--text-strong); font-size: var(--text-xl); line-height: 1.35; letter-spacing: -.02em; font-weight: var(--weight-strong); }
.dialog-meta { overflow: hidden; color: var(--text-muted); font-size: var(--text-sm); text-overflow: ellipsis; white-space: nowrap; }
.dialog-close { margin-inline-start: auto; border: 0; padding: 0; background: transparent; color: var(--text-faint); font-size: var(--text-xl); line-height: 1; cursor: pointer; }
.dialog-close:disabled { cursor: default; }
.dialog-body { display: grid; gap: 9px; padding: 15px 16px; color: var(--text-body); font-size: var(--text-base); line-height: 1.55; }
.dialog-body > p { margin: 0; text-wrap: pretty; }
.dialog-body > .form-status { min-height: 0; margin: 0; }
.dialog-body fieldset { display: grid; gap: 9px; }
.dialog-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; border-top: 1px solid var(--border-divider); padding: 12px 16px; background: var(--surface-subtle); }
/* The design system's ToastStack and Toast. The stack is the polite live region; it is fixed to the viewport so the
   outcome stays in view on a page taller than the window, 16px inside the frame, which is centred at 1440px with an
   18px page margin, rather than in the margin beside it. A toast has a 3px tone bar, its title and a sentence. */
.toast-stack { position: fixed; inset-block-end: 16px; inset-inline-end: calc(max(18px, (100% - 1440px) / 2) + 16px); z-index: 70; display: flex; flex-direction: column; gap: 9px; }
.toast { display: flex; align-items: flex-start; gap: 11px; width: min(100vw - 32px, 340px); border: 1px solid var(--border-frame); border-radius: var(--radius-card); padding: 11px 13px; background: var(--surface-card); box-shadow: var(--shadow-popover); }
.toast-bar { width: 3px; flex: none; align-self: stretch; border-radius: 2px; background: var(--dot-ok); }
.toast-content { min-width: 0; flex: 1; }
.toast-content p { margin: 0; }
.toast-title { color: var(--text-strong); font-size: var(--text-md); font-weight: var(--weight-semibold); }
.toast-content .toast-text:empty { display: none; }
.toast-content .toast-text { margin-top: 2px; color: var(--text-detail); font-size: var(--text-sm); line-height: 1.55; overflow-wrap: anywhere; }
.toast-close { flex: none; border: 0; padding: 0; background: transparent; color: var(--text-faint); font-size: var(--text-lg); line-height: 1; cursor: pointer; }
/* The design system's ErrorState: a surface that failed to load stands in place of the page, a title in the danger
   colour naming what failed, the server's words, and a sentence saying whether retrying can help. Red marks a failed
   system here, never wrong input. */
.error-state { display: grid; justify-items: center; gap: 7px; border: 1px dashed var(--border-danger); border-radius: var(--radius-card); padding: 44px 22px; background: var(--surface-card); text-align: center; }
.error-state h2 { margin: 0; color: var(--status-danger-fg); font-size: var(--text-2xl); font-weight: var(--weight-strong); letter-spacing: -.02em; }
.error-state p { max-width: 440px; margin: 0; color: var(--text-detail); font-size: var(--text-base); line-height: 1.55; overflow-wrap: anywhere; text-wrap: pretty; }
.error-state .error-state-retry { color: var(--text-muted); font-size: var(--text-xs); }
.error-state .button { margin-top: 4px; }
/* The design system's error row. */
.error-row { display: flex; align-items: flex-start; gap: 10px; margin: 12px 14px; border: 1px solid var(--border-danger); border-radius: var(--radius-input); padding: 11px 13px; background: var(--surface-danger-subtle); color: var(--text-body); font-size: var(--text-base); line-height: 1.55; }
.error-row::before { content: ""; width: 3px; flex: none; align-self: stretch; border-radius: 2px; background: var(--status-danger-strong); }
.canvas[data-failed] > :not(#dashboard-error):not([data-print="only"]) { display: none !important; }

/* The prepare-and-send steps, drawn as the design system's Tabs: the current step is underlined in the accent, and the
   rule is drawn inside the row. Where five steps do not fit on one line they wrap, so no step sits past the screen. */
.wizard-steps { display: flex; flex-wrap: wrap; column-gap: 18px; margin: 0 0 14px; box-shadow: inset 0 -1px 0 var(--border-divider); }
.wizard-steps button { flex: none; border: 0; border-bottom: 2px solid transparent; padding: 9px 0; background: transparent; color: var(--text-muted); font-size: var(--text-base); font-weight: var(--weight-regular); white-space: nowrap; cursor: pointer; transition: var(--transition-control); }
.wizard-steps button[aria-current="step"] { border-bottom-color: var(--accent); color: var(--text-strong); font-weight: var(--weight-strong); }
.wizard-steps button:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: -2px; }
/* One recipient is a block of controls in a ruled panel: who they are, then how they are routed, then how they are
   reached and checked, each line a field row so every label sits over the control it names. */
.recipient-row { display: grid; gap: 10px; margin: 10px 0 0; border: 1px solid var(--border-card); border-radius: var(--radius-card); padding: 12px; background: var(--surface-card); }
.recipient-row > .button { justify-self: end; }
.field-toolbar { align-items: end; margin-bottom: 10px; }
.toolbar-label { color: var(--text-muted); font-size: var(--text-xs); }
/* The authoring canvas: page images at the canvas frame's width, thumbnails beside them. */
.authoring-layout { display: grid; grid-template-columns: 96px minmax(0, 1fr); gap: 10px; align-items: start; margin-top: 12px; }
.authoring-canvas { display: grid; gap: 14px; margin: 0; zoom: var(--canvas-zoom, 1); }
.page-thumbnails { display: grid; gap: 6px; max-height: 70vh; overflow-y: auto; padding-inline-end: 4px; }
.page-thumbnail { display: grid; gap: 2px; border: 1px solid var(--border-card); border-radius: var(--radius-badge); padding: 3px; background: var(--surface-card); color: var(--text-faint); font-size: var(--text-2xs); text-align: start; cursor: pointer; }
.page-thumbnail span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.page-frame { position: relative; width: 100%; max-width: 720px; border: 1px solid var(--border-card); background: var(--surface-card); }
.page-frame img { width: 100%; user-select: none; }
.page-frame[data-placing="true"] { cursor: crosshair; }
.page-frame[data-placing="true"]:hover { outline: 2px dashed var(--accent-rule); }
/* A field on a page: the rectangle its value lands in, in the recipient's tone and with the recipient's name written on
   it, since the tone only reinforces the name. A required field carries the Field's muted asterisk. */
.field-box { position: absolute; display: flex; align-items: center; justify-content: center; border: 2px solid var(--field-tone, var(--accent)); border-radius: var(--radius-xs); background: color-mix(in srgb, var(--field-tone, var(--accent)) 12%, transparent); color: var(--text-strong); font-size: var(--text-2xs); font-weight: var(--weight-semibold); overflow: hidden; text-align: center; }
.field-box[data-tone="1"] { --field-tone: var(--accent); }
.field-box[data-tone="2"] { --field-tone: var(--status-ok-fg); }
.field-box[data-tone="3"] { --field-tone: var(--status-warn-fg); }
.field-box[data-tone="4"] { --field-tone: var(--status-danger-fg); }
.field-box[data-required="true"]::after { content: "*" / ""; position: absolute; top: 0; inset-inline-end: 2px; color: var(--text-muted); font-weight: var(--weight-regular); }
.field-box:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 1px; }
.field-box[data-selected="true"] { outline: 2px solid var(--border-emphasis); outline-offset: 1px; }
/* WCAG 2.5.8: the target is the hit area, not the painted box. A field box is drawn on the document rectangle the value
   lands in and must not move, so the 24 by 24 CSS pixel target is a transparent layer centred on it. --target-w and
   --target-h cap that layer at the midpoint of the gap to the nearest neighbouring field, as a percentage of the box's
   own size, so two targets meet but never overlap and no press lands on the wrong field. See DESIGN.md section 7. */
.field-box[data-hit-area="true"] { overflow: visible; isolation: isolate; }
.field-box[data-hit-area="true"]:not(.signature-slot)::before, .signature-slot .field-signature-button::before { content: ""; position: absolute; left: 50%; top: 50%; z-index: -1; transform: translate(-50%, -50%); width: max(100%, min(24px, var(--target-w, 24px))); height: max(100%, min(24px, var(--target-h, 24px))); }
/* The box no longer clips, so each thing inside it clips its own text. */
.field-box :is(a, span) { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.field-box input:not([type="checkbox"]):not([type="radio"]), .field-box select { width: 100%; height: 100%; min-height: 0; border: 0; border-radius: 0; padding: 0 4px; background: transparent; font-size: var(--text-sm); }
.field-box select { padding-inline-end: 4px; }
.field-box input:focus, .field-box select:focus { box-shadow: none; }
.field-box input[type="file"] { padding: 0; font-size: var(--text-2xs); }
.field-box input[type="file"]::file-selector-button { height: 100%; margin: 0 4px 0 0; padding: 0 4px; font-size: var(--text-2xs); }
.recipient-legend { display: flex; flex-wrap: wrap; gap: 6px; margin: 0; padding: 0; list-style: none; }
.recipient-key { border-inline-start: 4px solid var(--field-tone, var(--accent)); padding: 1px 6px; color: var(--text-strong); font-size: var(--text-sm); }
.recipient-key[data-tone="1"] { --field-tone: var(--accent); }
.recipient-key[data-tone="2"] { --field-tone: var(--status-ok-fg); }
.recipient-key[data-tone="3"] { --field-tone: var(--status-warn-fg); }
.recipient-key[data-tone="4"] { --field-tone: var(--status-danger-fg); }
/* A placed field's numeric position and its rules, under its row: small fields side by side. */
.field-row-controls { display: flex; flex-wrap: wrap; gap: 8px; align-items: end; }
.field-row-controls .field { width: 88px; }
.field-row-controls .field-wide { width: 200px; }
.field-row-controls input:not([type="checkbox"]) { height: var(--control-height-sm); border-radius: var(--radius-control); padding: 0 8px; font-size: var(--text-sm); }
.field-row-controls .choice { align-self: center; font-size: var(--text-sm); }

/* The recipient signing surface: a single column at most 960px wide, its header naming who sent what before anything is
   asked of the recipient (UX-006). It is used on a phone, so everything stacks and nothing needs sideways scrolling but
   the page image itself. */
.signing-page { min-height: 100vh; background: var(--surface-app); }
.signing-header { border-bottom: 1px solid var(--border-divider); background: var(--surface-card); }
.signing-header-inner { width: min(100% - 24px, 960px); display: flex; flex-wrap: wrap; align-items: center; gap: 10px 16px; margin: 0 auto; padding: 12px 0; }
.signing-header .brand-lockup { flex: none; }
.signing-brand-logo { max-height: 40px; max-width: 160px; }
.signing-identity { min-width: 0; flex: 1 1 320px; display: grid; gap: 2px; }
.signing-identity p { margin: 0; color: var(--text-body); font-size: var(--text-base); overflow-wrap: anywhere; }
.signing-identity .signing-label { color: var(--text-muted); }
.signing-identity strong { color: var(--text-strong); font-weight: var(--weight-semibold); }
.signing-meta { color: var(--text-muted); font-size: var(--text-xs); }
.signing-header .text-link { margin-top: 0; font-size: var(--text-sm); }
.signing-main { width: min(100% - 24px, 960px); display: grid; gap: 12px; margin: 0 auto; padding: 16px 0 60px; }
.signing-main > .callout { margin: 0; }
.signing-step { display: grid; gap: 12px; }
.signing-step.card { gap: 0; }
.signing-step.card > * + * { margin-top: 12px; }
.signing-step.card > .card-header + * { margin-top: 0; }
/* The review toolbar stays in reach while the recipient scrolls the pages: where they stand, the next required field,
   and the final action. The final action is the inverse, 40px button and stands apart from the field-level controls
   at the toolbar's end, so it cannot be mistaken for an autosave or a field's own control (UX-007). */
.signing-toolbar { position: sticky; top: 8px; z-index: 20; display: flex; flex-wrap: wrap; align-items: center; gap: 10px; border: 1px solid var(--border-card); border-radius: var(--radius-card); padding: 10px 12px; background: var(--surface-card); box-shadow: var(--shadow-popover); }
.signing-toolbar > p { min-width: 0; flex: 1 1 200px; margin: 0; color: var(--text-strong); font-size: var(--text-md); font-weight: var(--weight-semibold); }
.signing-toolbar .button-row { flex: 1 1 auto; justify-content: flex-end; }
.signing-final { margin-inline-start: 6px; }
.disclosure { max-height: 50vh; overflow-y: auto; white-space: pre-wrap; }
.signing-pages { display: grid; gap: 14px; justify-items: center; }
.signing-pages .page-frame { max-width: 100%; }
.field-box.signature-slot { cursor: pointer; }
.field-signature-button { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; border: 0; border-radius: 0; padding: 0 4px; background: transparent; color: var(--text-link); font-size: var(--text-base); font-weight: var(--weight-semibold); letter-spacing: -.01em; text-decoration: underline; text-underline-offset: 2px; cursor: pointer; }
.field-box.field-computed { border-style: dashed; background: color-mix(in srgb, var(--accent) 6%, transparent); color: var(--text-faint); }
.field-box[data-done="true"] { border-style: solid; background: color-mix(in srgb, var(--status-ok-fg) 14%, transparent); }
/* The typed signature, previewed in the italic Inter it is drawn in. */
.signature-preview { min-height: 64px; display: grid; place-items: center; border: 1px dashed var(--border-dashed); border-radius: var(--radius-input); color: var(--text-strong); font-size: var(--text-6xl); font-style: italic; }
#signature-canvas { display: block; width: 100%; max-width: 600px; height: auto; border: 1px solid var(--border-control); border-radius: var(--radius-input); background: var(--surface-control); touch-action: none; }
.signature-pad { display: grid; gap: 8px; justify-items: start; }
.signature-methods { --segments: 3; max-width: 320px; }
/* Focus is never hidden behind the sticky toolbar (WCAG 2.4.11): a field the keyboard reaches scrolls clear of it. */
html:has(> body.signing-page) { scroll-padding-block-start: 88px; }
@media (width < 600px) {
    html:has(> body.signing-page) { scroll-padding-block-start: 150px; }
    .signing-toolbar { top: 4px; padding: 8px 10px; }
    .signing-toolbar .button-row { justify-content: stretch; }
    .signing-toolbar .button-row > .button { flex: 1 1 auto; }
    .signing-final { flex-basis: 100%; margin-inline-start: 0; }
}

/* Surfaces that arrive -- the scrim, a dialog, a toast, a menu -- enter: the scrim fades over --duration-fast, a dialog
   or toast rises 6px and fades over --duration-normal, and a menu does the same over --duration-instant, on the block
   axis only so the movement is the same in either direction. Nothing that changes in place or reorders animates.
   Motion carries no information, so a reader who prefers reduced motion gets none of these entrances, and a pending
   button's indeterminate rule stands still for them at full width. */
@keyframes snaphop-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes snaphop-rise { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }
@keyframes snaphop-pending { 0% { transform: scaleX(0); } 50% { transform: scaleX(1); } 100% { transform: scaleX(0); } }
.dialog-scrim { animation: snaphop-fade var(--duration-fast) var(--ease-out); }
.dialog, .toast { animation: snaphop-rise var(--duration-normal) var(--ease-out); }
@media (prefers-reduced-motion: reduce) {
    .dialog-scrim, .dialog, .toast, .menu-panel { animation-duration: 1ms !important; animation-delay: 0ms !important; }
    /* The pending rule is the one animation that repeats, so it stops and stands still at full width. */
    .button[aria-busy="true"]::after, .workspace-trigger[aria-busy="true"]::after { animation: none !important; }
}

/* The design system's steps, window widths repeated as literal px because a media condition cannot read a custom
   property: --bp-sm 600, --bp-md 880, --bp-lg 1180, --bp-xl 1440. Each row holds from its width up, so a width on a
   step takes that step's row: from 1440 the aside is 372px beside main and the metric strip five-up; from 1180 the
   aside is 340px and the strip still five-up; below 1180 rail, main and aside no longer fit, so the aside moves under
   main and the strip goes three-up; below 880 the strip goes two-up; and below 600 the rail is replaced by the top
   bar's Menu. */
@media (width >= 1440px) { .main-aside { grid-template-columns: minmax(0, 1fr) 372px; } }
@media (width < 1180px) {
    .main-aside { grid-template-columns: minmax(0, 1fr); }
    .delivery-metrics, .delivery-metrics-six { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (width < 880px) {
    .delivery-metrics, .delivery-metrics-six { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .field-row-four { --field-row: repeat(2, minmax(0, 1fr)); }
}
@media (width < 600px) {
    .app-page { padding: 0; }
    .app-frame { grid-template-columns: minmax(0, 1fr); min-height: 100vh; border: 0; border-radius: 0; }
    .toast-stack { inset-inline-end: 16px; }
    .rail-toggle { display: flex; }
    /* The rail is replaced, not hidden: every entry it holds is in the top bar's Menu. */
    .app-rail { display: none; }
    .topbar { padding: 0 10px; }
    .canvas { padding: 14px 10px; }
    /* Fields side by side stack (the design system's [data-field-row] below --bp-sm). */
    [data-field-row] { grid-template-columns: minmax(0, 1fr); row-gap: 10px; }
    .authoring-layout { grid-template-columns: minmax(0, 1fr); }
    .page-thumbnails { display: none; }
    .dialog-layer { padding: 16px 10px; }
}

/* Paper keeps every piece of information and drops what can only be done (the design system's print.css). Chrome is
   marked at the source with data-print="hide"; a provenance line shown only on paper stays. Tints and shadows go,
   hairlines stay, a scroll container prints whole, a row or card does not split across a page, a pending rule has
   nothing to say on paper, and an open dialog prints in place without its scrim. */
@page { margin: 14mm; }
@media print {
    [data-print="hide"], .app-rail, .rail-toggle, .menu-panel, .toast-stack, .dialog-scrim, .skip-link, .signing-toolbar .button-row, [role="tooltip"] { display: none !important; }
    [data-print="only"] { display: block !important; }
    html, body, .app-page, .app-frame, .app-main, .canvas, .signing-page { background: #fff !important; }
    * { box-shadow: none !important; }
    .app-page { padding: 0; }
    .app-frame { display: block; border: 0; border-radius: 0; }
    .scroll-list, .table-scroll, .data-dump, .disclosure { max-height: none !important; overflow: visible !important; }
    .wizard-steps { box-shadow: none; }
    .wizard-steps button:not([aria-current="step"]) { display: none; }
    .card, .table-card, tr, snaphop-list-item, .callout, .card-footnote, .metric, .page-frame { break-inside: avoid !important; }
    [aria-busy="true"]::after { display: none !important; }
    .dialog-layer { position: static; padding: 0; }
    .dialog { width: 100% !important; max-width: 100% !important; border: 1px solid #000 !important; animation: none; }
}
