/* xconversion design tokens are in tokens.css; this is the type system.
 *
 * Four families, matching the canvas: Poppins for display and headings,
 * Hanken Grotesk for body and interface, JetBrains Mono for figures, and
 * IBM Plex Sans Arabic for every Arabic role — set in its own face, never
 * the Latin one letterspaced.
 *
 * Declared here rather than interpolated through Blade: {{ }} escapes, and an
 * escaped quote inside a family name invalidates the whole declaration.
 */

body {
    margin: 0;
    font-family: 'Hanken Grotesk', system-ui, -apple-system, 'Segoe UI', sans-serif;
    font-size: 15px;
    line-height: 1.45;
    background: var(--bg);
    color: var(--text);
}

html[lang="ar"] body {
    font-family: 'IBM Plex Sans Arabic', system-ui, sans-serif;
}

/* Arabic reads smaller at the same nominal size, so it is set a step up. */
html[lang="ar"] {
    font-size: 15.5px;
}

h1, h2, h3 {
    font-family: Poppins, system-ui, sans-serif;
}

html[lang="ar"] :where(h1, h2, h3) {
    font-family: 'IBM Plex Sans Arabic', system-ui, sans-serif;
    letter-spacing: normal;
}

/* Figures are tabular everywhere so columns do not jitter between renders. */
:where(.tabular) {
    font-variant-numeric: tabular-nums;
}

/* shell — the app chrome.
 *
 * The canvas expressed hover states with a `style-hover` attribute, which is a
 * design-runtime feature and does nothing in a real browser. Those states are
 * re-expressed here as ordinary CSS, one class per interactive element, with
 * the same values the canvas used. Everything else in the shell stays inline,
 * exactly as the design wrote it.
 */

/* ── nav rail ─────────────────────────────────────────────────────── */

.xc-nav-btn:hover {
    background: rgba(var(--rail-ink), .07) !important;
    color: var(--rail-text) !important;
}

.xc-nav-btn:hover svg {
    stroke: var(--rail-text) !important;
}

.xc-search-btn:hover {
    border-color: var(--peri) !important;
    color: var(--rail-text) !important;
}

.xc-return-btn:hover {
    background: rgba(232, 163, 61, .26) !important;
}

.xc-signout:hover {
    color: var(--rail-text) !important;
}

/* ── user menu ────────────────────────────────────────────────────── */

.xc-menu-item:hover {
    background: rgba(var(--ink), .06);
}

/* ── header ───────────────────────────────────────────────────────── */

.xc-icon-btn:hover {
    background: rgba(var(--ink), .09) !important;
}

.xc-ghost-btn:hover {
    background: rgba(var(--ink), .14) !important;
}

/* ── bottom bar (phone) ───────────────────────────────────────────── */

.xc-btm-btn:hover {
    color: var(--rail-text);
}

/* Skip link — the keyboard path starts here. Visually hidden until focused. */

.xc-skip {
    position: absolute;
    inset-inline-start: -9999px;
    inset-block-start: 12px;
    z-index: 100;
    background: var(--surface);
    color: var(--text);
    border: 1px solid var(--line);
    border-radius: 12px;
    padding: 10px 16px;
    font-size: 14px;
}

.xc-skip:focus {
    inset-inline-start: 16px;
}

/* The focus ring is global rather than remembered per component. */

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
    outline: 2px solid var(--peri);
    outline-offset: 2px;
    border-radius: 10px;
}

/* ── dashboard ────────────────────────────────────────────────────── */

/* The chart crosshair is pure CSS — no JS, so it works before app.js loads
 * and cannot desync from the DOM. The numbers are also in the labels row
 * beneath, so nothing is gated behind a pointer. */
.xc-chart-cell:hover .xc-chart-rule,
.xc-chart-cell:hover .xc-chart-dot,
.xc-chart-cell:hover .xc-chart-tip {
    opacity: 1;
}

.xc-thread-card:hover {
    border-color: #5B5BF0;
    background: var(--surface-2);
}

.xc-lane-row:hover {
    background: rgba(var(--ink), .07);
}

.xc-ledger-cta:hover {
    filter: brightness(1.08);
}

/* ── modals ─────────────────────────────────────────────────────────────
 * <dialog> gives us Escape, focus trapping and inertness for free. What it
 * does not give us is a backdrop worth looking at, and ::backdrop is
 * unreachable from a style attribute, so it lives here.
 */
dialog[data-modal] {
    color: var(--text);
    margin: auto;
}

dialog[data-modal]::backdrop {
    background: rgba(10, 10, 25, .45);
    backdrop-filter: blur(2px);
}

dialog[data-modal][open] {
    animation: xc-modal-in 200ms cubic-bezier(.2, .8, .25, 1) both;
}

@keyframes xc-modal-in {
    from { opacity: 0; transform: translateY(8px) scale(.98); }
    to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    dialog[data-modal][open] { animation: none; }
}

/* The `hidden` attribute loses to an inline display.
 *
 * A UA stylesheet gives [hidden] display:none, but this project sets layout in
 * style attributes, and an inline display:flex outranks it. Anything toggled
 * with el.hidden then stays on screen — silently, because the attribute is
 * there and looks right in the inspector.
 */
[hidden] { display: none !important; }

/* ── buttons ────────────────────────────────────────────────────────────
 * Action buttons were flat coloured labels: nothing said they were pressable
 * except the cursor, and "delete" sat at the same weight as "edit" beside it.
 * These give them an edge, a hover, a press, and a focus ring — and a variant
 * per intent, so destructive reads as destructive before it is clicked.
 */
.xc-act {
    appearance: none;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 12px;
    border-radius: 10px;
    border: 1px solid var(--line);
    background: var(--surface);
    color: rgba(var(--ink), .72);
    font: inherit;
    font-size: 12.5px;
    line-height: 1;
    text-decoration: none;
    cursor: pointer;
    white-space: nowrap;
    transition: background 140ms, border-color 140ms, transform 140ms, box-shadow 140ms;
}

.xc-act:hover {
    background: rgba(var(--ink), .05);
    border-color: rgba(var(--ink), .22);
    transform: translateY(-1px);
}

.xc-act:active { transform: none; }

.xc-act:focus-visible {
    outline: 2px solid var(--peri);
    outline-offset: 2px;
}

.xc-act svg { flex: none; }

.xc-act[disabled] {
    opacity: .45;
    cursor: not-allowed;
    transform: none;
}

/* Going live is the one that changes what customers hear. */
.xc-act--go {
    color: #00806A;
    border-color: rgba(0, 168, 134, .34);
    background: rgba(0, 168, 134, .09);
}

.xc-act--go:hover {
    background: rgba(0, 168, 134, .16);
    border-color: rgba(0, 168, 134, .5);
}

.xc-act--hold {
    color: #C8791A;
    border-color: rgba(232, 163, 61, .38);
    background: rgba(232, 163, 61, .1);
}

.xc-act--hold:hover {
    background: rgba(232, 163, 61, .18);
    border-color: rgba(232, 163, 61, .55);
}

.xc-act--danger {
    color: #b83636;
    border-color: rgba(214, 69, 69, .28);
    background: rgba(214, 69, 69, .07);
}

.xc-act--danger:hover {
    background: rgba(214, 69, 69, .14);
    border-color: rgba(214, 69, 69, .45);
}

/* Square, label-less. For the secondary actions in a tight row, where four
 * full-width buttons wrap and the wrap reads as an accident. The label moves
 * to aria-label and title, so it is still announced and still on hover. */
.xc-act--icon {
    /*
     * `box-sizing` because there is no global reset for it here: without it
     * the 30 below is the content box, the padding and border are added on
     * top, and every icon button in the product renders at 46px. Three of them
     * then wrapped out of a column measured for three.
     */
    box-sizing: border-box;
    padding: 0;
    inline-size: 34px;
    block-size: 34px;
    justify-content: center;
}

/*
 * Tinted by what the button does, not decorated.
 *
 * Three actions sit together on a row — look at it, change it, lose it — and
 * three identical grey squares make the third one as easy to hit as the first.
 * The colour is the only thing separating them at a glance, so it carries the
 * meaning rather than the mood: green is safe, indigo is the working action,
 * red is the one you cannot undo.
 */
.xc-act--look {
    color: #00806A;
    border-color: rgba(0, 168, 134, .28);
    background: rgba(0, 168, 134, .08);
}

.xc-act--look:hover {
    background: rgba(0, 168, 134, .16);
    border-color: rgba(0, 168, 134, .45);
}

.xc-act--edit {
    color: var(--acc);
    border-color: rgba(28, 28, 210, .24);
    background: rgba(28, 28, 210, .07);
}

.xc-act--edit:hover {
    background: rgba(28, 28, 210, .13);
    border-color: rgba(28, 28, 210, .4);
}

/* A row of them, kept on one line until it genuinely cannot be. */
.xc-acts {
    display: flex;
    gap: 7px;
    flex-wrap: wrap;
    align-items: center;
}

/* ── surfaces ───────────────────────────────────────────────────────────
 * The canvas draws two kinds of box and they are not the same thing. A panel
 * holds content and sits still. A card stands for something you can pick, and
 * lifts when the pointer is over it — which is the only thing on a grid of
 * eight identical rectangles that says "these are choices".
 *
 * These were inline styles repeated across nine screens, drifting by a pixel
 * of radius at a time.
 */
.xc-panel {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 18px;
    box-sizing: border-box;
}

.xc-card {
    background: var(--surface);
    border: 1.5px solid var(--line);
    border-radius: 18px;
    box-sizing: border-box;
    text-decoration: none;
    color: inherit;
    transition: transform 220ms cubic-bezier(.2, .8, .25, 1), box-shadow 220ms, border-color 220ms;
}

.xc-card:hover {
    transform: translateY(-4px);
    box-shadow: 0 14px 30px rgba(10, 10, 25, .09);
}

.xc-card:focus-visible {
    outline: 2px solid var(--peri);
    outline-offset: 3px;
}

/* The one currently chosen. Its ring is its own accent where it has one. */
.xc-card--on {
    border-color: var(--peri);
    box-shadow: 0 0 0 4px rgba(143, 143, 247, .18);
}

.xc-card--on:hover {
    transform: none;
}

/* ── KPI tiles ──────────────────────────────────────────────────────────
 * Icon chip, mono label, a big tabular number, a line of context. Built four
 * times inline before this existed.
 */
.xc-kpis {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 12px;
}

.xc-kpi {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 16px;
    padding: 15px 16px;
    display: flex;
    flex-direction: column;
    gap: 9px;
}

.xc-kpi__head {
    display: flex;
    align-items: center;
    gap: 9px;
}

.xc-kpi__chip {
    inline-size: 28px;
    block-size: 28px;
    border-radius: 9px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
}

.xc-kpi__label {
    font-family: 'JetBrains Mono', monospace;
    font-size: 9.5px;
    letter-spacing: .13em;
    color: rgba(var(--ink), .35);
}

.xc-kpi__value {
    font-family: 'JetBrains Mono', monospace;
    font-weight: 500;
    font-size: 26px;
    line-height: 1;
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
}

.xc-kpi__sub {
    font-size: 13px;
    color: rgba(var(--ink), .45);
}

