/* Shared fleet styles — one home for the DW-001 system every fleet
 * frontend consumes. Extracted verbatim from the blog's app.css (itself
 * ported from the retired Rails app); per-app stylesheets now hold only
 * what differs. Rules here change once, everywhere. */

:root {
    /* Tells the browser to render built-in controls appropriately for the
       active color scheme. */
    color-scheme: light dark;

    --bg: #f7f2e9;            /* warm cream paper */
    --fill: #fffdf8;          /* slightly lighter surface for fields and code */
    --text: #1f1a12;          /* warm near-black ink */
    --accent: #0066b1;
    --accent-contrast: #ffffff;
    --ink: #1f1a12;           /* button outlines and hard shadows */
    --good: #2f6f3e;

    /* These two DEPART from the shared fleet palette, deliberately.
       DW-001 §2 records that the canonical light-mode values fail WCAG AA for
       normal text — --text-muted #7a7264 is 4.26:1 on the paper and --danger
       #dc2626 is 4.33:1, both under the 4.5 threshold, both carrying real
       content at 0.7rem. The other three apps are read over the tailnet by one
       person who can pick his own lighting; this one is read by strangers on
       whatever screen they have. So it ships the corrected values the guide
       recommends: 5.00:1 and 5.14:1, same hue family, no visible change in
       character.

       This makes a fourth palette variant in a system whose guide already
       complains about drift (DW-001 §9). The intended repair is to move the
       other three apps onto these values, not to keep a special case here. */
    --text-muted: #6f675a;
    --danger: #c81e1e;

    --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
}

@media (prefers-color-scheme: dark) {
    :root {
        --bg: #121316;         /* cool charcoal, blue undertone, not warm */
        --fill: #1c1e22;       /* same family, one step lighter */
        --text: #eceef1;       /* neutral paper-white, drop the warm tint */
        --text-muted: #8b9199; /* cool gray — already 5.85:1, unchanged */
        --accent: #4d9de0;     /* dashboard backlight blue */
        --accent-contrast: #141311;
        --danger: #f87171;     /* already 6.72:1, unchanged */
        --ink: #000000;
        --good: #5cb974;
    }
}
/* Document shell: page base and the centered measure. Voices (type,
 * links, code, lists) all come from the Astryx atoms; the out-of-scope
 * Rails-era surfaces (sessions, rail, tabs, desk shell) still read the
 * DW-001 tokens.
 */

body {
    margin: 0;
    font-family: system-ui, sans-serif;
    font-size: 1rem;
    line-height: 1.6;
    color: var(--text);
    background: var(--bg);
}

/* Every page keeps the 40rem reading measure inside the 64rem shell. */
.container {
    max-width: 64rem;
    margin: 0 auto;
    padding: 6rem 1.25rem 5rem;
}

.measure {
    max-width: 40rem;
}
/* --- Astryx buttons (card #292): variants, sizes, states, a11y ---
 * Token scale (`--ax-*`) is shared with the chat surface in chat.css. */

.ax-button {
    --ax-button-focus-offset: var(--ax-focus-outline-offset);
    outline-offset: 0;
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--ax-spacing-2);
    padding-block: var(--ax-spacing-2);
    padding-inline: var(--ax-spacing-3);
    border-width: 0;
    border-style: none;
    border-radius: var(--ax-radius-element);
    font-family: inherit;
    font-size: var(--ax-text-label-size);
    line-height: var(--ax-text-label-leading);
    font-weight: var(--ax-font-weight-medium);
    white-space: nowrap;
    cursor: pointer;
    text-decoration: none;
    transition-property: background-image, background-color, color, opacity, transform;
    transition-duration: var(--ax-duration-fast);
    transition-timing-function: var(--ax-ease-standard);
}

@media (prefers-reduced-motion: reduce) {
    .ax-button { transition-duration: 0s; }
    .ax-button-spinner { animation: none; }
}

.ax-button:focus-visible {
    outline-offset: var(--ax-button-focus-offset);
    outline-width: var(--ax-focus-outline-width);
    outline-style: var(--ax-focus-outline-style);
    outline-color: var(--ax-focus-outline-color);
}

/* The ring matches the variant it rings: an accent outline on a red
   button reads as another control's focus. */
.ax-button--destructive:focus-visible {
    outline-color: var(--ax-color-error);
}

.ax-button:disabled,
.ax-button[aria-disabled="true"] {
    cursor: default;
}

/* Pressable squash; suppressed for inert buttons. */
.ax-button:active:where(:not(:disabled)) {
    transform: scale(0.98);
}

/* Explicitly disabled controls dim; loading ones keep full contrast so
   the spinner stays legible. */
.ax-button:disabled {
    opacity: 0.5;
}

.ax-button--sm { height: var(--ax-size-element-sm); }
.ax-button--md { height: var(--ax-size-element-md); }
.ax-button--lg { height: var(--ax-size-element-lg); }

.ax-button--primary {
    background-color: var(--ax-color-accent);
    color: var(--ax-color-on-accent);
}

.ax-button--secondary {
    background-color: var(--ax-color-neutral);
    color: var(--ax-color-text-primary);
}

.ax-button--ghost {
    background-color: transparent;
    color: var(--ax-color-text-primary);
}

.ax-button--destructive {
    background-color: var(--ax-color-error);
    color: var(--ax-color-on-error);
}

/* Hover/press overlays ride a background-image layer above the base. */
@media (hover: hover) {
    .ax-button:where(:not(:disabled)):hover {
        background-image: linear-gradient(var(--ax-color-overlay-hover), var(--ax-color-overlay-hover));
    }
}

.ax-button:where(:not(:disabled)):active {
    background-image: linear-gradient(var(--ax-color-overlay-pressed), var(--ax-color-overlay-pressed));
}

.ax-button--icon-only {
    aspect-ratio: 1 / 1;
    padding-inline: 0;
    padding-block: 0;
}

.ax-button-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.ax-button-icon--sm {
    width: 16px;
    height: 16px;
    font-size: 16px;
}

.ax-button-icon--lg {
    width: 20px;
    height: 20px;
    font-size: 20px;
}

.ax-button-label {
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
}

.ax-button-end {
    display: inline-flex;
    align-items: center;
    color: inherit;
}

.ax-button-content {
    display: contents;
}

/* Loading swaps the content for the spinner without resizing the button:
   hidden content holds the box, the overlay centers the ring. */
.ax-button-content--loading {
    color: transparent;
}

.ax-button-spinner {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    display: grid;
    place-items: center;
}

/* --- Back link --- */

.back-link {
    display: inline-block;
    color: var(--accent);
    text-decoration: none;
    font-weight: 600;
}

.back-link:hover {
    text-decoration: underline;
}
/* Shared fleet styles — one home for the DW-001 system every fleet
 * frontend consumes. Rules here change once, everywhere. */

/* --- Controlled inputs: the `inputs.rs` components ---
 *
 * These carry their own Astryx field voice (`.ax-field`): a bordered
 * surface wrapper that takes the accent border on focus-within and the
 * error border when invalid — nothing like the `.field` fill voice in
 * `forms.css`, which stays for the blog's post-and-hint forms. The single-
 * line error and the switch below are shared only in shape, not in voice.
 */

/* The field wrapper: bordered surface, accent border on focus-within,
 * error border when invalid. Values from Astryx's Field input wrapper. */