@media (max-width: 1100px) {
    .xc-kpis { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 620px) {
    .xc-kpis { grid-template-columns: 1fr; }
}

/* ── the primary call to action ─────────────────────────────────────────
 * Used as a class on nine screens and never actually defined — every one of
 * them carried the same inline styles instead.
 */
.xc-primary {
    appearance: none;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    border: 0;
    border-radius: 13px;
    padding: 10px 17px;
    /* The canvas's gradient, not a flat fill. It is the one place the brand
       colour moves, and a flat button beside a gradient one is the difference
       people notice without being able to name it. */
    background: linear-gradient(135deg, #1C1CD2, #5B5BF0);
    color: var(--onmine);
    font: inherit;
    font-size: 14px;
    font-weight: 600;
    line-height: 1;
    text-decoration: none;
    cursor: pointer;
    white-space: nowrap;
    transition: transform 160ms, box-shadow 160ms, filter 160ms;
}

/* The lift exists at rest too: the canvas keeps the glow under it always, and
   only deepens it on hover. */
.xc-primary {
    box-shadow: 0 12px 28px rgba(28, 28, 210, .3);
}

.xc-primary:hover {
    transform: translateY(-2px);
    filter: brightness(1.06);
    box-shadow: 0 16px 34px rgba(28, 28, 210, .36);
}

.xc-primary:active { transform: none; }

.xc-primary:focus-visible {
    outline: 2px solid var(--peri);
    outline-offset: 3px;
}

.xc-primary[disabled] {
    opacity: .45;
    cursor: not-allowed;
    transform: none;
    box-shadow: none;
}

/* A progress rail, as the canvas draws under a segment card. */
.xc-rail {
    display: block;
    block-size: 5px;
    border-radius: 3px;
    background: rgba(var(--ink), .06);
    overflow: hidden;
}

.xc-rail > span {
    display: block;
    block-size: 100%;
    border-radius: 3px;
    transition: inline-size 400ms cubic-bezier(.2, .8, .25, 1);
}

/* ── the hero figure ────────────────────────────────────────────────────
 * The canvas paints it with a gradient clipped to the glyphs, at 42px. It was
 * rendering as small flat body text, which is why the header read as a label
 * rather than as the headline it is.
 */
.xc-hero {
    font-family: 'JetBrains Mono', monospace;
    font-weight: 500;
    font-size: 38px;
    line-height: 1;
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
    background: linear-gradient(90deg, #1C1CD2, #5B5BF0);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

/* A dash is not a figure — paint it as absent rather than as a gradient. */
.xc-hero--none {
    background: none;
    color: rgba(var(--ink), .25);
}

.xc-hero__label {
    font-family: 'JetBrains Mono', monospace;
    font-size: 9px;
    letter-spacing: .14em;
    color: rgba(var(--ink), .35);
    white-space: nowrap;
}

/* ── stats inside a panel ───────────────────────────────────────────────
 * Distinct from .xc-kpi, which stands alone on the page background. These sit
 * inside a titled panel, so they take a tinted ground instead of a border —
 * the canvas's "what ran on its own" block.
 */
.xc-stats {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 12px;
}

.xc-stat {
    background: rgba(var(--ink), .035);
    border-radius: 16px;
    padding: 16px 18px;
    display: flex;
    flex-direction: column;
    gap: 9px;
}

@media (max-width: 900px) {
    .xc-stats { grid-template-columns: 1fr; }
}

/* The pulse the canvas puts on a call to action that has just appeared. */
@keyframes xc-halo {
    0%   { box-shadow: 0 0 0 0 rgba(28, 28, 210, .34); }
    70%  { box-shadow: 0 0 0 12px rgba(28, 28, 210, 0); }
    100% { box-shadow: 0 0 0 0 rgba(28, 28, 210, 0); }
}

/* ── quick links ────────────────────────────────────────────────────────
 * The canvas's side panel: a coloured bar, a label, a chevron. Used for the
 * two or three things somebody came to this screen to start.
 */
.xc-jump {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 11px 4px;
    text-decoration: none;
    color: var(--text);
    font-size: 14px;
    border-radius: 10px;
    transition: background 140ms, transform 140ms;
}

.xc-jump:hover {
    background: rgba(var(--ink), .04);
    transform: translateX(2px);
}

.xc-jump__bar {
    inline-size: 3px;
    block-size: 18px;
    border-radius: 3px;
    flex: none;
}

.xc-jump__go {
    margin-inline-start: auto;
    color: rgba(var(--ink), .3);
    flex: none;
}

/* ── the brand gradient, available everywhere ───────────────────────────
 * `--grad`, `--glow` and `--acc` were defined only on .xc-sheet-host, so any
 * component using them outside a modal got `background: var(--grad)` with no
 * value — which silently drops the declaration while `color:#fff` survives.
 * The segmented control on the channels screen came out as white text on a
 * white ground, with the *unchecked* option looking like the selected one.
 *
 * Defined here as the defaults; a sheet still overrides them per accent.
 */
:root {
    --acc: #1C1CD2;
    --grad: linear-gradient(135deg, #1C1CD2, #5B5BF0);
    --glow: rgba(28, 28, 210, .3);
}

/* ── the canvas's panel head ────────────────────────────────────────────
 * Title, then a mono counter or period in the corner, then whatever the panel
 * lets you do. One row, wrapping, on every panel that has all three.
 */
.xc-head {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.xc-head__title {
    margin: 0;
    flex: 1;
    min-inline-size: 130px;
    font-family: Poppins, sans-serif;
    font-weight: 600;
    font-size: 17px;
    letter-spacing: -0.01em;
}

.xc-meta {
    font-family: 'JetBrains Mono', monospace;
    font-size: 10.5px;
    letter-spacing: .12em;
    color: rgba(var(--ink), .35);
}

/* ── tiles ──────────────────────────────────────────────────────────────
 * The figures that live *inside* a panel, on the panel's own tinted ground —
 * as distinct from .xc-kpi, which is a card floating on the page.
 */
.xc-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: 12px;
}

.xc-tile {
    background: rgba(var(--ink), .05);
    border: 1px solid transparent;
    border-radius: 16px;
    padding: 16px 17px;
    display: flex;
    flex-direction: column;
    gap: 9px;
    transition: border-color 180ms;
}

.xc-tile:hover { border-color: #5B5BF0; }

.xc-tile__title {
    flex: 1;
    font-size: 14.5px;
    font-weight: 600;
}

.xc-tile__value {
    font-family: 'JetBrains Mono', monospace;
    font-weight: 500;
    font-size: 25px;
    line-height: 1.05;
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
}

.xc-tile__sub {
    font-size: 13.5px;
    color: rgba(var(--ink), .45);
    line-height: 1.45;
    text-wrap: pretty;
}

/* ── search, and the actions drawer beside it ───────────────────────────
 * A checkbox rather than a <details>: the drawer has to open as a full-width
 * row *below* the search, and a <details> can only ever open inside its own
 * box. The input stays focusable — moved off-screen, never display:none —
 * so the drawer opens from the keyboard.
 */
.xc-tools {
    display: flex;
    align-items: center;
    gap: 9px;
    flex-wrap: wrap;
}

.xc-find {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 1;
    min-inline-size: 180px;
    background: rgba(var(--ink), .05);
    border: 1px solid transparent;
    border-radius: 12px;
    padding: 9px 12px;
}

.xc-find:focus-within { border-color: var(--peri); }

.xc-find input {
    flex: 1;
    min-inline-size: 0;
    background: transparent;
    border: 0;
    font: inherit;
    font-size: 14px;
    color: var(--text);
    outline: none;
}

.xc-toggle {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    opacity: 0;
    pointer-events: none;
}

.xc-drop__btn {
    appearance: none;
    display: flex;
    align-items: center;
    gap: 8px;
    border: 1px solid var(--line);
    background: transparent;
    color: rgba(var(--ink), .6);
    border-radius: 12px;
    padding: 9px 14px;
    font-size: 13.5px;
    font-weight: 500;
    cursor: pointer;
    white-space: nowrap;
    user-select: none;
    transition: background 170ms, border-color 170ms, color 170ms;
}

.xc-drop__btn:hover { border-color: var(--peri); }

.xc-drop__caret { transition: transform 200ms; }

.xc-toggle:checked ~ .xc-tools .xc-drop__btn {
    background: rgba(28, 28, 210, .08);
    border-color: #5B5BF0;
    color: #1C1CD2;
}

.xc-toggle:checked ~ .xc-tools .xc-drop__caret { transform: rotate(180deg); }

.xc-toggle:focus-visible ~ .xc-tools .xc-drop__btn {
    outline: 2px solid var(--peri);
    outline-offset: 2px;
}

.xc-actbar {
    display: none;
    align-items: center;
    gap: 9px;
    flex-wrap: wrap;
    background: rgba(var(--ink), .04);
    border-radius: 14px;
    padding: 11px 12px;
    margin-block-start: 9px;
}

.xc-toggle:checked ~ .xc-actbar { display: flex; }

/* The drawer's buttons: tinted, bordered, one colour per kind of act. */
.xc-abtn {
    appearance: none;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    border: 1px solid var(--line);
    background: transparent;
    color: var(--text);
    border-radius: 12px;
    padding: 9px 15px;
    font: inherit;
    font-size: 13.5px;
    font-weight: 500;
    text-decoration: none;
    cursor: pointer;
    white-space: nowrap;
    transition: transform 170ms, filter 170ms;
}

.xc-abtn:hover { transform: translateY(-1px); }
.xc-abtn[disabled] { opacity: .45; cursor: not-allowed; transform: none; }

.xc-abtn--mine { background: #1C1CD2; border-color: #1C1CD2; color: #fff; font-weight: 600; }
.xc-abtn--go { background: rgba(0, 168, 134, .13); border-color: rgba(0, 168, 134, .3); color: var(--green); }
.xc-abtn--mid { background: rgba(154, 73, 214, .13); border-color: rgba(154, 73, 214, .3); color: #9A49D6; }
.xc-abtn--hold { background: rgba(232, 163, 61, .14); border-color: rgba(232, 163, 61, .32); color: #C8791A; }

/* ── the plain table ────────────────────────────────────────────────────
 * Columns come from the caller, because every table has different ones; the
 * rhythm — mono headers, 12px gutters, a row that lights on hover — does not.
 */
.xc-tbl {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.xc-tbl__head,
.xc-tbl__row {
    display: grid;
    gap: 0 16px;
    align-items: center;
}

.xc-tbl__head { padding: 0 12px 8px; }

.xc-tbl__head span {
    font-family: 'JetBrains Mono', monospace;
    font-size: 10px;
    letter-spacing: .14em;
    color: rgba(var(--ink), .32);
}

.xc-tbl__row {
    padding: 11px 12px;
    border-radius: 12px;
    font-size: 14px;
    transition: background 160ms;
}

.xc-tbl__row:hover { background: rgba(var(--ink), .05); }

.xc-tbl__dim { color: rgba(var(--ink), .45); }

.xc-tbl__mono {
    font-family: 'JetBrains Mono', monospace;
    font-variant-numeric: tabular-nums;
}

/* The line under a panel that says what it does not say. */
.xc-note {
    margin: 0;
    font-size: 13.5px;
    color: rgba(var(--ink), .55);
    line-height: 1.55;
    text-wrap: pretty;
}

/* ── the sheet ──────────────────────────────────────────────────────────
 * The canvas's modal: a gradient icon, a scrolling body of grouped fields,
 * a fixed footer, and — where the form produces a thing — a preview of that
 * thing beside it, on its own tinted ground.
 */
.xc-sheet-host {
    border: 0;
    padding: 0;
    background: transparent;
    inline-size: 100%;
    max-inline-size: min(760px, 94vw);
}

.xc-sheet-host--wide { max-inline-size: min(1010px, 96vw); }

.xc-sheet {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 22px;
    overflow: hidden;
    display: flex;
    max-block-size: 88vh;
    box-shadow: 0 44px 96px rgba(0, 0, 0, .42);
}

.xc-sheet__main {
    flex: 1;
    min-inline-size: 0;
    display: flex;
    flex-direction: column;
}

.xc-sheet__head {
    flex: none;
    display: flex;
    align-items: center;
    gap: 13px;
    padding: 19px 22px;
    border-block-end: 1px solid var(--line);
}

.xc-sheet__icon {
    inline-size: 44px;
    block-size: 44px;
    border-radius: 15px;
    background: var(--grad);
    box-shadow: 0 10px 24px var(--glow);
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
}

.xc-sheet__badge {
    flex: none;
    background: rgba(28, 28, 210, .09);
    color: var(--acc);
    border-radius: 20px;
    padding: 5px 12px;
    font-family: 'JetBrains Mono', monospace;
    font-size: 10px;
    letter-spacing: .14em;
}

.xc-sheet__x {
    appearance: none;
    background: rgba(var(--ink), .05);
    border: 0;
    border-radius: 11px;
    padding: 8px;
    display: flex;
    cursor: pointer;
    color: rgba(var(--ink), .45);
    flex: none;
    transition: background 160ms, color 160ms;
}

.xc-sheet__x:hover { background: rgba(var(--ink), .1); color: var(--text); }

.xc-sheet__body {
    flex: 1;
    min-block-size: 0;
    overflow-y: auto;
    padding: 18px 22px 22px;
    display: flex;
    flex-direction: column;
    gap: 20px;
}

.xc-sheet__foot {
    flex: none;
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 14px 22px;
    border-block-start: 1px solid var(--line);
}

.xc-sheet__esc {
    flex: 1;
    font-family: 'JetBrains Mono', monospace;
    font-size: 10px;
    letter-spacing: .12em;
    color: rgba(var(--ink), .3);
}

.xc-sheet__prev {
    inline-size: 314px;
    flex: none;
    border-inline-start: 1px solid var(--line);
    background: var(--surface-2);
    display: flex;
    flex-direction: column;
    gap: 14px;
    padding: 20px;
    overflow-y: auto;
}

.xc-quiet {
    appearance: none;
    background: rgba(var(--ink), .05);
    border: 0;
    border-radius: 12px;
    padding: 11px 17px;
    font: inherit;
    font-size: 14.5px;
    color: rgba(var(--ink), .6);
    cursor: pointer;
    transition: color 160ms;
}

.xc-quiet:hover { color: var(--text); }

/* The quiet one, in the brand colour.

   Grey on grey is the shape a disabled control has, and beside a filled
   button that is exactly how it reads. The brand text says "this does
   something" while the ground stays quiet, which is the whole job of a
   secondary action. */
.xc-quiet--brand {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: rgb(var(--brand));
    font-weight: 500;
}

.xc-quiet--brand:hover {
    background: rgba(var(--brand), .1);
    color: rgb(var(--brand));
}

.xc-primary--lg { padding: 11px 20px; font-size: 14.5px; border-radius: 12px; }

/* One column below the width where the preview would squeeze the form. */
@media (max-width: 880px) {
    .xc-sheet { flex-direction: column; }
    .xc-sheet__prev { inline-size: auto; border-inline-start: 0; border-block-start: 1px solid var(--line); }
}

/* ── fields inside a sheet ──────────────────────────────────────────────
 * A group is a mono heading with a rule running off it; fields sit two to a
 * row, which is the canvas's shape for every form it draws.
 */
.xc-grp {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.xc-grp__head {
    display: flex;
    align-items: center;
    gap: 10px;
}

.xc-grp__title {
    font-family: 'JetBrains Mono', monospace;
    font-size: 10px;
    letter-spacing: .16em;
    color: var(--acc);
}

.xc-grp__rule {
    flex: 1;
    block-size: 1px;
    background: var(--line);
}

.xc-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 13px;
}

.xc-f {
    display: flex;
    flex-direction: column;
    gap: 7px;
    min-inline-size: 0;
}

.xc-f--wide { grid-column: 1 / -1; }

/* Readable, not decorative.
 *
 * These were at .38 and the hints at .32, which looked calm on a mockup and
 * turned out to be the reason people fill a form in wrongly: the label is the
 * only thing saying what the box is for, and a label nobody reads is a box
 * everybody guesses at. Small and letter-spaced is still the style; faint is
 * not part of the style. */
.xc-f__label {
    font-family: 'JetBrains Mono', monospace;
    font-size: 10px;
    letter-spacing: .13em;
    color: rgba(var(--ink), .68);
}

.xc-f__hint {
    font-size: 12.5px;
    color: rgba(var(--ink), .58);
    line-height: 1.45;
}

.xc-f__err {
    font-size: 12.5px;
    color: #b83636;
}

.xc-in {
    inline-size: 100%;
    box-sizing: border-box;
    background: rgba(var(--ink), .05);
    border: 1px solid transparent;
    border-radius: 12px;
    padding: 11px 13px;
    font: inherit;
    font-size: 15px;
    color: var(--text);
    outline: none;
    transition: border-color 160ms;
}

.xc-in:focus { border-color: var(--acc); }

select.xc-in { appearance: none; cursor: pointer; }

/* A segmented control, built from radios so it submits without a line of JS. */
.xc-seg {
    display: flex;
    gap: 6px;
    background: rgba(var(--ink), .05);
    border-radius: 13px;
    padding: 4px;
}

.xc-seg label { flex: 1; cursor: pointer; }

.xc-seg input {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    opacity: 0;
    pointer-events: none;
}

.xc-seg span {
    display: block;
    border-radius: 10px;
    padding: 9px 12px;
    text-align: center;
    font-size: 14px;
    transition: background 180ms, color 180ms;
}

.xc-seg input:checked + span {
    background: var(--grad);
    color: #fff;
    font-weight: 600;
    box-shadow: 0 8px 18px var(--glow);
}

.xc-seg input:focus-visible + span {
    outline: 2px solid var(--peri);
    outline-offset: 2px;
}

/* The canvas's switch. A checkbox, so it submits and reads as one. */
.xc-switch {
    display: flex;
    align-items: center;
    gap: 11px;
    border-radius: 12px;
    padding: 9px 13px;
    background: rgba(var(--ink), .05);
    color: rgba(var(--ink), .55);
    font-size: 14px;
    cursor: pointer;
    transition: background 180ms, color 180ms;
}

.xc-switch input {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    opacity: 0;
    pointer-events: none;
}

.xc-switch__track {
    inline-size: 34px;
    block-size: 18px;
    border-radius: 12px;
    background: rgba(var(--ink), .18);
    flex: none;
    position: relative;
    transition: background 180ms;
}

.xc-switch__track::after {
    content: "";
    position: absolute;
    inset-block-start: 1px;
    inset-inline-start: 1px;
    inline-size: 16px;
    block-size: 16px;
    border-radius: 50%;
    background: #fff;
    transition: inset-inline-start 200ms cubic-bezier(.2, .8, .25, 1);
}

.xc-switch:has(input:checked) { background: rgba(28, 28, 210, .09); color: var(--acc); }
.xc-switch:has(input:checked) .xc-switch__track { background: var(--acc); }
.xc-switch:has(input:checked) .xc-switch__track::after { inset-inline-start: 17px; }
.xc-switch:has(input:focus-visible) { outline: 2px solid var(--peri); outline-offset: 2px; }

/* ── the preview card ───────────────────────────────────────────────────
 * What the form will produce, drawn as the thing itself rather than as a
 * summary of the fields.
 */
.xc-prev__label {
    flex: none;
    font-family: 'JetBrains Mono', monospace;
    font-size: 9.5px;
    letter-spacing: .16em;
    color: rgba(var(--ink), .32);
}

.xc-prev__card {
    flex: none;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 18px;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

.xc-prev__top {
    background: var(--grad);
    padding: 17px 18px;
    display: flex;
    align-items: center;
    gap: 11px;
}

.xc-prev__glyph {
    inline-size: 36px;
    block-size: 36px;
    border-radius: 12px;
    background: rgba(255, 255, 255, .2);
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
}

.xc-prev__name {
    color: #fff;
    font-family: Poppins, sans-serif;
    font-weight: 600;
    font-size: 15px;
    unicode-bidi: plaintext;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.xc-prev__in {
    padding: 16px 18px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.xc-prev__big {
    font-family: 'JetBrains Mono', monospace;
    font-weight: 500;
    font-size: 30px;
    line-height: 1;
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
}

.xc-prev__chips { display: flex; gap: 5px; flex-wrap: wrap; }

.xc-prev__chip {
    background: rgba(var(--ink), .06);
    color: rgba(var(--ink), .55);
    border-radius: 20px;
    padding: 3px 10px;
    font-size: 12.5px;
}

.xc-prev__lines { display: flex; flex-direction: column; gap: 7px; }

.xc-prev__line { display: flex; align-items: baseline; gap: 10px; }

.xc-prev__line > span:first-child { font-size: 13px; color: rgba(var(--ink), .42); flex: 1; }

.xc-prev__line > span:last-child {
    font-size: 13px;
    font-family: 'JetBrains Mono', monospace;
    text-align: end;
    unicode-bidi: plaintext;
    min-inline-size: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}


/* ── the composer's paperclip ───────────────────────────────────────────
 * A label wrapping a hidden file input, so it is a real control: focusable,
 * announced as a file chooser, and operable from the keyboard. A div with a
 * click handler is none of those.
 */
.xc-attach {
    display: flex;
    align-items: center;
    justify-content: center;
    inline-size: 40px;
    block-size: 40px;
    flex: none;
    border-radius: 12px;
    color: rgba(var(--ink), .45);
    cursor: pointer;
    transition: background 160ms, color 160ms;
}

.xc-attach:hover { background: rgba(var(--ink), .06); color: var(--text); }

.xc-attach:focus-within {
    outline: 2px solid var(--peri);
    outline-offset: 2px;
}

/* ── the line that says a click landed ──────────────────────────────────
 *
 * Actions no longer reload the page, which removes the browser's own spinner
 * and with it the only thing that said "something is happening". On a fast
 * connection nobody sees this; on a slow one it is the difference between
 * waiting and clicking twice.
 *
 * Fixed to the top of the viewport rather than the panel: it must be visible
 * wherever the reader has scrolled to, which is the whole point of the change
 * it belongs to.
 */
.xc-busy {
    position: fixed;
    inset-block-start: 0;
    inset-inline: 0;
    block-size: 2px;
    z-index: 999;
    background: var(--grad);
    transform: scaleX(0);
    transform-origin: inline-start;
    opacity: 0;
    pointer-events: none;
}

html[data-busy] .xc-busy {
    /* Creeps toward the end without reaching it: the request decides when it
     * is finished, and a bar that sits full while still loading is a lie. */
    animation: xc-creep 12s cubic-bezier(.1, .8, .2, 1) forwards;
    opacity: 1;
    transition: opacity .15s linear;
}

@keyframes xc-creep {
    0% { transform: scaleX(0); }
    40% { transform: scaleX(.6); }
    100% { transform: scaleX(.92); }
}

@media (prefers-reduced-motion: reduce) {
    html[data-busy] .xc-busy {
        animation: none;
        transform: scaleX(1);
    }
}

/* ── picking a glyph or a colour ────────────────────────────────────────
 *
 * Radios, not buttons. A colour swatch is a choice of one from many, which is
 * exactly what a radio group is — and getting that for free means the keyboard
 * works, the label is read out, and the form submits without a line of script.
 *
 * The input itself is taken out of the flow rather than hidden with
 * `display:none`, which would remove it from the tab order and from the
 * accessibility tree with it.
 */
.xc-pick {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    opacity: 0;
    pointer-events: none;
}

label:has(.xc-pick:checked) {
    outline: 2px solid var(--acc);
    outline-offset: 2px;
}

/* Focus has to be visible on the tile, because the input it belongs to is
 * one pixel wide and invisible. */
label:has(.xc-pick:focus-visible) {
    outline: 2px solid var(--acc);
    outline-offset: 3px;
}

/* A tick that only means something when it is the chosen one. */
.xc-pick--mark:not(:checked) + svg {
    opacity: 0;
}

/* A glyph stays legible unchosen — it is what the tile is for. */
.xc-pick--glyph:not(:checked) + svg {
    opacity: .38;
}

.xc-pick--glyph:checked + svg {
    color: var(--acc);
}

/* ── a panel that can be put away ───────────────────────────────────────
 *
 * <details> carries the behaviour; this only removes the browser's own marker
 * and turns the caret to say which way the panel will move.
 */
.xc-fold > summary::-webkit-details-marker { display: none; }
.xc-fold > summary::marker { content: ''; }

.xc-fold > summary:hover .xc-fold__caret {
    background: rgba(var(--ink), .1);
}

.xc-fold > summary:focus-visible {
    outline: 2px solid var(--acc);
    outline-offset: -2px;
    border-radius: 18px;
}

.xc-fold__caret {
    color: rgba(var(--ink), .5);
    transform: rotate(-90deg);
    transition: transform 180ms ease;
}

.xc-fold[open] > summary .xc-fold__caret {
    transform: none;
}

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

/* ── the wizard ─────────────────────────────────────────────────────────
 *
 * One form, several panels, one visible at a time. The steps are not separate
 * requests: a half-made agent saved across four posts is four chances to end
 * up with a row nobody finished.
 */
.xc-step[hidden] { display: none !important; }

.xc-dots {
    display: flex;
    gap: 7px;
    align-items: center;
}

.xc-dot {
    inline-size: 26px;
    block-size: 4px;
    border-radius: 4px;
    background: rgba(var(--ink), .12);
    transition: background 200ms ease;
}

.xc-dot[data-on] { background: var(--acc); }

/* ── the agent thinking ─────────────────────────────────────────────────
 *
 * Shown while a real model is being waited on. Three dots rather than a
 * spinner, because it is a message being written and that is what a person
 * writing a message looks like in every chat app they have ever used.
 */
.xc-think {
    display: inline-flex;
    gap: 4px;
    align-items: center;
}

.xc-think span {
    inline-size: 6px;
    block-size: 6px;
    border-radius: 50%;
    background: rgba(var(--ink), .35);
    animation: xc-think 1.2s infinite ease-in-out;
}

.xc-think span:nth-child(2) { animation-delay: .16s; }
.xc-think span:nth-child(3) { animation-delay: .32s; }

@keyframes xc-think {
    0%, 60%, 100% { transform: translateY(0); opacity: .45; }
    30% { transform: translateY(-4px); opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
    .xc-think span { animation: none; }
}

/* ── the mark that means a model is involved ────────────────────────────
 *
 * A sparkle, because every product now uses one for exactly this and a
 * brokerage should not have to learn our private symbol for it. Two stars at
 * different sizes rather than one: a single sparkle reads as decoration, two
 * reading at different rhythms read as something happening.
 *
 * It sits on the agent screens and nowhere else. A mark that appears on every
 * panel stops meaning anything, and the whole point is that it tells you which
 * parts of this product are a model rather than a rule.
 */
.xc-spark {
    display: inline-flex;
    flex: none;
    color: var(--acc);
}

.xc-spark__big,
.xc-spark__sm {
    transform-origin: center;
    animation: xc-spark 3.2s ease-in-out infinite;
}

.xc-spark__sm {
    animation-delay: 1.1s;
    animation-duration: 2.6s;
}

@keyframes xc-spark {
    0%, 70%, 100% { opacity: .85; transform: scale(1); }
    18% { opacity: 1; transform: scale(1.18); }
    34% { opacity: .7; transform: scale(.96); }
}

/* The live agent, breathing. Slow enough to read as "on" rather than as an
 * alert — a card that pulses quickly is a card asking to be clicked. */
.xc-alive {
    position: relative;
}

.xc-alive::after {
    content: '';
    position: absolute;
    inset: -1.5px;
    border-radius: inherit;
    pointer-events: none;
    box-shadow: 0 0 0 0 var(--glow);
    animation: xc-alive 3.6s ease-out infinite;
}

@keyframes xc-alive {
    0% { box-shadow: 0 0 0 0 rgba(28, 28, 210, .28); }
    70% { box-shadow: 0 0 0 10px rgba(28, 28, 210, 0); }
    100% { box-shadow: 0 0 0 0 rgba(28, 28, 210, 0); }
}

@media (prefers-reduced-motion: reduce) {
    .xc-spark__big,
    .xc-spark__sm,
    .xc-alive::after { animation: none; }
}

/* ── the veil, while something is being made ────────────────────────────
 *
 * Covers the form it belongs to rather than the screen. A page-wide overlay
 * says "the product is busy"; this says "the thing you pressed is happening",
 * which is the smaller and truer claim — everything else on the page still
 * works, and the rail is still there to click away from.
 *
 * The thin bar at the top of the window already says a request is in flight.
 * This is for the two actions where somebody has typed a lot and the question
 * "did that go?" is worth answering loudly.
 */
.xc-veil {
    position: absolute;
    inset: 0;
    z-index: 5;
    border-radius: inherit;
    background: color-mix(in srgb, var(--surface) 82%, transparent);
    backdrop-filter: blur(3px);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 14px;
    text-align: center;
    padding: 24px;
}

/* Breathes rather than spins. A spinner means "wait"; something growing and
 * settling means "being made", which is what is actually happening. */
.xc-veil__spark {
    color: var(--acc);
    animation: xc-veil-spark 1.9s ease-in-out infinite;
}

.xc-veil__spark svg { display: block; }

@keyframes xc-veil-spark {
    0%, 100% { transform: scale(.82) rotate(-6deg); opacity: .65; }
    50% { transform: scale(1.12) rotate(6deg); opacity: 1; }
}

/* A ring that opens outward from it, so the movement reads as something
 * radiating rather than as an icon wobbling. */
.xc-veil__ring {
    position: absolute;
    inline-size: 84px;
    block-size: 84px;
    border-radius: 50%;
    border: 2px solid var(--acc);
    opacity: 0;
    animation: xc-veil-ring 1.9s ease-out infinite;
}

.xc-veil__ring:nth-of-type(2) { animation-delay: .65s; }

@keyframes xc-veil-ring {
    0% { transform: scale(.55); opacity: .5; }
    80% { transform: scale(1.5); opacity: 0; }
    100% { opacity: 0; }
}

.xc-veil__text {
    font-size: 14px;
    color: rgba(var(--ink), .6);
    text-wrap: pretty;
}

@media (prefers-reduced-motion: reduce) {
    .xc-veil__spark,
    .xc-veil__ring { animation: none; }
    .xc-veil__ring { opacity: .3; }
}

/* ── the big one ──────────────────────────────────────────────────────────
 *
 * Same veil, given the room. Finishing the form that tells the agent what the
 * business *is* is the end of a job somebody sat down to do, and a 38px
 * sparkle in the middle of a full-height sheet reads as a spinner rather than
 * as an ending.
 */
.xc-veil--lg { gap: 18px; }

.xc-veil--lg .xc-veil__ring {
    inline-size: 150px;
    block-size: 150px;
    border-width: 2px;
}

.xc-veil--lg .xc-veil__text {
    font-size: 16.5px;
    font-weight: 600;
    color: rgba(var(--ink), .72);
}

/* ── the beat between two steps ───────────────────────────────────────────
 *
 * A transition, not a wait: nothing is happening behind this. It covers the
 * panels only, so the dots above keep advancing in plain sight — that is the
 * difference between a pause that reads as progress and one that reads as a
 * stall.
 *
 * Every rule here is decoration. With the stylesheet gone the steps still
 * change, instantly, which is the correct way for an animation to fail.
 */
.xc-stage { position: relative; }

.xc-stage__magic {
    position: absolute;
    inset: -8px;
    z-index: 4;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 16px;
    background:
        radial-gradient(60% 60% at 50% 50%, rgba(91, 91, 240, .10), transparent 70%),
        color-mix(in srgb, var(--surface) 72%, transparent);
    backdrop-filter: blur(2.5px);
    -webkit-backdrop-filter: blur(2.5px);
    animation: xc-stage-in .16s ease-out;
}

@keyframes xc-stage-in {
    from { opacity: 0; }
}

.xc-stage__spark {
    color: var(--acc);
    animation: xc-stage-spark .38s cubic-bezier(.3, .8, .3, 1);
}

.xc-stage__spark svg { display: block; }

/* Out and back: the sparkle arrives small, swells as the panel behind it is
   swapped, and is gone before it can be looked at directly. */
@keyframes xc-stage-spark {
    0% { transform: scale(.5) rotate(-24deg); opacity: 0; }
    45% { transform: scale(1.18) rotate(6deg); opacity: 1; }
    100% { transform: scale(.94) rotate(0); opacity: .5; }
}

/* The panel that just arrived, rising into place. Short, and under the veil
   for the first half of it, so it is felt more than watched. */
.xc-step--came { animation: xc-step-came .34s cubic-bezier(.2, .75, .3, 1); }

@keyframes xc-step-came {
    from { opacity: 0; transform: translateY(9px) scale(.99); }
}

@media (prefers-reduced-motion: reduce) {
    .xc-stage__magic,
    .xc-stage__spark,
    .xc-step--came { animation: none; }
}

/* ── the knowledge panel, and the parts of the form ───────────────────────
 *
 * Everything below is decoration. With the stylesheet gone the panel is a
 * list and the form is a form, which is the correct way for decoration to
 * fail.
 */

/* A slow band of colour along the top edge of the one panel on the screen.
   Not a border and not a highlight — a sign that something on this page is
   alive, on the page whose whole subject is a thing that answers by itself. */
/* `flex: none` is load-bearing, not tidiness. `overflow: hidden` gives a flex
   item an automatic minimum size of zero, so without this the panel shrinks
   below its own content and the bottom half of the page is simply clipped —
   with no scrollbar, because the column above it never learns the content was
   taller. */
.xc-aurora { position: relative; overflow: hidden; flex: none; }

.xc-aurora::before {
    content: '';
    position: absolute;
    inset-block-start: 0;
    inset-inline: 0;
    block-size: 2px;
    background: linear-gradient(90deg,
        transparent, rgba(28, 28, 210, .75), rgba(154, 73, 214, .75),
        rgba(61, 140, 232, .75), transparent);
    background-size: 220% 100%;
    animation: xc-aurora 9s linear infinite;
}

@keyframes xc-aurora {
    to { background-position: 220% 0; }
}

/* The icon beside each part of the form, in that part's own colour. */
.xc-glowbox {
    inline-size: 34px;
    block-size: 34px;
    border-radius: 12px;
    background: rgba(var(--tint), .12);
    box-shadow: 0 0 0 1px rgba(var(--tint), .16), 0 6px 16px -8px rgba(var(--tint), .6);
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
}

/* A dot in a section's colour, standing in for an icon on a list row. */
.xc-bead {
    inline-size: 7px;
    block-size: 7px;
    border-radius: 50%;
    flex: none;
    background: rgb(var(--tint, 91, 91, 240));
    box-shadow: 0 0 0 3px rgba(var(--tint, 91, 91, 240), .16);
}

/* The label above an answer. Monospaced and small, so six of them down a
   panel read as a form rather than as six headings. */
.xc-tag {
    font-size: 11px;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: rgba(var(--ink), .62);
    font-family: 'JetBrains Mono', ui-monospace, monospace;
}

/* Stored, not yet acted on. Said plainly rather than left to be discovered. */
.xc-wait {
    font-size: 10.5px;
    letter-spacing: .05em;
    text-transform: uppercase;
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    color: #8A6A1F;
    background: rgba(232, 163, 61, .14);
    border-radius: 20px;
    padding: 3px 9px;
    flex: none;
    /* Wraps rather than running off the edge of its card. It used to be
       `nowrap`, which is right for two words and wrong the moment somebody
       writes a sentence into a badge — and somebody did. */
    max-inline-size: 100%;
    box-sizing: border-box;
    text-wrap: pretty;
}

/* One call a connector may make. */
.xc-tool {
    font-size: 10.5px;
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    color: rgba(var(--ink), .55);
    background: rgba(var(--ink), .05);
    border-radius: 6px;
    padding: 2px 7px;
    overflow-wrap: anywhere;
}

/* The empty state, which is the state this screen is really about. The glow
   behind the sparkle breathes; nothing else on the panel moves, so it is the
   one thing the eye is taken to. */
.xc-invite {
    border: 1px dashed var(--line);
    border-radius: 16px;
    padding: 26px 22px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
    text-align: center;
    background: radial-gradient(70% 90% at 50% 0%, rgba(91, 91, 240, .06), transparent 70%);
}

.xc-invite__halo {
    inline-size: 56px;
    block-size: 56px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: radial-gradient(circle, rgba(91, 91, 240, .18), rgba(91, 91, 240, 0) 70%);
    animation: xc-halo 3.4s ease-in-out infinite;
}

@keyframes xc-halo {
    0%, 100% { transform: scale(.94); opacity: .75; }
    50% { transform: scale(1.06); opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
    .xc-aurora::before,
    .xc-invite__halo { animation: none; }
}

/* An example, not an answer. Distinct from typed text and still readable —
   the forms on this product lean on worked examples to explain themselves,
   and an example nobody can read explains nothing. */
.xc-in::placeholder {
    color: rgba(var(--ink), .42);
    opacity: 1;
}

/* What was typed, at full strength. A field somebody has filled in is the
   most important text on a form and was inheriting the body colour. */
.xc-in {
    color: rgba(var(--ink), .92);
}

/* ── choosing a document ──────────────────────────────────────────────────
 *
 * The browser's own file input is a grey button and the words "no file
 * chosen", which on a panel about the documents an agent will quote reads as
 * an afterthought. The input is still underneath all of this — invisible,
 * covering the whole zone — so clicking and tabbing to it work with the
 * script and the stylesheet both gone.
 */
.xc-drop {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 7px;
    padding: 26px 20px;
    border: 1.5px dashed var(--line);
    border-radius: 16px;
    background: radial-gradient(80% 100% at 50% 0%, rgba(61, 140, 232, .05), transparent 70%);
    text-align: center;
    cursor: pointer;
    transition: border-color .15s, background-color .15s;
}

.xc-drop:hover,
.xc-drop:focus-within { border-color: rgba(61, 140, 232, .55); }

/* While something is being dragged over it. */
.xc-drop[data-over] {
    border-color: rgb(61, 140, 232);
    border-style: solid;
    background: rgba(61, 140, 232, .07);
}

/* The real control. Invisible, not absent: `display:none` would take it off
   the keyboard and out of the click. */
.xc-drop__input {
    position: absolute;
    inset: 0;
    inline-size: 100%;
    block-size: 100%;
    opacity: 0;
    cursor: pointer;
}

.xc-drop__icon {
    inline-size: 46px;
    block-size: 46px;
    border-radius: 14px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(61, 140, 232, .12);
    color: rgb(61, 140, 232);
}

.xc-drop__say {
    font-size: 14px;
    font-weight: 600;
    color: rgba(var(--ink), .78);
}

.xc-drop__types {
    font-size: 12px;
    color: rgba(var(--ink), .5);
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    letter-spacing: .01em;
    text-wrap: pretty;
}

/* One chosen file, before it has been saved. */
.xc-file {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 9px 11px;
    border: 1px solid var(--line);
    border-radius: 12px;
    background: var(--surface);
}

.xc-file[data-bad] {
    border-color: rgba(184, 54, 54, .4);
    background: rgba(184, 54, 54, .04);
}

.xc-file__thumb {
    inline-size: 38px;
    block-size: 38px;
    border-radius: 9px;
    flex: none;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(var(--ink), .06);
}

.xc-file__thumb img {
    inline-size: 100%;
    block-size: 100%;
    object-fit: cover;
    display: block;
}

/* A picture shows itself; everything else shows what it is. */
.xc-file__thumb[data-ext] {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 9.5px;
    letter-spacing: .05em;
    color: rgba(var(--ink), .55);
}

.xc-file__said {
    flex: 1;
    min-inline-size: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.xc-file__name {
    font-size: 13.5px;
    font-weight: 600;
    color: rgba(var(--ink), .88);
    overflow-wrap: anywhere;
}

.xc-file__meta {
    font-size: 11.5px;
    color: rgba(var(--ink), .5);
    font-family: 'JetBrains Mono', ui-monospace, monospace;
}

.xc-file[data-bad] .xc-file__meta { color: #b83636; }

.xc-file__out {
    inline-size: 28px;
    block-size: 28px;
    border-radius: 9px;
    border: 1px solid var(--line);
    background: var(--surface);
    color: rgba(var(--ink), .55);
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
    cursor: pointer;
}

.xc-file__out:hover {
    border-color: rgba(184, 54, 54, .4);
    color: #b83636;
}

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

/* The caption under the sparkle, fading between one stage and the next. */
.xc-veil__text { transition: opacity .22s ease; }

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

/* ── a grid of choices ────────────────────────────────────────────────────
 * Three template cards, then four, then however many ship. Auto-fit rather
 * than a fixed column count, so the shelf reflows instead of the cards
 * getting narrower than their own sentences.
 */
.xc-cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(255px, 1fr));
    gap: 11px;
}

/* A small count on a card: "installed twice". */
.xc-pill {
    font-size: 10.5px;
    letter-spacing: .04em;
    text-transform: uppercase;
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    color: rgba(var(--ink), .6);
    background: rgba(var(--ink), .07);
    border-radius: 20px;
    padding: 3px 9px;
    flex: none;
    white-space: nowrap;
}

/* ── a numbered rule, and a list of words ─────────────────────────────────*/

/* The position of a routing rule. A number in a tinted square rather than a
   column of digits: the order is the whole point of that panel. */
.xc-ord {
    inline-size: 24px;
    block-size: 24px;
    border-radius: 8px;
    flex: none;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 11.5px;
    font-weight: 500;
    color: rgb(var(--tint));
    background: rgba(var(--tint), .13);
}

/* Where that rule sends it. */
.xc-goes {
    font-size: 12.5px;
    color: rgba(var(--ink), .72);
    font-weight: 500;
    flex: none;
    max-inline-size: 40%;
    text-align: end;
    text-wrap: pretty;
}

/* One word in a list of them. */
.xc-chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 4px 6px 4px 11px;
    border-radius: 20px;
    background: rgba(91, 91, 240, .1);
    color: rgba(var(--ink), .82);
    font-size: 13px;
    unicode-bidi: plaintext;
}

.xc-chip button {
    inline-size: 18px;
    block-size: 18px;
    border-radius: 50%;
    border: 0;
    background: rgba(var(--ink), .08);
    color: rgba(var(--ink), .55);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    flex: none;
}

.xc-chip button:hover {
    background: rgba(184, 54, 54, .14);
    color: #b83636;
}

/* ── one of two ways of working ───────────────────────────────────────────
 *
 * A card you press, wrapping the radio that actually carries the answer. The
 * radio keeps `.xc-pick`, which is what makes it one invisible pixel and lets
 * `label:has(.xc-pick:checked)` draw the chosen state — so this is only the
 * box around it.
 */
.xc-choice {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 13px 15px;
    border: 1px solid var(--line);
    border-radius: 14px;
    background: var(--surface);
    cursor: pointer;
    position: relative;
    transition: border-color .15s, background-color .15s;
}

.xc-choice:hover { border-color: rgba(var(--ink), .22); }

label.xc-choice:has(.xc-pick:checked) {
    border-color: var(--acc);
    background: rgba(91, 91, 240, .05);
    /* The generic rule draws an outline; on a card a border reads better, so
       the outline is taken back off just here. */
    outline: none;
}

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

/* ── a capital letter at the front ────────────────────────────────────────
 *
 * Every heading and button in this product is written in sentence case with a
 * lowercase first letter — a deliberate style that reads as casual on a chat
 * tool and as unfinished on a business one, which is the half somebody
 * noticed.
 *
 * Done in CSS with ::first-letter rather than by rewriting several hundred
 * strings in two languages. `text-transform: capitalize` was the obvious
 * alternative and is wrong: it would produce "Who A Lead Goes To", which is
 * not title case in English and is nonsense in Arabic.
 *
 * Arabic has no letter case, so this is a no-op there rather than something
 * that has to be switched off.
 *
 * ── The three that used to be in this list ───────────────────────────────
 *
 * `.xc-primary`, `.xc-act` and `.xc-abtn` were here and never did anything.
 * All three are `display: inline-flex`, and ::first-letter applies to block
 * containers only — and a flex container puts a bare text node in an
 * anonymous box, so there is not even a child left to name.
 *
 * So the product kept a stylesheet that said it capitalised every button and
 * a screen full of buttons reading "check eligibility" and "rotate secret".
 * Those labels are capitalised where they are written instead: see
 * LABEL_PATHS in scripts/genlang.py.
 *
 * What is left here is the block ones, where the selector reaches.
 */
.xc-head__title::first-letter,
.xc-quiet::first-letter,
.xc-fold > summary .xc-cap::first-letter {
    text-transform: uppercase;
}

/* The picture at the top of a template card. A fixed height so a shelf of
   cards has one horizon rather than three, and a dotted ground borrowed from
   the canvas so it reads as a diagram rather than as a photograph. */
.xc-art {
    display: block;
    block-size: 112px;
    flex: none;
    background:
        radial-gradient(rgba(var(--ink), .09) 1px, transparent 1px) 0 0 / 11px 11px,
        linear-gradient(160deg, rgba(var(--tint), .07), rgba(var(--tint), .02));
    border-block-end: 1px solid var(--line);
}

.xc-art svg {
    inline-size: 100%;
    block-size: 100%;
    display: block;
}

/* ── save, test, publish ──────────────────────────────────────────────────
 *
 * The bar above a workflow being configured. In that order because the order
 * is the advice: test before publish is the whole point of a draft.
 */
.xc-bar {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    padding: 11px 13px;
    border: 1px solid var(--line);
    border-radius: 14px;
    background: var(--surface);
}

.xc-bar__state {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 9.5px;
    letter-spacing: .11em;
    text-transform: uppercase;
    border-radius: 20px;
    padding: 4px 10px;
    color: rgba(var(--ink), .5);
    background: rgba(var(--ink), .07);
}

.xc-bar__state[data-on="live"] { color: var(--green); background: rgba(0, 168, 134, .14); }
.xc-bar__state[data-on="paused"] { color: #C8791A; background: rgba(232, 163, 61, .15); }

/* Testing is neither a save nor a publish, so it is neither grey nor brand. */
.xc-act--go {
    color: var(--green);
    border-color: rgba(0, 168, 134, .35);
    background: rgba(0, 168, 134, .08);
}

.xc-act--go:hover { background: rgba(0, 168, 134, .15); }

/* ── six stops ────────────────────────────────────────────────────────────
 *
 * Numbered stops rather than a progress bar. A bar says how far along
 * something is; these say what the remaining screens are about, which on a
 * builder somebody will leave and come back to is the more useful fact.
 */
.xc-stops {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.xc-stop > a,
.xc-stop > span {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 7px 13px 7px 8px;
    border-radius: 20px;
    font-size: 13px;
    color: rgba(var(--ink), .45);
    background: rgba(var(--ink), .04);
    text-decoration: none;
    white-space: nowrap;
}

.xc-stop > a:hover { background: rgba(var(--ink), .08); color: rgba(var(--ink), .7); }

.xc-stop__n {
    inline-size: 22px;
    block-size: 22px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 11px;
    background: rgba(var(--ink), .09);
    color: rgba(var(--ink), .5);
    flex: none;
}

/* Reached, and behind you. */
.xc-stop[data-done] > a { color: rgba(var(--ink), .72); }
.xc-stop[data-done] .xc-stop__n { background: rgba(0, 168, 134, .16); color: var(--green); }

/* Where you are now. */
.xc-stop[data-on] > span {
    background: var(--grad);
    color: #fff;
    box-shadow: 0 6px 16px -8px var(--glow, rgba(28, 28, 210, .5));
}

.xc-stop[data-on] .xc-stop__n { background: rgba(255, 255, 255, .22); color: #fff; }

/* A group of related questions on a builder screen. Three light groups beat
   six boxes in a column: each one is a question somebody can answer without
   having to read the next. */
.xc-lot {
    display: flex;
    flex-direction: column;
    gap: 13px;
    padding: 16px 17px;
    border: 1px solid var(--line);
    border-radius: 16px;
    background: var(--surface);
}

.xc-lot__title {
    font-family: Poppins, sans-serif;
    font-weight: 600;
    font-size: 14.5px;
}

/* A tickable word — a language, an exit condition. */
.xc-tick {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 8px 13px;
    border: 1px solid var(--line);
    border-radius: 20px;
    cursor: pointer;
    font-size: 13.5px;
    user-select: none;
}

.xc-tick:has(input:checked) {
    border-color: var(--acc);
    background: rgba(91, 91, 240, .07);
    color: rgba(var(--ink), .9);
}

.xc-tick input { accent-color: var(--acc); }

/* Locked on, and saying why rather than looking broken. */
.xc-tick[data-locked] { opacity: .75; cursor: not-allowed; }

/* ── a step, as a card ────────────────────────────────────────────────────
 *
 * A vertical list rather than a canvas with lines. A canvas is better for
 * looking at a flow and worse for writing one, and every real flow here is
 * nearer a list than a map.
 */
.xc-scard {
    border: 1px solid var(--line);
    border-radius: 16px;
    background: var(--surface);
    overflow: hidden;
}

.xc-scard__head {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 11px 13px;
    background: rgba(var(--ink), .03);
    border-block-end: 1px solid var(--line);
    flex-wrap: wrap;
}

.xc-scard__n {
    inline-size: 24px;
    block-size: 24px;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 11.5px;
    background: rgba(91, 91, 240, .13);
    color: var(--acc);
    flex: none;
}

/* The name is edited where it is read. A card whose title opened a dialog
   would be a dialog per rename, and renaming is most of tidying a flow up. */
.xc-scard__name {
    flex: 1;
    min-inline-size: 140px;
    border: 1px solid transparent;
    background: transparent;
    border-radius: 9px;
    padding: 5px 8px;
    font: inherit;
    font-size: 14px;
    font-weight: 600;
    color: rgba(var(--ink), .9);
}

.xc-scard__name:hover { border-color: var(--line); }
.xc-scard__name:focus { border-color: var(--acc); outline: none; background: var(--surface); }

.xc-scard__acts { display: flex; gap: 5px; flex: none; }

.xc-scard__body {
    padding: 13px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.xc-scard__exits {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    padding-block-start: 11px;
    border-block-start: 1px dashed var(--line);
}

.xc-scard__exits .xc-f { flex: 1 1 190px; }

/* A message in one language, with its tag and its variable picker. */
.xc-say { display: flex; align-items: flex-start; gap: 8px; }

.xc-say__lang {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 10px;
    letter-spacing: .06em;
    color: rgba(var(--ink), .5);
    background: rgba(var(--ink), .06);
    border-radius: 6px;
    padding: 6px 7px;
    flex: none;
    margin-block-start: 5px;
}

.xc-say textarea { flex: 1; min-inline-size: 0; }

.xc-vars {
    flex: none;
    /* Wide enough for its own label. It was 42px, which is wide enough for a
       select's arrow and not for the word next to it. */
    inline-size: 96px;
    border: 1px solid var(--line);
    border-radius: 9px;
    background: rgba(var(--ink), .04);
    color: rgba(var(--ink), .6);
    font-size: 12px;
    padding: 7px 4px;
    cursor: pointer;
    align-self: flex-start;
}

/* One repeatable row: an option, a rule, a header. */
.xc-row {
    display: flex;
    gap: 7px;
    align-items: center;
    flex-wrap: wrap;
}

.xc-row .xc-in { flex: 1; min-inline-size: 110px; }

/* Choosing what kind of step to add. */
.xc-picker {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 8px;
    padding: 13px;
    border: 1px solid var(--line);
    border-radius: 16px;
    background: var(--surface);
    margin-block-end: 10px;
}

.xc-picker__one {
    display: flex;
    flex-direction: column;
    gap: 3px;
    align-items: flex-start;
    text-align: start;
    padding: 11px 13px;
    border: 1px solid var(--line);
    border-radius: 12px;
    background: var(--surface);
    cursor: pointer;
}

.xc-picker__one:hover { border-color: var(--acc); background: rgba(91, 91, 240, .05); }

.xc-picker__name { font-size: 13.5px; font-weight: 600; color: rgba(var(--ink), .9); }
.xc-picker__sub { font-size: 12px; color: rgba(var(--ink), .55); text-wrap: pretty; }

/* A read-only summary: label on the left, fact on the right. */
.xc-facts {
    margin: 0;
    display: grid;
    grid-template-columns: minmax(120px, auto) 1fr;
    gap: 8px 16px;
    align-items: baseline;
}

.xc-facts dt {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 10px;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: rgba(var(--ink), .5);
}

.xc-facts dd {
    margin: 0;
    font-size: 13.5px;
    color: rgba(var(--ink), .85);
    text-wrap: pretty;
    unicode-bidi: plaintext;
}

/* A share of something, as a bar. Wide enough to compare at a glance and
   short enough that the number beside it stays the thing being read. */
.xc-meter {
    flex: 1;
    min-inline-size: 60px;
    block-size: 8px;
    border-radius: 6px;
    background: rgba(var(--ink), .07);
    overflow: hidden;
}

.xc-meter__fill {
    display: block;
    block-size: 100%;
    border-radius: 6px;
}

/* ── rows arriving ────────────────────────────────────────────────────────
 *
 * A short stagger on a list that has just been drawn. Decoration, and it fails
 * correctly: with the stylesheet gone the rows are simply there.
 *
 * `--i` is the row's index, set inline, and the delay is capped by the small
 * multiplier — a workspace of forty people must not have its last row arrive
 * two seconds after its first. Past about eight rows the difference stops
 * being perceptible anyway, which is why this is 26ms and not 80.
 */
.xc-row--in {
    animation: xc-row-in .34s cubic-bezier(.2, .75, .3, 1) backwards;
    animation-delay: calc(var(--i, 0) * 26ms);
}

@keyframes xc-row-in {
    from { opacity: 0; transform: translateY(7px); }
}

/* A row that can be acted on lifts very slightly under the cursor. Enough to
   say "this is a thing", not enough to move the text somebody is reading. */
.xc-rows > .xc-row {
    transition: border-color 160ms, transform 160ms, box-shadow 160ms;
}

.xc-rows > .xc-row:hover {
    border-color: rgba(var(--ink), .18);
    transform: translateY(-1px);
    box-shadow: 0 6px 18px rgba(var(--ink), .05);
}

@media (prefers-reduced-motion: reduce) {
    .xc-row--in { animation: none; }
    .xc-rows > .xc-row:hover { transform: none; }
}

/* A team card's banner. Shorter than a workflow's, because a team card
   carries a queue count and a row of names under it and would otherwise be
   mostly picture. */
.xc-art--team {
    block-size: 72px;
    border-block-end: 0;
    border-end-start-radius: 0;
    border-end-end-radius: 0;
}

/* ── the getting-started checklist ────────────────────────────────────────
 *
 * Built on <details>, like every other fold in this product: the browser
 * already knows how to open one, reach it with a keyboard, and find text
 * inside a closed one. Without the stylesheet each step is an open disclosure
 * with a heading, which is the right way for decoration to fail.
 */
.xc-task {
    border: 1px solid var(--line);
    border-radius: 14px;
    background: var(--surface-2);
    overflow: hidden;
    transition: border-color 160ms, background 160ms;
}

.xc-task[open] {
    border-color: rgba(var(--tint), .35);
    background: rgba(var(--tint), .045);
}

.xc-task__head {
    list-style: none;
    cursor: pointer;
    padding: 13px 15px;
    display: flex;
    align-items: center;
    gap: 12px;
}

.xc-task__head::-webkit-details-marker { display: none; }

/* The number, and then the tick. Never a control — nothing here can be
   clicked to pretend a step is finished. */
/* A ring with a tick in it, grey until the step is done and green after.
   The same shape either way on purpose: a checklist whose marks change shape
   as they complete is a checklist that moves under the reader. */
.xc-task__mark {
    flex: none;
    display: flex;
    align-items: center;
    justify-content: center;
    color: rgba(var(--ink), .28);
}

.xc-task__mark[data-done] {
    color: var(--green);
    animation: xc-ticked .4s cubic-bezier(.2, .8, .3, 1);
}

@keyframes xc-ticked {
    0% { transform: scale(.4); opacity: 0; }
    60% { transform: scale(1.12); }
}

.xc-task__caret {
    flex: none;
    color: rgba(var(--ink), .35);
    transition: transform 180ms;
}

.xc-task[open] .xc-task__caret { transform: rotate(180deg); }

.xc-task__body {
    padding: 0 15px 16px 56px;
    display: flex;
    gap: 18px;
    align-items: flex-start;
    flex-wrap: wrap;
}

/* The bar filling in. Animated from nothing on first paint, so a workspace
   that has just finished a step sees it move rather than finding it moved. */
.xc-meter__fill--grow { animation: xc-grow .6s cubic-bezier(.2, .8, .3, 1); }

@keyframes xc-grow {
    from { inline-size: 0; }
}

@media (prefers-reduced-motion: reduce) {
    .xc-task__mark[data-done],
    .xc-meter__fill--grow { animation: none; }
    .xc-task__caret { transition: none; }
}

/* On a phone the body loses the indent: 53px of empty gutter on a 360px
   screen is a third of the line length spent on alignment. */
@media (max-width: 720px) {
    /* 56px of empty gutter on a 360px screen is a sixth of the line length
       spent on alignment. */
    .xc-task__body { padding-inline-start: 15px; }
}

/* ── "connect whatsapp to go live" ────────────────────────────────────────
 *
 * One line high, on every screen, until there is a number. Deliberately slim:
 * something permanent that takes a fifth of the screen is something people
 * learn to look past, and something that takes 38px is something they
 * eventually click.
 *
 * Never WhatsApp green. The band is amber when it is asking and grey-blue
 * while it waits, because green here would read as "connected".
 */
/* A plain checkbox, sized up and tinted.

   Native rather than a drawn one: it keeps the keyboard behaviour, the
   indeterminate state, the platform's own focus ring and the screen-reader
   role, all of which a <span> pretending to be a checkbox has to reimplement
   and usually reimplements incompletely. `accent-color` is the whole styling
   budget this needs. */
.xc-check {
    inline-size: 17px;
    block-size: 17px;
    flex: none;
    accent-color: rgb(var(--brand));
    cursor: pointer;
}

/* ── saying something went wrong, so it is seen ────────────────────────── */

/* The small one, for a field. */
.xc-alarm {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    margin: 0;
    padding: 10px 13px;
    border-radius: 12px;
    font-size: 13px;
    line-height: 1.5;
    background: rgba(214, 69, 69, .09);
    color: #B83636;
}

/* The loud one, for a thing that stops the flow.

   The version this replaced was a line of small orange text in a summary
   column — the one place somebody who has just pressed a button is not
   looking. An error nobody sees is pressed past twice and reported as "it
   does nothing". */
.xc-alarm--big {
    gap: 11px;
    padding: 14px 16px;
    border: 1px solid rgba(214, 69, 69, .35);
    border-radius: 14px;
    background: rgba(214, 69, 69, .1);
    font-size: 14px;
    font-weight: 500;
}

/* ── "something is happening" ──────────────────────────────────────────── */

/* `xc-hold`, not `xc-busy` — and not `xc-veil` either.

   `xc-busy` is the two-pixel line across the top of the window that says a
   click landed, and it has been since long before this. Borrowing the name
   for a full-screen overlay put two unrelated rules under one selector — and
   the script that later rewrote "the busy block" cut from the first of them
   to the end of the second, taking fourteen hundred lines of unrelated
   stylesheet with it. The workflow shelf lost its grid and its card art; the
   damage was visible three screens away from anything to do with loading. */

.xc-hold {
    position: fixed;
    inset: 0;
    /* Above the sheet, which the browser puts in the top layer. A dialog
       outranks any z-index in the page, so this has to be on the body and
       fixed rather than inside the sheet — see modules/busy.js. */
    z-index: 2147483000;
    display: flex;
    align-items: center;
    justify-content: center;
    /* Translucent, so the thing being worked on is still visible underneath.
       An opaque screen would be a different page appearing, which is a bigger
       claim than "one moment". */
    background: rgba(var(--scrim), .3);
    backdrop-filter: blur(2px);
    animation: xc-fade .16s ease both;
}

/* The spinner sits on a card rather than bare on the scrim: a ring floating
   over a blurred page reads as something that has gone wrong, and a small
   white card reads as the product doing a thing. */
.xc-hold__card {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 13px;
    padding: 26px 34px;
    min-width: 190px;
    border-radius: 18px;
    background: var(--surface);
    box-shadow: 0 18px 50px rgba(var(--scrim), .26);
}

/* A ring with a quarter of it lit.

   The first version was 2.5px at 30px with the track at .18 alpha, and at
   that weight the track disappeared into the panel behind it: what was left
   was a short bright arc, which reads as a stray diagonal mark rather than as
   a spinner. Thicker, larger, and a track you can see — a ring only reads as
   turning when there is a ring to compare the lit part against.

   `border-top-color`, not the logical property: the logical one flips with
   direction, and the Arabic build would start its lit quarter somewhere else
   for no reason anybody could explain. */
.xc-hold__ring {
    width: 38px;
    height: 38px;
    flex: none;
    border-radius: 50%;
    border: 3.5px solid rgba(var(--brand), .2);
    border-top-color: rgb(var(--brand));
    animation: xc-spin .8s linear infinite;
}

.xc-hold__say {
    font-size: 13.4px;
    font-weight: 500;
    color: rgba(var(--ink), .6);
    text-align: center;
    max-inline-size: 26ch;
    text-wrap: pretty;
}

/* Empty unless the form named one. Left in the markup either way so the live
   region exists before there is anything to announce. */
.xc-hold__say:empty { display: none; }

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

@media (prefers-reduced-motion: reduce) {
    /* Still says something is happening — it just stops turning. */
    .xc-hold__ring { animation: none; opacity: .55; }
}

/* ── the review's four totals ──────────────────────────────────────────── */

.xc-tally {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 10px;
}

.xc-tally__one {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 12px 14px;
    border-radius: 13px;
    background: rgba(var(--ink), .03);
}

/* Colour only where there is something to count. Four tinted cards, three of
   them zero, is four things claiming to be news. */
.xc-tally__one[data-any] { background: rgba(var(--tint), .1); }

.xc-tally__n {
    font-family: 'JetBrains Mono', monospace;
    font-size: 22px;
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
    color: rgba(var(--ink), .25);
}

.xc-tally__one[data-any] .xc-tally__n { color: rgb(var(--tint)); }

.xc-tally__say {
    font-size: 12.2px;
    color: rgba(var(--ink), .45);
}

@media (max-width: 820px) {
    .xc-tally { grid-template-columns: repeat(2, 1fr); }
}

/* ── settings ──────────────────────────────────────────────────────────── */

/* A row of real choices. Two buttons with one of them marked, rather than a
   toggle: a toggle is smaller and does not say which state it is in without
   somebody having learned the convention. */
.xc-picks {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
}

.xc-pick2 {
    appearance: none;
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 11px 15px;
    border: 1.5px solid var(--line);
    border-radius: 14px;
    background: var(--surface);
    color: rgba(var(--ink), .6);
    font: inherit;
    font-size: 13.6px;
    text-decoration: none;
    cursor: pointer;
    transition: border-color .16s ease, background .16s ease, color .16s ease, transform .16s ease;
}

.xc-pick2:hover {
    border-color: rgba(var(--brand), .45);
    color: var(--text);
    transform: translateY(-1px);
}

.xc-pick2[data-on] {
    border-color: rgb(var(--brand));
    background: rgba(var(--brand), .06);
    color: rgb(var(--brand));
    font-weight: 600;
}

.xc-pick2__tick { flex: none; }

.xc-pick2__code {
    display: flex;
    align-items: center;
    justify-content: center;
    inline-size: 30px;
    block-size: 24px;
    flex: none;
    border-radius: 7px;
    background: rgba(var(--ink), .06);
    font-family: 'JetBrains Mono', monospace;
    font-size: 11px;
    letter-spacing: .06em;
}

.xc-pick2[data-on] .xc-pick2__code {
    background: rgba(var(--brand), .14);
    color: rgb(var(--brand));
}

/* Three bars in the colours of the theme they stand for — drawn rather than
   named, because "light" and "dark" describe a result somebody can just be
   shown. Fixed hexes on purpose: this swatch has to show the theme you are
   *not* in, so it cannot read the tokens of the one you are. */
.xc-pick2__swatch {
    display: flex;
    flex-direction: column;
    gap: 2px;
    justify-content: center;
    inline-size: 30px;
    block-size: 24px;
    flex: none;
    padding: 4px;
    border-radius: 7px;
    border: 1px solid rgba(var(--ink), .1);
}

.xc-pick2__swatch > span {
    block-size: 3px;
    border-radius: 2px;
}

.xc-pick2__swatch[data-theme-swatch="light"] { background: #F1F1F5; }
.xc-pick2__swatch[data-theme-swatch="light"] > span:nth-child(1) { background: #15151C; inline-size: 100%; }
.xc-pick2__swatch[data-theme-swatch="light"] > span:nth-child(2) { background: #9A9AA8; inline-size: 70%; }
.xc-pick2__swatch[data-theme-swatch="light"] > span:nth-child(3) { background: #4B4BE6; inline-size: 45%; }

.xc-pick2__swatch[data-theme-swatch="dark"] { background: #16161B; }
.xc-pick2__swatch[data-theme-swatch="dark"] > span:nth-child(1) { background: #FFFFFF; inline-size: 100%; }
.xc-pick2__swatch[data-theme-swatch="dark"] > span:nth-child(2) { background: #6A6A78; inline-size: 70%; }
.xc-pick2__swatch[data-theme-swatch="dark"] > span:nth-child(3) { background: #8F8FF7; inline-size: 45%; }

/* A card pointing at another screen. */
.xc-place {
    display: flex;
    align-items: center;
    gap: 13px;
    padding: 16px 17px;
    border: 1px solid var(--line);
    border-radius: 16px;
    background: var(--surface);
    text-decoration: none;
    color: inherit;
    transition: border-color .16s ease, transform .16s ease, box-shadow .16s ease;
}

.xc-place:hover {
    border-color: rgba(var(--tint), .5);
    transform: translateY(-2px);
    box-shadow: 0 10px 26px rgba(var(--scrim), .08);
    color: inherit;
}

.xc-place:hover .xc-place__go { transform: translateX(3px); color: rgb(var(--tint)); }

.xc-place__mark {
    display: flex;
    align-items: center;
    justify-content: center;
    inline-size: 38px;
    block-size: 38px;
    flex: none;
    border-radius: 13px;
    background: rgba(var(--tint), .12);
    color: rgb(var(--tint));
}

.xc-place__on {
    font-family: 'JetBrains Mono', monospace;
    font-size: 9px;
    letter-spacing: .1em;
    padding: 2px 7px;
    border-radius: 20px;
    background: rgba(0, 168, 134, .14);
    color: #0F7D64;
}

.xc-place__go {
    flex: none;
    color: rgba(var(--ink), .25);
    transition: transform .16s ease, color .16s ease;
}

/* Plain facts, two columns, monospace where the value is an identifier
   somebody may have to read out or paste. */
.xc-facts {
    margin: 0;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px 26px;
}

.xc-facts__one {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-inline-size: 0;
}

.xc-facts__one dt {
    font-family: 'JetBrains Mono', monospace;
    font-size: 9.5px;
    letter-spacing: .13em;
    color: rgba(var(--ink), .38);
}

.xc-facts__one dd {
    margin: 0;
    font-size: 14px;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
}

.xc-facts__mono {
    font-family: 'JetBrains Mono', monospace;
    font-size: 12.6px !important;
    color: var(--peri) !important;
    user-select: all;
}

/* Each panel a beat after the one above it. Sixty milliseconds apart — enough
   that the eye follows the page down rather than being handed all of it at
   once, and short enough that nobody waiting on a setting notices they
   waited. Six is the ceiling; past that the last card is late. */
[data-stagger] > * { animation: xc-riseup .32s cubic-bezier(.22, .68, .3, 1) both; }
[data-stagger] > *:nth-child(2) { animation-delay: .06s; }
[data-stagger] > *:nth-child(3) { animation-delay: .12s; }
[data-stagger] > *:nth-child(4) { animation-delay: .18s; }
[data-stagger] > *:nth-child(n+5) { animation-delay: .24s; }

@keyframes xc-riseup {
    from { opacity: 0; transform: translateY(9px); }
    to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    /* The whole point of it was movement, so there is nothing left to keep. */
    [data-stagger] > * { animation: none; }
    .xc-pick2:hover, .xc-place:hover { transform: none; }
}

@media (max-width: 820px) {
    .xc-facts { grid-template-columns: minmax(0, 1fr); }
}

/* ── a screen with questions down the side ─────────────────────────────── */

/* Used by reports, and by settings. A rail of its own rather than tabs across
   the top: seven tabs wrap on a laptop, and a wrapped tab strip is a menu
   pretending not to be one. */
.xc-subnav {
    inline-size: 214px;
    flex: none;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 3px;
    padding: 8px;
    border: 1px solid var(--line);
    border-radius: 18px;
    background: var(--surface);
}

.xc-subnav__one {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 11px;
    border-radius: 12px;
    font-size: 13.8px;
    text-decoration: none;
    color: rgba(var(--ink), .58);
    transition: background .15s ease, color .15s ease;
}

.xc-subnav__one:hover {
    background: rgba(var(--ink), .04);
    color: var(--text);
}

/* The chosen one wears its own accent rather than the brand: on a screen
   whose whole job is telling seven answers apart, the colour is doing work. */
.xc-subnav__one[data-on] {
    background: rgba(var(--tint), .1);
    color: rgb(var(--tint));
    font-weight: 600;
}

.xc-subnav__mark {
    display: flex;
    align-items: center;
    justify-content: center;
    inline-size: 28px;
    block-size: 28px;
    flex: none;
    border-radius: 9px;
    background: rgba(var(--ink), .05);
    color: rgba(var(--ink), .45);
    transition: background .15s ease, color .15s ease;
}

.xc-subnav__one[data-on] .xc-subnav__mark {
    background: rgba(var(--tint), .16);
    color: rgb(var(--tint));
}

/* Its header: the question, what it means, and the controls that change it. */
.xc-rephead {
    display: flex;
    align-items: center;
    gap: 13px;
    flex-wrap: wrap;
    padding: 16px 20px;
}

.xc-rephead__mark {
    display: flex;
    align-items: center;
    justify-content: center;
    inline-size: 38px;
    block-size: 38px;
    flex: none;
    border-radius: 13px;
    background: rgba(var(--tint), .13);
    color: rgb(var(--tint));
}

@media (max-width: 900px) {
    /* The rail lies down above the content rather than squeezing beside it. */
    .xc-subnav {
        inline-size: auto;
        flex-direction: row;
        overflow-x: auto;
        gap: 6px;
    }

    .xc-subnav__one { flex: none; }
    .xc-subnav__mark { display: none; }
}

/* ── the contacts list ─────────────────────────────────────────────────── */

/* A grid, not a <table>. Five tracks, and the two carrying a person's own
   words — their name and their tags — get the room. */
.xc-rows {
    display: flex;
    flex-direction: column;
}

.xc-rows__head,
.xc-rows__one {
    display: grid;
    grid-template-columns: 38px minmax(0, 1.4fr) 170px minmax(0, 1fr) 130px 76px;
    align-items: center;
    gap: 14px;
    padding: 11px 2px;
}

.xc-rows__head {
    padding-block: 6px;
    font-family: 'JetBrains Mono', monospace;
    font-size: 9.5px;
    letter-spacing: .13em;
    color: rgba(var(--ink), .35);
    border-block-end: 1px solid var(--line);
}

.xc-rows__one { border-block-end: 1px solid var(--line); }

.xc-rows__one:last-of-type { border-block-end: 0; }

.xc-rows__one:hover { background: rgba(var(--ink), .018); }

/* The one destructive control on the screen, and it stays quiet until it is
   reached. Red on hover rather than red always: a row of red buttons reads as
   a list of problems. */
.xc-rows__act {
    appearance: none;
    display: flex;
    align-items: center;
    justify-content: center;
    inline-size: 30px;
    block-size: 30px;
    border: 1px solid var(--line);
    border-radius: 9px;
    background: transparent;
    color: rgba(var(--ink), .38);
    cursor: pointer;
    transition: color .14s ease, border-color .14s ease, background .14s ease;
}

.xc-rows__act:hover {
    color: rgb(var(--brand));
    border-color: rgba(var(--brand), .4);
    background: rgba(var(--brand), .07);
}

/* The destructive one, and only on hover. A row of red buttons reads as a
   list of problems; red at the moment of reaching for it is a warning. */
.xc-rows__act--bad:hover {
    color: #B83636;
    border-color: rgba(214, 69, 69, .4);
    background: rgba(214, 69, 69, .07);
}

/* A contact's own tag.

   `xc-ctag`, because `xc-tag` and `xc-chip` were both taken — by the quiet uppercase label above,
   which this flattened when it borrowed the name. A filled pill with padding,
   dropped into a flex column, stretches to the full width of its card: on the
   workflow shelf that was a grey bar across every card where a small word had
   been. */
.xc-ctag {
    font-size: 11.6px;
    padding: 2px 9px;
    border-radius: 999px;
    background: rgba(var(--brand), .08);
    color: rgb(var(--brand));
    white-space: nowrap;
    /* So it never stretches, wherever it is dropped. */
    align-self: flex-start;
}

.xc-ctag[data-more] {
    background: rgba(var(--ink), .05);
    color: rgba(var(--ink), .45);
}

/* Filter pills. Buttons rather than links: the typed search travels with the
   choice, and a link carries nothing. */
.xc-pills {
    display: flex;
    gap: 5px;
    flex: none;
    padding: 3px;
    border-radius: 999px;
    background: rgba(var(--ink), .045);
}

.xc-pills__one {
    appearance: none;
    border: 0;
    padding: 6px 14px;
    border-radius: 999px;
    background: transparent;
    font-size: 12.8px;
    color: rgba(var(--ink), .5);
    cursor: pointer;
    white-space: nowrap;
    transition: background .14s ease, color .14s ease;
}

.xc-pills__one:hover { color: var(--text); }

.xc-pills__one[data-on] {
    background: rgb(var(--brand));
    color: #FFFFFF;
    font-weight: 500;
}

/* ── the import's first step ───────────────────────────────────────────── */

/* A label wrapping a hidden input, so the whole box is the control — no
   JavaScript holding it together. drop.js adds dragging on top. */
.xc-drop {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 5px;
    padding: 30px 20px;
    border: 1.5px dashed rgba(var(--brand), .35);
    border-radius: 16px;
    background: rgba(var(--brand), .025);
    color: rgb(var(--brand));
    cursor: pointer;
    text-align: center;
    transition: background .14s ease, border-color .14s ease;
}

.xc-drop:hover,
.xc-drop[data-over] {
    background: rgba(var(--brand), .06);
    border-color: rgba(var(--brand), .55);
}

/* Off-screen rather than `display:none`, which would take it out of the tab
   order and out of the accessibility tree — a file input nobody can reach by
   keyboard is a form nobody can fill in by keyboard. */
.xc-drop__input {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    opacity: 0;
    pointer-events: none;
}

.xc-drop__input:focus-visible + svg { outline: 2px solid rgb(var(--brand)); outline-offset: 4px; border-radius: 4px; }

.xc-drop__say {
    font-family: Poppins, sans-serif;
    font-weight: 600;
    font-size: 15px;
    color: var(--text);
}

.xc-drop__sub {
    font-size: 12.6px;
    line-height: 1.5;
    color: rgba(var(--ink), .45);
    max-inline-size: 42ch;
    text-wrap: pretty;
}

.xc-drop__file {
    margin-block-start: 6px;
    padding: 4px 12px;
    border-radius: 999px;
    background: rgb(var(--brand));
    color: #FFFFFF;
    font-family: 'JetBrains Mono', monospace;
    font-size: 11.6px;
    max-inline-size: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* "or paste it", as a rule with words in the middle. */
.xc-or {
    display: flex;
    align-items: center;
    gap: 12px;
    font-family: 'JetBrains Mono', monospace;
    font-size: 9.5px;
    letter-spacing: .14em;
    color: rgba(var(--ink), .3);
}

.xc-or::before,
.xc-or::after {
    content: '';
    flex: 1;
    block-size: 1px;
    background: var(--line);
}

@media (max-width: 1000px) {
    /* Tags go first: they are the only column somebody can reconstruct from
       the contact itself. */
    .xc-rows__head,
    .xc-rows__one { grid-template-columns: 34px minmax(0, 1.4fr) 150px 120px 76px; }
    /* Tags go first: they are the only column somebody can reconstruct from
       the contact itself. One later than before, because of the tick. */
    .xc-rows__head > span:nth-child(4),
    .xc-rows__one > span:nth-child(4) { display: none; }
}

/* ── the CSV import: steps, and the column table ───────────────────────── */

/* Three pills. Not links — each step is a POST carrying the file and the
   choices so far, and a link can carry neither. */
.xc-steps {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.xc-steps__one {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 13px 6px 7px;
    border-radius: 999px;
    font-size: 13.2px;
    font-weight: 500;
    background: rgba(var(--ink), .045);
    color: rgba(var(--ink), .45);
}

.xc-steps__one[data-state="now"] {
    background: rgb(var(--brand));
    color: #FFFFFF;
}

.xc-steps__one[data-state="done"] {
    background: rgba(0, 168, 134, .12);
    color: #0F7D64;
}

.xc-steps__n {
    display: flex;
    align-items: center;
    justify-content: center;
    inline-size: 21px;
    block-size: 21px;
    flex: none;
    border-radius: 50%;
    font-family: 'JetBrains Mono', monospace;
    font-size: 11px;
    background: rgba(var(--ink), .07);
    color: rgba(var(--ink), .5);
}

.xc-steps__one[data-state="now"] .xc-steps__n {
    background: rgba(255, 255, 255, .22);
    color: #FFFFFF;
}

.xc-steps__one[data-state="done"] .xc-steps__n {
    background: rgba(0, 168, 134, .2);
    color: #0F7D64;
}

/* The filter. Revealed by mapcols.js — without it the rows are all there
   anyway, and a search box that searches nothing is furniture. */
.xc-mapsearch {
    flex: none;
    display: flex;
    align-items: center;
    gap: 8px;
    inline-size: 250px;
    padding: 8px 12px;
    border: 1px solid var(--line);
    border-radius: 11px;
    background: var(--surface-2);
    color: rgba(var(--ink), .4);
}

.xc-mapsearch input {
    flex: 1;
    min-inline-size: 0;
    appearance: none;
    border: 0;
    outline: none;
    background: transparent;
    font-size: 13.4px;
    color: var(--text);
}

.xc-mapwarn {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    padding: 10px 13px;
    border-radius: 12px;
    font-size: 13px;
    line-height: 1.5;
    background: rgba(214, 69, 69, .08);
    color: #B83636;
}

/* ── the table ─────────────────────────────────────────────────────────
   A grid rather than a <table>: the row is a <label>, so a click anywhere on
   it that is not the select toggles the column. Five tracks, and the two that
   hold a person's own words get the room. */
.xc-maptable {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--line);
    border-radius: 14px;
    overflow: hidden;
    /* Inside a sheet the table is the tall part, so it scrolls rather than the
       whole body — the header row stays put and the footer button never walks
       off the bottom of a twenty-eight column file. */
    max-block-size: min(46vh, 420px);
    overflow-y: auto;
}

.xc-maprow--head {
    position: sticky;
    inset-block-start: 0;
    z-index: 2;
    /* Opaque, or the rows scroll through it. */
    background: var(--surface-2);
}

.xc-maprow {
    display: grid;
    grid-template-columns: 44px minmax(0, 1.1fr) minmax(0, 1fr) 24px 250px;
    align-items: center;
    gap: 12px;
    padding: 9px 14px 9px 4px;
    border-block-start: 1px solid var(--line);
    cursor: pointer;
    transition: background .14s ease, opacity .14s ease;
}

.xc-maprow:first-of-type { border-block-start: 0; }

.xc-maprow:hover { background: rgba(var(--ink), .022); }

.xc-maprow--head {
    cursor: default;
    padding-block: 10px;
    background: rgba(var(--ink), .035);
    font-family: 'JetBrains Mono', monospace;
    font-size: 9.5px;
    letter-spacing: .13em;
    color: rgba(var(--ink), .42);
}

.xc-maprow--head:hover { background: rgba(var(--ink), .035); }

/* Dimmed, not hidden: a column somebody chose to leave out should still be
   visible as a column they chose to leave out. */
.xc-maprow[data-off] { opacity: .42; }

.xc-maprow__tick {
    display: flex;
    align-items: center;
    justify-content: center;
}

/* The value, first, because it is what a person recognises — `amm_numero`
   means nothing and `AMM-001` means everything. */
.xc-maprow__sample {
    font-size: 13.6px;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.xc-maprow__name {
    font-family: 'JetBrains Mono', monospace;
    font-size: 12.4px;
    color: rgba(var(--ink), .5);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.xc-maprow__arrow { color: rgba(var(--ink), .22); }

.xc-maprow__none {
    margin: 0;
    padding: 18px 14px;
    font-size: 13.2px;
    color: rgba(var(--ink), .42);
    border-block-start: 1px solid var(--line);
}

.xc-mapfield {
    appearance: none;
    inline-size: 100%;
    padding: 8px 11px;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--surface-2);
    font-size: 13.2px;
    color: var(--text);
    cursor: pointer;
}

.xc-mapfield:disabled { cursor: not-allowed; }

.xc-mapfoot {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    padding-block-start: 4px;
}

/* Green once an identifier has been chosen, muted until then. It is a
   statement of the rule either way — never an error, because arriving on this
   screen with nothing chosen is the normal case, not a mistake. */
.xc-mapfoot__note {
    font-size: 12.6px;
    color: rgba(var(--ink), .45);
    text-wrap: pretty;
}

.xc-mapfoot__note[data-ok="1"] { color: var(--green); }

/* ── the read-back on the review step ──────────────────────────────── */
.xc-mapread {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

.xc-mapread__one {
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 5px 11px;
    border: 1px solid var(--line);
    border-radius: 999px;
    font-size: 12.6px;
    color: rgba(var(--ink), .3);
    max-inline-size: 100%;
}

.xc-mapread__from {
    font-family: 'JetBrains Mono', monospace;
    font-size: 11.6px;
    color: rgba(var(--ink), .5);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.xc-mapread__to { color: var(--text); font-weight: 500; }

.xc-mapread__one[data-custom] .xc-mapread__to { color: var(--peri); }

@media (max-width: 1000px) {
    /* The header column goes before the sample does: on a narrow screen the
       value is still the half that identifies the column. */
    .xc-maprow { grid-template-columns: 40px minmax(0, 1fr) 0 0 190px; }
    .xc-maprow__name,
    .xc-maprow__arrow { display: none; }
    .xc-maprow--head > span:nth-child(3),
    .xc-maprow--head > span:nth-child(4) { display: none; }
}

/* Getting started, on the rail.

   Above the groups and outside them, because it is the only rail entry that
   disappears: after the first week there is nothing to link to. It is given
   the brand colour rather than the rail's usual muted ink — for that week it
   is the item that matters, and a nav item that looks like all the others is
   one nobody picks out. */
.xc-railsetup {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 9px 10px;
    border-radius: 12px;
    text-decoration: none;
    font-size: 15px;
    color: var(--rail-text);
    background: rgba(var(--rail-ink), .06);
    border: 1px solid rgba(var(--rail-ink), .12);
    transition: background 160ms, border-color 160ms;
}

.xc-railsetup:hover,
.xc-railsetup[data-on] {
    color: var(--rail-text);
    background: var(--rail-active);
    border-color: transparent;
}

.xc-railsetup[data-on] { font-weight: 600; }

.xc-railsetup svg { color: var(--peri); }

/* The count. Monospace so 1/4 and 4/4 are the same width and the label beside
   them does not shift as somebody works through the list. */
.xc-railsetup__count {
    flex: none;
    font-family: 'JetBrains Mono', monospace;
    font-size: 11px;
    color: rgba(var(--rail-ink), .5);
}

/* A small pulsing dot, wherever something is in flight. It was part of the
   go-live band; the band became a card and the dot outlived it. */
.xc-pulsedot {
    flex: none;
    inline-size: 7px;
    block-size: 7px;
    border-radius: 50%;
    background: currentColor;
    animation: xc-pulse 2.4s ease-in-out infinite;
}

@keyframes xc-pulse {
    50% { opacity: .35; }
}

@media (prefers-reduced-motion: reduce) {
    .xc-pulsedot { animation: none; }
}

.xc-alert {
    flex: none;
    position: relative;
    overflow: hidden;
    display: flex;
    /* Centred, because there is one row now. It was `flex-start` when the
       button sat under the sentence and the mark had to line up with the
       first line rather than the middle. */
    align-items: center;
    gap: 12px;
    /* Inside the panel, under the title. The inline margin matches the
       padding every screen's content uses, so the card and the content below
       it share an edge. */
    margin: 0 16px 12px;
    padding: 11px 14px;
    border: 1px solid var(--line);
    border-radius: 14px;
    /* A faint wash rather than the panel colour. On a page whose own panels
       are white, a white card on a white ground is a card nobody can see —
       and this one is supposed to be noticed. */
    background: rgba(var(--ink), .028);
    color: rgba(var(--ink), .85);
}

/* Amber while it is asking, grey-blue while it waits. Never WhatsApp green:
   green here reads as "connected", which is the one thing it is not. */
.xc-alert[data-tone="ask"] {
    border-color: rgba(232, 163, 61, .3);
    background: linear-gradient(103deg, rgba(232, 163, 61, .08), rgba(232, 163, 61, .02) 62%, transparent);
}

.xc-alert__mark {
    flex: none;
    display: flex;
    align-items: center;
    justify-content: center;
    inline-size: 32px;
    block-size: 32px;
    border-radius: 11px;
    background: rgba(var(--ink), .05);
    color: rgba(var(--ink), .5);
}

.xc-alert[data-tone="ask"] .xc-alert__mark {
    background: rgba(232, 163, 61, .16);
    color: #B77C18;
}

/* The chip that holds someone else's logo.

   WhatsApp's mark is green and the asking card is amber, and green-on-amber
   reads as two companies arguing in a 32px square. A plain light chip is what
   an app icon sits on everywhere else, so the logo is left to be the only
   coloured thing in it. */
.xc-alert__mark[data-brand] {
    background: #FFFFFF;
    border: 1px solid rgba(var(--ink), .08);
    box-shadow: 0 1px 2px rgba(var(--ink), .06);
}

.xc-alert[data-tone="ask"] .xc-alert__mark[data-brand] {
    background: #FFFFFF;
}

.xc-alert__say {
    flex: 1;
    /* Enough room that the artwork never crowds the sentence, and the
       sentence wins when there is not enough for both. */
    min-inline-size: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.xc-alert__title {
    font-family: Poppins, sans-serif;
    font-weight: 600;
    font-size: 14px;
    letter-spacing: -0.01em;
}

.xc-alert__sub {
    font-size: 12.6px;
    line-height: 1.45;
    color: rgba(var(--ink), .52);
    /* One line. A permanent notice that wraps to three is a paragraph, and a
       paragraph on every screen is something people learn to scroll past. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.xc-alert__act {
    flex: none;
    /* Above the artwork, which is absolutely placed behind everything. */
    position: relative;
}

/* The component inside brings its own column layout, which is right in a
   panel and wrong here. Flattened rather than given a second variant: one
   connect button, four places, and the places do the arranging. */
.xc-alert__go,
.xc-alert__act > div {
    flex-direction: row !important;
    align-items: center;
    gap: 10px !important;
}

/* The small print under the button belongs in a panel, not on a nudge. */
.xc-alert__act > div > span:last-of-type,
.xc-alert noscript { display: none; }

.xc-alert__link {
    font-size: 13px;
    font-weight: 600;
    color: rgba(var(--ink), .7);
    text-decoration: underline;
    text-underline-offset: 3px;
    white-space: nowrap;
}

.xc-alert__link:hover { color: rgb(var(--brand)); }

@media (max-width: 720px) {
    .xc-alert { margin-inline: 12px; padding: 10px 12px; gap: 10px; }
    .xc-alert__mark { inline-size: 28px; block-size: 28px; border-radius: 9px; }
    .xc-alert__title { font-size: 13.4px; }
    .xc-alert__sub { display: none; }
}
    .xc-alert__title { font-size: 14px; }
    .xc-alert__sub { font-size: 12.5px; }
}
}

/* A sheet that becomes a sheet on a phone. A dialog with 40px of backdrop on
   each side of a 360px screen looks like a dialog that failed to load. */
@media (max-width: 640px) {
    .xc-sheet-host--phone {
        inset: auto 0 0 0;
        max-inline-size: 100%;
        inline-size: 100%;
        margin: 0;
    }

    .xc-sheet-host--phone .xc-sheet {
        border-end-start-radius: 0;
        border-end-end-radius: 0;
        max-block-size: 92vh;
    }
}

/* ── the picture beside an open checklist step ────────────────────────────
 *
 * One gradient and one glyph, themed from the step's own tint. Gone below
 * 900px, where the paragraph already fills the width and a decoration would
 * push the button under the fold.
 */
.xc-stepart {
    flex: 0 0 210px;
    align-self: stretch;
    min-block-size: 132px;
    border-radius: 14px;
    position: relative;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(145deg, rgba(var(--tint), .30), rgba(var(--tint), .10));
}

.xc-stepart__glow {
    position: absolute;
    inset-block-start: -30%;
    inset-inline-start: -14%;
    inline-size: 74%;
    aspect-ratio: 1;
    border-radius: 50%;
    background: rgba(255, 255, 255, .22);
}

.xc-stepart__mark {
    position: relative;
    inline-size: 60px;
    block-size: 60px;
    border-radius: 50%;
    background: var(--surface);
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 8px 22px rgba(var(--tint), .28);
}

@media (max-width: 900px) {
    .xc-stepart { display: none; }
}

/* ── the welcome ──────────────────────────────────────────────────────────
 *
 * Its own sheet rather than the shared one. `.xc-sheet` is the chrome for a
 * form — a header rule, an icon tile, a footer with cancel and submit — and
 * that frame is right for "new campaign" and wrong for the one screen in this
 * product whose entire job is to be glad somebody arrived.
 *
 * Both borders are deliberately absent: the black outline a <dialog> draws by
 * default, and the hairline the shared sheet puts round itself. A welcome in a
 * box reads as a system message.
 */
.xc-welcome {
    border: 0;
    outline: 0;
    padding: 0;
    background: transparent;
    inline-size: 100%;
    max-inline-size: min(520px, 94vw);
    color: var(--text);
}

.xc-welcome::backdrop {
    /* Darker than the shared sheet's, because there is nothing behind this
       worth reading yet and the contrast is what makes the banner sing. */
    background: rgba(10, 10, 24, .58);
    backdrop-filter: blur(3px);
}

.xc-welcome__sheet {
    position: relative;
    background: var(--surface);
    border-radius: 24px;
    overflow: hidden;
    box-shadow: 0 40px 90px rgba(10, 10, 40, .45);
    animation: xc-welcome-in .42s cubic-bezier(.2, .8, .3, 1);
}

@keyframes xc-welcome-in {
    from { opacity: 0; transform: translateY(14px) scale(.985); }
}

/* The banner. One gradient — the only one on this screen. */
.xc-welcome__top {
    position: relative;
    block-size: 132px;
    background: linear-gradient(135deg, #1C1CD2, #5B5BF0 55%, #7A5BF0);
    display: flex;
    align-items: center;
    justify-content: center;
}

.xc-welcome__confetti {
    position: absolute;
    inset: 0;
    inline-size: 100%;
    block-size: 100%;
}

.xc-welcome__pop {
    position: relative;
    inline-size: 74px;
    block-size: 74px;
    border-radius: 50%;
    background: var(--surface);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 36px;
    line-height: 1;
    box-shadow: 0 10px 28px rgba(10, 10, 60, .28);
    animation: xc-pop-in .5s .1s cubic-bezier(.2, 1.3, .4, 1) backwards;
}

@keyframes xc-pop-in {
    from { opacity: 0; transform: scale(.4) rotate(-18deg); }
}

.xc-welcome__body {
    padding: 22px 26px 24px;
    display: flex;
    flex-direction: column;
    gap: 16px;
    max-block-size: calc(88vh - 132px);
    overflow-y: auto;
}

/* The one thing being asked for, on its own ground so the eye lands there
   rather than on the paragraph above it. */
.xc-welcome__do {
    background: var(--surface-2);
    border-radius: 15px;
    padding: 15px 17px;
}

.xc-welcome__foot {
    display: flex;
    align-items: center;
    gap: 12px;
    padding-block-start: 14px;
    border-block-start: 1px solid var(--line);
}

/* Over the banner, so it is visible without a rule to sit on. */
.xc-welcome__x {
    position: absolute;
    inset-block-start: 14px;
    inset-inline-end: 14px;
    inline-size: 32px;
    block-size: 32px;
    border: 0;
    border-radius: 50%;
    background: rgba(255, 255, 255, .18);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: background 160ms;
}

.xc-welcome__x:hover { background: rgba(255, 255, 255, .32); }

.xc-welcome__x:focus-visible {
    outline: 2px solid #fff;
    outline-offset: 2px;
}

/* On a phone it is the whole bottom of the screen. A dialog with 30px of
   backdrop either side of a 360px viewport looks like one that failed. */
@media (max-width: 560px) {
    .xc-welcome {
        max-inline-size: 100%;
        inset: auto 0 0 0;
        margin: 0;
    }

    .xc-welcome__sheet {
        border-end-start-radius: 0;
        border-end-end-radius: 0;
    }

    .xc-welcome__top { block-size: 104px; }
    .xc-welcome__pop { inline-size: 62px; block-size: 62px; font-size: 30px; }
}

@media (prefers-reduced-motion: reduce) {
    .xc-welcome__sheet,
    .xc-welcome__pop { animation: none; }
}

/* ── the channel catalogue ────────────────────────────────────────────────
 *
 * A card per thing that can be connected. One today, and the grid is built
 * for more rather than for one, because the day there are three is not the
 * day to rewrite this.
 *
 * The tint is the channel's, never its brand colour: a WhatsApp-green card
 * reads as an official WhatsApp surface, and what we are is a business built
 * on their API — a true and much smaller claim.
 */
.xc-chan {
    display: flex;
    flex-direction: column;
    gap: 13px;
    padding: 17px 18px 15px;
    border: 1px solid var(--line);
    border-radius: 17px;
    background: var(--surface-2);
    color: inherit;
    text-decoration: none;
    transition: border-color 160ms, transform 160ms, box-shadow 160ms;
}

.xc-chan:hover {
    border-color: rgba(var(--tint), .45);
    transform: translateY(-2px);
    box-shadow: 0 10px 26px rgba(var(--tint), .13);
}

.xc-chan:focus-visible {
    outline: 2px solid rgb(var(--tint));
    outline-offset: 2px;
}

.xc-chan__top {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 10px;
}

.xc-chan__mark {
    flex: none;
    inline-size: 48px;
    block-size: 48px;
    border-radius: 15px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: rgb(var(--tint));
    background: rgba(var(--tint), .12);
}

.xc-chan__go {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 13.2px;
    font-weight: 600;
    color: rgb(var(--tint));
}

.xc-chan:hover .xc-chan__go svg { transform: translateX(2px); }

.xc-chan__go svg { transition: transform 160ms; }

@media (prefers-reduced-motion: reduce) {
    .xc-chan,
    .xc-chan__go svg { transition: none; }
    .xc-chan:hover { transform: none; }
}

/* ── a password you can look at ──────────────────────────────────────────
 *
 * The button sits inside the field's box rather than beside it, so the field
 * keeps its full width and the control cannot be mistaken for something that
 * submits. 42px of end padding is the room it needs; without it the reveal
 * sits on top of the last characters of a long password, which is exactly
 * when somebody reaches for it.
 */
.xc-peek { position: relative; display: flex; align-items: stretch; }

.xc-peek__in {
    flex: 1;
    min-inline-size: 0;
    padding-inline-end: 42px !important;
}

.xc-peek__eye {
    position: absolute;
    inset-inline-end: 4px;
    inset-block: 4px;
    inline-size: 34px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 0;
    border-radius: 9px;
    color: rgba(var(--ink), .42);
    cursor: pointer;
    padding: 0;
    transition: color 150ms, background 150ms;
}

.xc-peek__eye:hover { color: var(--text); background: rgba(var(--ink), .06); }

.xc-peek__eye:focus-visible {
    outline: 2px solid var(--peri);
    outline-offset: -2px;
    color: var(--text);
}

/* One icon at a time, chosen by the state the button reports. */
.xc-peek__eye .xc-peek__off { display: none; }
.xc-peek__eye[aria-pressed="true"] { color: var(--acc); }
.xc-peek__eye[aria-pressed="true"] .xc-peek__on { display: none; }
.xc-peek__eye[aria-pressed="true"] .xc-peek__off { display: block; }