.ax-field {
    --ax-font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --ax-color-text-primary: light-dark(#0a1317, #dfe2e5);
    --ax-color-text-secondary: light-dark(#4e606f, #aaafb5);
    --ax-color-border-emphasized: light-dark(#ccd3db, #494d53);
    --ax-color-accent: light-dark(#0066b1, #4d9de0);
    --ax-color-error: light-dark(#e3193b, #f5394f);
    --ax-color-background-surface: light-dark(#ffffff, #262626);
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.ax-field-label {
    font-family: var(--ax-font-body);
    font-size: 0.875rem;
    line-height: 1.4286;
    font-weight: 500;
    color: var(--ax-color-text-secondary);
}

.ax-field-box {
    box-sizing: border-box;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding-block: 0.25rem;
    padding-inline: 0.5rem;
    border: 1px solid var(--ax-color-border-emphasized);
    border-radius: 8px;
    background-color: var(--ax-color-background-surface);
    transition: border-color 175ms cubic-bezier(0.24, 1, 0.4, 1);
}

.ax-field-box:focus-within {
    border-color: var(--ax-color-accent);
}

.ax-field--invalid .ax-field-box {
    border-color: var(--ax-color-error);
}

/* The control itself: borderless body text on transparent, so the wrapper
 * draws the field. Coarse pointers get the 16px floor, like every Astryx
 * text entry. */
.ax-field-input {
    display: block;
    flex: 1;
    min-width: 0;
    width: 100%;
    padding: 0;
    border: 0;
    font-family: var(--ax-font-body);
    font-size: 0.875rem;
    line-height: 1.4286;
    color: var(--ax-color-text-primary);
    background-color: transparent;
    outline: none;
}

.ax-field-input::placeholder {
    color: var(--ax-color-text-secondary);
}

@media (pointer: coarse) {
    .ax-field-input,
    .ax-field-input::placeholder {
        font-size: max(1rem, 0.875rem);
    }
}

/* One-line field error under the box, rendered only when non-empty. */
.ax-field-error {
    margin: 0;
    font-family: var(--ax-font-body);
    font-size: 0.75rem;
    line-height: 1.6667;
    font-weight: 600;
    color: var(--ax-color-error);
}

/* Controlled textareas grow with their content where the browser supports
 * it (`field-sizing` is progressive enhancement); `rows` stays the resting
 * height everywhere else. */
.inputs-textarea {
    field-sizing: content;
    min-height: 4.5rem;
    resize: vertical;
}

/* --- Toggle switch in Astryx's Switch voice: gray track, accent when on,
 * surface thumb travelling the track, dimmed when disabled. Geometry and
 * colors resolve from the source's md size; forced-colors system paints
 * stay out like everywhere else in this crate. */

.toggle {
    --ax-color-accent: light-dark(#0066b1, #4d9de0);
    --ax-color-background-gray: light-dark(#e2e2e2, #303030);
    --ax-color-background-surface: light-dark(#ffffff, #262626);
    display: inline-flex;
    align-items: center;
    gap: 0.75rem;
    font-weight: 600;
    cursor: pointer;
}

/* The native box stays in the tab order and the accessibility tree; the
 * track beside it is the visible control. */
.toggle-input {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
    margin: 0;
}

.toggle-track {
    flex: none;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    width: 40px;
    height: 24px;
    padding: 4px;
    border-radius: 9999px;
    background-color: var(--ax-color-background-gray);
    transition: background-color 175ms cubic-bezier(0.24, 1, 0.4, 1);
}

.toggle-track::after {
    content: "";
    display: block;
    width: 16px;
    height: 16px;
    border-radius: 9999px;
    background-color: var(--ax-color-background-surface);
    transition: transform 175ms cubic-bezier(0.24, 1, 0.4, 1);
}

.toggle-input:checked + .toggle-track {
    background-color: var(--ax-color-accent);
}

.toggle-input:checked + .toggle-track::after {
    transform: translateX(12px);
}

:is([dir="rtl"] *) .toggle-input:checked + .toggle-track::after {
    transform: translateX(-12px);
}

.toggle-input:focus-visible + .toggle-track {
    outline: 2px solid var(--ax-color-accent);
    outline-offset: 2px;
}

.toggle-input:disabled + .toggle-track {
    opacity: 0.5;
}

.toggle:has(.toggle-input:disabled) {
    cursor: not-allowed;
}
/* Markdown voices: the shapes model prose arrives in. Each root sets the
 * variables it reads, so the voices work wherever they mount. Every voice
 * follows the matching `@astryxdesign/core` module: headings reuse the
 * shared display scale (see text.css), quotes carry the Blockquote rule,
 * rules are drawn dividers, inline code carries the Code wash, tables the
 * row-divider grid with label-voice headers. */

/* Headings: none of their own — MarkdownHeading renders the shared
 * Heading, so the display scale lives in text.css exactly once. */

/* Paragraphs: body voice, no margins — the stack gap owns block spacing. */

.ax-md-paragraph {
    margin: 0;
}

/* Lists: native markers, the desk indent and gaps. The reset strips
 * markers globally, so each list redeclares its own. */

.ax-md-list {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin: 0 0 0 1.25rem;
    padding: 0;
}

.ax-md-list--unordered {
    list-style: disc;
}

.ax-md-list--ordered {
    list-style: decimal;
}

.ax-md-li {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    min-width: 0;
}

/* Tables: the scroll wrapper plus row dividers in the border color;
 * headers read the semibold secondary label voice. Tabular numerals stay
 * for numeric columns. */

.ax-md-table-scroll {
    overflow-x: auto;
    max-width: 100%;
}

.ax-md-table {
    --ax-color-border: light-dark(#05365919, #f2f4f619);
    --ax-color-text-secondary: light-dark(#4e606f, #aaafb5);
    width: 100%;
    border-collapse: collapse;
    font-variant-numeric: tabular-nums;
}

.ax-md-th {
    font-weight: 600;
    color: var(--ax-color-text-secondary);
    text-align: left;
    vertical-align: bottom;
    padding: 0.25rem 1rem 0.25rem 0;
    border-bottom: 1px solid var(--ax-color-border);
}

.ax-md-td {
    text-align: left;
    vertical-align: top;
    padding: 0.25rem 1rem 0.25rem 0;
    border-bottom: 1px solid var(--ax-color-border);
}

/* Quotes: the Blockquote voice — an inline-start rule in the emphasized
 * border, secondary ink, zero margins. */

.ax-md-quote {
    --ax-color-border-emphasized: light-dark(#ccd3db, #494d53);
    --ax-color-text-secondary: light-dark(#4e606f, #aaafb5);
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    margin: 0;
    padding: 0 0 0 1rem;
    border-inline-start: 2px solid var(--ax-color-border-emphasized);
    color: var(--ax-color-text-secondary);
}

/* Rules: a drawn divider — a one-pixel top border, like Astryx's hr. */

.ax-md-rule {
    --ax-color-border: light-dark(#05365919, #f2f4f619);
    border: 0;
    border-top: 1px solid var(--ax-color-border);
    margin: 0;
}

/* Inline code: the Code voice — the code stack at body size on a muted
 * wash with inner rounding. */

.ax-md-code {
    --ax-font-code: ui-monospace, "SF Mono", Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
    --ax-color-background-muted: light-dark(#f1f1f1, #1b1b1b);
    --ax-radius-inner: 4px;
    font-family: var(--ax-font-code);
    background-color: var(--ax-color-background-muted);
    padding-inline: 0.25rem;
    padding-block: 0;
    border-radius: var(--ax-radius-inner);
}

/* Links: accent ink with underline and hover tint — if it's blue, you
 * can click it. */

.ax-md-link {
    --ax-color-accent: light-dark(#0066b1, #4d9de0);
    color: var(--ax-color-accent);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.ax-md-link:hover {
    color: color-mix(in srgb, var(--ax-color-accent), light-dark(black, white) 15%);
}

/* Strong and strike. */

.ax-md-strong {
    font-weight: 600;
}

.ax-md-strike {
    --ax-color-muted: light-dark(#6f675a, #8b9199);
    color: var(--ax-color-muted);
}
/* Astryx code fence: bordered card on the syntax background, header label
 * in the supporting code voice, ghost copy control, keyboard-scrollable
 * code region. Token spans ride the syntax palette below. Each root sets
 * the variables it reads, so the fence works wherever it mounts. Values
 * resolved from @astryxdesign/core 0.6.0's CodeBlock and the neutral
 * theme's syntax tokens; tokens are verbatim. */

.ax-codeblock {
    --ax-font-code: ui-monospace, "SF Mono", Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
    --ax-color-syntax-keyword: light-dark(#6b187c, #efa8ff);
    --ax-color-syntax-string: light-dark(#0b5615, #a4d6a3);
    --ax-color-syntax-comment: light-dark(#6a6a6a, #9e9e9e);
    --ax-color-syntax-number: light-dark(#733100, #ffb37e);
    --ax-color-syntax-function: light-dark(#00458c, #a1caff);
    --ax-color-syntax-variable: light-dark(#111111, #e2e2e2);
    --ax-color-syntax-tag: light-dark(#8a0011, #ffaea7);
    --ax-color-syntax-background: light-dark(#ffffff, #111111);
    --ax-color-border: light-dark(#05365919, #f2f4f619);
    --ax-text-code-size: 0.875rem;
    --ax-text-code-leading: 1.4286;
    --ax-text-supporting-size: 0.75rem;
    --ax-text-supporting-leading: 1.6667;
    --ax-font-weight-medium: 500;
    --ax-focus-outline-width: 2px;
    --ax-focus-outline-style: solid;
    --ax-focus-outline-color: var(--ax-color-accent, #0066b1);
    position: relative;
    isolation: isolate;
    display: flex;
    flex-direction: column;
    width: fit-content;
    min-width: min(100%, 400px);
    max-width: 100%;
    margin: 0;
    background-color: var(--ax-color-syntax-background);
    border: 1px solid var(--ax-color-border);
    border-radius: 8px;
    overflow: hidden;
}

.ax-codeblock-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding-inline: 1rem;
    padding-block: 0.5rem;
    background-color: var(--ax-color-syntax-background);
}

.ax-codeblock-title {
    display: flex;
    align-items: center;
    margin: 0;
    font-family: var(--ax-font-code);
    font-size: var(--ax-text-supporting-size);
    line-height: var(--ax-text-supporting-leading);
    font-weight: var(--ax-font-weight-medium);
    color: var(--ax-color-syntax-comment);
}

/* The copy control rests in the syntax-comment voice so it blends into
 * the header; Button owns its padding, radius, and hover surface. */
.ax-codeblock-copy {
    display: inline-flex;
    color: var(--ax-color-syntax-comment);
}

.ax-codeblock-copy--absolute {
    position: absolute;
    top: 0.5rem;
    inset-inline-end: 0.5rem;
}

.ax-codeblock-scroll {
    overflow-x: auto;
    overflow-y: auto;
}

.ax-codeblock-scroll:focus-visible {
    outline-width: var(--ax-focus-outline-width);
    outline-style: var(--ax-focus-outline-style);
    outline-color: var(--ax-focus-outline-color);
}

.ax-codeblock-pre {
    display: flex;
    min-width: fit-content;
    margin: 0;
}

.ax-codeblock-code {
    display: block;
    flex: 1;
    margin: 0;
    padding-block: 0.75rem;
    padding-inline: 1rem;
    font-family: var(--ax-font-code);
    font-size: var(--ax-text-code-size);
    line-height: var(--ax-text-code-leading);
    color: var(--ax-color-syntax-variable);
    tab-size: 2;
    white-space: pre;
}

.ax-codeblock--sm .ax-codeblock-code {
    font-size: var(--ax-text-supporting-size);
}

/* Pre-highlighted token spans: the wire's highlight roles voiced by the
 * syntax palette. Diff lines ride the red/green syntax voices. */

.ax-syntax-keyword {
    color: var(--ax-color-syntax-keyword);
}

.ax-syntax-string {
    color: var(--ax-color-syntax-string);
}

.ax-syntax-comment {
    color: var(--ax-color-syntax-comment);
}

.ax-syntax-deleted {
    color: var(--ax-color-syntax-tag);
}

.ax-syntax-inserted {
    color: var(--ax-color-syntax-string);
}
/* Shared fleet styles — one home for the DW-001 system every fleet
 * frontend consumes. Rules here change once, everywhere. */

/* The gargoyle (DW-001 §7): the 404's one allowed moment of playfulness — a
   stone grotesque drawn in muted ink, the only ornament on the page. Moved
   here from the retired static 404 (docs/deepwater-404.html, DW-404) with
   the markup. He sits left-aligned with the honest line under him; the old
   page centered the whole composition, but this body renders inside the
   normal page flow beside admin content, where centering would read as an
   accident. */
.gargoyle {
    margin: 2.5rem 0;
    width: 10rem;
    height: 10rem;
    color: var(--text-muted);
}
.gargoyle svg {
    width: 100%;
    height: 100%;
    fill: none;
    stroke: currentColor;
    stroke-width: 2.5;
    stroke-linecap: round;
    stroke-linejoin: round;
}
/* Shared fleet styles — one home for the DW-001 system every fleet
 * frontend consumes. Rules here change once, everywhere. */

/* Recorded component trees: components only, no bullets, no dividers — the
   indent does the work (rule 1). Names ride the monospace voice; props sit
   beside them as instrumentation. */
ul.tree {
    list-style: none;
    padding: 0;
    margin: 0;
}
ul.tree ul.tree {
    padding-left: 1.5rem;
    margin-top: 0.25rem;
}
.tree-node {
    padding: 0.15rem 0;
}
.tree-node .meta {
    margin-left: 0.5rem;
}

/* App diagrams: static SVG, so every paint rule lives here rather than in
   attributes. Boxes sit on the fill surface; names set in the page voices
   (serif pages, monospace components); usage curves are muted ink. The page
   boxes link to their drill-down and take the accent voice on hover, like
   any other link. */
.tgraph-scroll {
    /* Full-bleed diagram: the tree breaks out of the centered measure and
       takes the viewport width, scrolling horizontally when the tree is
       wider. This stays an SVG — not canvas — on purpose: links,
       hover, text sharpness, and accessible names come free with SVG,
       while canvas would reimplement all four by hand for graphs two
       orders of magnitude below the size where canvas wins. */
    width: 100vw;
    max-width: none;
    margin-left: calc(50% - 50vw);
    overflow-x: auto;
    padding: 2rem 0;
}
.tgraph {
    display: block;
    height: auto;
}
.tgraph .node-box {
    fill: var(--fill);
}
.tgraph text {
    fill: var(--text);
    font-size: 12.5px;
}
.tgraph .page-label {
    font-family: ui-serif, Georgia, serif;
}
.tgraph .comp-label {
    font-family: var(--mono);
}
.tgraph .edge {
    fill: none;
    stroke: var(--text-muted);
    stroke-width: 2;
}
.tgraph .tnode-link {
    text-decoration: none;
}
.tgraph .tnode-link:hover .node-box {
    stroke: var(--accent);
    stroke-width: 2;
}
.tgraph .tnode-link:hover text {
    fill: var(--accent);
}
/* --- Astryx key caps: verbatim from @astryxdesign/core 0.6.0's Kbd ---
 *
 * One cap per key, joined with a 4px gap. The wrapper's inline-flex comes
 * from the component's own layout (the source's wrapper props resolve to
 * the same row); every cap value below resolved from the built styles.
 * Like the text voices, the caps set the `--ax-*` variables they read on
 * themselves, so they work wherever they mount. */

.ax-kbd {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    flex-shrink: 0;
}

.ax-kbd-key {
    --ax-font-family-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --ax-color-neutral: light-dark(rgba(5, 54, 89, 0.1), rgba(223, 226, 229, 0.2));
    --ax-color-border-emphasized: light-dark(#ccd3db, #494d53);
    --ax-color-text-secondary: light-dark(#4e606f, #aaafb5);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 20px;
    height: 20px;
    padding-inline: 4px;
    background-color: var(--ax-color-neutral);
    border-bottom: 2px solid var(--ax-color-border-emphasized);
    border-radius: 4px;
    color: var(--ax-color-text-secondary);
    font-family: var(--ax-font-family-body);
    font-size: 0.75rem;
    font-weight: 500;
    line-height: 1.6667;
    user-select: none;
}
/* Shared fleet styles — one home for the DW-001 system every fleet
 * frontend consumes. Rules here change once, everywhere. */

/* --- Desk topbar: plain layout, no document chrome --- */

.desk-shell {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 2rem;
}

.desk-title {
    font-weight: 700;
    font-size: 1.1rem;
}

/* The status line takes the middle and pushes the actions right; when it
 * is absent the actions' own margin does that job instead. */
.desk-status {
    flex: 1 1 auto;
    font-size: 0.85rem;
}

.desk-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-left: auto;
}
/* Astryx collapsible, faithfully recreated. The root sets the `--ax-*`
 * variables it reads, so the region works wherever it mounts — and never
 * leaks into the DW-001 system around it. Values resolved from
 * @astryxdesign/core 0.6.0's built styles; tokens are verbatim.
 *
 * Trigger type is the large voice (17px semibold); the chevron is a 17px
 * box around the 12px glyph, rotating closed 0° to open 180° on the fast
 * ease. Content pads 4px on top; closed content hides without unmounting. */

.ax-collapsible {
    --ax-font-family-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --ax-color-text-primary: light-dark(#0a1317, #dfe2e5);
    --ax-color-text-secondary: light-dark(#4e606f, #aaafb5);
    --ax-duration-fast: 175ms;
    --ax-ease-standard: cubic-bezier(0.24, 1, 0.4, 1);
    width: 100%;
    font-family: var(--ax-font-family-body);
    color: var(--ax-color-text-primary);
}

.ax-collapsible-trigger {
    box-sizing: border-box;
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding-block: 8px;
    background-color: transparent;
    border: 0;
    color: var(--ax-color-text-primary);
    font-family: var(--ax-font-family-body);
    font-size: 1.0625rem;
    font-weight: 600;
    line-height: 1.4118;
    text-align: start;
    cursor: pointer;
}

.ax-collapsible-trigger--disabled {
    opacity: 0.5;
    cursor: default;
}

.ax-collapsible-trigger-label {
    flex-grow: 1;
}

.ax-collapsible-chevron {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 1.0625rem;
    height: 1.0625rem;
    color: var(--ax-color-text-secondary);
    transition-property: transform;
    transition-duration: var(--ax-duration-fast);
    transition-timing-function: var(--ax-ease-standard);
    transform: rotate(0deg);
}

.ax-collapsible-chevron--open {
    transform: rotate(180deg);
}

.ax-collapsible-content {
    padding-top: 4px;
    background-color: transparent;
    font-size: 0.875rem;
    font-weight: 400;
    line-height: 1.4286;
}
/* --- Astryx dialogs (card #291): the native dialog element, modal --- */

.ax-dialog {
    color-scheme: light dark;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    color: light-dark(#0a1317, #dfe2e5);

    /* Every token below is verbatim from @astryxdesign/core 0.6.0's theme
     * tokens. Like the shell, list, and chat scopes, the dialog carries
     * its own set: dialogs mount outside every other scope (straight off
     * the body), so without this the surface, scrim, radius, and shadow
     * resolve to nothing — a transparent menu over a blue page. (Two
     * names keep the crate's `--ax-` infix where Astryx itself uses the
     * uninherited `--radius-container` and `--shadow-low`.) */
    --ax-color-background-surface: light-dark(#ffffff, #1f1f22);
    --ax-color-neutral: light-dark(rgba(5, 54, 89, 0.1), rgba(223, 226, 229, 0.2));
    --ax-color-overlay: light-dark(#01122866, #11111299);
    --ax-color-text-primary: light-dark(#0a1317, #dfe2e5);
    --ax-color-text-secondary: light-dark(#4e606f, #aaafb5);
    --ax-color-border: light-dark(#05365919, #f2f4f619);
    --ax-radius-container: 12px;
    --ax-shadow-low: 0px 1px 1px light-dark(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.2)), 0px 2px 8px light-dark(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.2));
    --ax-border-width: 1px;
    --ax-spacing-0-5: 2px;
    --ax-spacing-2: 8px;
    --ax-spacing-3: 12px;
    --ax-text-body-size: 0.875rem;
    --ax-text-body-leading: 1.4286;
    --ax-text-supporting-size: 0.75rem;
    --ax-text-supporting-leading: 1.6667;
    --ax-font-weight-semibold: 600;
    --ax-duration-medium: 410ms;
    --ax-ease-standard: cubic-bezier(0.24, 1, 0.4, 1);

    position: fixed;
    margin: auto;
    padding: 0;
    border: none;
    background-color: var(--ax-color-background-surface, var(--ax-color-neutral));
    border-radius: var(--ax-radius-container);
    box-shadow: var(--ax-shadow-low);
    color: var(--ax-color-text-primary);
    display: none;
    flex-direction: column;
    height: fit-content;
    overscroll-behavior: contain;
    opacity: 0;
}

/* Visibility rides an explicit class, never the `open` attribute: the
 * effect below owns modality through `showModal()`/`close()` alone, so no
 * attribute toggle can ever disagree with the top layer about whether
 * this dialog is open. */
.ax-dialog.ax-dialog--open {
    display: flex;
    opacity: 1;
}

@media (prefers-reduced-motion: no-preference) {
    .ax-dialog.ax-dialog--open {
        animation: ax-dialog-enter var(--ax-duration-medium, 410ms) var(--ax-ease-standard);
        animation-fill-mode: backwards;
    }
}

@keyframes ax-dialog-enter {
    from {
        opacity: 0;
        transform: translate(0, 16px) scale(0.95);
    }
    to {
        opacity: 1;
        transform: translate(0, 0) scale(1);
    }
}

.ax-dialog::backdrop {
    background-color: var(--ax-color-overlay, rgba(5, 54, 89, 0.48));
}

.ax-dialog--fullscreen {
    width: 100dvw;
    height: 100dvh;
    max-width: 100dvw;
    max-height: 100dvh;
    border-radius: 0;
    margin: 0;
    inset: 0;
}

/* Scroll container inside the dialog: content scrolls, the dialog frame
   (and any header divider) stays put. */
.ax-dialog-inner {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
    border-radius: inherit;
}

/* --- Dialog header: title row with flanking action slots --- */

.ax-dialog-header {
    display: flex;
    align-items: flex-start;
    gap: var(--ax-spacing-3);
}

.ax-dialog-header--divided {
    border-bottom: var(--ax-border-width) solid var(--ax-color-border);
    padding-bottom: var(--ax-spacing-3);
    margin-bottom: var(--ax-spacing-3);
}

.ax-dialog-titles {
    flex: 1 1 auto;
    min-width: 0;
}

.ax-dialog-title {
    font-size: var(--ax-text-body-size);
    line-height: var(--ax-text-body-leading);
    font-weight: var(--ax-font-weight-semibold);
    color: var(--ax-color-text-primary);
    outline: none;
}

.ax-dialog-subtitle {
    font-size: var(--ax-text-supporting-size);
    line-height: var(--ax-text-supporting-leading);
    color: var(--ax-color-text-secondary);
    margin-top: var(--ax-spacing-0-5);
}

.ax-dialog-actions {
    display: flex;
    align-items: center;
    gap: var(--ax-spacing-2);
    flex-shrink: 0;
}
/* --- Astryx text areas (card #293): label, painted container, overlays ---
 * Token scale (`--ax-*`) is shared with the chat surface in chat.css. */

.ax-textarea {
    display: block;
}

.ax-textarea-label {
    display: block;
    font-size: var(--ax-text-label-size);
    line-height: var(--ax-text-label-leading);
    font-weight: var(--ax-font-weight-medium);
    color: var(--ax-color-text-primary);
    margin-bottom: var(--ax-spacing-1);
}

/* Visually hidden but still the field's accessible name. */
.ax-textarea-label--hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.ax-textarea-optional {
    font-weight: var(--ax-font-weight-normal);
    color: var(--ax-color-text-secondary);
    margin-inline-start: var(--ax-spacing-1);
}

.ax-textarea-description {
    font-size: var(--ax-text-supporting-size);
    line-height: var(--ax-text-supporting-leading);
    color: var(--ax-color-text-secondary);
    margin-bottom: var(--ax-spacing-1);
}

/* The painted input container: overlays (icon, end slot, counter) anchor
   to its corners while the textarea spans the full box, so the native
   resize grip stays in the true bottom-right corner. */
.ax-textarea-wrap {
    position: relative;
    z-index: 1;
    background-color: var(--ax-color-input-background, var(--ax-color-neutral));
    border: var(--ax-border-width) solid var(--ax-color-border);
    border-radius: var(--ax-radius-element);
}

.ax-textarea-wrap:focus-within {
    border-color: var(--ax-color-border-emphasized);
}

.ax-textarea--warning .ax-textarea-wrap {
    border-color: var(--ax-color-warning, var(--ax-color-text-secondary));
}

.ax-textarea--error .ax-textarea-wrap {
    border-color: var(--ax-color-error);
}

.ax-textarea--success .ax-textarea-wrap {
    border-color: var(--ax-color-success, var(--ax-color-text-secondary));
}

.ax-textarea-control {
    display: block;
    width: 100%;
    box-sizing: border-box;
    min-width: 0;
    border-width: 0;
    border-style: none;
    padding-block: var(--ax-spacing-1);
    padding-inline: var(--ax-spacing-2);
    font-family: inherit;
    font-size: var(--ax-text-body-size);
    line-height: var(--ax-text-body-leading);
    color: var(--ax-color-text-primary);
    background-color: transparent;
    outline: none;
    resize: vertical;
}

.ax-textarea-control::placeholder {
    color: var(--ax-color-text-secondary);
}

@media (pointer: coarse) {
    .ax-textarea-control {
        font-size: max(1rem, var(--ax-text-body-size));
    }
}

.ax-textarea--lg .ax-textarea-control {
    padding-block: var(--ax-spacing-2);
}

/* Reserved space so text clears the overlays. */
.ax-textarea-control--with-icon {
    padding-inline-start: calc(var(--ax-spacing-2) + var(--ax-spacing-6));
}

.ax-textarea-control--with-status {
    padding-inline-end: calc(var(--ax-spacing-2) + var(--ax-spacing-6));
}

.ax-textarea-control--with-counter {
    padding-bottom: var(--ax-spacing-7);
}

.ax-textarea-control:disabled {
    cursor: default;
}

.ax-textarea-icon {
    position: absolute;
    top: var(--ax-spacing-2);
    inset-inline-start: var(--ax-spacing-2);
    pointer-events: none;
    display: flex;
}

.ax-textarea-end {
    position: absolute;
    top: var(--ax-spacing-2);
    inset-inline-end: var(--ax-spacing-2);
    pointer-events: none;
    display: flex;
    align-items: center;
    gap: var(--ax-spacing-2);
}

.ax-textarea-counter {
    position: absolute;
    bottom: var(--ax-spacing-1);
    inset-inline-end: var(--ax-spacing-2);
    pointer-events: none;
    display: flex;
    align-items: center;
    gap: var(--ax-spacing-1);
    font-size: var(--ax-text-supporting-size);
    line-height: var(--ax-text-supporting-leading);
    color: var(--ax-color-text-secondary);
}

.ax-textarea-counter--over {
    color: var(--ax-color-error);
}

/* Attached status message: bordered box directly below the field. */
.ax-textarea-status {
    margin-top: var(--ax-spacing-1);
    padding: var(--ax-spacing-1) var(--ax-spacing-2);
    border: var(--ax-border-width) solid var(--ax-color-border);
    border-radius: var(--ax-radius-element);
    font-size: var(--ax-text-supporting-size);
    line-height: var(--ax-text-supporting-leading);
}

.ax-textarea-status--warning {
    border-color: var(--ax-color-warning, var(--ax-color-text-secondary));
}

.ax-textarea-status--error {
    border-color: var(--ax-color-error);
}

.ax-textarea-status--success {
    border-color: var(--ax-color-success, var(--ax-color-text-secondary));
}

.ax-textarea-status--muted {
    color: var(--ax-color-text-secondary);
}

/* Counter live region: in the accessibility tree, never on screen. */
.ax-textarea-live {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}
/* Shared fleet styles — one home for the DW-001 system every fleet
 * frontend consumes. Rules here change once, everywhere. */

/* --- Side-rail rows: full-width destinations with an inline hint --- */

.rail-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.5rem;
    width: 100%;
    padding: 0.4rem 0.6rem;
    border: 1px solid transparent;
    border-radius: 6px;
    background: transparent;
    color: var(--text);
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.rail-row:hover {
    border-color: var(--text-muted);
}

/* The current row: the filled voice, so it reads without colour. */
.rail-row--selected {
    background: var(--text);
    color: var(--bg);
}

.rail-row:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

/* The shortcut hint: the monospace voice at a smaller size, quiet beside
 * the label. The label carries the meaning, so the hint stays a hint. */
.rail-row .rail-hint {
    font-family: var(--mono);
    font-size: 0.8em;
    font-weight: 400;
    padding: 0.1rem 0.35rem;
    border: 1px solid currentColor;
    border-radius: 4px;
    opacity: 0.75;
}
/* Astryx command palette, faithfully recreated. Every rule sets the
 * `--ax-*` variables it reads on the class itself, so the palette works
 * wherever its parts mount: the input, list, and footer each set the variables they read, rows inherit the list scope, and the dialog scope backstops it all — and never leaks into the
 * DW-001 system around it. Spacing, type, and colors resolved from
 * @astryxdesign/core 0.6.0's built styles; tokens are verbatim.
 *
 * Scale used here: spacing 1/2/3/4/8 = 4/8/12/16/32px; body 14px normal
 * 1.4286; supporting 12px normal 1.6667; radius-inner 4px. */

.ax-command-palette-input {
    --ax-font-family-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --ax-color-text-primary: light-dark(#0a1317, #dfe2e5);
    --ax-color-text-secondary: light-dark(#4e606f, #aaafb5);
    display: flex;
    align-items: center;
    gap: 8px;
    padding-inline: 16px;
    padding-block: 12px;
    flex-shrink: 0;
}

.ax-command-palette-input-icon {
    display: flex;
    align-items: center;
    flex-shrink: 0;
    color: var(--ax-color-text-secondary);
}

.ax-command-palette-input-icon svg {
    width: 16px;
    height: 16px;
}

.ax-command-palette-field {
    flex: 1;
    min-width: 0;
    outline: none;
    background-color: transparent;
    border: 0;
    padding: 0;
    color: var(--ax-color-text-primary);
    font-family: var(--ax-font-family-body);
    /* 16px floors the field against mobile auto-zoom, like the source. */
    font-size: max(1rem, 0.875rem);
    line-height: 1.4286;
}

.ax-command-palette-field::placeholder {
    color: var(--ax-color-text-secondary);
}

/* The scrollable results box: 4px padded, capped so long result lists
 * stay inside the dialog with the input and footer. */

.ax-command-palette-list {
    --ax-font-family-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --ax-color-text-primary: light-dark(#0a1317, #dfe2e5);
    --ax-color-text-secondary: light-dark(#4e606f, #aaafb5);
    --ax-color-overlay-hover: light-dark(#0536590c, #ffffff0c);
    --ax-color-accent-muted: light-dark(#0082fb33, #0082fb3f);
    overflow-y: auto;
    max-height: 50dvh;
    padding: 4px;
    display: flex;
    flex-direction: column;
    gap: 2px;
    color: var(--ax-color-text-primary);
    font-family: var(--ax-font-family-body);
}

/* One command row: full-width, label-size, pointer on hover. The
 * highlighted row wears the hover wash, the selected row the accent wash
 * — the same two washes the source uses, never DW-001 depth. */

.ax-command-palette-item {
    --ax-color-overlay-hover: light-dark(#0536590c, #ffffff0c);
    --ax-color-accent-muted: light-dark(#0082fb33, #0082fb3f);
    width: 100%;
    display: flex;
    align-items: center;
    gap: 8px;
    padding-inline: 12px;
    padding-block: 8px;
    border-radius: 4px;
    background-color: transparent;
    color: var(--ax-color-text-primary);
    font-family: var(--ax-font-family-body);
    font-size: 0.875rem;
    text-align: start;
    cursor: pointer;
    user-select: none;
}

.ax-command-palette-item--highlighted {
    background-color: var(--ax-color-overlay-hover);
}

.ax-command-palette-item--selected {
    background-color: var(--ax-color-accent-muted);
}

.ax-command-palette-item--disabled {
    opacity: 0.5;
    cursor: default;
}

.ax-command-palette-item--disabled:hover {
    background-color: transparent;
}

/* Groups: the heading is 12px secondary supporting type, never uppercase. */

.ax-command-palette-group {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding-block: 4px;
}

.ax-command-palette-group-heading {
    padding-inline: 12px;
    padding-block: 4px;
    color: var(--ax-color-text-secondary);
    font-family: var(--ax-font-family-body);
    font-size: 0.75rem;
    line-height: 1.6667;
    user-select: none;
}

/* The empty state: centered, padded, quiet. */

.ax-command-palette-empty {
    display: flex;
    justify-content: center;
    padding-block: 32px;
    padding-inline: 16px;
    color: var(--ax-color-text-secondary);
    font-family: var(--ax-font-family-body);
    font-size: 0.75rem;
    line-height: 1.6667;
    text-align: center;
}

/* The footer: hint rows in the same 12px secondary voice, each hint a
 * 4px-gapped row of caps plus a word. */

.ax-command-palette-footer {
    --ax-font-family-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --ax-color-text-secondary: light-dark(#4e606f, #aaafb5);
    display: flex;
    align-items: center;
    gap: 16px;
    padding-inline: 16px;
    padding-block: 8px;
    flex-shrink: 0;
    color: var(--ax-color-text-secondary);
    font-family: var(--ax-font-family-body);
    font-size: 0.75rem;
    line-height: 1.6667;
}

.ax-command-palette-hint {
    display: flex;
    align-items: center;
    gap: 4px;
}
/* Astryx text voices, faithfully recreated. Every rule sets the `--ax-*`
 * variables it reads on the class itself, so the voices work wherever they
 * mount without an ancestor scope — and never leak into the DW-001 system
 * around them. Sizes, weights, and line-heights are verbatim from
 * @astryxdesign/core 0.6.0's type scale; colors are verbatim from its
 * theme tokens.
 *
 * Scale (rem at 16px root): 4xs .375, 3xs .4375, 2xs .5, xs .625,
 * sm .75, base .875, lg 1.0625, xl 1.25, 2xl 1.5, 3xl 1.8125.
 */

.ax-text {
    --ax-font-family-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --ax-font-family-mono: ui-monospace, SFMono-Regular, Menlo, monospace;
    --ax-color-text-primary: light-dark(#0a1317, #dfe2e5);
    --ax-color-text-secondary: light-dark(#4e606f, #aaafb5);
    --ax-color-accent: light-dark(#0064e0, #2694fe);
    font-family: var(--ax-font-family-body);
}

.ax-text--body {
    font-size: 0.875rem;
    font-weight: 400;
    line-height: 1.4286;
}

.ax-text--large {
    font-size: 1.0625rem;
    font-weight: 600;
    line-height: 1.4118;
}

.ax-text--label {
    font-size: 0.875rem;
    font-weight: 500;
    line-height: 1.4286;
}

.ax-text--supporting {
    font-size: 0.75rem;
    font-weight: 400;
    line-height: 1.6667;
}

.ax-text--code {
    font-family: var(--ax-font-family-mono);
    font-size: 0.875rem;
    font-weight: 400;
    line-height: 1.4286;
}

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

.ax-text--secondary {
    color: var(--ax-color-text-secondary);
}

.ax-text--accent {
    color: var(--ax-color-accent);
}

.ax-text--inherit {
    color: inherit;
}

/* Headings: the semibold display scale, always blocks with no margin —
 * the scale carries the hierarchy, not surrounding space. */

.ax-heading {
    --ax-color-text-primary: light-dark(#0a1317, #dfe2e5);
    --ax-color-text-secondary: light-dark(#4e606f, #aaafb5);
    --ax-color-accent: light-dark(#0064e0, #2694fe);
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    font-weight: 600;
    display: block;
    margin: 0;
}

.ax-heading--1 {
    font-size: 1.5rem;
    line-height: 1.3333;
}

.ax-heading--2 {
    font-size: 1.25rem;
    line-height: 1.4;
}

.ax-heading--3 {
    font-size: 1.0625rem;
    line-height: 1.4118;
}

.ax-heading--4 {
    font-size: 0.875rem;
    line-height: 1.4286;
}

.ax-heading--5 {
    font-size: 0.75rem;
    line-height: 1.6667;
}

.ax-heading--6 {
    font-size: 0.625rem;
    line-height: 1.6;
}
/* The workspace layout: the one/two-pane grid and the responsive home
 * split. Only spacing follows Astryx here (the 48px pane gap is its
 * spacing-12); the content measure, paddings, and column floors are the
 * desk's layout constants, moved with the markup. Breakpoints match the
 * shell's lg: 64rem. */

.ax-panes {
    display: grid;
    gap: 3rem;
    margin: 0 auto;
    max-width: 110rem;
    min-width: 0;
    padding: 1.25rem;
}

.ax-pane {
    min-width: 0;
    outline: 0;
}

@media (max-width: 63.999rem) {
    .ax-panes[data-count="two"] .ax-pane[data-active="false"] {
        display: none;
    }
}

@media (min-width: 64rem) {
    .ax-panes {
        padding: 2rem 3rem 4rem;
    }

    .ax-panes[data-count="two"] {
        grid-template-columns: minmax(22rem, 0.8fr) minmax(32rem, 1.2fr);
    }
}

/* The home split: the narrow tree below lg, the wide tree at and above.
 * Both stay mounted — the toggle is display only. Content padding matches
 * the panes, so the split and the grid align at every width. */

.ax-split {
    min-width: 0;
    padding: 1.25rem;
}

.ax-split--narrow {
    display: none;
}

.ax-split--wide {
    display: block;
    margin: 0 auto;
    max-width: 110rem;
}

@media (width < 64rem) {
    .ax-split--narrow {
        display: block;
    }

    .ax-split--wide {
        display: none;
    }
}

@media (min-width: 64rem) {
    .ax-split {
        padding: 2rem 3rem 4rem;
    }
}
/* Astryx chat surfaces, faithfully recreated. Every rule lives under the
 * `ax-chat` scope and every token is `--ax-*`, so this second visual
 * language never leaks into — or fights — the DW-001 system around it.
 * Values are verbatim from @astryxdesign/core 0.6.0's theme tokens and the
 * Chat module's StyleX rules; the structure mirrors those files section by
 * section. Like Astryx's own Theme, the scope sets the body font and ink,
 * so a chat tree reads identically wherever it mounts.
 *
 * Icon paths are Meta's defaultIcons (MIT), copied for the status icons
 * the chat surface needs.
 */

.ax-chat {
    color-scheme: light dark;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    color: light-dark(#0a1317, #dfe2e5);

    /* --- color --- */
    --ax-color-accent: light-dark(#0064e0, #2694fe);
    --ax-color-accent-muted: light-dark(#0082fb33, #0082fb3f);
    --ax-color-on-accent: #ffffff;
    --ax-color-neutral: light-dark(rgba(5, 54, 89, 0.1), rgba(223, 226, 229, 0.2));
    --ax-color-background-popover: light-dark(#ffffff, #28292c);
    --ax-color-overlay-hover: light-dark(#0536590c, #ffffff0c);
    --ax-color-overlay-pressed: light-dark(#05365919, #ffffff19);
    --ax-color-text-primary: light-dark(#0a1317, #dfe2e5);
    --ax-color-text-secondary: light-dark(#4e606f, #aaafb5);
    --ax-color-text-disabled: light-dark(#a4b0bc, #6f747c);
    --ax-color-on-dark: #ffffff;
    --ax-color-success: #0d8626;
    --ax-color-on-success: #ffffff;
    --ax-color-error: light-dark(#e3193b, #f5394f);
    --ax-color-error-muted: light-dark(#e3193b33, #f5394f3f);
    --ax-color-on-error: #ffffff;
    --ax-color-warning: light-dark(#e9af08, #f2c00b);
    --ax-color-warning-muted: light-dark(#e2a40033, #e2a4003f);
    --ax-color-on-warning: #0a1317;
    --ax-color-border: light-dark(#05365919, #f2f4f619);
    --ax-color-border-emphasized: light-dark(#ccd3db, #494d53);
    --ax-color-track: light-dark(#ccd3db, #5a5e66);
    --ax-color-text-red: light-dark(#7b0210, #ffb2b8);
    --ax-color-text-yellow: light-dark(#753f07, #fbce03);
    --ax-color-background-blue: light-dark(#0171e333, #0171e333);
    --ax-color-text-blue: light-dark(#042f97, #afd7ff);
    --ax-color-background-cyan: light-dark(#03a7d733, #03a7d733);
    --ax-color-text-cyan: light-dark(#014975, #a1eef9);
    --ax-color-background-green: light-dark(#24bb5e33, #24bb5e33);
    --ax-color-text-green: light-dark(#09441f, #a5f690);
    --ax-color-background-orange: light-dark(#f2790233, #f2790233);
    --ax-color-text-orange: light-dark(#6b2203, #fdb876);
    --ax-color-background-pink: light-dark(#e638b333, #e638b333);
    --ax-color-text-pink: light-dark(#650053, #feade3);
    --ax-color-background-purple: light-dark(#7952ff33, #7952ff33);
    --ax-color-text-purple: light-dark(#3e0697, #b3b0fe);
    --ax-color-background-red: light-dark(#e3193b33, #e3193b33);
    --ax-color-background-teal: light-dark(#0db7af33, #0db7af33);
    --ax-color-text-teal: light-dark(#083943, #40dccd);
    --ax-color-background-yellow: light-dark(#e2a40033, #e2a40033);

    /* --- spacing --- */
    --ax-spacing-0: 0px;
    --ax-spacing-0-5: 2px;
    --ax-spacing-1: 4px;
    --ax-spacing-1-5: 6px;
    --ax-spacing-2: 8px;
    --ax-spacing-3: 12px;
    --ax-spacing-4: 16px;
    --ax-spacing-5: 20px;
    --ax-spacing-6: 24px;
    --ax-spacing-8: 32px;
    --ax-spacing-10: 40px;

    /* --- sizes, borders, focus --- */
    --ax-size-element-sm: 28px;
    --ax-size-element-md: 32px;
    --ax-size-element-lg: 40px;
    --ax-border-width: 1px;
    --ax-focus-outline-width: 2px;
    --ax-focus-outline-style: solid;
    --ax-focus-outline-color: var(--ax-color-accent);
    --ax-focus-outline-offset: 3px;

    /* --- radius --- */
    --ax-radius-inner: 4px;
    --ax-radius-element: 8px;
    --ax-radius-container: 12px;
    --ax-radius-chat: 28px;
    --ax-radius-full: 9999px;

    /* --- shadow --- */
    --ax-shadow-low: 0px 1px 1px light-dark(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.2)), 0px 2px 8px light-dark(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.2));
    --ax-shadow-med: 0px 1px 2px light-dark(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.2)), 0px 2px 12px light-dark(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.2));

    /* --- motion --- */
    --ax-duration-fast: 175ms;
    --ax-duration-fast-max: 230ms;
    --ax-duration-medium: 410ms;
    --ax-duration-slow-min: 730ms;
    --ax-ease-standard: cubic-bezier(0.24, 1, 0.4, 1);

    /* --- type --- */
    --ax-font-family-code: "SF Mono", Monaco, Consolas, monospace;
    --ax-text-body-size: 0.875rem;
    --ax-text-body-leading: 1.4286;
    --ax-text-label-size: 0.875rem;
    --ax-text-label-leading: 1.4286;
    --ax-text-supporting-size: 0.75rem;
    --ax-text-supporting-leading: 1.6667;
    --ax-font-weight-normal: 400;
    --ax-font-weight-medium: 500;
    --ax-font-weight-semibold: 600;
}

/* --- ChatMessage: the sender context wrapper --- */

.ax-chat-message {
    display: flex;
    align-items: flex-start;
    max-width: 100%;
}

.ax-chat-message--gap-compact { gap: var(--ax-spacing-1-5); }
.ax-chat-message--gap-balanced { gap: var(--ax-spacing-2); }
.ax-chat-message--gap-spacious { gap: var(--ax-spacing-3); }

.ax-chat-message--assistant {
    flex-direction: row;
    justify-content: flex-start;
}

.ax-chat-message--user {
    flex-direction: row-reverse;
    justify-content: flex-start;
}

.ax-chat-message--system {
    flex-direction: row;
    justify-content: center;
}

.ax-chat-message-avatar {
    flex-shrink: 0;
}

/* When a name row shows, the avatar drops to align with the body. */
.ax-chat-message-avatar:has(~ * [data-chat-name]) {
    margin-block-start: var(--ax-spacing-5);
}

.ax-chat-message-content {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-width: 0;
}

.ax-chat-message-content--system {
    max-width: 90%;
    align-items: center;
}

.ax-chat-message-content--assistant { align-items: flex-start; }
.ax-chat-message-content--user { align-items: flex-end; }

.ax-chat-message-name {
    font-size: var(--ax-text-supporting-size);
    font-weight: var(--ax-font-weight-semibold);
    color: var(--ax-color-text-secondary);
    line-height: var(--ax-text-supporting-leading);
    margin-block-end: var(--ax-spacing-1);
}

.ax-chat-message-children {
    display: flex;
    flex-direction: column;
    min-width: 0;
    width: 100%;
}

.ax-chat-message-children--assistant { align-items: flex-start; }
.ax-chat-message-children--user { align-items: flex-end; }
.ax-chat-message-children--system { align-items: center; }
.ax-chat-message-children--gap-compact { gap: var(--ax-spacing-0-5); }
.ax-chat-message-children--gap-balanced { gap: var(--ax-spacing-1); }
.ax-chat-message-children--gap-spacious { gap: var(--ax-spacing-1-5); }

/* --- ChatMessageBubble: the styled content container --- */

.ax-chat-bubble {
    display: flex;
    flex-direction: column;
    max-width: max(80%, 280px);
    border-radius: var(--ax-radius-chat);
    font-size: var(--ax-text-body-size);
    line-height: var(--ax-text-body-leading);
    overflow-wrap: break-word;
    word-break: break-word;
}

.ax-chat-bubble--radius-compact { border-radius: var(--ax-radius-container); }

.ax-chat-bubble--padding-compact,
.ax-chat-bubble--padding-balanced {
    padding-block: var(--ax-spacing-3);
    padding-inline: var(--ax-spacing-4);
}

.ax-chat-bubble--padding-spacious {
    padding-block: var(--ax-spacing-4);
    padding-inline: var(--ax-spacing-5);
}

.ax-chat-bubble--sender-assistant,
.ax-chat-bubble--sender-user {
    background-color: var(--ax-color-neutral);
    color: var(--ax-color-text-primary);
}

.ax-chat-bubble--ghost {
    background-color: transparent;
    color: var(--ax-color-text-primary);
    padding-block: 0;
}

/* Grouped corners: the sender-side corners tuck toward the group. */
.ax-chat-bubble--group-first-assistant { border-end-start-radius: var(--ax-radius-inner); }
.ax-chat-bubble--group-middle-assistant {
    border-start-start-radius: var(--ax-radius-inner);
    border-end-start-radius: var(--ax-radius-inner);
}
.ax-chat-bubble--group-last-assistant { border-start-start-radius: var(--ax-radius-inner); }
.ax-chat-bubble--group-first-user { border-end-end-radius: var(--ax-radius-inner); }
.ax-chat-bubble--group-middle-user {
    border-start-end-radius: var(--ax-radius-inner);
    border-end-end-radius: var(--ax-radius-inner);
}
.ax-chat-bubble--group-last-user { border-start-end-radius: var(--ax-radius-inner); }

/* Name and metadata slots align with the bubble's text column. */
.ax-chat-bubble-name {
    height: var(--ax-spacing-5);
    display: flex;
    align-items: center;
    margin-block-end: calc(-1 * var(--ax-spacing-1-5));
}

.ax-chat-bubble-metadata {
    margin-block-start: calc(-1 * var(--ax-spacing-1-5));
}

.ax-chat-bubble-slot--padding-compact,
.ax-chat-bubble-slot--padding-balanced {
    padding-inline: var(--ax-spacing-4);
}

.ax-chat-bubble-slot--padding-spacious {
    padding-inline: var(--ax-spacing-5);
}

.ax-chat-bubble-slot--end { text-align: end; }

/* --- ChatMessageList: the presentational message container --- */

.ax-chat-list {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
}

.ax-chat-list-inner {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
}

.ax-chat-list-inner--compact {
    gap: var(--ax-spacing-2);
    padding-block: var(--ax-spacing-2);
    padding-inline: var(--ax-spacing-3);
}

.ax-chat-list-inner--balanced {
    gap: var(--ax-spacing-4);
    padding-block: var(--ax-spacing-4);
    padding-inline: var(--ax-spacing-4);
}

.ax-chat-list-inner--spacious {
    gap: var(--ax-spacing-6);
    padding-block: var(--ax-spacing-6);
    padding-inline: var(--ax-spacing-6);
}

.ax-chat-list-inner--gap-0 { gap: var(--ax-spacing-0); }
.ax-chat-list-inner--gap-0-5 { gap: var(--ax-spacing-0-5); }
.ax-chat-list-inner--gap-1 { gap: var(--ax-spacing-1); }
.ax-chat-list-inner--gap-1-5 { gap: var(--ax-spacing-1-5); }
.ax-chat-list-inner--gap-2 { gap: var(--ax-spacing-2); }
.ax-chat-list-inner--gap-3 { gap: var(--ax-spacing-3); }
.ax-chat-list-inner--gap-4 { gap: var(--ax-spacing-4); }
.ax-chat-list-inner--gap-5 { gap: var(--ax-spacing-5); }
.ax-chat-list-inner--gap-6 { gap: var(--ax-spacing-6); }
.ax-chat-list-inner--gap-8 { gap: var(--ax-spacing-8); }
.ax-chat-list-inner--gap-10 { gap: var(--ax-spacing-10); }

.ax-chat-list-spacer {
    flex: 1;
    min-height: 0;
}

.ax-chat-list-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 1;
    min-height: 0;
}

/* --- ChatMessageMetadata: timestamp, footer, status --- */

.ax-chat-metadata {
    display: flex;
    align-items: center;
    gap: var(--ax-spacing-1);
    margin-block-start: var(--ax-spacing-1);
    font-size: var(--ax-text-supporting-size);
    font-weight: var(--ax-font-weight-normal);
    line-height: var(--ax-text-supporting-leading);
    color: var(--ax-color-text-secondary);
}

.ax-chat-metadata--user { flex-direction: row-reverse; }
.ax-chat-metadata--assistant { flex-direction: row; }

.ax-chat-metadata-status {
    display: inline-flex;
    align-items: center;
    gap: var(--ax-spacing-1);
}

.ax-chat-metadata-status--error { color: var(--ax-color-error); }

@keyframes ax-chat-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.5; }
}

.ax-chat-metadata-status--pulse {
    animation-name: ax-chat-pulse;
    animation-duration: 1.5s;
    animation-timing-function: ease-in-out;
    animation-iteration-count: infinite;
}

@media (prefers-reduced-motion: reduce) {
    .ax-chat-metadata-status--pulse { animation-name: none; }
}

/* --- ChatSystemMessage: centered notices and date separators --- */

.ax-chat-system {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--ax-spacing-2);
    padding-block: var(--ax-spacing-1);
    font-size: var(--ax-text-supporting-size);
    font-weight: var(--ax-font-weight-normal);
    color: var(--ax-color-text-secondary);
    text-align: center;
}

.ax-chat-system--divider { width: 100%; }

.ax-chat-system-icon {
    display: inline-flex;
    align-items: center;
    flex-shrink: 0;
}

.ax-chat-system-content {
    display: inline-flex;
    align-items: center;
    gap: var(--ax-spacing-1-5);
    flex-shrink: 0;
    white-space: nowrap;
}

.ax-chat-system-rule {
    display: flex;
    align-items: center;
    width: 100%;
}

.ax-chat-system-rule-line {
    height: var(--ax-border-width);
    flex-grow: 1;
    flex-shrink: 1;
    background-color: var(--ax-color-border);
}

.ax-chat-system-rule-label {
    flex-shrink: 0;
    padding-inline: var(--ax-spacing-3);
    font-size: var(--ax-text-supporting-size);
    line-height: var(--ax-text-supporting-leading);
    color: var(--ax-color-text-secondary);
}

/* --- ChatToolCalls: tool invocation rows, grouped when many --- */

.ax-chat-tool-calls {
    display: flex;
    flex-direction: column;
    margin-block-start: var(--ax-spacing-2);
}

.ax-chat-tool-row--toggle {
    cursor: pointer;
}

.ax-chat-tool-row--toggle:disabled,
.ax-chat-tool-row--toggle[aria-disabled="true"] {
    cursor: default;
}

.ax-chat-tool-group-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 16px;
    height: 16px;
    color: var(--ax-color-text-secondary);
}

.ax-chat-tool-group-label {
    font-size: var(--ax-text-supporting-size);
    line-height: var(--ax-text-supporting-leading);
    font-weight: var(--ax-font-weight-medium);
    color: var(--ax-color-text-secondary);
}

.ax-chat-tool-chevron {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 14px;
    height: 14px;
    color: var(--ax-color-text-disabled);
}

.ax-chat-tool-chevron > svg {
    transition: transform var(--ax-duration-fast) var(--ax-ease-standard);
}

@media (prefers-reduced-motion: reduce) {
    .ax-chat-tool-chevron > svg { transition: none; }
}

.ax-chat-tool-chevron--expanded > svg { transform: rotate(180deg); }

.ax-chat-tool-group-content {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows var(--ax-duration-medium) var(--ax-ease-standard);
}

@media (prefers-reduced-motion: reduce) {
    .ax-chat-tool-group-content { transition: none; }
}

.ax-chat-tool-group-content--expanded { grid-template-rows: 1fr; }

.ax-chat-tool-group-content-inner {
    overflow: hidden;
    min-height: 0;
    padding-inline: var(--ax-spacing-1);
    margin-inline: calc(-1 * var(--ax-spacing-1));
}

.ax-chat-tool-list {
    display: flex;
    flex-direction: column;
    padding-inline: var(--ax-spacing-1);
    margin-inline: calc(-1 * var(--ax-spacing-1));
}

.ax-chat-tool-row {
    display: flex;
    align-items: center;
    gap: var(--ax-spacing-1-5);
    min-height: 24px;
    padding-block: var(--ax-spacing-0-5);
}

.ax-chat-tool-row--clickable {
    cursor: pointer;
    border-radius: var(--ax-radius-element);
    padding-inline: var(--ax-spacing-1);
    margin-inline: calc(-1 * var(--ax-spacing-1));
}

@media (hover: hover) {
    .ax-chat-tool-row--clickable:hover:where(:not(:disabled, [aria-disabled="true"])) {
        background-color: var(--ax-color-overlay-hover);
    }
}

.ax-chat-tool-status {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 16px;
    height: 16px;
    border-radius: var(--ax-radius-full);
}

.ax-chat-tool-status--pending { color: var(--ax-color-text-disabled); }
.ax-chat-tool-status--running { color: var(--ax-color-accent); }
.ax-chat-tool-status--complete { color: var(--ax-color-success); }
.ax-chat-tool-status--error { color: var(--ax-color-error); }

.ax-chat-tool-name {
    font-size: var(--ax-text-supporting-size);
    line-height: var(--ax-text-supporting-leading);
    font-family: var(--ax-font-family-code);
    font-weight: var(--ax-font-weight-medium);
    color: var(--ax-color-text-secondary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    flex-shrink: 1;
    min-width: 4ch;
}

.ax-chat-tool-target {
    font-size: var(--ax-text-supporting-size);
    line-height: var(--ax-text-supporting-leading);
    color: var(--ax-color-text-disabled);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    flex-shrink: 10;
    min-width: 0;
}

.ax-chat-tool-duration {
    font-size: var(--ax-text-supporting-size);
    line-height: var(--ax-text-supporting-leading);
    color: var(--ax-color-text-disabled);
    white-space: nowrap;
    flex-shrink: 0;
}

.ax-chat-tool-node { flex-shrink: 0; }

.ax-chat-tool-stats {
    display: flex;
    align-items: center;
    gap: var(--ax-spacing-1);
    font-size: var(--ax-text-supporting-size);
    line-height: var(--ax-text-supporting-leading);
    color: var(--ax-color-text-disabled);
    flex-shrink: 0;
}

.ax-chat-tool-stats-additions { color: var(--ax-color-success); }
.ax-chat-tool-stats-deletions { color: var(--ax-color-error); }

.ax-chat-tool-detail-chevron {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 14px;
    height: 14px;
    color: var(--ax-color-text-disabled);
    margin-inline-start: auto;
}

.ax-chat-tool-detail-chevron > svg {
    transition: transform var(--ax-duration-fast) var(--ax-ease-standard);
}

@media (prefers-reduced-motion: reduce) {
    .ax-chat-tool-detail-chevron > svg { transition: none; }
}

.ax-chat-tool-detail-chevron--expanded > svg { transform: rotate(180deg); }

.ax-chat-tool-detail-content {
    padding-inline-start: calc(16px + var(--ax-spacing-1-5));
    padding-block-end: var(--ax-spacing-2);
}

.ax-chat-tool-count {
    display: inline-flex;
    align-items: center;
    gap: var(--ax-spacing-0-5);
    font-size: var(--ax-text-supporting-size);
    line-height: var(--ax-text-supporting-leading);
    color: var(--ax-color-text-disabled);
    flex-shrink: 0;
}

/* --- ChatBadge: status pills and token chips --- */

.ax-chat-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--ax-spacing-1);
    height: var(--ax-spacing-5);
    padding-block: 0;
    padding-inline: var(--ax-spacing-2);
    border-radius: var(--ax-radius-full);
    font-family: inherit;
    font-size: var(--ax-text-supporting-size);
    line-height: var(--ax-text-supporting-leading);
    font-weight: var(--ax-font-weight-medium);
    white-space: nowrap;
    max-width: 100%;
    min-width: 0;
}

.ax-chat-badge-label {
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
}

.ax-chat-badge--neutral {
    background-color: var(--ax-color-neutral);
    color: var(--ax-color-text-primary);
}

.ax-chat-badge--info {
    background-color: var(--ax-color-accent);
    color: var(--ax-color-on-accent);
}

.ax-chat-badge--success {
    background-color: var(--ax-color-success);
    color: var(--ax-color-on-success);
}

.ax-chat-badge--warning {
    background-color: var(--ax-color-warning);
    color: var(--ax-color-on-warning);
}

.ax-chat-badge--error {
    background-color: var(--ax-color-error);
    color: var(--ax-color-on-error);
}

.ax-chat-badge--blue {
    background-color: var(--ax-color-background-blue);
    color: var(--ax-color-text-blue);
}

.ax-chat-badge--cyan {
    background-color: var(--ax-color-background-cyan);
    color: var(--ax-color-text-cyan);
}

.ax-chat-badge--green {
    background-color: var(--ax-color-background-green);
    color: var(--ax-color-text-green);
}

.ax-chat-badge--orange {
    background-color: var(--ax-color-background-orange);
    color: var(--ax-color-text-orange);
}

.ax-chat-badge--pink {
    background-color: var(--ax-color-background-pink);
    color: var(--ax-color-text-pink);
}

.ax-chat-badge--purple {
    background-color: var(--ax-color-background-purple);
    color: var(--ax-color-text-purple);
}

.ax-chat-badge--red {
    background-color: var(--ax-color-background-red);
    color: var(--ax-color-text-red);
}

.ax-chat-badge--teal {
    background-color: var(--ax-color-background-teal);
    color: var(--ax-color-text-teal);
}

.ax-chat-badge--yellow {
    background-color: var(--ax-color-background-yellow);
    color: var(--ax-color-text-yellow);
}

/* --- ChatSpinner: the ring loader --- */

.ax-chat-spinner {
    display: inline-grid;
    place-items: center;
    vertical-align: middle;
    flex-shrink: 0;
}

.ax-chat-spinner--sm { width: 14px; height: 14px; }
.ax-chat-spinner--md { width: 20px; height: 20px; }
.ax-chat-spinner--lg { width: 24px; height: 24px; }
.ax-chat-spinner--xl { width: 36px; height: 36px; }

.ax-chat-spinner-ring {
    backface-visibility: hidden;
    display: block;
    width: 100%;
    height: 100%;
    overflow: visible;
    will-change: transform;
    animation-duration: var(--ax-duration-slow-min);
    animation-iteration-count: infinite;
    animation-name: ax-chat-spin;
    animation-timing-function: linear;
}

@media (prefers-reduced-motion: reduce) {
    .ax-chat-spinner-ring { animation-duration: 3s; }
}

@keyframes ax-chat-spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}

.ax-chat-spinner-ring circle {
    fill: none;
    transform-box: fill-box;
    transform-origin: center;
    stroke-linecap: round;
}

.ax-chat-spinner-arc { transform: rotate(-90deg); }

/* --- ChatIcon: registry glyphs at chat sizes --- */

.ax-chat-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.ax-chat-icon--xsm {
    width: 0.75rem;
    height: 0.75rem;
    font-size: 0.75rem;
}

.ax-chat-icon--sm {
    width: 1rem;
    height: 1rem;
    font-size: 1rem;
}

.ax-chat-icon--md {
    width: 1.25rem;
    height: 1.25rem;
    font-size: 1.25rem;
}

.ax-chat-icon--lg {
    width: 1.5rem;
    height: 1.5rem;
    font-size: 1.5rem;
}

/* --- Screen-reader-only text --- */

.ax-chat-vh {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border-style: none;
    inset-block-start: 0;
    inset-inline-start: 0;
    pointer-events: none;
    user-select: none;
}

/* --- ChatLayout: the full chat shell --- */

.ax-chat-layout {
    position: relative;
    container-type: inline-size;
    min-height: 0;
    flex: 1;
    display: flex;
    flex-direction: column;
}

.ax-chat-layout--scrollable {
    overflow-y: auto;
    overflow-x: hidden;
}

.ax-chat-layout--scrollable:is([data-astryx-scrolling]) {
    scrollbar-width: none;
}

.ax-chat-layout-messages {
    display: flex;
    flex-direction: column;
    margin-inline: auto;
    flex-grow: 1;
    flex-shrink: 0;
    flex-basis: auto;
    padding-block-end: var(--ax-spacing-6);
    width: 100%;
    max-width: 100%;
    padding-inline: 0;
}

.ax-chat-layout-messages--compact,
.ax-chat-layout-messages--balanced {
    max-width: 100%;
    padding-inline: 0;
}

.ax-chat-layout-messages--spacious {
    max-width: 800px;
    padding-inline: var(--ax-spacing-4);
}

.ax-chat-layout-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 1;
    min-height: 200px;
}

.ax-chat-layout-dock-container {
    bottom: 0;
    inset-inline-start: 0;
    inset-inline-end: 0;
    z-index: 0;
    isolation: isolate;
    pointer-events: none;
    flex-shrink: 0;
}

.ax-chat-layout-dock-container--fixed { position: fixed; }
.ax-chat-layout-dock-container--sticky { position: sticky; }

.ax-chat-layout-blur {
    position: absolute;
    bottom: 0;
    inset-inline-start: 0;
    inset-inline-end: 0;
    pointer-events: none;
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    height: 100px;
    mask-image: linear-gradient(to bottom, transparent, black 36px);
    -webkit-mask-image: linear-gradient(to bottom, transparent, black 36px);
}

.ax-chat-layout-blur--compact {
    height: 80px;
    mask-image: linear-gradient(to bottom, transparent, black 24px);
    -webkit-mask-image: linear-gradient(to bottom, transparent, black 24px);
}

.ax-chat-layout-blur--balanced {
    height: 100px;
    mask-image: linear-gradient(to bottom, transparent, black 36px);
    -webkit-mask-image: linear-gradient(to bottom, transparent, black 36px);
}

.ax-chat-layout-blur--spacious {
    height: 120px;
    mask-image: linear-gradient(to bottom, transparent, black 48px);
    -webkit-mask-image: linear-gradient(to bottom, transparent, black 48px);
}

.ax-chat-layout-dock {
    position: relative;
    z-index: 1;
    pointer-events: auto;
    padding-inline: var(--ax-spacing-3);
    padding-block-end: var(--ax-spacing-3);
}

.ax-chat-layout-dock--compact {
    padding-inline: var(--ax-spacing-2);
    padding-block-end: var(--ax-spacing-2);
}

.ax-chat-layout-dock--balanced {
    padding-inline: var(--ax-spacing-3);
    padding-block-end: var(--ax-spacing-3);
}

.ax-chat-layout-dock--spacious {
    padding-inline: var(--ax-spacing-4);
    padding-block-end: var(--ax-spacing-3);
}

.ax-chat-layout-dock-inner {
    margin-inline: auto;
    width: 100%;
    max-width: 100%;
}

.ax-chat-layout-dock-inner--compact { max-width: 100%; }
.ax-chat-layout-dock-inner--balanced { max-width: 100%; }
.ax-chat-layout-dock-inner--spacious { max-width: 800px; }

/* --- ChatLayoutScrollButton: the floating pill --- */

.ax-chat-scroll-button-wrap {
    display: flex;
    justify-content: center;
    padding-block-end: var(--ax-spacing-3);
}

.ax-chat-scroll-button-pill {
    pointer-events: auto;
    contain: layout style;
    overflow: hidden;
    border-radius: var(--ax-radius-full);
    background-color: var(--ax-color-background-popover);
    box-shadow: var(--ax-shadow-med);
    height: 32px;
    transition-property: opacity, transform, max-width;
    transition-timing-function: var(--ax-ease-standard);
    transition-duration: var(--ax-duration-fast-max);
}

@media (prefers-reduced-motion: reduce) {
    .ax-chat-scroll-button-pill { transition-duration: 0s; }
}

.ax-chat-scroll-button-pill--hidden {
    opacity: 0;
    pointer-events: none;
    max-width: 32px;
}

.ax-chat-scroll-button-pill--visible {
    opacity: 1;
    pointer-events: auto;
}

.ax-chat-scroll-button-pill--collapsed { max-width: 32px; }
.ax-chat-scroll-button-pill--expanded { max-width: 200px; }

/* --- Chat buttons: circular send/stop and the ghost pill button --- */

.ax-chat-button {
    --ax-chat-button-focus-offset: var(--ax-focus-outline-offset);
    outline-offset: 0;
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--ax-spacing-2);
    padding-block: var(--ax-spacing-2);
    padding-inline: var(--ax-spacing-3);
    border-width: 0;
    border-style: none;
    border-radius: var(--ax-radius-full);
    font-family: inherit;
    font-size: var(--ax-text-label-size);
    line-height: var(--ax-text-label-leading);
    font-weight: var(--ax-font-weight-medium);
    white-space: nowrap;
    cursor: pointer;
    transition-property: background-image, background-color, color, opacity, transform;
    transition-duration: var(--ax-duration-fast);
    transition-timing-function: var(--ax-ease-standard);
}

@media (prefers-reduced-motion: reduce) {
    .ax-chat-button { transition-duration: 0s; }
}

.ax-chat-button:focus-visible {
    outline-offset: var(--ax-chat-button-focus-offset);
    outline-width: var(--ax-focus-outline-width);
    outline-style: var(--ax-focus-outline-style);
    outline-color: var(--ax-focus-outline-color);
}

.ax-chat-button:disabled,
.ax-chat-button[aria-disabled="true"] {
    cursor: default;
}

.ax-chat-button--pressable { transform: scale(1); }

.ax-chat-button--pressable:active:where(:not(:disabled, [aria-disabled="true"])) {
    transform: scale(0.98);
}

.ax-chat-button--icon-only {
    aspect-ratio: 1 / 1;
    padding-inline: 0;
    padding-block: 0;
}

.ax-chat-button--sm { height: var(--ax-size-element-sm); }
.ax-chat-button--md { height: var(--ax-size-element-md); }

.ax-chat-button--primary {
    background-color: var(--ax-color-accent);
    color: var(--ax-color-on-accent);
}

.ax-chat-button--secondary {
    background-color: var(--ax-color-neutral);
    color: var(--ax-color-text-primary);
}

.ax-chat-button--ghost {
    background-color: transparent;
    color: var(--ax-color-text-primary);
}

.ax-chat-button--disabled { opacity: 0.5; }

.ax-chat-button--inactive {
    cursor: default;
    background-image: none;
    transform: none;
}

.ax-chat-button--inactive:active { transform: none; }

/* The hover/press overlay rides a background-image layer above the base. */
.ax-chat-button:where(:not(:disabled, [aria-disabled="true"])):active {
    background-image: linear-gradient(var(--ax-color-overlay-pressed), var(--ax-color-overlay-pressed));
}

@media (hover: hover) {
    .ax-chat-button:where(:not(:disabled, [aria-disabled="true"])):hover {
        background-image: linear-gradient(var(--ax-color-overlay-hover), var(--ax-color-overlay-hover));
    }

    .ax-chat-button:where(:not(:disabled, [aria-disabled="true"])):active {
        background-image: linear-gradient(var(--ax-color-overlay-pressed), var(--ax-color-overlay-pressed));
    }
}

.ax-chat-button-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.ax-chat-button-icon--sm,
.ax-chat-button-icon--md {
    width: 16px;
    height: 16px;
    font-size: 16px;
}

.ax-chat-button-label {
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
}

/* The scroll pill's ghost button: full radius, breathing room with a label. */
.ax-chat-scroll-button {
    white-space: nowrap;
    padding-inline: var(--ax-spacing-2);
}

.ax-chat-scroll-button--labeled {
    padding-inline-end: var(--ax-spacing-3);
}

/* --- ChatComposer: the input shell --- */

.ax-chat-composer {
    position: relative;
    z-index: 0;
    isolation: isolate;
    display: flex;
    flex-direction: column;
    --ax-chat-composer-radius: var(--ax-radius-chat);
    --ax-chat-composer-padding: var(--ax-spacing-3);
}

.ax-chat-composer--disabled {
    opacity: 0.6;
    pointer-events: none;
}

.ax-chat-composer-body {
    position: relative;
    z-index: 2;
    display: flex;
    flex-direction: column;
    padding: var(--ax-chat-composer-padding);
    gap: var(--ax-spacing-2);
    border-radius: var(--ax-chat-composer-radius);
    background-color: var(--ax-color-background-popover);
    cursor: text;
    transition: box-shadow var(--ax-duration-fast) var(--ax-ease-standard), border-color var(--ax-duration-fast) var(--ax-ease-standard);
}

.ax-chat-composer-body--low {
    box-shadow: var(--ax-shadow-low);
}

@media (hover: hover) {
    .ax-chat-composer-body--low:hover:where(:not(:disabled, [aria-disabled="true"])) {
        box-shadow: var(--ax-shadow-med);
    }
}

.ax-chat-composer-body--low:focus-within {
    box-shadow: var(--ax-shadow-med);
}

.ax-chat-composer-body--none {
    border-width: var(--ax-border-width);
    border-style: solid;
    border-color: var(--ax-color-border-emphasized);
    padding: calc(var(--ax-chat-composer-padding) - var(--ax-border-width));
    box-shadow: none;
}

.ax-chat-composer-body--none:focus-within {
    border-color: var(--ax-color-accent);
    box-shadow: inset 0px 0px 0px 2px var(--ax-color-accent-muted);
}

@media (hover: hover) {
    .ax-chat-composer-body--none:hover:not(:focus-within):where(:not(:disabled, [aria-disabled="true"])) {
        box-shadow: inset 0px 0px 0px 2px color-mix(in srgb, var(--ax-color-border-emphasized) 30%, transparent);
    }
}

/* The keyboard-only focus ring: the component adds this class when the
 * editor holds keyboard focus, mirroring Astryx's modality tracking. */
.ax-chat-composer-body--kbd-focus {
    outline-width: var(--ax-focus-outline-width);
    outline-style: var(--ax-focus-outline-style);
    outline-color: var(--ax-focus-outline-color);
    outline-offset: var(--ax-focus-outline-offset);
}

.ax-chat-composer-body--compact {
    --ax-chat-composer-padding: var(--ax-spacing-2);
    gap: var(--ax-spacing-1);
}

.ax-chat-composer-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ax-spacing-2);
    min-height: 28px;
}

.ax-chat-composer-header-left {
    display: flex;
    align-items: center;
    gap: var(--ax-spacing-1);
}

.ax-chat-composer-header-right {
    display: flex;
    align-items: center;
    gap: var(--ax-spacing-2);
    margin-inline-start: auto;
    font-size: var(--ax-text-supporting-size);
    line-height: var(--ax-text-supporting-leading);
    color: var(--ax-color-text-secondary);
}

.ax-chat-composer-input-area {
    display: flex;
    flex-direction: column;
}

.ax-chat-composer-textarea {
    all: unset;
    display: block;
    width: 100%;
    box-sizing: border-box;
    resize: none;
    font-size: var(--ax-text-body-size);
    line-height: var(--ax-text-body-leading);
    color: var(--ax-color-text-primary);
    background-color: transparent;
    caret-color: var(--ax-color-accent);
    overflow-y: auto;
    max-height: 176px;
    /* Progressive enhancement: grow with content where supported. */
    field-sizing: content;
}

.ax-chat-composer-textarea::placeholder {
    color: var(--ax-color-text-disabled);
}

/* Coarse pointers get the 16px floor against mobile auto-zoom, mirroring
 * Astryx's composer input (field and placeholder alike). */
@media (pointer: coarse) {
    .ax-chat-composer-textarea,
    .ax-chat-composer-textarea::placeholder {
        font-size: max(1rem, var(--ax-text-body-size));
    }
}

/* The editor never draws its own focus ring. Focus indication lives on
 * the composer body instead — the shadow bump, plus the keyboard-only
 * ring — exactly as Astryx does. */
.ax-chat-composer-textarea:focus {
    outline: none;
    box-shadow: none;
}

.ax-chat-composer-textarea:disabled {
    cursor: default;
}

.ax-chat-composer-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ax-spacing-2);
    min-height: 32px;
}

.ax-chat-composer-footer-left,
.ax-chat-composer-footer-right {
    display: flex;
    align-items: center;
    gap: var(--ax-spacing-1);
}

.ax-chat-composer-status {
    position: relative;
    z-index: 0;
    display: flex;
    align-items: center;
    gap: var(--ax-spacing-2);
    padding-inline: var(--ax-spacing-4);
    font-size: var(--ax-text-supporting-size);
    line-height: var(--ax-text-supporting-leading);
}

.ax-chat-composer-status--top {
    padding-block-start: var(--ax-chat-composer-padding);
    padding-block-end: calc(var(--ax-chat-composer-padding) + var(--ax-chat-composer-radius));
    margin-block-end: calc(-1 * var(--ax-chat-composer-radius));
    border-start-start-radius: var(--ax-chat-composer-radius);
    border-start-end-radius: var(--ax-chat-composer-radius);
}

.ax-chat-composer-status--bottom {
    padding-block-start: calc(var(--ax-chat-composer-padding) + var(--ax-chat-composer-radius));
    padding-block-end: var(--ax-chat-composer-padding);
    margin-block-start: calc(-1 * var(--ax-chat-composer-radius));
    border-end-start-radius: var(--ax-chat-composer-radius);
    border-end-end-radius: var(--ax-chat-composer-radius);
}

.ax-chat-composer-status-icon {
    display: inline-flex;
    align-items: center;
    flex-shrink: 0;
}

.ax-chat-composer-status--error .ax-chat-composer-status-icon {
    color: var(--ax-color-error);
}

.ax-chat-composer-status--warning .ax-chat-composer-status-icon {
    color: var(--ax-color-warning);
}

.ax-chat-composer-status--error {
    background-color: var(--ax-color-error-muted);
    color: var(--ax-color-text-red);
}

.ax-chat-composer-status--warning {
    background-color: var(--ax-color-warning-muted);
    color: var(--ax-color-text-yellow);
}
/* Astryx app shell, faithfully recreated. Every rule lives under the
 * `ax-shell` scope and every token is `--ax-*`, so this second visual
 * language never leaks into — or fights — the DW-001 system around it.
 * Values are verbatim from @astryxdesign/core 0.6.0's theme tokens and the
 * AppShell, Layout, TopNav, SideNav, and MobileNav modules' StyleX rules;
 * the structure mirrors those files section by section. Like Astryx's own
 * Theme, the scope sets the body font and ink, so a shell tree reads
 * identically wherever it mounts.
 *
 * Three deliberate departures from the source mechanics (see shell.rs):
 * the breakpoint is a media query rather than matchMedia state, the drawer
 * is a checkbox disclosure rather than a modal dialog, and the narrow
 * layout keys off the shell's own modifier classes instead of render
 * contexts. The pixels are the point; the machinery is CSS.
 */

.ax-shell {
    color-scheme: light dark;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    color: light-dark(#0a1317, #dfe2e5);

    /* --- color --- */
    --ax-color-accent: light-dark(#0064e0, #2694fe);
    --ax-color-neutral: light-dark(rgba(5, 54, 89, 0.1), rgba(223, 226, 229, 0.2));
    --ax-color-background-surface: light-dark(#ffffff, #1f1f22);
    --ax-color-background-body: light-dark(#f1f4f7, #111112);
    --ax-color-overlay: light-dark(#01122866, #11111299);
    --ax-color-overlay-hover: light-dark(#0536590c, #ffffff0c);
    --ax-color-overlay-pressed: light-dark(#05365919, #ffffff19);
    --ax-color-text-primary: light-dark(#0a1317, #dfe2e5);
    --ax-color-text-secondary: light-dark(#4e606f, #aaafb5);
    --ax-color-text-disabled: light-dark(#a4b0bc, #6f747c);
    --ax-color-text-accent: light-dark(#0064e0, #3e9efb);
    --ax-color-icon-secondary: light-dark(#4e606f, #aaafb5);
    --ax-color-icon-disabled: light-dark(#a4b0bc, #6f747c);
    --ax-color-border: light-dark(#05365919, #f2f4f619);

    /* --- spacing --- */
    --ax-spacing-0: 0px;
    --ax-spacing-0-5: 2px;
    --ax-spacing-1: 4px;
    --ax-spacing-1-5: 6px;
    --ax-spacing-2: 8px;
    --ax-spacing-3: 12px;
    --ax-spacing-4: 16px;
    --ax-spacing-5: 20px;
    --ax-spacing-6: 24px;
    --ax-spacing-8: 32px;
    --ax-spacing-10: 40px;
    --ax-spacing-12: 48px;

    /* --- sizes, borders, focus --- */
    --ax-size-element-sm: 28px;
    --ax-size-element-md: 32px;
    --ax-size-element-lg: 36px;
    --ax-border-width: 1px;
    --ax-focus-outline-width: 2px;
    --ax-focus-outline-style: solid;
    --ax-focus-outline-color: var(--ax-color-accent);
    --ax-focus-outline-offset: 3px;

    /* --- radius --- */
    --ax-radius-element: 8px;
    --ax-radius-page: 28px;

    /* --- motion --- */
    --ax-duration-fast: 175ms;
    --ax-duration-medium: 410ms;
    --ax-ease-standard: cubic-bezier(0.24, 1, 0.4, 1);

    /* --- type --- */
    --ax-text-large-size: 1.0625rem;
    --ax-text-large-leading: 1.4118;
    --ax-text-label-size: 0.875rem;
    --ax-text-label-leading: 1.4286;
    --ax-text-supporting-size: 0.75rem;
    --ax-text-supporting-leading: 1.6667;
    --ax-font-weight-medium: 500;
    --ax-font-weight-semibold: 600;
}

/* --- AppShell: root, variants, height --- */

.ax-shell {
    display: flex;
    flex-direction: column;
    position: relative;
    overflow: clip;
}

.ax-shell--wash {
    background-color: var(--ax-color-background-body);
}

.ax-shell--surface {
    background-color: var(--ax-color-background-surface);
}

.ax-shell--section {
    background-color: var(--ax-color-background-surface);
}

.ax-shell--elevated {
    background-color: var(--ax-color-background-body);
}

.ax-shell--fill {
    height: 100dvh;
}

.ax-shell--auto {
    min-height: 100dvh;
}

/* --- AppShell: skip link --- */
/* Visually hidden until focused, then a fixed pill up top. The ring is the
 * shared focus outline Astryx wraps the link in. */

.ax-shell-skip {
    position: absolute;
    width: 1px;
    height: 1px;
    padding-block: 0;
    padding-inline: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border-width: 0;
    background-color: var(--ax-color-background-surface);
    color: var(--ax-color-text-accent);
    z-index: 9999;
    text-decoration: none;
    font-weight: var(--ax-font-weight-semibold);
    font-size: var(--ax-text-label-size);
}

.ax-shell-skip:focus {
    position: fixed;
    width: auto;
    height: auto;
    padding-block: var(--ax-spacing-2);
    padding-inline: var(--ax-spacing-4);
    margin: 0;
    overflow: visible;
    clip-path: none;
    white-space: normal;
    top: var(--ax-spacing-2);
    inset-inline-start: var(--ax-spacing-2);
}

.ax-shell-skip:focus-visible {
    outline-width: var(--ax-focus-outline-width);
    outline-style: var(--ax-focus-outline-style);
    outline-color: var(--ax-focus-outline-color);
    outline-offset: var(--ax-focus-outline-offset);
}

/* The main landmark is a programmatic focus target only (tabindex -1, never
 * tabbable), so a focus ring around the whole content area would be noise
 * rather than guidance. */

.ax-shell-content:focus {
    outline: none;
}

/* --- AppShell: header, banner, narrow bar --- */

.ax-shell-header {
    flex-shrink: 0;
}

.ax-shell-banner {
    flex-shrink: 0;
}

/* Nav-area backgrounds: wash and elevated sit on the wash, surface on the
 * surface, and section inherits the shell's own surface. */

.ax-shell--wash .ax-shell-header,
.ax-shell--elevated .ax-shell-header,
.ax-shell--wash .ax-shell-banner,
.ax-shell--elevated .ax-shell-banner,
.ax-shell--wash .ax-shell-mobilebar,
.ax-shell--elevated .ax-shell-mobilebar {
    background-color: var(--ax-color-background-body);
}

.ax-shell--surface .ax-shell-header,
.ax-shell--surface .ax-shell-banner,
.ax-shell--surface .ax-shell-mobilebar {
    background-color: var(--ax-color-background-surface);
}

/* Sticky header for auto height. The section header paints its surface
 * itself so content scrolling beneath it stays covered. */

.ax-shell--auto .ax-shell-header,
.ax-shell--auto .ax-shell-mobilebar {
    position: sticky;
    top: 0;
    z-index: 1;
}

.ax-shell--auto.ax-shell--section .ax-shell-header,
.ax-shell--auto.ax-shell--section .ax-shell-mobilebar {
    background-color: var(--ax-color-background-surface);
}

/* Section dividers: the header earns its bottom border only beside a top
 * nav; the narrow bar always draws one, as in the source. */

.ax-shell--section.ax-shell--has-topnav .ax-shell-header {
    border-block-end-width: var(--ax-border-width);
    border-block-end-style: solid;
    border-block-end-color: var(--ax-color-border);
}

.ax-shell--section .ax-shell-mobilebar {
    border-block-end-width: var(--ax-border-width);
    border-block-end-style: solid;
    border-block-end-color: var(--ax-color-border);
}

/* The sidenav-only narrow bar: a 48px strip carrying just the toggle.
 * Hidden above the breakpoint; each breakpoint block below shows it. */

.ax-shell-mobilebar {
    display: none;
    align-items: center;
    height: var(--ax-spacing-12);
    padding-inline: var(--ax-spacing-2);
    flex-shrink: 0;
}

.ax-shell-mobilebar .ax-mobilenav-toggle {
    margin-inline-start: auto;
}

/* --- Layout: middle row, side panel, content --- */
/* The middle row is Astryx's horizontal stack: plain flex, no gap. */

.ax-shell-middle {
    display: flex;
    flex-direction: row;
    flex: 1;
    min-height: 0;
}

/* The panel is LayoutPanel at padding 0: no padding, full bleed. It owns
 * the side nav's background (the nav inherits it) and scrolls
 * independently in fill mode. */

.ax-shell-panel {
    box-sizing: border-box;
    flex-shrink: 0;
    overflow: clip;
    padding: 0;
}

.ax-shell--fill .ax-shell-panel {
    overflow: auto;
}

.ax-shell--wash .ax-shell-panel,
.ax-shell--elevated .ax-shell-panel {
    background-color: var(--ax-color-background-body);
}

.ax-shell--surface .ax-shell-panel,
.ax-shell--auto .ax-shell-panel {
    background-color: var(--ax-color-background-surface);
}

.ax-shell--section.ax-shell--has-sidenav .ax-shell-panel {
    border-inline-end-width: var(--ax-border-width);
    border-inline-end-style: solid;
    border-inline-end-color: var(--ax-color-border);
}

/* LayoutContent at an explicit padding: uniform spacing steps, independent
 * scroll in fill mode. The min-size reset is the stack item's — flex
 * children never shrink below their content without it. */

.ax-shell-content {
    box-sizing: border-box;
    height: 100%;
    flex: 1;
    min-height: 0;
    min-width: 0;
    overflow: clip;
}

.ax-shell--fill .ax-shell-content {
    overflow: auto;
}

.ax-shell--wash .ax-shell-content {
    background-color: var(--ax-color-background-body);
}

.ax-shell--surface .ax-shell-content,
.ax-shell--elevated .ax-shell-content {
    background-color: var(--ax-color-background-surface);
}

/* The elevated corner: transparent content over an opaque rounded
 * backdrop. Below the breakpoint the media blocks repaint the surface
 * and drop the backdrop. */

.ax-shell--elevated.ax-shell--has-topnav.ax-shell--has-sidenav .ax-shell-content {
    background-color: transparent;
    isolation: isolate;
}

.ax-shell-elevated-wrap {
    position: relative;
    display: flex;
    flex: 1;
    min-height: 0;
    min-width: 0;
    height: 100%;
}

.ax-shell-elevated-backdrop {
    position: absolute;
    inset: 0;
    background-color: var(--ax-color-background-surface);
    border-start-start-radius: var(--ax-radius-page);
    pointer-events: none;
}

.ax-shell-pad-0 {
    padding: 0;
}

.ax-shell-pad-0-5 {
    padding: var(--ax-spacing-0-5);
}

.ax-shell-pad-1 {
    padding: var(--ax-spacing-1);
}

.ax-shell-pad-1-5 {
    padding: var(--ax-spacing-1-5);
}

.ax-shell-pad-2 {
    padding: var(--ax-spacing-2);
}

.ax-shell-pad-3 {
    padding: var(--ax-spacing-3);
}

.ax-shell-pad-4 {
    padding: var(--ax-spacing-4);
}

.ax-shell-pad-5 {
    padding: var(--ax-spacing-5);
}

.ax-shell-pad-6 {
    padding: var(--ax-spacing-6);
}

.ax-shell-pad-8 {
    padding: var(--ax-spacing-8);
}

.ax-shell-pad-10 {
    padding: var(--ax-spacing-10);
}

/* --- Drawer: checkbox, scrim, panel close --- */
/* The drawer is a checkbox disclosure: the state input hides up top while
 * the toggle, scrim, and panel close label all point at it. The input sits
 * outside the tab order — keyboard drawer operation needs client script
 * (see shell.rs), so there is deliberately no focus style here. */

.ax-shell-nav-state {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    clip-path: inset(50%);
    overflow: hidden;
    white-space: nowrap;
}

/* The scrim only exists below the breakpoint; each breakpoint block shows
 * it. Above the breakpoint it stays display none. */

.ax-shell-scrim {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 40;
    background-color: var(--ax-color-overlay);
    backdrop-filter: blur(2px);
    cursor: default;
    margin: 0;
}

/* The panel close rides absolute over the side nav's header zone — 8px
 * from the top and inline end, beside the heading with clearance the
 * breakpoint blocks reserve. Shown only while the drawer is open. */

.ax-shell-panel-close {
    position: absolute;
    top: var(--ax-spacing-2);
    inset-inline-end: var(--ax-spacing-2);
    z-index: 1;
    margin: 0;
}

/* --- Drawer toggle and panel close: the ghost button look --- */
/* Astryx's icon-only ghost Button at md: a 32px square, transparent over
 * text ink, overlay washes on hover and press, the shared focus ring.
 * The enabled guard from the source's overlay styles has nothing to guard
 * here — labels take no disabled state. */

.ax-mobilenav-toggle,
.ax-shell-panel-close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: var(--ax-size-element-md);
    aspect-ratio: 1 / 1;
    padding-block: 0;
    padding-inline: 0;
    border-width: 0;
    border-style: none;
    border-radius: var(--ax-radius-element);
    background-color: transparent;
    color: var(--ax-color-text-primary);
    cursor: pointer;
    transition-property: background-image, background-color, color, opacity, transform;
    transition-duration: var(--ax-duration-fast);
    transition-timing-function: var(--ax-ease-standard);
}

@media (hover: hover) {
    .ax-mobilenav-toggle:hover,
    .ax-shell-panel-close:hover {
        background-image: linear-gradient(var(--ax-color-overlay-hover), var(--ax-color-overlay-hover));
    }
}

.ax-mobilenav-toggle:active,
.ax-shell-panel-close:active {
    background-image: linear-gradient(var(--ax-color-overlay-pressed), var(--ax-color-overlay-pressed));
    transform: scale(0.98);
}

.ax-mobilenav-toggle:focus-visible,
.ax-shell-panel-close:focus-visible {
    outline-width: var(--ax-focus-outline-width);
    outline-style: var(--ax-focus-outline-style);
    outline-color: var(--ax-focus-outline-color);
    outline-offset: var(--ax-focus-outline-offset);
}

/* The toggle hides above the breakpoint (the breakpoint blocks show it)
 * and anywhere outside a shell with a drawer. */

.ax-topnav .ax-mobilenav-toggle {
    display: none;
}

/* The panel close shows only while the drawer is open (breakpoint
 * blocks); this hide sits after the ghost block so it wins the tie. */

.ax-shell-panel-close {
    display: none;
}

.ax-topnav .ax-mobilenav-toggle,
.ax-shell-mobilebar .ax-mobilenav-toggle,
.ax-shell-panel-close {
    flex-shrink: 0;
}

/* --- Shell icons and visually-hidden text --- */

.ax-shell-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    flex-shrink: 0;
}

.ax-shell-icon svg {
    display: block;
    width: 16px;
    height: 16px;
}

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

/* --- TopNav: bar and slots --- */
/* Flex by default; the centered variant switches to a three-column grid
 * so the center stays truly centered whatever the sides weigh. */

.ax-topnav {
    align-items: center;
    width: 100%;
    padding: var(--ax-spacing-2);
    box-sizing: border-box;
    display: flex;
}

.ax-topnav--center {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
}

.ax-topnav-left {
    display: flex;
    align-items: center;
    gap: var(--ax-spacing-4);
    flex: 1 1 0%;
    min-width: 0;
}

.ax-topnav-heading {
    display: flex;
    align-items: center;
    flex-shrink: 0;
}

.ax-topnav-start {
    display: flex;
    align-items: center;
    gap: var(--ax-spacing-1);
}

.ax-topnav-center {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--ax-spacing-1);
}

.ax-topnav-right {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--ax-spacing-1);
}

.ax-topnav-end {
    display: flex;
    align-items: center;
    gap: var(--ax-spacing-1);
    flex-shrink: 0;
    margin-inline-start: auto;
}

/* --- TopNav and SideNav headings --- */
/* One shape serves both navs — Astryx mirrors them, and the only style
 * difference (the side text block flexes to fill) keys off location. */

.ax-nav-heading {
    display: flex;
    align-items: center;
    gap: var(--ax-spacing-2);
    min-height: var(--ax-spacing-8);
    padding-inline-start: var(--ax-spacing-2);
    padding-inline-end: var(--ax-spacing-2);
    padding-block: 0;
    box-sizing: border-box;
    text-decoration: none;
    color: var(--ax-color-text-primary);
    cursor: default;
}

.ax-nav-heading:has(.ax-nav-heading-logo) {
    padding-inline-start: 0;
}

.ax-nav-heading--link {
    cursor: pointer;
    border-radius: var(--ax-radius-element);
    border-width: 0;
    border-style: none;
    background-color: transparent;
    font-family: inherit;
    font-size: inherit;
    font-weight: var(--ax-font-weight-normal);
    text-align: start;
}

@media (hover: hover) {
    .ax-nav-heading--link:hover {
        background-color: var(--ax-color-overlay-hover);
    }
}

.ax-nav-heading--link:focus-visible {
    outline-width: var(--ax-focus-outline-width);
    outline-style: var(--ax-focus-outline-style);
    outline-color: var(--ax-focus-outline-color);
    outline-offset: var(--ax-focus-outline-offset);
}

.ax-nav-heading-logo {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

.ax-nav-heading-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.ax-sidenav .ax-nav-heading-text {
    flex: 1;
}

.ax-nav-heading-super {
    font-size: var(--ax-text-supporting-size);
    line-height: var(--ax-text-supporting-leading);
    color: var(--ax-color-text-secondary);
    text-decoration: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ax-nav-heading-heading {
    font-size: var(--ax-text-large-size);
    font-weight: var(--ax-font-weight-semibold);
    line-height: var(--ax-text-large-leading);
    color: var(--ax-color-text-primary);
    text-decoration: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ax-nav-heading-sub {
    font-size: var(--ax-text-supporting-size);
    line-height: var(--ax-text-supporting-leading);
    color: var(--ax-color-text-secondary);
    text-decoration: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* --- TopNavItem --- */
/* The bar-mode pill: medium secondary ink over a hover wash, deemphasized
 * neutral fill and semibold primary ink when selected. Disabled is the
 * shared nav-item disabled treatment (see the side item below). */

.ax-topnav-item {
    display: inline-flex;
    align-items: center;
    gap: var(--ax-spacing-2);
    padding-block: var(--ax-spacing-1-5);
    padding-inline: var(--ax-spacing-3);
    border-radius: var(--ax-radius-element);
    font-size: var(--ax-text-label-size);
    line-height: var(--ax-text-label-leading);
    font-weight: var(--ax-font-weight-medium);
    color: var(--ax-color-text-secondary);
    text-decoration: none;
    cursor: pointer;
    transition-property: background-color, color;
    transition-duration: var(--ax-duration-fast);
    transition-timing-function: var(--ax-ease-standard);
}

.ax-topnav-item--selected {
    color: var(--ax-color-text-primary);
    font-weight: var(--ax-font-weight-semibold);
    background-color: var(--ax-color-neutral);
}

@media (hover: hover) {
    .ax-topnav-item:hover {
        background-color: var(--ax-color-overlay-hover);
    }

    .ax-topnav-item--selected:hover {
        background-color: var(--ax-color-neutral);
    }
}

.ax-topnav-item:active {
    background-color: var(--ax-color-overlay-pressed);
}

.ax-topnav-item--selected:active {
    background-color: var(--ax-color-neutral);
}

.ax-topnav-item--icon-only {
    padding-inline: var(--ax-spacing-2);
}

.ax-topnav-item:focus-visible {
    outline-width: var(--ax-focus-outline-width);
    outline-style: var(--ax-focus-outline-style);
    outline-color: var(--ax-focus-outline-color);
    outline-offset: var(--ax-focus-outline-offset);
}

.ax-topnav-item--disabled {
    color: var(--ax-color-text-disabled);
    cursor: default;
    pointer-events: none;
}

/* --- SideNav: zones --- */

.ax-sidenav {
    display: flex;
    flex-direction: column;
    height: 100%;
    width: 260px;
    background-color: inherit;
    box-sizing: border-box;
    overflow: hidden;
}

.ax-sidenav-top {
    display: flex;
    flex-direction: column;
    flex-shrink: 0;
    position: sticky;
    top: 0;
    z-index: 1;
    background-color: inherit;
    padding-block-start: var(--ax-spacing-2);
    padding-block-end: var(--ax-spacing-2);
    padding-inline: var(--ax-spacing-2);
    gap: var(--ax-spacing-2);
}

.ax-sidenav-scroll {
    flex: 1;
    overflow-y: auto;
    overflow-x: hidden;
    padding-inline: var(--ax-spacing-2);
    padding-block-start: var(--ax-spacing-2);
    padding-block-end: var(--ax-spacing-2);
}

.ax-sidenav-scroll--with-top {
    padding-block-start: var(--ax-spacing-1);
}

.ax-sidenav-scroll--with-bottom {
    padding-block-end: var(--ax-spacing-1);
}

.ax-sidenav-bottom {
    display: flex;
    flex-direction: column;
    flex-shrink: 0;
    margin-top: auto;
    position: sticky;
    bottom: 0;
    background-color: inherit;
    gap: var(--ax-spacing-2);
    padding-inline: var(--ax-spacing-2);
    padding-block-start: var(--ax-spacing-1);
    padding-block-end: var(--ax-spacing-2);
}

.ax-sidenav-footericons {
    display: flex;
    align-items: center;
    gap: var(--ax-spacing-1);
}

/* --- SideNavSection --- */

.ax-sidenav-section {
    display: flex;
    flex-direction: column;
    padding-block: var(--ax-spacing-1);
}

.ax-sidenav-section-header {
    display: flex;
    align-items: center;
    gap: var(--ax-spacing-2);
    padding-inline: var(--ax-spacing-2);
    padding-block: var(--ax-spacing-1);
    cursor: default;
    user-select: none;
}

.ax-sidenav-section-titles {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-width: 0;
}

.ax-sidenav-section-title {
    font-size: var(--ax-text-supporting-size);
    font-weight: var(--ax-font-weight-semibold);
    line-height: var(--ax-text-supporting-leading);
    color: var(--ax-color-text-secondary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ax-sidenav-section-subtitle {
    font-size: var(--ax-text-supporting-size);
    line-height: var(--ax-text-supporting-leading);
    color: var(--ax-color-text-secondary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ax-sidenav-section-end {
    flex-shrink: 0;
    display: flex;
    align-items: center;
}

.ax-sidenav-section-items {
    display: flex;
    flex-direction: column;
    gap: var(--ax-spacing-0-5);
}

/* --- SideNavItem --- */
/* The shared nav-item appearance: a 32px row over hover and pressed
 * washes, neutral fill and medium weight when selected. Forced colors
 * flatten the neutral away, so the selected row takes the platform
 * Highlight there — the source's rule, verbatim. */

.ax-sidenav-item-root {
    display: flex;
    flex-direction: column;
    width: 100%;
}

.ax-sidenav-item {
    display: flex;
    align-items: center;
    gap: var(--ax-spacing-2);
    width: 100%;
    height: var(--ax-size-element-md);
    padding-inline: var(--ax-spacing-2);
    padding-block: 0;
    border-radius: var(--ax-radius-element);
    border-width: 0;
    border-style: none;
    background-color: transparent;
    color: var(--ax-color-text-primary);
    text-decoration: none;
    cursor: pointer;
    font-family: inherit;
    font-size: var(--ax-text-label-size);
    font-weight: var(--ax-font-weight-normal);
    line-height: var(--ax-text-label-leading);
    text-align: start;
    box-sizing: border-box;
}

.ax-sidenav-item--sm {
    height: var(--ax-size-element-sm);
    padding-inline: var(--ax-spacing-1);
}

.ax-sidenav-item--md {
    height: var(--ax-size-element-md);
    padding-inline: var(--ax-spacing-2);
}

.ax-sidenav-item--lg {
    height: var(--ax-size-element-lg);
    padding-inline: var(--ax-spacing-2);
}

@media (hover: hover) {
    .ax-sidenav-item:hover {
        background-color: var(--ax-color-overlay-hover);
    }
}

.ax-sidenav-item:active {
    background-color: var(--ax-color-overlay-pressed);
}

.ax-sidenav-item--selected {
    background-color: var(--ax-color-neutral);
    font-weight: var(--ax-font-weight-medium);
}

@media (hover: hover) {
    .ax-sidenav-item--selected:hover {
        background-color: var(--ax-color-neutral);
    }
}

.ax-sidenav-item--selected:active {
    background-color: var(--ax-color-neutral);
}

@media (forced-colors: active) {
    .ax-sidenav-item--selected {
        background-color: Highlight;
        color: HighlightText;
    }
}

.ax-sidenav-item--disabled {
    color: var(--ax-color-text-disabled);
    cursor: default;
    pointer-events: none;
}

.ax-sidenav-item:focus-visible {
    outline-width: var(--ax-focus-outline-width);
    outline-style: var(--ax-focus-outline-style);
    outline-color: var(--ax-focus-outline-color);
    outline-offset: var(--ax-focus-outline-offset);
}

.ax-sidenav-item-label {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ax-sidenav-item-icon {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    color: var(--ax-color-icon-secondary);
}

.ax-sidenav-item--selected .ax-sidenav-item-icon {
    color: inherit;
}

.ax-sidenav-item--disabled .ax-sidenav-item-icon {
    color: var(--ax-color-icon-disabled);
}

.ax-sidenav-item-end {
    flex-shrink: 0;
    display: flex;
    align-items: center;
}

/* Static subgroup: indented, always expanded. */

.ax-sidenav-item-children {
    padding-inline-start: var(--ax-spacing-6);
}

/* --- Narrow layout, below sm (640px) --- */
/* Without a drawer the panel simply hides and the top nav stays whole.
 * With one, the panel becomes the drawer: fixed, off-screen until the
 * checkbox opens it. Visibility carries the open state so the slide
 * transition has something to run against; it flips instantly on open
 * and after the slide-out on close. */

@media (width < 640px) {
    .ax-shell--bp-sm:not(.ax-shell--has-drawer) .ax-shell-panel {
        display: none;
    }

    .ax-shell--bp-sm.ax-shell--has-drawer .ax-shell-panel {
        position: fixed;
        top: 0;
        bottom: 0;
        display: flex;
        flex-direction: column;
        background-color: var(--ax-color-background-surface);
        box-sizing: border-box;
        overflow: hidden;
        z-index: 50;
        width: 100vw;
        max-width: var(--ax-drawer-width, 320px);
        border-inline-end-width: 0;
        visibility: hidden;
        transition: transform var(--ax-duration-medium) var(--ax-ease-standard), visibility 0s linear var(--ax-duration-medium);
    }

    .ax-shell--bp-sm.ax-shell--has-drawer.ax-shell--drawer-start .ax-shell-panel {
        inset-inline-start: 0;
        border-inline-end-width: var(--ax-border-width);
        border-inline-end-style: solid;
        border-inline-end-color: var(--ax-color-border);
        transform: translateX(-100%);
    }

    .ax-shell--bp-sm.ax-shell--has-drawer.ax-shell--drawer-start .ax-shell-panel:is([dir="rtl"] *) {
        transform: translateX(100%);
    }

    .ax-shell--bp-sm.ax-shell--has-drawer.ax-shell--drawer-end .ax-shell-panel {
        inset-inline-end: 0;
        border-inline-start-width: var(--ax-border-width);
        border-inline-start-style: solid;
        border-inline-start-color: var(--ax-color-border);
        transform: translateX(100%);
    }

    .ax-shell--bp-sm.ax-shell--has-drawer.ax-shell--drawer-end .ax-shell-panel:is([dir="rtl"] *) {
        transform: translateX(-100%);
    }

    .ax-shell--bp-sm.ax-shell--has-drawer .ax-shell-nav-state:checked ~ .ax-shell-middle .ax-shell-panel {
        transform: translateX(0);
        visibility: visible;
        transition: transform var(--ax-duration-medium) var(--ax-ease-standard), visibility 0s;
    }

    .ax-shell--bp-sm.ax-shell--has-drawer .ax-shell-scrim {
        display: block;
        visibility: hidden;
        opacity: 0;
        transition: opacity var(--ax-duration-medium) var(--ax-ease-standard), visibility 0s linear var(--ax-duration-medium);
    }

    .ax-shell--bp-sm.ax-shell--has-drawer .ax-shell-nav-state:checked ~ .ax-shell-scrim {
        visibility: visible;
        opacity: 1;
        transition: opacity var(--ax-duration-medium) var(--ax-ease-standard), visibility 0s;
    }

    .ax-shell--bp-sm.ax-shell--has-drawer .ax-shell-nav-state:checked ~ .ax-shell-middle .ax-shell-panel-close {
        display: inline-flex;
    }

    .ax-shell--bp-sm.ax-shell--has-drawer .ax-shell-nav-state:checked ~ .ax-shell-middle .ax-sidenav-top {
        padding-inline-end: calc(var(--ax-spacing-2) + var(--ax-size-element-md) + var(--ax-spacing-2));
    }

    .ax-shell--bp-sm.ax-shell--has-drawer .ax-topnav {
        display: flex;
    }

    .ax-shell--bp-sm.ax-shell--has-drawer .ax-topnav-start,
    .ax-shell--bp-sm.ax-shell--has-drawer .ax-topnav-center {
        display: none;
    }

    .ax-shell--bp-sm.ax-shell--has-drawer .ax-topnav .ax-mobilenav-toggle {
        display: inline-flex;
    }

    .ax-shell--bp-sm.ax-shell--has-drawer .ax-shell-mobilebar {
        display: flex;
    }

    .ax-shell--bp-sm .ax-shell-elevated-backdrop {
        display: none;
    }

    .ax-shell--bp-sm.ax-shell--elevated.ax-shell--has-topnav.ax-shell--has-sidenav .ax-shell-content {
        background-color: var(--ax-color-background-surface);
    }
}

/* --- Narrow layout, below md (768px) --- */

@media (width < 768px) {
    .ax-shell--bp-md:not(.ax-shell--has-drawer) .ax-shell-panel {
        display: none;
    }

    .ax-shell--bp-md.ax-shell--has-drawer .ax-shell-panel {
        position: fixed;
        top: 0;
        bottom: 0;
        display: flex;
        flex-direction: column;
        background-color: var(--ax-color-background-surface);
        box-sizing: border-box;
        overflow: hidden;
        z-index: 50;
        width: 100vw;
        max-width: var(--ax-drawer-width, 320px);
        border-inline-end-width: 0;
        visibility: hidden;
        transition: transform var(--ax-duration-medium) var(--ax-ease-standard), visibility 0s linear var(--ax-duration-medium);
    }

    .ax-shell--bp-md.ax-shell--has-drawer.ax-shell--drawer-start .ax-shell-panel {
        inset-inline-start: 0;
        border-inline-end-width: var(--ax-border-width);
        border-inline-end-style: solid;
        border-inline-end-color: var(--ax-color-border);
        transform: translateX(-100%);
    }

    .ax-shell--bp-md.ax-shell--has-drawer.ax-shell--drawer-start .ax-shell-panel:is([dir="rtl"] *) {
        transform: translateX(100%);
    }

    .ax-shell--bp-md.ax-shell--has-drawer.ax-shell--drawer-end .ax-shell-panel {
        inset-inline-end: 0;
        border-inline-start-width: var(--ax-border-width);
        border-inline-start-style: solid;
        border-inline-start-color: var(--ax-color-border);
        transform: translateX(100%);
    }

    .ax-shell--bp-md.ax-shell--has-drawer.ax-shell--drawer-end .ax-shell-panel:is([dir="rtl"] *) {
        transform: translateX(-100%);
    }

    .ax-shell--bp-md.ax-shell--has-drawer .ax-shell-nav-state:checked ~ .ax-shell-middle .ax-shell-panel {
        transform: translateX(0);
        visibility: visible;
        transition: transform var(--ax-duration-medium) var(--ax-ease-standard), visibility 0s;
    }

    .ax-shell--bp-md.ax-shell--has-drawer .ax-shell-scrim {
        display: block;
        visibility: hidden;
        opacity: 0;
        transition: opacity var(--ax-duration-medium) var(--ax-ease-standard), visibility 0s linear var(--ax-duration-medium);
    }

    .ax-shell--bp-md.ax-shell--has-drawer .ax-shell-nav-state:checked ~ .ax-shell-scrim {
        visibility: visible;
        opacity: 1;
        transition: opacity var(--ax-duration-medium) var(--ax-ease-standard), visibility 0s;
    }

    .ax-shell--bp-md.ax-shell--has-drawer .ax-shell-nav-state:checked ~ .ax-shell-middle .ax-shell-panel-close {
        display: inline-flex;
    }

    .ax-shell--bp-md.ax-shell--has-drawer .ax-shell-nav-state:checked ~ .ax-shell-middle .ax-sidenav-top {
        padding-inline-end: calc(var(--ax-spacing-2) + var(--ax-size-element-md) + var(--ax-spacing-2));
    }

    .ax-shell--bp-md.ax-shell--has-drawer .ax-topnav {
        display: flex;
    }

    .ax-shell--bp-md.ax-shell--has-drawer .ax-topnav-start,
    .ax-shell--bp-md.ax-shell--has-drawer .ax-topnav-center {
        display: none;
    }

    .ax-shell--bp-md.ax-shell--has-drawer .ax-topnav .ax-mobilenav-toggle {
        display: inline-flex;
    }

    .ax-shell--bp-md.ax-shell--has-drawer .ax-shell-mobilebar {
        display: flex;
    }

    .ax-shell--bp-md .ax-shell-elevated-backdrop {
        display: none;
    }

    .ax-shell--bp-md.ax-shell--elevated.ax-shell--has-topnav.ax-shell--has-sidenav .ax-shell-content {
        background-color: var(--ax-color-background-surface);
    }
}

/* --- Narrow layout, below lg (1024px) --- */

@media (width < 1024px) {
    .ax-shell--bp-lg:not(.ax-shell--has-drawer) .ax-shell-panel {
        display: none;
    }

    .ax-shell--bp-lg.ax-shell--has-drawer .ax-shell-panel {
        position: fixed;
        top: 0;
        bottom: 0;
        display: flex;
        flex-direction: column;
        background-color: var(--ax-color-background-surface);
        box-sizing: border-box;
        overflow: hidden;
        z-index: 50;
        width: 100vw;
        max-width: var(--ax-drawer-width, 320px);
        border-inline-end-width: 0;
        visibility: hidden;
        transition: transform var(--ax-duration-medium) var(--ax-ease-standard), visibility 0s linear var(--ax-duration-medium);
    }

    .ax-shell--bp-lg.ax-shell--has-drawer.ax-shell--drawer-start .ax-shell-panel {
        inset-inline-start: 0;
        border-inline-end-width: var(--ax-border-width);
        border-inline-end-style: solid;
        border-inline-end-color: var(--ax-color-border);
        transform: translateX(-100%);
    }

    .ax-shell--bp-lg.ax-shell--has-drawer.ax-shell--drawer-start .ax-shell-panel:is([dir="rtl"] *) {
        transform: translateX(100%);
    }

    .ax-shell--bp-lg.ax-shell--has-drawer.ax-shell--drawer-end .ax-shell-panel {
        inset-inline-end: 0;
        border-inline-start-width: var(--ax-border-width);
        border-inline-start-style: solid;
        border-inline-start-color: var(--ax-color-border);
        transform: translateX(100%);
    }

    .ax-shell--bp-lg.ax-shell--has-drawer.ax-shell--drawer-end .ax-shell-panel:is([dir="rtl"] *) {
        transform: translateX(-100%);
    }

    .ax-shell--bp-lg.ax-shell--has-drawer .ax-shell-nav-state:checked ~ .ax-shell-middle .ax-shell-panel {
        transform: translateX(0);
        visibility: visible;
        transition: transform var(--ax-duration-medium) var(--ax-ease-standard), visibility 0s;
    }

    .ax-shell--bp-lg.ax-shell--has-drawer .ax-shell-scrim {
        display: block;
        visibility: hidden;
        opacity: 0;
        transition: opacity var(--ax-duration-medium) var(--ax-ease-standard), visibility 0s linear var(--ax-duration-medium);
    }

    .ax-shell--bp-lg.ax-shell--has-drawer .ax-shell-nav-state:checked ~ .ax-shell-scrim {
        visibility: visible;
        opacity: 1;
        transition: opacity var(--ax-duration-medium) var(--ax-ease-standard), visibility 0s;
    }

    .ax-shell--bp-lg.ax-shell--has-drawer .ax-shell-nav-state:checked ~ .ax-shell-middle .ax-shell-panel-close {
        display: inline-flex;
    }

    .ax-shell--bp-lg.ax-shell--has-drawer .ax-shell-nav-state:checked ~ .ax-shell-middle .ax-sidenav-top {
        padding-inline-end: calc(var(--ax-spacing-2) + var(--ax-size-element-md) + var(--ax-spacing-2));
    }

    .ax-shell--bp-lg.ax-shell--has-drawer .ax-topnav {
        display: flex;
    }

    .ax-shell--bp-lg.ax-shell--has-drawer .ax-topnav-start,
    .ax-shell--bp-lg.ax-shell--has-drawer .ax-topnav-center {
        display: none;
    }

    .ax-shell--bp-lg.ax-shell--has-drawer .ax-topnav .ax-mobilenav-toggle {
        display: inline-flex;
    }

    .ax-shell--bp-lg.ax-shell--has-drawer .ax-shell-mobilebar {
        display: flex;
    }

    .ax-shell--bp-lg .ax-shell-elevated-backdrop {
        display: none;
    }

    .ax-shell--bp-lg.ax-shell--elevated.ax-shell--has-topnav.ax-shell--has-sidenav .ax-shell-content {
        background-color: var(--ax-color-background-surface);
    }
}

/* --- Narrow layout, below xl (1280px) --- */

@media (width < 1280px) {
    .ax-shell--bp-xl:not(.ax-shell--has-drawer) .ax-shell-panel {
        display: none;
    }

    .ax-shell--bp-xl.ax-shell--has-drawer .ax-shell-panel {
        position: fixed;
        top: 0;
        bottom: 0;
        display: flex;
        flex-direction: column;
        background-color: var(--ax-color-background-surface);
        box-sizing: border-box;
        overflow: hidden;
        z-index: 50;
        width: 100vw;
        max-width: var(--ax-drawer-width, 320px);
        border-inline-end-width: 0;
        visibility: hidden;
        transition: transform var(--ax-duration-medium) var(--ax-ease-standard), visibility 0s linear var(--ax-duration-medium);
    }

    .ax-shell--bp-xl.ax-shell--has-drawer.ax-shell--drawer-start .ax-shell-panel {
        inset-inline-start: 0;
        border-inline-end-width: var(--ax-border-width);
        border-inline-end-style: solid;
        border-inline-end-color: var(--ax-color-border);
        transform: translateX(-100%);
    }

    .ax-shell--bp-xl.ax-shell--has-drawer.ax-shell--drawer-start .ax-shell-panel:is([dir="rtl"] *) {
        transform: translateX(100%);
    }

    .ax-shell--bp-xl.ax-shell--has-drawer.ax-shell--drawer-end .ax-shell-panel {
        inset-inline-end: 0;
        border-inline-start-width: var(--ax-border-width);
        border-inline-start-style: solid;
        border-inline-start-color: var(--ax-color-border);
        transform: translateX(100%);
    }

    .ax-shell--bp-xl.ax-shell--has-drawer.ax-shell--drawer-end .ax-shell-panel:is([dir="rtl"] *) {
        transform: translateX(-100%);
    }

    .ax-shell--bp-xl.ax-shell--has-drawer .ax-shell-nav-state:checked ~ .ax-shell-middle .ax-shell-panel {
        transform: translateX(0);
        visibility: visible;
        transition: transform var(--ax-duration-medium) var(--ax-ease-standard), visibility 0s;
    }

    .ax-shell--bp-xl.ax-shell--has-drawer .ax-shell-scrim {
        display: block;
        visibility: hidden;
        opacity: 0;
        transition: opacity var(--ax-duration-medium) var(--ax-ease-standard), visibility 0s linear var(--ax-duration-medium);
    }

    .ax-shell--bp-xl.ax-shell--has-drawer .ax-shell-nav-state:checked ~ .ax-shell-scrim {
        visibility: visible;
        opacity: 1;
        transition: opacity var(--ax-duration-medium) var(--ax-ease-standard), visibility 0s;
    }

    .ax-shell--bp-xl.ax-shell--has-drawer .ax-shell-nav-state:checked ~ .ax-shell-middle .ax-shell-panel-close {
        display: inline-flex;
    }

    .ax-shell--bp-xl.ax-shell--has-drawer .ax-shell-nav-state:checked ~ .ax-shell-middle .ax-sidenav-top {
        padding-inline-end: calc(var(--ax-spacing-2) + var(--ax-size-element-md) + var(--ax-spacing-2));
    }

    .ax-shell--bp-xl.ax-shell--has-drawer .ax-topnav {
        display: flex;
    }

    .ax-shell--bp-xl.ax-shell--has-drawer .ax-topnav-start,
    .ax-shell--bp-xl.ax-shell--has-drawer .ax-topnav-center {
        display: none;
    }

    .ax-shell--bp-xl.ax-shell--has-drawer .ax-topnav .ax-mobilenav-toggle {
        display: inline-flex;
    }

    .ax-shell--bp-xl.ax-shell--has-drawer .ax-shell-mobilebar {
        display: flex;
    }

    .ax-shell--bp-xl .ax-shell-elevated-backdrop {
        display: none;
    }

    .ax-shell--bp-xl.ax-shell--elevated.ax-shell--has-topnav.ax-shell--has-sidenav .ax-shell-content {
        background-color: var(--ax-color-background-surface);
    }
}

/* --- Narrow layout, below 2xl (1536px) --- */

@media (width < 1536px) {
    .ax-shell--bp-2xl:not(.ax-shell--has-drawer) .ax-shell-panel {
        display: none;
    }

    .ax-shell--bp-2xl.ax-shell--has-drawer .ax-shell-panel {
        position: fixed;
        top: 0;
        bottom: 0;
        display: flex;
        flex-direction: column;
        background-color: var(--ax-color-background-surface);
        box-sizing: border-box;
        overflow: hidden;
        z-index: 50;
        width: 100vw;
        max-width: var(--ax-drawer-width, 320px);
        border-inline-end-width: 0;
        visibility: hidden;
        transition: transform var(--ax-duration-medium) var(--ax-ease-standard), visibility 0s linear var(--ax-duration-medium);
    }

    .ax-shell--bp-2xl.ax-shell--has-drawer.ax-shell--drawer-start .ax-shell-panel {
        inset-inline-start: 0;
        border-inline-end-width: var(--ax-border-width);
        border-inline-end-style: solid;
        border-inline-end-color: var(--ax-color-border);
        transform: translateX(-100%);
    }

    .ax-shell--bp-2xl.ax-shell--has-drawer.ax-shell--drawer-start .ax-shell-panel:is([dir="rtl"] *) {
        transform: translateX(100%);
    }

    .ax-shell--bp-2xl.ax-shell--has-drawer.ax-shell--drawer-end .ax-shell-panel {
        inset-inline-end: 0;
        border-inline-start-width: var(--ax-border-width);
        border-inline-start-style: solid;
        border-inline-start-color: var(--ax-color-border);
        transform: translateX(100%);
    }

    .ax-shell--bp-2xl.ax-shell--has-drawer.ax-shell--drawer-end .ax-shell-panel:is([dir="rtl"] *) {
        transform: translateX(-100%);
    }

    .ax-shell--bp-2xl.ax-shell--has-drawer .ax-shell-nav-state:checked ~ .ax-shell-middle .ax-shell-panel {
        transform: translateX(0);
        visibility: visible;
        transition: transform var(--ax-duration-medium) var(--ax-ease-standard), visibility 0s;
    }

    .ax-shell--bp-2xl.ax-shell--has-drawer .ax-shell-scrim {
        display: block;
        visibility: hidden;
        opacity: 0;
        transition: opacity var(--ax-duration-medium) var(--ax-ease-standard), visibility 0s linear var(--ax-duration-medium);
    }

    .ax-shell--bp-2xl.ax-shell--has-drawer .ax-shell-nav-state:checked ~ .ax-shell-scrim {
        visibility: visible;
        opacity: 1;
        transition: opacity var(--ax-duration-medium) var(--ax-ease-standard), visibility 0s;
    }

    .ax-shell--bp-2xl.ax-shell--has-drawer .ax-shell-nav-state:checked ~ .ax-shell-middle .ax-shell-panel-close {
        display: inline-flex;
    }

    .ax-shell--bp-2xl.ax-shell--has-drawer .ax-shell-nav-state:checked ~ .ax-shell-middle .ax-sidenav-top {
        padding-inline-end: calc(var(--ax-spacing-2) + var(--ax-size-element-md) + var(--ax-spacing-2));
    }

    .ax-shell--bp-2xl.ax-shell--has-drawer .ax-topnav {
        display: flex;
    }

    .ax-shell--bp-2xl.ax-shell--has-drawer .ax-topnav-start,
    .ax-shell--bp-2xl.ax-shell--has-drawer .ax-topnav-center {
        display: none;
    }

    .ax-shell--bp-2xl.ax-shell--has-drawer .ax-topnav .ax-mobilenav-toggle {
        display: inline-flex;
    }

    .ax-shell--bp-2xl.ax-shell--has-drawer .ax-shell-mobilebar {
        display: flex;
    }

    .ax-shell--bp-2xl .ax-shell-elevated-backdrop {
        display: none;
    }

    .ax-shell--bp-2xl.ax-shell--elevated.ax-shell--has-topnav.ax-shell--has-sidenav .ax-shell-content {
        background-color: var(--ax-color-background-surface);
    }
}

/* --- Reduced motion --- */
/* The drawer and scrim flip instantly instead of sliding; the ghost
 * controls drop their fades. Nav-item transitions keep the source's
 * behavior — Astryx animates those regardless. */

@media (prefers-reduced-motion: reduce) {
    .ax-shell-panel,
    .ax-shell-scrim,
    .ax-mobilenav-toggle,
    .ax-shell-panel-close {
        transition: none;
    }
}
/* The Astryx list rows: `List`, `ListItem`, and the `Item` primitive they
 * share. A port of the List, ListItem, and Item modules of
 * `@astryxdesign/core` 0.6.0 (MIT, Meta): markup, styles, and behavior
 * follow the source; the rustdoc on `list.rs` records what changed.
 *
 * Like its `shell.css` sibling this is a second visual language inside a
 * DW-001 crate: every rule lives under the `ax-list` / `ax-item` roots,
 * every token is `--ax-*`. Both roots declare the token subset the rows
 * need, so a standalone `Item` outside any `List` still resolves them.
 */

.ax-list,
.ax-item {
    --ax-color-accent: light-dark(#0064e0, #2694fe);
    --ax-color-accent-muted: light-dark(#0082fb33, #0082fb3f);
    --ax-color-border: light-dark(#05365919, #f2f4f619);
    --ax-color-overlay-hover: light-dark(#0536590c, #ffffff0c);
    --ax-color-overlay-pressed: light-dark(#05365919, #ffffff19);
    --ax-color-text-primary: light-dark(#0a1317, #dfe2e5);
    --ax-color-text-secondary: light-dark(#4e606f, #aaafb5);
    --ax-spacing-0-5: 2px;
    --ax-spacing-1: 4px;
    --ax-spacing-2: 8px;
    --ax-spacing-3: 12px;
    --ax-spacing-4: 16px;
    --ax-border-width: 1px;
    --ax-focus-outline-width: 2px;
    --ax-focus-outline-style: solid;
    --ax-focus-outline-color: var(--ax-color-accent);
    --ax-focus-outline-offset: 3px;
    --ax-radius-element: 8px;
    --ax-duration-fast-min: 130ms;
    --ax-ease-standard: cubic-bezier(0.24, 1, 0.4, 1);
    --ax-text-body-size: 0.875rem;
    --ax-text-body-leading: 1.4286;
    --ax-text-supporting-size: 0.75rem;
    --ax-text-supporting-leading: 1.6667;
}

/* The list shell: a bare column with a hair of gap. Markers are
 * custom-rendered by the rows, never native list-style. */
.ax-list {
    margin: 0;
    padding-inline-start: 0;
    list-style-type: none;
    display: flex;
    flex-direction: column;
    gap: var(--ax-spacing-0-5);
}

/* Divided rows touch; the borders do the separating. */
.ax-list--dividers {
    gap: 0;
}

/* The decimal counter's reset. A custom `start` arrives as an inline
 * `counter-reset` instead (same declaration, computed value). */
.ax-list--counted {
    counter-reset: astryx-list;
}

/* The header wraps list and heading so the heading keeps its margin. */
.ax-list-wrap {
    display: flex;
    flex-direction: column;
}

.ax-list-header {
    margin-bottom: var(--ax-spacing-2);
}

/* The row: marker, start slot, label block, end slot in one flex line. The
 * ring paints on `:has(:focus-visible)` (the focusWithin contract): the row
 * itself is never the tab stop, its invisible anchor or button is. */
.ax-item {
    display: flex;
    align-items: center;
    gap: var(--ax-spacing-2);
    padding-inline: var(--ax-spacing-2);
    position: relative;
    box-sizing: border-box;
    text-align: start;
    border-radius: var(--ax-radius-element);
    outline-width: 0;
    outline-style: none;
    outline-offset: 0;
}

.ax-item:has(:focus-visible) {
    outline-width: var(--ax-focus-outline-width);
    outline-style: var(--ax-focus-outline-style);
    outline-color: var(--ax-focus-outline-color);
    outline-offset: var(--ax-focus-outline-offset);
}

/* Density is block padding only — spacious also widens the inline padding. */
.ax-item--compact {
    padding-block: var(--ax-spacing-1);
}

.ax-item--balanced {
    padding-block: var(--ax-spacing-2);
}

.ax-item--spacious {
    padding-block: var(--ax-spacing-3);
    padding-inline: var(--ax-spacing-3);
}

.ax-item--align-start {
    align-items: flex-start;
}

/* Interactive rows: pointer cursor, a fast background transition, and the
 * shared hover/press overlay matrix. The `:where` guard keeps every state
 * off disabled rows; the bare `:active` is the touch fallback where
 * `(hover: hover)` never matches, and repeating it inside the hover branch
 * gives press the same specificity as hover so press wins while held. */
.ax-item--interactive {
    cursor: pointer;
    transition-property: background-color;
    transition-duration: var(--ax-duration-fast-min);
    transition-timing-function: var(--ax-ease-standard);
    background-color: transparent;
}

.ax-item--interactive:is(:disabled, [aria-disabled="true"]) {
    cursor: default;
}

.ax-item--interactive:where(:not(:disabled, [aria-disabled="true"])):active {
    background-color: var(--ax-color-overlay-pressed);
}

@media (hover: hover) {
    .ax-item--interactive:where(:not(:disabled, [aria-disabled="true"])):hover {
        background-color: var(--ax-color-overlay-hover);
    }

    .ax-item--interactive:where(:not(:disabled, [aria-disabled="true"])):active {
        background-color: var(--ax-color-overlay-pressed);
    }
}

/* Forced-hover, selection, and the inert row. A disabled row takes itself
 * out of pointer events; its content dims except the start slot, verbatim. */
.ax-item--highlighted {
    background-color: var(--ax-color-overlay-hover);
}

.ax-item--selected {
    background-color: var(--ax-color-accent-muted);
}

.ax-item--disabled {
    cursor: default;
    pointer-events: none;
}

.ax-item--disabled > .ax-item-content,
.ax-item--disabled > .ax-item-link,
.ax-item--disabled > .ax-item-button,
.ax-item--disabled > .ax-item-end {
    opacity: 0.5;
}

/* Divided rows trade their radius for a bottom border; the last row keeps
 * neither border nor radius. */
.ax-item--divider {
    border-block-end-width: var(--ax-border-width);
    border-block-end-style: solid;
    border-block-end-color: var(--ax-color-border);
    border-radius: 0;
}

.ax-item--divider:last-child {
    border-block-end: none;
}

/* Rows feed the decimal counter whenever the list shows markers. */
.ax-item--counted {
    counter-increment: astryx-list;
}

/* The label block: a plain span, or the invisible anchor/button that makes
 * the row's text its tab stop. `all: unset` first, then the flex column
 * back — the source order, since `all` resets at its own position. */
.ax-item-content,
.ax-item-link,
.ax-item-button {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-width: 0;
    text-align: start;
}

.ax-item-link,
.ax-item-button {
    all: unset;
    cursor: inherit;
    font: inherit;
    color: inherit;
    display: flex;
    flex-direction: column;
    flex: 1;
    min-width: 0;
    text-align: start;
    outline: none;
}

.ax-item-link {
    text-decoration: none;
}

.ax-item-link:is(:disabled, [aria-disabled="true"]),
.ax-item-button:is(:disabled, [aria-disabled="true"]) {
    cursor: default;
}

/* Label and description: single-line truncation always — the port takes
 * plain strings, and Astryx truncates string labels that way. A parent
 * recolors either line through `--_item-label-color` /
 * `--_item-description-color` (the destructive-menu hook). */
.ax-item-label {
    color: var(--_item-label-color, var(--ax-color-text-primary));
    font-size: var(--ax-text-body-size);
    line-height: var(--ax-text-body-leading);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ax-item-description {
    color: var(--_item-description-color, var(--ax-color-text-secondary));
    font-size: var(--ax-text-supporting-size);
    line-height: var(--ax-text-supporting-leading);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* The slots: fixed flex children, the end slot pushed to the far edge. */
.ax-item-start {
    flex: 0 0 auto;
    display: flex;
}

.ax-item-end {
    flex: 0 0 auto;
    display: flex;
    margin-inline-start: auto;
}

/* Custom markers instead of native list-style: a 6px dot or ring in a
 * spacing-4 box nudged onto the label's baseline, or the decimal counter
 * rendered through `::before`. */
.ax-item-marker {
    align-self: baseline;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: var(--ax-spacing-4);
    margin-top: calc((1em * var(--ax-text-body-leading) - 6px) / 2);
}

.ax-item-marker-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background-color: var(--ax-color-text-primary);
}

.ax-item-marker-circle {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    border-width: 1px;
    border-style: solid;
    border-color: var(--ax-color-text-primary);
    background-color: transparent;
}

.ax-item-marker-number {
    align-self: baseline;
    flex-shrink: 0;
    color: var(--ax-color-text-primary);
    font-size: var(--ax-text-body-size);
    line-height: var(--ax-text-body-leading);
    width: var(--ax-spacing-4);
}

.ax-item-marker-number::before {
    content: counter(astryx-list) ".";
}

/* The row transition is decorative motion: off under reduced motion.
 * Astryx animates regardless; the shell port set this precedent. */
@media (prefers-reduced-motion: reduce) {
    .ax-item--interactive {
        transition: none;
    }
}
/* Shared fleet styles — one home for the DW-001 system every fleet
 * frontend consumes. Rules here change once, everywhere. */

/* --- Source errors: failing sources render as Astryx rows in a danger
 * scope. The destructive hooks recolor every descendant row's label and
 * description; the red is Astryx's --color-error verbatim
 * (@astryxdesign/core 0.6.0 tokens.stylex.ts), routed through the token —
 * never written into the hooks — so the gothic theme's muted red wins
 * where it applies (its hook outranks this scope and ships last). */
.source-errors {
    --ax-color-error: light-dark(#e3193b, #f5394f);
    --_item-label-color: var(--ax-color-error);
    --_item-description-color: var(--ax-color-error);
}
/* The Astryx gothic theme, recreated for the fleet-ui components. Values
 * are verbatim from @astryxdesign/theme-gothic 0.6.2's built `theme.css`
 * (`:scope` block) and its source `gothicTheme.ts`; the core defaults it
 * layers over are identical in 0.6.0 and 0.6.2, so the values apply cleanly
 * to the 0.6.0-based ports.
 *
 * The opt-in is Astryx's own contract: `data-astryx-theme="gothic"` on any
 * ancestor (or the component root itself) themes the whole subtree — one
 * attribute on `<html>` goes full-page. Each block below beats the ports'
 * self-declared tokens on specificity (0,2,0 over 0,1,0), and this fragment
 * ships last in the manifest so the DW-001 hook below wins its 0,1,0 tie
 * with `:root` in both color schemes. Gothic is dark-only, so every block
 * also pins `color-scheme: dark`: tokens the theme never defines (spacing,
 * sizes, `--ax-color-track`, the easing) keep resolving from the ports' own
 * `light-dark()` declarations, which now pick their dark leg.
 *
 * Two deliberate non-copies. `--radius-chat` stays 28px: gothic sets explicit
 * radius tokens rather than the scale config, and neither its source nor its
 * built CSS defines a chat radius, so upstream falls through to the core
 * default too. And there is no display-face rule: the ports render no display
 * text, so Manufacturing Consent has nothing to attach to (when a display
 * component lands, it takes the theme's blackletter stack verbatim).
 *
 * The DW-001 block maps the legacy tokens onto their gothic analogs so a
 * themed page reads as one document — transparent ax components (lists, chat)
 * inherit the page ink and ground. `--fill` is the card step: the role is
 * "one step lighter than the page", which is `--color-background-card`, not
 * the two-steps-lighter popover the chat composer uses for itself. Body type
 * follows the theme (Fustat) on full-page gothic only; headings keep the
 * fleet serif and the masthead keeps its blackletter — both already read
 * gothic, and the guide owns them. Every mapped color passes WCAG AA on the
 * `#101314` ground by a wide margin, which quietly retires the DW-001 §2
 * contrast problem for themed pages.
 */

[data-astryx-theme="gothic"] {
    color-scheme: dark;
    font-family: Fustat, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

    --bg: #101314;
    --fill: #1a1d20;
    --text: #E8F1F6;
    --text-muted: #96A0AB;
    --accent: #E8F1F6;
    --accent-contrast: #101314;
    --ink: #000000;
    --good: #b3c79a;
    --danger: #c6a6a2;
    --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
}

/* `body` sets its own face, which beats what it would inherit from the hook
 * above — so full-page gothic restates the theme voice here. Subtree gothic
 * (the hook on a `<div>`) keeps the page face outside the hook and lets the
 * ax roots below carry Fustat inside it. */
html[data-astryx-theme="gothic"] body {
    font-family: Fustat, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

/* --- AppShell under gothic --- */

[data-astryx-theme="gothic"] .ax-shell,
.ax-shell[data-astryx-theme="gothic"] {
    color-scheme: dark;
    font-family: Fustat, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    color: #E8F1F6;

    /* --- color --- */
    --ax-color-accent: #E8F1F6;
    --ax-color-neutral: #E8F1F61A;
    --ax-color-background-surface: #101314;
    --ax-color-background-body: #101314;
    --ax-color-overlay: #101314CC;
    --ax-color-overlay-hover: #E8F1F60D;
    --ax-color-overlay-pressed: #E8F1F61A;
    --ax-color-text-primary: #E8F1F6;
    --ax-color-text-secondary: #96A0AB;
    --ax-color-text-disabled: #495056;
    --ax-color-text-accent: #E8F1F6;
    --ax-color-icon-secondary: #96A0AB;
    --ax-color-icon-disabled: #495056;
    --ax-color-border: #E8F1F61A;

    /* --- radius --- */
    --ax-radius-element: 0.5rem;
    --ax-radius-page: 1.5rem;

    /* --- motion (theatrical: gothic doesn't rush) --- */
    --ax-duration-fast: 150ms;
    --ax-duration-medium: 350ms;

    /* --- type (base 16 / ratio 1.25) --- */
    --ax-text-large-size: 1.25rem;
    --ax-text-large-leading: 1.4;
    --ax-text-label-size: 1rem;
    --ax-text-label-leading: 1.5;
    --ax-text-supporting-size: 0.8125rem;
    --ax-text-supporting-leading: 1.5385;
}

/* --- Lists under gothic --- */
/* The list roots set no face of their own — they inherit the page voice —
 * so the theme states it here, or subtree lists would read system-ui beside
 * Fustat siblings. */

[data-astryx-theme="gothic"] .ax-list,
.ax-list[data-astryx-theme="gothic"],
[data-astryx-theme="gothic"] .ax-item,
.ax-item[data-astryx-theme="gothic"] {
    color-scheme: dark;
    font-family: Fustat, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

    --ax-color-accent: #E8F1F6;
    --ax-color-accent-muted: #E8F1F620;
    --ax-color-border: #E8F1F61A;
    --ax-color-overlay-hover: #E8F1F60D;
    --ax-color-overlay-pressed: #E8F1F61A;
    --ax-color-text-primary: #E8F1F6;
    --ax-color-text-secondary: #96A0AB;
    --ax-radius-element: 0.5rem;
    --ax-duration-fast-min: 115ms;
    --ax-text-body-size: 1rem;
    --ax-text-body-leading: 1.5;
    --ax-text-supporting-size: 0.8125rem;
    --ax-text-supporting-leading: 1.5385;
}

/* --- Text and headings under gothic --- */
/* The text root voices through its tokens; the heading hardcodes the
 * system face, so the theme restates Fustat here the way the shell does. */

[data-astryx-theme="gothic"] .ax-text,
.ax-text[data-astryx-theme="gothic"],
[data-astryx-theme="gothic"] .ax-heading,
.ax-heading[data-astryx-theme="gothic"] {
    color-scheme: dark;
    font-family: Fustat, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

    --ax-font-family-body: Fustat, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --ax-font-family-mono: "JetBrains Mono", "SF Mono", Monaco, Consolas, monospace;
    --ax-color-text-primary: #E8F1F6;
    --ax-color-text-secondary: #96A0AB;
    --ax-color-accent: #E8F1F6;
}

/* --- Fields under gothic --- */

[data-astryx-theme="gothic"] .ax-field,
.ax-field[data-astryx-theme="gothic"] {
    color-scheme: dark;
    font-family: Fustat, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

    --ax-font-body: Fustat, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --ax-color-text-primary: #E8F1F6;
    --ax-color-text-secondary: #96A0AB;
    --ax-color-border-emphasized: #495056;
    --ax-color-accent: #E8F1F6;
    --ax-color-error: #c6a6a2;
    --ax-color-background-surface: #101314;
}

/* --- Chat under gothic --- */

[data-astryx-theme="gothic"] .ax-chat,
.ax-chat[data-astryx-theme="gothic"] {
    color-scheme: dark;
    font-family: Fustat, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    color: #E8F1F6;

    /* --- color --- */
    --ax-color-accent: #E8F1F6;
    --ax-color-accent-muted: #E8F1F620;
    --ax-color-on-accent: #101314;
    --ax-color-neutral: #E8F1F61A;
    --ax-color-background-popover: #24292D;
    --ax-color-overlay-hover: #E8F1F60D;
    --ax-color-overlay-pressed: #E8F1F61A;
    --ax-color-text-primary: #E8F1F6;
    --ax-color-text-secondary: #96A0AB;
    --ax-color-text-disabled: #495056;
    --ax-color-on-dark: #E8F1F6;
    --ax-color-success: #b3c79a;
    --ax-color-on-success: #101314;
    --ax-color-error: #c6a6a2;
    --ax-color-error-muted: #c6a6a2;
    --ax-color-on-error: #101314;
    --ax-color-warning: #d3c490;
    --ax-color-warning-muted: #d3c490;
    --ax-color-on-warning: #101314;
    --ax-color-border: #E8F1F61A;
    --ax-color-border-emphasized: #495056;
    --ax-color-text-red: #4a2520;
    --ax-color-text-yellow: #6c5010;
    --ax-color-background-blue: #a3b5d6;
    --ax-color-text-blue: #1f2c54;
    --ax-color-background-cyan: #a3c2cf;
    --ax-color-text-cyan: #204858;
    --ax-color-background-green: #b3c79a;
    --ax-color-text-green: #244023;
    --ax-color-background-orange: #d3b89a;
    --ax-color-text-orange: #6e3812;
    --ax-color-background-pink: #c89aab;
    --ax-color-text-pink: #71223c;
    --ax-color-background-purple: #b29bc4;
    --ax-color-text-purple: #481b58;
    --ax-color-background-red: #c6a6a2;
    --ax-color-background-teal: #a3c2b6;
    --ax-color-text-teal: #174a40;
    --ax-color-background-yellow: #d3c490;

    /* --- radius --- */
    --ax-radius-inner: 0.25rem;
    --ax-radius-element: 0.5rem;
    --ax-radius-container: 0.75rem;

    /* --- shadow --- */
    --ax-shadow-low: 0 2px 4px #00000033, 0 4px 8px #00000040;
    --ax-shadow-med: 0 2px 4px #00000033, 0 4px 12px #00000040;

    /* --- motion --- */
    --ax-duration-fast: 150ms;
    --ax-duration-fast-max: 200ms;
    --ax-duration-medium: 350ms;
    --ax-duration-slow-min: 600ms;

    /* --- type --- */
    --ax-font-family-code: "JetBrains Mono", "SF Mono", Monaco, Consolas, monospace;
    --ax-text-body-size: 1rem;
    --ax-text-body-leading: 1.5;
    --ax-text-label-size: 1rem;
    --ax-text-label-leading: 1.5;
    --ax-text-supporting-size: 0.8125rem;
    --ax-text-supporting-leading: 1.5385;
}

/* --- Dialogs under gothic --- */
/* The dialog hardcodes its ink, so the theme restates it the way the
 * shell does. Spacing, border width, weights, and the ease keep resolving
 * from the port's own declarations — the theme defines none of them. */

[data-astryx-theme="gothic"] .ax-dialog,
.ax-dialog[data-astryx-theme="gothic"] {
    color-scheme: dark;
    font-family: Fustat, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    color: #E8F1F6;

    --ax-color-background-surface: #101314;
    --ax-color-neutral: #E8F1F61A;
    --ax-color-overlay: #101314CC;
    --ax-color-text-primary: #E8F1F6;
    --ax-color-text-secondary: #96A0AB;
    --ax-color-border: #E8F1F61A;
    --ax-radius-container: 0.75rem;
    --ax-shadow-low: 0 2px 4px #00000033, 0 4px 8px #00000040;
    --ax-text-body-size: 1rem;
    --ax-text-body-leading: 1.5;
    --ax-text-supporting-size: 0.8125rem;
    --ax-text-supporting-leading: 1.5385;
    --ax-duration-medium: 350ms;
}

/* --- Collapsibles under gothic --- */

[data-astryx-theme="gothic"] .ax-collapsible,
.ax-collapsible[data-astryx-theme="gothic"] {
    color-scheme: dark;
    font-family: Fustat, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

    --ax-font-family-body: Fustat, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --ax-color-text-primary: #E8F1F6;
    --ax-color-text-secondary: #96A0AB;
    --ax-duration-fast: 150ms;
}

/* --- Codeblocks under gothic --- */
/* The focus outline reads `--ax-color-accent` through its fallback, so
 * the block states the accent even though the port never declares it —
 * otherwise the ring stays neutral blue on a gothic page. Weights and the
 * outline geometry keep their port declarations. */

[data-astryx-theme="gothic"] .ax-codeblock,
.ax-codeblock[data-astryx-theme="gothic"] {
    color-scheme: dark;

    --ax-font-code: "JetBrains Mono", "SF Mono", Monaco, Consolas, monospace;
    --ax-color-accent: #E8F1F6;
    --ax-color-syntax-keyword: #c39adb;
    --ax-color-syntax-string: #a3c987;
    --ax-color-syntax-comment: #6b7079;
    --ax-color-syntax-number: #dec074;
    --ax-color-syntax-function: #8aa1d8;
    --ax-color-syntax-variable: #E8F1F6;
    --ax-color-syntax-tag: #d97580;
    --ax-color-syntax-background: #101314;
    --ax-color-border: #E8F1F61A;
    --ax-text-code-size: 1rem;
    --ax-text-code-leading: 1.5;
    --ax-text-supporting-size: 0.8125rem;
    --ax-text-supporting-leading: 1.5385;
}

/* --- Markdown under gothic --- */
/* One block for the five roots that declare tokens; paragraphs, lists,
 * and strong voice through their elements and need nothing. Strike keeps
 * its port declaration — the theme defines no muted ink, so its dark leg
 * stands. */

[data-astryx-theme="gothic"] .ax-md-table,
.ax-md-table[data-astryx-theme="gothic"],
[data-astryx-theme="gothic"] .ax-md-quote,
.ax-md-quote[data-astryx-theme="gothic"],
[data-astryx-theme="gothic"] .ax-md-rule,
.ax-md-rule[data-astryx-theme="gothic"],
[data-astryx-theme="gothic"] .ax-md-code,
.ax-md-code[data-astryx-theme="gothic"],
[data-astryx-theme="gothic"] .ax-md-link,
.ax-md-link[data-astryx-theme="gothic"] {
    color-scheme: dark;

    --ax-font-code: "JetBrains Mono", "SF Mono", Monaco, Consolas, monospace;
    --ax-color-border: #E8F1F61A;
    --ax-color-border-emphasized: #495056;
    --ax-color-text-secondary: #96A0AB;
    --ax-color-accent: #E8F1F6;
    --ax-color-background-muted: #24292D;
    --ax-radius-inner: 0.25rem;
}

/* --- Command palettes under gothic --- */

[data-astryx-theme="gothic"] .ax-command-palette-input,
.ax-command-palette-input[data-astryx-theme="gothic"],
[data-astryx-theme="gothic"] .ax-command-palette-list,
.ax-command-palette-list[data-astryx-theme="gothic"],
[data-astryx-theme="gothic"] .ax-command-palette-item,
.ax-command-palette-item[data-astryx-theme="gothic"],
[data-astryx-theme="gothic"] .ax-command-palette-footer,
.ax-command-palette-footer[data-astryx-theme="gothic"] {
    color-scheme: dark;
    font-family: Fustat, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

    --ax-font-family-body: Fustat, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --ax-color-text-primary: #E8F1F6;
    --ax-color-text-secondary: #96A0AB;
    --ax-color-overlay-hover: #E8F1F60D;
    --ax-color-accent-muted: #E8F1F620;
}

/* --- Key caps under gothic --- */

[data-astryx-theme="gothic"] .ax-kbd-key,
.ax-kbd-key[data-astryx-theme="gothic"] {
    color-scheme: dark;
    font-family: Fustat, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

    --ax-font-family-body: Fustat, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --ax-color-neutral: #E8F1F61A;
    --ax-color-border-emphasized: #495056;
    --ax-color-text-secondary: #96A0AB;
}
