@layer components {
.blinc-button {
    background: var(--primary);
    color: var(--text-inverse);
    transition:
        background-color var(--duration-fast) var(--ease-state),
        color var(--duration-fast) var(--ease-state),
        border-color var(--duration-fast) var(--ease-state);
}
.blinc-button:hover:not(:disabled) { background: var(--primary-hover); }
.blinc-button:active:not(:disabled) { background: var(--primary-active); }
.blinc-button:disabled {
    background: var(--input-bg-disabled);
    color: var(--text-tertiary);
}

/* The box is the element; fill, border colour, hover and the mark follow its
   `checked` and `disabled` attributes. Border width is set in Rust because it
   varies with the size. */
.blinc-checkbox {
    background: var(--input-bg);
    border-color: var(--border);
    border-radius: var(--radius-sm);
    color: var(--text-inverse);
    cursor: pointer;
    transition:
        background-color var(--duration-fast) var(--ease-state),
        border-color var(--duration-fast) var(--ease-state),
        transform var(--duration-fast) var(--ease-state);
}
.blinc-checkbox:hover:not(:disabled):not(:checked) { border-color: var(--border-hover); }
.blinc-checkbox:hover:not(:disabled) { transform: scale(1.05); }
.blinc-checkbox:checked {
    background: var(--primary);
    border-color: var(--primary);
}
/* A disabled box takes the disabled palette shared with the button, select
   and switch. */
.blinc-checkbox:disabled {
    background: var(--input-bg-disabled);
    border-color: var(--border-secondary);
    opacity: 0.5;
    cursor: not-allowed;
}
.blinc-checkbox-mark {
    opacity: 0;
    transition: opacity var(--duration-fast) var(--ease-state);
}
.blinc-checkbox:checked > .blinc-checkbox-mark { opacity: 1; }
.blinc-checkbox-label { color: var(--text-primary); }
.blinc-checkbox-row:disabled > .blinc-checkbox-label { color: var(--text-tertiary); }

/* The ring is the element; its border colour, the dot and the disabled fill
   follow its `checked` and `disabled` attributes. Border width is set in Rust
   because it varies with the size. */
.blinc-radio {
    background: transparent;
    border-color: var(--border-secondary);
    border-radius: var(--radius-full);
    cursor: pointer;
    transition:
        border-color var(--duration-fast) var(--ease-state),
        transform var(--duration-fastest) var(--ease-state);
}
.blinc-radio:hover:not(:disabled) {
    border-color: var(--primary);
    transform: scale(1.05, 1.05);
}
.blinc-radio:checked { border-color: var(--primary); }
.blinc-radio:disabled {
    background: var(--input-bg-disabled);
    border-color: var(--border-secondary);
    opacity: 0.5;
    cursor: not-allowed;
}
.blinc-radio-dot {
    background: var(--primary);
    border-radius: var(--radius-full);
    opacity: 0;
    transition:
        opacity var(--duration-fast) var(--ease-state),
        transform var(--duration-fastest) var(--ease-state);
}
.blinc-radio:checked > .blinc-radio-dot { opacity: 1; }
.blinc-radio-label { color: var(--text-primary); }
.blinc-radio-row:disabled > .blinc-radio-label { color: var(--text-tertiary); }
.blinc-radio-group-label { color: var(--text-secondary); }
.blinc-radio-group:disabled > .blinc-radio-group-label { color: var(--text-tertiary); }
.blinc-radio:active:not(:disabled) .blinc-radio-dot { transform: scale(0.8, 0.8); }

/* A button that stays pressed: clear when off, a faint wash of the text
   colour when on; the outline variant keeps a hairline either way. Sizes and
   variants are attributes, so one set of rules serves a toggle, and the items
   of a group that sets them for its items. */
.blinc-toggle {
    flex-direction: row;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: 36px;
    min-width: 36px;
    padding: 0 12px;
    font-size: var(--text-sm);
    font-weight: 500;
    border: 1px solid transparent;
    border-radius: var(--radius-default);
    background: transparent;
    color: var(--text-primary);
    cursor: pointer;
    transition:
        background-color var(--duration-fast) var(--ease-state),
        border-color var(--duration-fast) var(--ease-state),
        transform var(--duration-faster) var(--ease-state);
}
.blinc-toggle:hover:not(:disabled) {
    background: color-mix(in srgb, var(--text-primary) 5%, transparent);
}
.blinc-toggle:active:not(:disabled) {
    background: color-mix(in srgb, var(--text-primary) 10%, transparent);
    transform: scale(0.97);
}
.blinc-toggle[data-state="on"] {
    background: color-mix(in srgb, var(--text-primary) 10%, var(--background));
}
.blinc-toggle[data-state="on"]:hover:not(:disabled) {
    background: color-mix(in srgb, var(--text-primary) 14%, var(--background));
}
.blinc-toggle:disabled { opacity: 0.5; cursor: not-allowed; }
.blinc-toggle[data-variant="outline"],
.blinc-toggle-group[data-variant="outline"] > .blinc-toggle {
    border-color: var(--border-secondary);
}
.blinc-toggle[data-size="sm"],
.blinc-toggle-group[data-size="sm"] > .blinc-toggle {
    height: 32px;
    min-width: 32px;
    padding: 0 8px;
    font-size: var(--text-xs);
    border-radius: var(--radius-sm);
}
.blinc-toggle[data-size="lg"],
.blinc-toggle-group[data-size="lg"] > .blinc-toggle {
    height: 40px;
    min-width: 40px;
    padding: 0 16px;
    font-size: var(--text-base);
}
.blinc-toggle > svg { flex-shrink: 0; }
.blinc-toggle-group {
    flex-direction: row;
    align-items: center;
    gap: 4px;
}

/* The field is the element: hover and focus come from the pointer and the
   router's focus, `disabled` and `data-invalid` are attributes the widget
   keeps in step with its data. An invalid value keeps its error border while
   hovered or focused. */
.blinc-ime-composition { text-decoration: underline; }

.blinc-input {
    background: var(--input-bg);
    border-color: var(--border-secondary);
    cursor: text;
    transition:
        background-color var(--duration-fast) var(--ease-state),
        border-color var(--duration-fast) var(--ease-state);
}
.blinc-input:hover:not(:disabled) {
    background: var(--input-bg-hover);
    border-color: var(--border-hover);
}
.blinc-input:focus:not(:disabled) {
    background: var(--input-bg-focus);
    border-color: var(--border-focus);
}
.blinc-input[data-invalid]:not(:disabled) { border-color: var(--border-error); }
.blinc-input:disabled {
    background: var(--input-bg-disabled);
    border-color: var(--border-secondary);
    cursor: not-allowed;
}

/* Text and tables. */
.blinc-link { color: var(--text-link); }
.blinc-link:hover { color: var(--primary-hover); }
.blinc-blockquote {
    background: var(--surface-overlay);
    border-left: 4px solid var(--border);
}
.blinc-hr { background: var(--border); }
.blinc-list-marker { color: var(--text-tertiary); }
.blinc-task-box { border-color: var(--text-tertiary); }
.blinc-task-box[checked] { background: var(--text-tertiary); color: #ffffff; }
.blinc-thead, .blinc-tfoot { background: var(--surface-overlay); }
.blinc-th { color: var(--text-primary); }
.blinc-td { color: var(--text-secondary); }
.blinc-tr-alt { background: var(--accent-subtle); }
.blinc-table-separator { background: var(--border); }

/* Code blocks and the code editor. Syntax themes colour the text, fill and
   line numbers inline; these are the plain look. The caret is drawn in
   `--blinc-code-caret`, the accent when unset. */
.blinc-code { background: var(--surface); color: var(--text-primary); }
.blinc-code-line-number, .blinc-code-fold, .blinc-code-fold-hint { color: var(--text-tertiary); }
.blinc-code-active-line { background: color-mix(in srgb, var(--primary) 5%, transparent); }
.blinc-code-selection { background: var(--selection); }
.blinc-code-guide { background: color-mix(in srgb, var(--border) 55%, transparent); }
.blinc-code-bracket {
    background: color-mix(in srgb, var(--primary) 15%, transparent);
    border: 1px solid color-mix(in srgb, var(--primary) 65%, transparent);
}
.blinc-code-find-match {
    background: color-mix(in srgb, var(--warning) 25%, transparent);
    border: 1px solid var(--warning);
}
.blinc-code-find-match[data-active] { background: color-mix(in srgb, var(--warning) 50%, transparent); }
.blinc-code-minimap { border-left: 1px solid var(--border); }
.blinc-code-minimap-slider { background: color-mix(in srgb, var(--text-primary) 8%, transparent); }
.blinc-code-minimap-line { background: color-mix(in srgb, var(--text-primary) 40%, transparent); }

/* The code editor's find and replace bar. */
.blinc-find {
    background: var(--surface-elevated);
    color: var(--text-primary);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 8px;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
}
.blinc-find-row { gap: 6px; }

/* A solid 1px border: opaque colours, and a whole-pixel width so it stays
   crisp (the plain input default is 1.5px). */
.blinc-find-input {
    height: 28px;
    background: var(--surface-overlay);
    border-width: 1px;
    border-color: var(--border-secondary);
    border-radius: var(--radius-md);
    color: var(--text-primary);
}
.blinc-find-input:hover { border-color: var(--text-secondary); }
.blinc-find-input:focus {
    background: var(--surface-overlay);
    border-color: var(--border-focus);
}

.blinc-find-button {
    border-radius: var(--radius-md);
    transition: background 120ms ease;
}
.blinc-find-button:hover { background: var(--border); }
.blinc-find-button:active { background: var(--border-hover); }

.blinc-find-toggle {
    border-radius: var(--radius-sm);
    color: var(--text-secondary);
    transition: background 120ms ease;
}
.blinc-find-toggle:hover { background: var(--border); color: var(--text-primary); }
.blinc-find-toggle--on,
.blinc-find-toggle--on:hover { background: var(--accent-subtle); color: var(--accent); }

.blinc-find-count { color: var(--text-secondary); padding: 0 6px; }
.blinc-find-count--none { color: var(--error); }

/* Media controls. The seek bar, volume level and waveform are drawn in
   `--blinc-media-track`, `--blinc-media-buffered`, `--blinc-media-progress`,
   `--blinc-media-level`, `--blinc-media-level-rest`, `--blinc-waveform-played`
   and `--blinc-waveform-unplayed`, theme colours when unset. */
.blinc-media-play-btn { background: var(--surface-elevated); color: var(--text-primary); }
.blinc-media-time, .blinc-media-volume { color: var(--text-tertiary); }
.blinc-media-mute-btn { color: var(--text-secondary); }
.blinc-media-seek-rail { background: var(--surface-elevated); }
.blinc-media-seek-fill { background: var(--primary); }
.blinc-media-live-badge { background: var(--error); color: #ffffff; }

/* The rich text editor. Text without a colour of its own takes the
   document's; the caret is drawn in `--blinc-rich-text-caret`, the text
   colour when unset. */
.blinc-rich-text { color: var(--text-primary); }
.blinc-rich-text-marker { color: var(--text-tertiary); }
.blinc-rich-text-quote-bar { background: var(--border-secondary); }
.blinc-rich-text-divider { background: var(--border); }
.blinc-rich-text-code { color: var(--warning); }
.blinc-rich-text-selection { background: var(--selection); }
.blinc-rte-toolbar {
    background: var(--surface-elevated);
    color: var(--text-primary);
    border-color: var(--border);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.45);
}
.blinc-rte-separator { background: var(--border); }
.blinc-rte-button:hover, .blinc-rte-pill:hover { background: var(--border); }
.blinc-rte-pill { background: var(--surface-overlay); }
.blinc-rte-swatch { border-color: var(--border-secondary); }
.blinc-rte-swatch--default { background: var(--text-primary); }
.blinc-rte-link-input { background: var(--surface); border-color: var(--border-secondary); }
.blinc-rte-link-placeholder { color: var(--text-tertiary); }

/* The document's text colour, which text and icons that set none inherit,
   as a page's root colour is. */
:root {
    color: var(--text-primary);
    /* What a chart's canvas draws its grid, pointer cursor and dot rings in;
       series take --chart-1 to --chart-5 from the theme. */
    --cn-chart-grid: var(--border);
    --cn-chart-cursor: var(--text-secondary);
    --cn-chart-surface: var(--surface);
}

/* ============================================================================
   Typography base — every cn widget inherits the theme's canonical
   sans, body line-height, and dense-HID letter-spacing. CN_STYLES
   was previously silent on these, leaving widgets to fall back to
   the platform default font and ignore the theme's deliberate
   "Noto Sans + 13px text_sm + tracking_tight" choice.
   ============================================================================ */

.cn-button, .cn-card, .cn-card-header, .cn-card-footer,
.cn-badge, .cn-alert, .cn-alert-box,
.cn-input, .cn-textarea, .cn-label,
.cn-checkbox, .cn-switch, .cn-radio, .cn-toggle,
.cn-tabs-list, .cn-tabs-trigger,
.cn-select-trigger, .cn-select-content, .cn-select-item,
.cn-combobox-trigger, .cn-combobox-content, .cn-combobox-item,
.cn-slider-field, .cn-progress,
.cn-avatar, .cn-tooltip,
.cn-dialog, .cn-drawer, .cn-sheet, .cn-toast,
.cn-accordion, .cn-accordion-trigger, .cn-accordion-content,
.cn-breadcrumb, .cn-breadcrumb-item,
.cn-pagination, .cn-pagination-btn,
.cn-nav-menu, .cn-nav-link,
.cn-sidebar, .cn-sidebar-item,
.cn-dropdown-menu, .cn-dropdown-item,
.cn-context-menu, .cn-context-menu-item,
.cn-menubar, .cn-menubar-trigger, .cn-menubar-content, .cn-menubar-item,
.cn-popover-content, .cn-hover-card-content,
.cn-tree, .cn-skeleton {
    font-family: var(--font-sans);
}

.cn-kbd {
    font-family: var(--font-mono);
}

/* Body-text widgets get the theme's line-height so multi-line
   content (alert descriptions, accordion content, tooltips) breathes
   correctly. */
.cn-alert, .cn-alert-box, .cn-accordion-content, .cn-tooltip {
    line-height: var(--leading-normal);
}

/* Dense-HID tracking on interactive labels. Picks up the variant's
   tracking_tight value (Universal HID = -0.025em). */
.cn-button, .cn-tabs-trigger,
.cn-input, .cn-textarea,
.cn-select-trigger, .cn-combobox-trigger {
    letter-spacing: var(--tracking-tight);
}

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

/* Button: each variant's fill, text colour, border and shadow, and how they
   change on hover, press and while disabled, are rules, eased by the
   transition. Geometry tokens flow from the active theme's RadiusTokens so
   each variant (Restrained / Hybrid / Expressive) gets its own corner reach. */
.cn-button {
    border-radius: var(--radius-default);
    cursor: pointer;
    transition:
        background-color var(--duration-fast) var(--ease-state),
        color var(--duration-fast) var(--ease-state),
        border-color var(--duration-fast) var(--ease-state),
        box-shadow var(--duration-fast) var(--ease-state),
        transform var(--duration-faster) var(--ease-state);
}
.cn-button:disabled { cursor: not-allowed; }
/* Keyboard focus rings for pressable controls. */
.cn-button:focus-visible, .cn-checkbox:focus-visible, .cn-switch:focus-visible, .cn-toggle:focus-visible,
.cn-radio:focus-visible, .cn-tabs-trigger:focus-visible, .cn-select-trigger:focus-visible,
.cn-combobox-trigger:focus-visible, [aria-haspopup=menu]:focus-visible, .cn-accordion-trigger:focus-visible,
.cn-collapsible-trigger:focus-visible, .cn-menubar-trigger:focus-visible, .cn-nav-link:focus-visible,
.cn-sidebar-item:focus-visible, .cn-pagination-btn:focus-visible, .cn-breadcrumb-item:focus-visible,
.cn-sheet-close:focus-visible, .cn-drawer-close:focus-visible, .cn-slider:focus-visible,
.cn-number-gauge:focus-visible, .blinc-link:focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: 2px;
}
/* Press feedback: a pressed button shrinks a little and eases back. A link
   button is flat, so it dims instead. */
.cn-button:active:not(:disabled) {
    transform: scale(0.97, 0.97);
}
.cn-button--link:active:not(:disabled) {
    transform: none;
    opacity: 0.8;
}
.cn-button--primary {
    background: var(--primary);
    color: var(--text-inverse);
    box-shadow: var(--shadow-md);
}
.cn-button--primary:hover:not(:disabled) { background: var(--primary-hover); }
.cn-button--primary:active:not(:disabled) { background: var(--primary-active); }
.cn-button--secondary {
    background: var(--secondary);
    color: var(--text-inverse);
    box-shadow: var(--shadow-md);
}
.cn-button--secondary:hover:not(:disabled) { background: var(--secondary-hover); }
.cn-button--secondary:active:not(:disabled) { background: var(--secondary-active); }
.cn-button--destructive {
    background: var(--error);
    color: var(--text-inverse);
    box-shadow: var(--shadow-md);
}
.cn-button--destructive:hover:not(:disabled) { background: color-mix(in srgb, var(--error) 90%, black); }
.cn-button--destructive:active:not(:disabled) { background: color-mix(in srgb, var(--error) 85%, black); }
.cn-button--outline {
    background: transparent;
    color: var(--text-primary);
    border: 1px solid var(--border);
    box-shadow: var(--shadow-sm);
}
.cn-button--ghost {
    background: transparent;
    color: var(--text-primary);
}
.cn-button--outline:hover:not(:disabled), .cn-button--ghost:hover:not(:disabled) {
    background: color-mix(in srgb, var(--text-primary) 5%, transparent);
}
.cn-button--outline:active:not(:disabled), .cn-button--ghost:active:not(:disabled) {
    background: color-mix(in srgb, var(--text-primary) 10%, transparent);
}
.cn-button--link {
    background: transparent;
    color: var(--primary);
}
/* Disabled: a filled tonal surface with muted text, a thin outline and no
   shadow. Opacity dimming on a saturated fill washed out to a pale tint, so
   the fill is swapped instead. The hover and press rules leave a disabled
   button alone. */
.cn-button:disabled {
    background: var(--input-bg-disabled);
    color: var(--text-tertiary);
    border: 1px solid var(--border-secondary);
    box-shadow: none;
    transform: none;
}
.cn-button--sm { border-radius: var(--radius-sm); }
.cn-button--md { border-radius: var(--radius-default); }
.cn-button--lg { border-radius: var(--radius-lg); }
.cn-button--icon { border-radius: var(--radius-default); }

/* ============================================================================
   Card
   ============================================================================ */

.cn-card {
    background: var(--cn-card-bg, var(--surface));
    border: 1px solid var(--cn-card-border, var(--border));
    border-radius: var(--cn-card-radius, var(--radius-xl));
    padding: var(--space-6);
    gap: var(--space-4);
}

.cn-card-header {
    gap: var(--space-1-5);
}

.cn-card-footer {
    gap: var(--space-2);
}
.cn-card-title { color: var(--text-primary); }
.cn-card-description { color: var(--text-secondary); }

/* ============================================================================
   Badge
   ============================================================================ */

.cn-badge {
    border-radius: var(--radius-full);
    font-size: var(--text-xs);
    /* `2 10` doesn't have an exact spacing token (space-0-5 = 2,
       space-2-5 = 10) — use the closest matching pair. */
    padding: var(--space-0-5) var(--space-2-5);
}

/* Soft (default) — pale tinted bg + 1px same-hue border + same-hue
   text. The thin colored border gives the pill more definition
   against neutral surfaces; without it the soft fill alone reads
   as a weak smudge on light themes. Mirrors the Alert component's
   family so a `Success` badge sits next to a `Success` alert and
   reads as part of the same status system. */
.cn-badge--soft-default {
    background: var(--accent-subtle);
    border: 1px solid var(--primary);
    color: var(--primary);
}
.cn-badge--soft-secondary {
    background: var(--surface-elevated);
    border: 1px solid var(--border);
    color: var(--text-secondary);
}
.cn-badge--soft-success {
    background: var(--success-bg);
    border: 1px solid var(--success);
    color: var(--success);
}
.cn-badge--soft-warning {
    background: var(--warning-bg);
    border: 1px solid var(--warning);
    color: var(--warning);
}
.cn-badge--soft-destructive {
    background: var(--error-bg);
    border: 1px solid var(--error);
    color: var(--error);
}

/* Solid — legacy filled style. Useful when the badge sits on a
   page-tinted surface and a soft variant would disappear. */
.cn-badge--solid-default {
    background: var(--primary);
    color: var(--text-inverse);
}
.cn-badge--solid-secondary {
    background: var(--secondary);
    color: var(--text-inverse);
}
.cn-badge--solid-success {
    background: var(--success);
    color: var(--text-inverse);
}
.cn-badge--solid-warning {
    background: var(--warning);
    color: var(--text-inverse);
}
.cn-badge--solid-destructive {
    background: var(--error);
    color: var(--text-inverse);
}

/* Outline — transparent + variant-coloured border + variant-
   coloured text. Quietest of the three when used in a dense set. */
.cn-badge--outline-default {
    background: transparent;
    border: 1px solid var(--primary);
    color: var(--primary);
}
.cn-badge--outline-secondary {
    background: transparent;
    border: 1px solid var(--border);
    color: var(--text-primary);
}
.cn-badge--outline-success {
    background: transparent;
    border: 1px solid var(--success);
    color: var(--success);
}
.cn-badge--outline-warning {
    background: transparent;
    border: 1px solid var(--warning);
    color: var(--warning);
}
.cn-badge--outline-destructive {
    background: transparent;
    border: 1px solid var(--error);
    color: var(--error);
}

/* Icon tint — target the inner SVG shape elements (`path`,
   `circle`, …) directly instead of the `<svg>` wrapper. The
   `blinc_icons` / `blinc_tabler_icons` generators emit paths with
   only the `d` attribute and rely on `stroke="currentColor"` on
   the outer `<svg>` for the tint. Blinc's CSS engine doesn't
   propagate `stroke` from `<svg>` down to child paths, so a rule
   on `svg { stroke: … }` has no effect; the path needs its own
   matching selector. Listing each SVG shape tag covers both
   line-style icons (Lucide / Tabler outline — stroke-driven) and
   filled icons (Tabler filled — fill-driven). Setting both stroke
   and fill is safe because each shape carries `fill="none"` in
   the outline sets, which the per-shape CSS rule overrides only
   for shapes that actually fill.
   Inline `.color(...)` on the icon element wins via specificity
   for one-off overrides. */
.cn-badge--soft-default :is(path, circle, rect, ellipse, line, polygon, polyline, g),
.cn-badge--outline-default :is(path, circle, rect, ellipse, line, polygon, polyline, g) {
    stroke: var(--primary);
}
.cn-badge--soft-secondary :is(path, circle, rect, ellipse, line, polygon, polyline, g),
.cn-badge--outline-secondary :is(path, circle, rect, ellipse, line, polygon, polyline, g) {
    stroke: var(--text-secondary);
}
.cn-badge--soft-success :is(path, circle, rect, ellipse, line, polygon, polyline, g),
.cn-badge--outline-success :is(path, circle, rect, ellipse, line, polygon, polyline, g) {
    stroke: var(--success);
}
.cn-badge--soft-warning :is(path, circle, rect, ellipse, line, polygon, polyline, g),
.cn-badge--outline-warning :is(path, circle, rect, ellipse, line, polygon, polyline, g) {
    stroke: var(--warning);
}
.cn-badge--soft-destructive :is(path, circle, rect, ellipse, line, polygon, polyline, g),
.cn-badge--outline-destructive :is(path, circle, rect, ellipse, line, polygon, polyline, g) {
    stroke: var(--error);
}
.cn-badge--solid-default :is(path, circle, rect, ellipse, line, polygon, polyline, g),
.cn-badge--solid-secondary :is(path, circle, rect, ellipse, line, polygon, polyline, g),
.cn-badge--solid-success :is(path, circle, rect, ellipse, line, polygon, polyline, g),
.cn-badge--solid-warning :is(path, circle, rect, ellipse, line, polygon, polyline, g),
.cn-badge--solid-destructive :is(path, circle, rect, ellipse, line, polygon, polyline, g) {
    stroke: var(--text-inverse);
}

/* ============================================================================
   Alert
   ============================================================================ */

.cn-alert {
    background: var(--cn-alert-bg, var(--surface));
    border: 1px solid var(--cn-alert-border, var(--border));
    border-radius: var(--radius-default);
    color: var(--text-primary);
    font-size: var(--text-sm);
    padding: var(--space-4);
}
.cn-alert-box {
    background: var(--cn-alert-bg, var(--surface));
    border: 1px solid var(--cn-alert-border, var(--border));
    border-radius: var(--radius-default);
    color: var(--text-primary);
    font-size: var(--text-sm);
    padding: var(--space-4);
    gap: var(--space-3);
}
.cn-alert--success {
    background: var(--success-bg);
    border-color: var(--success);
    color: var(--success);
}
.cn-alert--warning {
    background: var(--warning-bg);
    border-color: var(--warning);
    color: var(--warning);
}
.cn-alert--error {
    background: var(--error-bg);
    border-color: var(--error);
    color: var(--error);
}
.cn-alert--info {
    background: var(--info-bg);
    border-color: var(--info);
    color: var(--info);
}

/* ============================================================================
   Separator
   ============================================================================ */

.cn-separator {
    background: var(--cn-separator-color, var(--border));
}

/* ============================================================================
   Skeleton
   ============================================================================ */

/* A placeholder that pulses while content loads. */
.cn-skeleton {
    background: var(--cn-skeleton-bg, var(--surface-elevated));
    border-radius: var(--radius-sm);
    animation: cn-skeleton-pulse 1500ms var(--ease-in-out) infinite;
}
.cn-skeleton--circle { border-radius: var(--radius-full); }
@keyframes cn-skeleton-pulse {
    from { opacity: 1; }
    50%  { opacity: 0.4; }
    to   { opacity: 1; }
}

/* ============================================================================
   Input
   ============================================================================ */

/* The message under a field: an error, or a description. */
.cn-field-error { color: var(--error); }
.cn-field-description { color: var(--text-tertiary); }

.cn-input {
    box-shadow: var(--shadow-sm);
    background: var(--cn-input-bg, var(--input-bg));
    border-color: var(--border);
    border-radius: var(--radius-default);
    color: var(--text-primary);
    /* Idle ring: same width, transparent, gap of 1 px so the focus
       transition "scales" the gap from 1 → 2 px while the colour fades
       in. Without a base outline the transition has no starting point
       and the ring pops in. */
    outline: 2px solid transparent;
    outline-offset: 1px;
    transition:
        background-color var(--duration-fast) var(--ease-state),
        border-color var(--duration-fast) var(--ease-state),
        outline-color var(--duration-fast) var(--ease-state),
        outline-offset var(--duration-fast) var(--ease-out);
}
/* The border and fill per state are the layout input's `.blinc-input`
   rules, which these sit beside at the same specificity. */
.cn-input:focus:not(:disabled) {
    /* HID focus affordance: the border brightens AND a 2px outer ring is
       drawn 2px out from the input edge. The ring uses the fainter
       `--focus-ring` (alpha-tinted variant token) so the crisp border edge
       stays distinguishable from the soft halo. */
    outline: 2px solid var(--focus-ring);
    outline-offset: 2px;
}
.cn-input:disabled,
.cn-textarea:disabled,
.cn-input-otp-slot:disabled {
    box-shadow: none;
}
.cn-input[data-invalid]:not(:disabled),
.cn-input[data-invalid]:hover:not(:disabled),
.cn-input[data-invalid]:focus:not(:disabled) {
    border-color: var(--border-error);
}
.cn-input[data-invalid]:focus:not(:disabled) {
    outline: 2px solid var(--focus-ring-error);
}
.cn-input.cn-input--success:not(:disabled),
.cn-input.cn-input--success:hover:not(:disabled),
.cn-input.cn-input--success:focus:not(:disabled) {
    border-color: var(--success);
}
.cn-input.cn-input--success:focus:not(:disabled) {
    outline: 2px solid var(--focus-ring-success);
}

.cn-input--sm { font-size: var(--text-xs); }
.cn-input--md { font-size: var(--text-sm); }
.cn-input--lg { font-size: var(--text-lg); }

/* Input OTP. The slot is a layout input; the border and fill per state are
   its `.blinc-input` rules. */

.cn-input-otp-slot {
    box-shadow: var(--shadow-sm);
    background: var(--cn-input-bg, var(--input-bg));
    border-color: var(--border);
    border-radius: var(--radius-md);
    color: var(--text-primary);
    outline: 2px solid transparent;
    outline-offset: 1px;
    transition:
        background-color var(--duration-fast) var(--ease-state),
        border-color var(--duration-fast) var(--ease-state),
        outline-color var(--duration-fast) var(--ease-state),
        outline-offset var(--duration-fast) var(--ease-out);
}
.cn-input-otp-slot:focus:not(:disabled) {
    /* HID focus ring — see `.cn-input:focus` for rationale. */
    outline: 2px solid var(--focus-ring);
    outline-offset: 2px;
}
.cn-input-otp-slot.cn-input-otp-slot--error:not(:disabled),
.cn-input-otp-slot.cn-input-otp-slot--error:hover:not(:disabled),
.cn-input-otp-slot.cn-input-otp-slot--error:focus:not(:disabled) {
    border-color: var(--border-error);
}
.cn-input-otp-slot.cn-input-otp-slot--error:focus:not(:disabled) {
    outline: 2px solid var(--focus-ring-error);
}
/* The combobox's search field sits on the dropdown's surface and shows the
   focus border while hovered as well as focused. */
.cn-combobox-search {
    background: var(--surface);
    border-color: var(--border);
}
.cn-combobox-search:hover:not(:disabled),
.cn-combobox-search:focus:not(:disabled) {
    background: var(--surface);
    border-color: var(--border-focus);
}
.cn-input-otp--disabled {
    opacity: 0.5;
}

/* ============================================================================
   Textarea
   ============================================================================ */

.cn-textarea {
    box-shadow: var(--shadow-sm);
    background: var(--cn-textarea-bg, var(--input-bg));
    border-color: var(--border);
    border-radius: var(--radius-default);
    color: var(--text-primary);
    outline: 2px solid transparent;
    outline-offset: 1px;
    transition:
        background-color var(--duration-fast) var(--ease-state),
        border-color var(--duration-fast) var(--ease-state),
        outline-color var(--duration-fast) var(--ease-state),
        outline-offset var(--duration-fast) var(--ease-out);
}
/* The border and fill per state are the layout input's `.blinc-input`
   rules, which these sit beside at the same specificity. */
.cn-textarea:focus:not(:disabled) {
    /* HID focus ring — see `.cn-input:focus` for rationale. */
    outline: 2px solid var(--focus-ring);
    outline-offset: 2px;
}
.cn-textarea[data-invalid]:not(:disabled),
.cn-textarea[data-invalid]:hover:not(:disabled),
.cn-textarea[data-invalid]:focus:not(:disabled) {
    border-color: var(--border-error);
}
.cn-textarea[data-invalid]:focus:not(:disabled) {
    outline: 2px solid var(--focus-ring-error);
}
.cn-textarea.cn-textarea--success:not(:disabled),
.cn-textarea.cn-textarea--success:hover:not(:disabled),
.cn-textarea.cn-textarea--success:focus:not(:disabled) {
    border-color: var(--success);
}
.cn-textarea.cn-textarea--success:focus:not(:disabled) {
    outline: 2px solid var(--focus-ring-success);
}

/* Number input: a number between a - and a +, one bordered
   piece. The steps are transparent and tint on hover and press; the field is
   borderless and clear (set in Rust, so the input rules give way to it). */
.cn-number-input-group {
    box-shadow: var(--shadow-sm);
    background: var(--input-bg);
    border-color: var(--border);
}
.cn-number-input-group:disabled {
    background: var(--input-bg-disabled);
    box-shadow: none;
}
.cn-number-input-step {
    background: transparent;
    color: var(--text-secondary);
    transition:
        background-color var(--duration-fast) var(--ease-state),
        color var(--duration-fast) var(--ease-state);
}
.cn-number-input-step--dec { border-right: 1px solid var(--border); }
.cn-number-input-step--inc { border-left: 1px solid var(--border); }
.cn-number-input-step:hover:not(:disabled) {
    background: color-mix(in srgb, var(--text-primary) 6%, transparent);
    color: var(--text-primary);
}
.cn-number-input-step:active:not(:disabled) {
    background: color-mix(in srgb, var(--text-primary) 10%, transparent);
}
.cn-number-input-step:disabled { color: var(--text-tertiary); }

/* Number gauge: a number over a range as a fill tinted from
   the primary, the value centred on it and a six-dot grip at the fill's edge.
   The grip deepens while the gauge is hovered, pressed, dragged or keyed. */
.cn-number-gauge {
    border-color: var(--border);
    background: var(--input-bg);
    color: var(--text-primary);
    cursor: ew-resize;
    outline: 2px solid transparent;
    outline-offset: 2px;
    transition: border-color var(--duration-fast) var(--ease-state);
}
.cn-number-gauge--sm { border-radius: var(--radius-sm); }
.cn-number-gauge--md, .cn-number-gauge--lg { border-radius: var(--radius-default); }
.cn-number-gauge:hover:not(:disabled) { border-color: var(--border-hover); }
.cn-number-gauge[data-focus-visible] { outline-color: var(--focus-ring); }
.cn-number-gauge-fill { background: color-mix(in srgb, var(--primary) 22%, var(--input-bg)); }
.cn-number-gauge-rest { background: transparent; }
.cn-number-gauge-thumb {
    background: color-mix(in srgb, var(--primary) 30%, var(--input-bg));
    color: var(--primary);
    transition: background-color var(--duration-fast) var(--ease-state);
}
.cn-number-gauge:hover:not(:disabled) > .cn-number-gauge-thumb,
.cn-number-gauge:active:not(:disabled) > .cn-number-gauge-thumb,
.cn-number-gauge[data-state="dragging"] > .cn-number-gauge-thumb,
.cn-number-gauge[data-focus-visible] > .cn-number-gauge-thumb {
    background: color-mix(in srgb, var(--primary) 44%, var(--input-bg));
}
.cn-number-gauge:disabled { color: var(--text-tertiary); cursor: default; }
.cn-number-gauge:disabled > .cn-number-gauge-fill { background: var(--input-bg-disabled); }
.cn-number-gauge:disabled > .cn-number-gauge-thumb {
    background: var(--border-secondary);
    color: var(--text-tertiary);
}
/* A range gauge stacks two faces: the upper paints the interval, the lower
   covers what lies before its grip with the track. */
.cn-number-gauge-layer[data-endpoint="lower"] > .cn-number-gauge-fill { background: var(--input-bg); }
.cn-number-gauge:hover:not(:disabled) > .cn-number-gauge-layer > .cn-number-gauge-thumb,
.cn-number-gauge:active:not(:disabled) > .cn-number-gauge-layer > .cn-number-gauge-thumb,
.cn-number-gauge[data-state="dragging"] > .cn-number-gauge-layer > .cn-number-gauge-thumb,
.cn-number-gauge[data-focus-visible] > .cn-number-gauge-layer > .cn-number-gauge-thumb {
    background: color-mix(in srgb, var(--primary) 44%, var(--input-bg));
}
.cn-number-gauge:disabled > .cn-number-gauge-layer > .cn-number-gauge-fill { background: var(--input-bg-disabled); }
.cn-number-gauge:disabled > .cn-number-gauge-layer > .cn-number-gauge-thumb {
    background: var(--border-secondary);
    color: var(--text-tertiary);
}

/* ============================================================================
   Label
   ============================================================================ */

.cn-label {
    color: var(--cn-label-color, var(--text-primary));
}
.cn-label-text { color: var(--cn-label-color, var(--text-primary)); }
.cn-label:disabled > .cn-label-text { color: var(--text-tertiary); }
.cn-label-required { color: var(--error); }

/* ============================================================================
   Kbd
   ============================================================================ */

.cn-kbd {
    background: var(--cn-kbd-bg, var(--surface));
    border: 1px solid var(--cn-kbd-border, var(--border));
    border-bottom-width: 3px;
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-sm);
    color: var(--text-secondary);
}

/* ============================================================================
   Checkbox
   ============================================================================ */

/* The look is the layout checkbox's `.blinc-checkbox` rules. These are cn's
   hooks on top of them: the custom properties a theme can set, and the
   disabled class. */
.cn-checkbox:checked {
    background: var(--cn-checkbox-checked-bg, var(--primary)) !important;
    border-color: var(--cn-checkbox-checked-border, var(--primary)) !important;
    color: var(--cn-checkbox-checked-color, var(--text-inverse)) !important;
}

.cn-checkbox:checked:disabled {
    background: var(--input-bg-disabled) !important;
    border-color: var(--border-secondary) !important;
}

/* ============================================================================
   Switch
   ============================================================================ */

/* The track is the element; its fill follows hover, `checked` and disabled,
   and the thumb slides by a transform per size (track - thumb - 4px). */
.cn-switch {
    background: var(--border-secondary);
    border-radius: var(--radius-full);
    cursor: pointer;
    transition: background-color var(--duration-normal) var(--ease-state);
}
/* A wash of the text colour over the idle track, so hovering moves it the same
   way in either scheme (`--border-hover` is translucent and reads darker than
   this solid track on a dark theme). */
.cn-switch:hover:not(:disabled) {
    background: color-mix(in srgb, var(--text-primary) 10%, var(--border-secondary));
}
.cn-switch:checked { background: var(--primary) !important; }
.cn-switch:checked:hover:not(:disabled) { background: var(--primary-hover) !important; }
/* A disabled track takes the disabled-button palette, with a thin outline so
   it keeps a silhouette. */
.cn-switch:disabled {
    background: var(--input-bg-disabled);
    border: 1px solid var(--border-secondary);
    opacity: 0.5;
    cursor: not-allowed;
}
.cn-switch:checked:disabled { background: var(--input-bg-disabled) !important; }
.cn-switch:checked > .cn-switch-thumb { background: var(--cn-switch-checked-thumb, var(--text-inverse)) !important; }
.cn-switch-thumb {
    background: var(--text-inverse);
    border-radius: var(--radius-full);
    box-shadow: var(--shadow-sm);
    transition: transform var(--duration-normal) var(--ease-state);
}
.cn-switch:disabled > .cn-switch-thumb {
    box-shadow: none;
    border: 1px solid var(--border-secondary);
}
.cn-switch--sm:checked > .cn-switch-thumb { transform: translateX(14px); }
.cn-switch--md:checked > .cn-switch-thumb { transform: translateX(20px); }
.cn-switch--lg:checked > .cn-switch-thumb { transform: translateX(24px); }
.cn-switch:active:not(:disabled) > .cn-switch-thumb { transform: scale(0.9); }
.cn-switch--sm:checked:active:not(:disabled) > .cn-switch-thumb { transform: translateX(14px) scale(0.9); }
.cn-switch--md:checked:active:not(:disabled) > .cn-switch-thumb { transform: translateX(20px) scale(0.9); }
.cn-switch--lg:checked:active:not(:disabled) > .cn-switch-thumb { transform: translateX(24px) scale(0.9); }
.cn-switch-label { color: var(--text-primary); }
.cn-switch-row:disabled > .cn-switch-label { color: var(--text-tertiary); }

/* ============================================================================
   Toggle (binary on/off button — shadcn `<Toggle>`)
   ============================================================================ */

/* The look is the layout toggle's `.blinc-toggle` rules (fill by state, the
   outline variant, the size ladder), selected by `data-state`, `data-variant`
   and `data-size`. `.cn-toggle` and its variant and size classes are hooks for
   an app's own rules. */

.cn-toggle[data-state="on"] {
    background: var(--cn-toggle-selected-bg, color-mix(in srgb, var(--text-primary) 10%, var(--background))) !important;
    color: var(--cn-toggle-selected-color, var(--text-primary)) !important;
}
.cn-toggle[data-state="on"]:hover:not(:disabled) {
    background: var(--cn-toggle-selected-hover-bg, color-mix(in srgb, var(--text-primary) 14%, var(--background))) !important;
}

/* ============================================================================
   Radio
   ============================================================================ */

/* The look is the layout radio's `.blinc-radio` rules. These are cn's hooks on
   top of them: the custom properties a theme can set. */
.cn-radio { border-color: var(--cn-radio-border, var(--border-secondary)); }
.cn-radio:hover:not(:disabled) { border-color: var(--cn-radio-hover-border, var(--primary)); }
.cn-radio:checked { border-color: var(--cn-radio-selected, var(--primary)) !important; }
.cn-radio:checked:disabled { border-color: var(--border-secondary) !important; }
.cn-radio:checked > .cn-radio-dot { background: var(--cn-radio-dot, var(--primary)) !important; }
.cn-radio-dot { background: var(--cn-radio-dot, var(--primary)); }

/* ============================================================================
   Tabs
   ============================================================================ */

.cn-tabs-list {
    /* Tonal tray for the trigger row — uses surface-overlay so the
       active trigger (raised to --surface) reads as elevated. */
    background: var(--cn-tabs-list-bg, var(--surface-overlay));
    border-radius: var(--radius-md);
    padding: var(--space-1);
    gap: var(--space-1);
}
.cn-tabs-trigger {
    border-radius: var(--radius-default);
    cursor: pointer;
    color: var(--text-secondary);
    transition: color var(--duration-fast) var(--ease-state);
}
.cn-tabs-trigger:hover:not(.cn-tabs-trigger--active) {
    color: var(--text-primary);
}
.cn-tabs-trigger--active {
    color: var(--text-primary) !important;
    font-weight: 500;
}
/* The pill behind the active trigger, raised to --surface over the
   --surface-overlay tray. It slides to the next trigger on a switch. */
.cn-tabs-indicator {
    background: var(--cn-tabs-active-bg, var(--surface)) !important;
    border-radius: var(--radius-default);
    box-shadow: var(--shadow-sm);
}
.cn-tabs-trigger--disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* A panel enters and leaves by its `data-transition`: it fades, or slides a
   little from a side as it fades. `slide` goes the way the active tab moved,
   by `data-direction`: to a tab further along, the new panel comes from the
   right and the old one leaves to the left. */
@keyframes cn-tab-from-left {
    from { opacity: 0; transform: translateX(-20px); }
    to { opacity: 1; transform: translateX(0); }
}
@keyframes cn-tab-to-left {
    from { opacity: 1; transform: translateX(0); }
    to { opacity: 0; transform: translateX(-20px); }
}
@keyframes cn-tab-from-right {
    from { opacity: 0; transform: translateX(20px); }
    to { opacity: 1; transform: translateX(0); }
}
@keyframes cn-tab-to-right {
    from { opacity: 1; transform: translateX(0); }
    to { opacity: 0; transform: translateX(20px); }
}
@keyframes cn-tab-from-top {
    from { opacity: 0; transform: translateY(-20px); }
    to { opacity: 1; transform: translateY(0); }
}
@keyframes cn-tab-to-top {
    from { opacity: 1; transform: translateY(0); }
    to { opacity: 0; transform: translateY(-20px); }
}
@keyframes cn-tab-from-bottom {
    from { opacity: 0; transform: translateY(20px); }
    to { opacity: 1; transform: translateY(0); }
}
@keyframes cn-tab-to-bottom {
    from { opacity: 1; transform: translateY(0); }
    to { opacity: 0; transform: translateY(20px); }
}
.cn-tabs-panel[data-transition="fade"][data-motion="enter"] { animation: cn-fade-in var(--duration-normal) var(--ease-out); }
.cn-tabs-panel[data-transition="fade"][data-motion="exit"] { animation: cn-fade-out var(--duration-fast) var(--ease-in) forwards; }
.cn-tabs-panel[data-transition="slide"][data-direction="next"][data-motion="enter"] { animation: cn-tab-from-right var(--duration-normal) var(--ease-out); }
.cn-tabs-panel[data-transition="slide"][data-direction="next"][data-motion="exit"] { animation: cn-tab-to-left var(--duration-fast) var(--ease-in) forwards; }
.cn-tabs-panel[data-transition="slide"][data-direction="prev"][data-motion="enter"] { animation: cn-tab-from-left var(--duration-normal) var(--ease-out); }
.cn-tabs-panel[data-transition="slide"][data-direction="prev"][data-motion="exit"] { animation: cn-tab-to-right var(--duration-fast) var(--ease-in) forwards; }
.cn-tabs-panel[data-transition="slide-left"][data-motion="enter"] { animation: cn-tab-from-left var(--duration-normal) var(--ease-out); }
.cn-tabs-panel[data-transition="slide-left"][data-motion="exit"] { animation: cn-tab-to-left var(--duration-fast) var(--ease-in) forwards; }
.cn-tabs-panel[data-transition="slide-right"][data-motion="enter"] { animation: cn-tab-from-right var(--duration-normal) var(--ease-out); }
.cn-tabs-panel[data-transition="slide-right"][data-motion="exit"] { animation: cn-tab-to-right var(--duration-fast) var(--ease-in) forwards; }
.cn-tabs-panel[data-transition="slide-up"][data-motion="enter"] { animation: cn-tab-from-top var(--duration-normal) var(--ease-out); }
.cn-tabs-panel[data-transition="slide-up"][data-motion="exit"] { animation: cn-tab-to-top var(--duration-fast) var(--ease-in) forwards; }
.cn-tabs-panel[data-transition="slide-down"][data-motion="enter"] { animation: cn-tab-from-bottom var(--duration-normal) var(--ease-out); }
.cn-tabs-panel[data-transition="slide-down"][data-motion="exit"] { animation: cn-tab-to-bottom var(--duration-fast) var(--ease-in) forwards; }

/* A panel leaving after a switch overlays the new one instead of sitting
   above it, so the content does not jump while it fades out. */
.cn-tabs-panel--leaving {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
}

/* Tab trigger sizes — content + padding determines height (no fixed
   heights). Vertical padding kept tight to keep the tray compact. */
.cn-tabs-trigger--sm { padding: var(--space-1) var(--space-3); font-size: var(--text-sm); }
.cn-tabs-trigger--md { padding: var(--space-1-5) var(--space-4); font-size: var(--text-sm); }
.cn-tabs-trigger--lg { padding: var(--space-2) var(--space-5); font-size: var(--text-lg); }

/* ============================================================================
   Select
   ============================================================================ */

/* The caret of a trigger turns half a turn while its list is open, eased by a
   transition so it spins rather than flips. */
.cn-chevron {
    transition: transform var(--duration-normal) var(--ease-state);
}
.cn-select-trigger[data-state="open"] > .cn-chevron,
.cn-combobox-trigger[data-state="open"] > .cn-chevron,
.cn-dropdown-trigger[data-state="open"] > .cn-chevron,
.cn-collapsible-trigger[data-state="open"] > .cn-chevron,
.cn-accordion-trigger[data-state="open"] > .cn-chevron {
    transform: rotate(180deg);
}

.cn-select-trigger {
    color: var(--text-primary);
    background: transparent;
    box-shadow: var(--shadow-sm);
    border-color: var(--border);
    border-radius: var(--radius-default);
    cursor: pointer;
    transition:
        background-color var(--duration-fast) var(--ease-state),
        border-color var(--duration-fast) var(--ease-state);
}
/* Hover and press tint as the outline button's do; the border darkens while
   the list is open. */
.cn-select-trigger:hover:not(:disabled) {
    background: color-mix(in srgb, var(--text-primary) 5%, transparent);
}
.cn-select-trigger:active:not(:disabled) {
    background: color-mix(in srgb, var(--text-primary) 10%, transparent);
}
.cn-select-trigger[data-state="open"]:not(:disabled) {
    border-color: var(--border-hover);
}
.cn-combobox-box:disabled { opacity: 0.5; }
/* No value chosen, or disabled: the shown text, which inherits, dims. */
.cn-select-trigger[data-placeholder] { color: var(--text-tertiary); }
.cn-select-trigger:disabled {
    color: var(--text-tertiary);
    box-shadow: none;
    background: var(--input-bg-disabled);
    border-color: var(--border-secondary);
    cursor: not-allowed;
}

.cn-select-content {
    /* Floating dropdown panel → elevation 2.
       Shared overlay-menu chrome — keep `.cn-dropdown-menu`,
       `.cn-context-menu`, and `.cn-combobox-content` in sync.
       No outer padding: items extend edge-to-edge and the rounded
       overflow_clip on the panel (see `ClipShape::rounded_rect_shaped`)
       trims their hover bg to the panel's outer curve, so the
       highlight follows the rounded corner instead of leaving a
       gap between the item's small radius and the panel's larger
       one. */
    background: var(--surface-elevated);
    border: 1px solid var(--border);
    border-radius: var(--radius-default);
    /* Reuse the dropdown keyframes — same top-anchored slide/fade. */
    animation: cn-dropdown-menu-enter var(--duration-fast) var(--ease-state);
    transform-origin: top center;
    color: var(--text-primary);
    box-shadow: var(--shadow-md);
}

.cn-select-item {
    padding: var(--space-2) var(--space-3);
    cursor: pointer;
    color: var(--text-primary);
    /* No `border-radius` — item bg is a clean rectangle so the
       panel's rounded clip can shape the first/last items into the
       outer curve. A small radius here would leave a visible band
       between the item's curve and the panel's curve. */
    /* No CSS `transition` here — same rationale as cn-menubar-item:
       when the cursor slides across rows quickly the bg transition
       leaves multiple rows partially highlighted (each at a different
       point in the fade-out) and reads as a stuck-hover bug. Instant
       on/off matches the HID. */
}
/* Item hover uses `--accent-subtle` because the parent panel is
   already at `--surface-elevated`; hovering to the same colour
   would be invisible. `--accent-subtle` is a low-alpha accent
   tint specifically designed for this use. */
.cn-select-item:hover:not(:disabled) {
    background: var(--accent-subtle);
}
/* `--selection` (~24 % alpha accent on Hybrid, 20 % on macOS) vs hover's
   `--accent-subtle` (~10 % alpha) so the currently-chosen row is
   visibly distinct from hovered rows and from the panel itself. */
.cn-select-item--selected {
    background: var(--selection) !important;
    color: var(--accent) !important;
}
.cn-select-item--selected:disabled {
    color: var(--text-tertiary) !important;
    background: transparent !important;
}
.cn-select-item:disabled {
    color: var(--text-tertiary);
    background: transparent;
    cursor: not-allowed;
}
.cn-select-trigger > .cn-chevron { color: var(--text-tertiary); }
.cn-dropdown-trigger > .cn-chevron { color: var(--text-secondary); }

/* ============================================================================
   Slider
   ============================================================================ */

/* A fill, the thumb and the rest of the track in a row. The thumb grows
   under the pointer and more while held; a disabled slider mutes every part
   instead of fading. */
.cn-slider {
    border-radius: var(--radius-full);
    cursor: pointer;
    outline: 2px solid transparent;
    outline-offset: 2px;
}
.cn-slider[data-focus-visible] { outline-color: var(--focus-ring); }
.cn-slider-fill {
    background: var(--cn-slider-fill-bg, var(--primary));
    border-radius: var(--radius-full) 0 0 var(--radius-full);
}
.cn-slider-rest {
    background: var(--cn-slider-track-bg, var(--border));
    border-radius: 0 var(--radius-full) var(--radius-full) 0;
}
.cn-slider-thumb {
    background: var(--cn-slider-thumb-bg, var(--text-inverse));
    border: 2px solid var(--primary);
    border-radius: var(--radius-full);
    box-shadow: var(--shadow-sm);
    transition: transform var(--duration-fast) var(--ease-state),
        border-color var(--duration-fast) var(--ease-state);
}
.cn-slider:hover:not(:disabled) > .cn-slider-thumb {
    transform: scale(1.1);
    box-shadow: var(--shadow-md);
    border-color: var(--primary-hover);
}
.cn-slider:active:not(:disabled) > .cn-slider-thumb,
.cn-slider[data-state="dragging"] > .cn-slider-thumb {
    transform: scale(1.2);
}
.cn-slider:disabled { cursor: not-allowed; }
.cn-slider:disabled > .cn-slider-rest { background: var(--input-bg-disabled); }
.cn-slider:disabled > .cn-slider-fill { background: var(--border-secondary); }
.cn-slider:disabled > .cn-slider-thumb {
    background: var(--input-bg-disabled);
    border: 1px solid var(--border-secondary);
    box-shadow: none;
}
.cn-slider-label { color: var(--text-primary); }
.cn-slider-value { color: var(--text-secondary); }
.cn-slider-field[data-disabled] .cn-slider-label,
.cn-slider-field[data-disabled] .cn-slider-value { color: var(--text-tertiary); }

/* ============================================================================
   Progress
   ============================================================================ */

/* A track with a bar grown to the value, easing to each new one. An
   indeterminate bar covers part of the track and pulses. */
.cn-progress {
    background: var(--cn-progress-track, var(--border));
    border-radius: var(--radius-full);
}
.cn-progress-bar {
    background: var(--cn-progress-bar, var(--primary));
    border-radius: var(--radius-full);
    transition: flex-grow var(--duration-slow) var(--ease-nav);
}
@keyframes cn-progress-pulse {
    from { opacity: 0.35; }
    to { opacity: 1; }
}
.cn-progress[data-indeterminate] > .cn-progress-bar {
    animation: cn-progress-pulse var(--duration-slowest) var(--ease-in-out) infinite alternate;
}

/* ============================================================================
   Chart
   ============================================================================ */

/* A plot drawn on a canvas, with its labels, tooltip and legend as parts. */
.cn-chart { gap: 12px; }
.cn-chart-axis { font-size: var(--text-xs); color: var(--text-tertiary); }
.cn-chart-axis[data-hidden] { opacity: 0; }
.cn-chart-legend {
    gap: 16px;
    font-size: var(--text-xs);
    color: var(--text-secondary);
}
.cn-chart-legend-item { gap: 6px; }
.cn-chart-swatch { border-radius: 3px; }
.cn-chart-c1 { background: var(--chart-1); }
.cn-chart-c2 { background: var(--chart-2); }
.cn-chart-c3 { background: var(--chart-3); }
.cn-chart-c4 { background: var(--chart-4); }
.cn-chart-c5 { background: var(--chart-5); }
.cn-chart-tooltip {
    gap: 6px;
    padding: 8px 10px;
    min-width: 128px;
    background: var(--surface-elevated);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    font-size: var(--text-xs);
}
.cn-chart-tooltip-title { font-weight: 500; color: var(--text-primary); }
.cn-chart-tooltip-row { gap: 8px; }
.cn-chart-tooltip-name { flex-grow: 1; color: var(--text-secondary); }
.cn-chart-tooltip-value { margin-left: 12px; font-weight: 500; color: var(--text-primary); }
.cn-chart-band-label { font-size: 10px; color: var(--text-secondary); }
.cn-chart-note { font-size: var(--text-xs); font-weight: 500; color: var(--text-secondary); }
.cn-chart-note[data-tone="bad"] { color: var(--error); }
.cn-chart-note[data-tone="good"] { color: var(--success); }
.cn-chart-pie-total { font-size: var(--text-2xl); font-weight: 700; color: var(--text-primary); }
.cn-chart-pie-caption { font-size: var(--text-xs); color: var(--text-secondary); }

/* ============================================================================
   Avatar
   ============================================================================ */

.cn-avatar {
    background: var(--cn-avatar-bg, var(--surface));
    color: var(--cn-avatar-fg, var(--text-primary));
    border-radius: var(--radius-full);
    overflow: hidden;
}
.cn-avatar-placeholder { color: var(--text-tertiary); }
.cn-avatar-status[data-status="online"] { background: var(--success); }
.cn-avatar-status[data-status="offline"] { background: var(--text-tertiary); }
.cn-avatar-status[data-status="away"] { background: var(--warning); }
.cn-avatar-status[data-status="busy"] { background: var(--error); }
/* Avatars in a group are ringed so they read apart where they overlap. */
.cn-avatar-group .cn-avatar { border-color: var(--border-secondary); }
.cn-avatar-group__more {
    background: var(--surface-elevated);
    border-color: var(--border-secondary);
    color: var(--text-tertiary);
}
.cn-avatar--square {
    border-radius: var(--radius-default);
}

/* ============================================================================
   Spinner
   ============================================================================ */

/* A faint track with a half-circle arc going round, a turn a second. */
.cn-spinner {
    color: var(--cn-spinner-color, var(--primary));
}
.cn-spinner__track { border-color: var(--cn-spinner-track, var(--border)); }
.cn-spinner__arc {
    border-color: var(--cn-spinner-color, var(--primary));
    animation: cn-spinner-turn 1000ms linear infinite;
}
@keyframes cn-spinner-turn {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
}

/* ============================================================================
   Tooltip
   ============================================================================ */

.cn-tooltip {
    background: var(--cn-tooltip-bg, var(--tooltip-bg));
    color: var(--cn-tooltip-text, var(--tooltip-text));
    border-radius: var(--radius-sm);
    font-size: var(--text-xs);
    padding: var(--space-1-5) var(--space-3);
    box-shadow: var(--shadow-sm);
    /* Fades in, growing out of the edge that faces its trigger. */
    animation: cn-tooltip-enter var(--duration-fast) var(--ease-out);
    transform-origin: bottom center;
}

.cn-tooltip--bottom { transform-origin: top center; }
.cn-tooltip--left { transform-origin: right center; }
.cn-tooltip--right { transform-origin: left center; }

@keyframes cn-tooltip-enter {
    from { opacity: 0; transform: scale(0.96); }
    to   { opacity: 1; transform: scale(1); }
}

/* ============================================================================
   Dialog
   ============================================================================ */

.cn-dialog {
    /* Modal → elevation 2 (lifts above surrounding cards) */
    background: var(--cn-dialog-bg, var(--surface-elevated));
    border: 1px solid var(--cn-dialog-border, var(--border));
    border-radius: var(--radius-xl);
    color: var(--text-primary);
    box-shadow: var(--cn-dialog-shadow, var(--shadow-xl));
    padding: var(--space-6);
    gap: var(--space-4);
    /* Enter/exit motion is driven by the OverlayBuilder motion_enter /
       motion_exit; no CSS keyframe here. */
}
.cn-dialog-title { color: var(--text-primary); }
.cn-dialog-description { color: var(--text-secondary); }

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

.cn-drawer {
    /* Modal overlay → elevation 2. Enter/exit motion is driven by the
       DrawerBuilder motion_enter / motion_exit. */
    background: var(--cn-drawer-bg, var(--surface-elevated));
    border: 1px solid var(--cn-drawer-border, var(--border));
}
.cn-drawer, .cn-sheet {
    color: var(--text-primary);
    box-shadow: var(--shadow-xl);
}
.cn-drawer-title, .cn-sheet-title { color: var(--text-primary); }
.cn-sheet-description { color: var(--text-secondary); }
.cn-drawer-separator, .cn-sheet-separator { background: var(--border); }
/* The close button: quiet until hovered. */
.cn-drawer-close, .cn-sheet-close {
    color: var(--text-secondary);
    border-radius: var(--radius-md);
    transition:
        background-color var(--duration-fast) var(--ease-state),
        color var(--duration-fast) var(--ease-state);
}
.cn-drawer-close:hover, .cn-sheet-close:hover {
    background: color-mix(in srgb, var(--text-primary) 8%, transparent);
    color: var(--text-primary);
}
.cn-drawer-header {
    border-bottom: 1px solid var(--border);
    padding: var(--space-4);
}
.cn-drawer-footer {
    padding: var(--space-4);
}

/* ============================================================================
   Sheet
   ============================================================================ */

.cn-sheet {
    /* Modal overlay → elevation 2. Enter/exit motion is driven by the
       SheetBuilder motion_enter / motion_exit. */
    background: var(--cn-sheet-bg, var(--surface-elevated));
    border: 1px solid var(--cn-sheet-border, var(--border));
}

/* ============================================================================
   Toast
   ============================================================================ */

/* A notification: success, warning and destructive toasts colour their
   border and icon by `data-variant`. */
.cn-toast {
    background: var(--cn-toast-bg, var(--surface));
    border: 1px solid var(--cn-toast-border, var(--border));
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    color: var(--text-primary);
}
.cn-toast[data-variant="success"] { border-color: var(--success); }
.cn-toast[data-variant="warning"] { border-color: var(--warning); }
.cn-toast[data-variant="destructive"] { border-color: var(--error); }
.cn-toast[data-variant="success"] .cn-toast-icon { color: var(--success); }
.cn-toast[data-variant="warning"] .cn-toast-icon { color: var(--warning); }
.cn-toast[data-variant="destructive"] .cn-toast-icon { color: var(--error); }
.cn-toast-title { color: var(--text-primary); }
.cn-toast-description { color: var(--text-secondary); }
.cn-toast-close {
    border-radius: var(--radius-sm);
    color: var(--text-secondary);
}
.cn-toast-close:hover { color: var(--text-primary); }

/* ============================================================================
   Accordion
   ============================================================================ */

.cn-accordion {
    /* Accordion outer is a card-tier container, not a modal —
       elevation 1 (--surface). */
    background: var(--cn-accordion-bg, var(--surface));
    border: 1.5px solid var(--cn-accordion-border, var(--border));
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-md);
}
.cn-accordion-separator { background: var(--cn-accordion-border, var(--border)); }
.cn-accordion-trigger > .cn-chevron { color: var(--text-secondary); }
.cn-accordion-trigger {
    padding: var(--space-4) var(--space-3);
    cursor: pointer;
    color: var(--text-primary);
    font-size: var(--text-sm);
}
.cn-accordion-trigger:hover {
    background: var(--surface-overlay);
}
.cn-accordion-content {
    /* Expanded content recedes to the canvas tone inside the
       elevated container. */
    background: var(--cn-accordion-content-bg, var(--background));
    border-top: 1px solid var(--border);
    color: var(--text-secondary);
    overflow: hidden;
}
/* Closed, laid out at no height and without its divider; opening and
   closing are a change of size, which the layout animation eases. */
.cn-accordion-content[data-state="closed"] { height: 0; border-top-width: 0; }

/* ============================================================================
   Breadcrumb
   ============================================================================ */

.cn-breadcrumb {
    gap: var(--space-2);
    color: var(--text-secondary);
}
.cn-breadcrumb-item { color: var(--text-secondary); }
.cn-breadcrumb-item[data-link]:hover { color: var(--text-primary); }
.cn-breadcrumb-item[aria-current="page"] {
    color: var(--text-primary);
    font-weight: 500;
}
.cn-breadcrumb-separator { color: var(--text-tertiary); }

/* ============================================================================
   Pagination
   ============================================================================ */

.cn-pagination {
    gap: var(--space-1);
}
.cn-pagination-btn {
    border: 1px solid var(--border);
    border-radius: var(--radius-default);
    cursor: pointer;
    color: var(--text-primary);
    transition: background var(--duration-fast) var(--ease-state),
        border-color var(--duration-fast) var(--ease-state);
}
.cn-pagination-btn:hover { background: var(--surface-elevated); }
/* The current page keeps its fill under the pointer; a button with nowhere
   to go keeps its dimmed look. */
.cn-pagination-btn[aria-current="page"],
.cn-pagination-btn[aria-current="page"]:hover {
    background: var(--primary);
    border-color: var(--primary);
    color: var(--text-inverse);
    cursor: default;
}
.cn-pagination-btn:disabled,
.cn-pagination-btn:disabled:hover {
    background: transparent;
    opacity: 0.5;
    cursor: not-allowed;
}
.cn-pagination-ellipsis { color: var(--text-secondary); }

/* ============================================================================
   Navigation Menu
   ============================================================================ */

.cn-nav-menu {
    gap: var(--space-1);
}
.cn-nav-link {
    padding: var(--space-2) var(--space-3);
    cursor: pointer;
    color: var(--text-secondary);
}
.cn-nav-link:hover {
    background: var(--surface-elevated);
    color: var(--text-primary);
}
.cn-nav-link--active {
    background: var(--surface-elevated) !important;
    color: var(--text-primary) !important;
}
/* The dropdown panel (`.cn-nav-menu-content`) is itself painted at
   `--surface-elevated`, so the generic `.cn-nav-link:hover` rule
   above (which sets the same fill) leaves items inside the panel
   with no visible hover affordance. Override with `--accent-subtle`
   for the descendant case — same convention combobox / select /
   dropdown-menu items use against their own surface-elevated panels. */
.cn-nav-menu-content .cn-nav-link:hover {
    background: var(--accent-subtle);
}
/* Inside the panel a link's title is primary and its description secondary. */
.cn-nav-menu-content .cn-nav-link { color: var(--text-primary); }
.cn-nav-link-description { color: var(--text-secondary); }

.cn-nav-menu-content {
    /* Floating overlay → elevation 2 */
    background: var(--surface-elevated);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    color: var(--text-primary);
    box-shadow: var(--shadow-md);
    /* CSS-driven enter — slide down + fade. Motion FSM workaround. */
    animation: cn-nav-menu-enter var(--duration-fast) var(--ease-state);
    transform-origin: top center;
}

@keyframes cn-nav-menu-enter {
    from { opacity: 0; transform: scale(0.98) translateY(-4px); }
    to   { opacity: 1; transform: scale(1) translateY(0); }
}

/* ============================================================================
   Sidebar
   ============================================================================ */

/* Collapsing eases the rail's width to its icons' and back; the content
   beside it is laid out again each frame and moves with it. What the rail
   holds stays laid out, clipped by the narrowing width: labels fade and
   group titles fold away. */
.cn-sidebar-layout { flex-direction: row; align-items: stretch; overflow: hidden; }
.cn-sidebar {
    flex-direction: column;
    flex-shrink: 0;
    gap: 2px;
    padding: 8px 0;
    overflow: hidden;
    width: var(--cn-sidebar-width, 200px);
    background: var(--cn-sidebar-bg, var(--surface));
    border-right: 1px solid var(--border);
    transition: width var(--duration-normal) var(--ease-state);
}
.cn-sidebar[data-state="collapsed"] { width: var(--cn-sidebar-collapsed-width, 41px); }
.cn-sidebar-toggle {
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text-secondary);
    cursor: pointer;
    transition: background var(--duration-fast) var(--ease-state);
}
.cn-sidebar-toggle:hover { background: var(--accent-subtle); color: var(--text-primary); }
/* Points left while the rail is open and turns right while it is collapsed. */
.cn-sidebar-chevron { transition: transform var(--duration-normal) var(--ease-state); }
.cn-sidebar[data-state="collapsed"] .cn-sidebar-chevron { transform: rotate(180deg); }
.cn-sidebar-group { flex-direction: column; gap: 2px; }
.cn-sidebar-group-label {
    flex-shrink: 0;
    height: 26px;
    padding: 8px 12px 0;
    overflow: hidden;
    color: var(--text-tertiary);
    transition: height var(--duration-normal) var(--ease-state),
        padding-top var(--duration-normal) var(--ease-state),
        opacity var(--duration-fast) var(--ease-state);
}
.cn-sidebar[data-state="collapsed"] .cn-sidebar-group-label { height: 0; padding: 0 12px; opacity: 0; }
.cn-sidebar-item {
    padding: 8px 12px;
    color: var(--text-secondary);
    background: transparent;
    cursor: pointer;
    transition: background var(--duration-fast) var(--ease-state),
        color var(--duration-fast) var(--ease-state);
}
.cn-sidebar-item:hover { background: var(--accent-subtle); color: var(--text-primary); }
.cn-sidebar-item[data-active], .cn-sidebar-item[data-active]:hover {
    background: var(--surface-elevated);
    color: var(--text-primary);
}
.cn-sidebar-item[data-active] > .cn-sidebar-icon { color: var(--primary); }
.cn-sidebar-label { transition: opacity var(--duration-fast) var(--ease-state); }
.cn-sidebar[data-state="collapsed"] .cn-sidebar-label { opacity: 0; }
.cn-sidebar-inset { flex-grow: 1; flex-direction: column; min-width: 0; }

/* ============================================================================
   Scroll Area
   ============================================================================ */

.cn-scroll-area {
    overflow: hidden;
}

/* ============================================================================
   Menus: the panel, rows, shortcuts, submenu chevrons and separators every
   cn menu is built from. The dropdown, context and menubar menus add their
   own class for their enter animation and row padding.
   ============================================================================ */

/* No padding: rows run to the rounded edge, which clips their highlight. */
.cn-menu {
    background: var(--surface-elevated);
    border: 1px solid var(--border);
    border-radius: var(--radius-default);
    color: var(--text-primary);
    box-shadow: var(--shadow-md);
}
/* No transition on rows: sweeping the pointer across them would leave several
   half-lit at once. */
.cn-menu-item {
    color: var(--text-primary);
    font-size: var(--text-sm);
    cursor: pointer;
}
/* `--accent-subtle`, since the panel already sits at `--surface-elevated`. */
.cn-menu-item:hover:not(:disabled),
.cn-menu-item:focus-visible:not(:disabled) {
    background: var(--accent-subtle);
}
.cn-menu-item:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}
.cn-menu-shortcut { color: var(--text-secondary); letter-spacing: 0.05em; }
.cn-menu-chevron { color: var(--text-tertiary); }
.cn-menu-separator { background: var(--border); margin: var(--space-1) 0; }

/* ============================================================================
   Dropdown Menu
   ============================================================================ */

.cn-dropdown-menu {
    /* CSS-driven enter — slight scale + fade. Motion FSM workaround. */
    animation: cn-dropdown-menu-enter var(--duration-fast) var(--ease-state);
    transform-origin: top center;
}

@keyframes cn-dropdown-menu-enter {
    from { opacity: 0; transform: scale(0.96) translateY(-4px); }
    to   { opacity: 1; transform: scale(1) translateY(0); }
}
.cn-dropdown-item {
    padding: var(--space-2) var(--space-3);
}
.cn-dropdown-item--destructive {
    color: var(--error);
}

/* ============================================================================
   Context Menu
   ============================================================================ */

.cn-context-menu {
    /* CSS-driven enter — small scale + fade. */
    animation: cn-context-menu-enter var(--duration-fast) var(--ease-state);
    transform-origin: top left;
}

@keyframes cn-context-menu-enter {
    from { opacity: 0; transform: scale(0.96) translateY(-2px); }
    to   { opacity: 1; transform: scale(1) translateY(0); }
}

/* Belt-and-braces marker for "parent menu should not re-enter when a
   submenu is hovered". The real fix lives in
   `RenderTree::sweep_stale_css_animations` — the parent menu's
   ActiveCssAnimation now survives the OverlayStack-driven Structural
   rebuild because the wrapper's stable id is re-minted unchanged, so
   `start_all_css_animations`' contains_key gate suppresses the
   restart. This `:has()` rule does not actively stop a running
   animation (state-style passes don't reach into css_anim_store) but
   documents the intent and would no-op a fresh start if any future
   rebuild path bypasses the sweep. */
.cn-context-menu:has(.cn-context-menu-item--has-submenu:hover) {
    background: var(--surface-elevated);
    animation: none;
}
.cn-context-menu-item {
    /* `space-1-5 / space-3` (~6×12) gives a tighter row height that
       matches `.cn-menubar-trigger`. The earlier `space-2` (8px
       vertical) left items reading taller than the surrounding
       menubar / dropdown chrome — reducing to space-1-5 lines them
       up. Horizontal padding stays at space-3 so the row chrome's
       hit area extends comfortably past the label edge. */
    padding: var(--space-1-5) var(--space-3);
}

/* ============================================================================
   Menubar
   ============================================================================ */

.cn-menubar {
    /* Elevated container → elevation 2 */
    background: var(--surface-elevated);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: var(--space-1);
    gap: var(--space-1);
}
.cn-menubar-trigger {
    padding: var(--space-1-5) var(--space-3);
    border-radius: var(--radius-sm);
    cursor: pointer;
    color: var(--text-primary);
    font-size: var(--text-sm);
    background: transparent;
}
.cn-menubar-trigger:hover {
    background: var(--surface-elevated);
}
/* Dropdown panel that opens when a menubar trigger is activated.
   Shared chrome with .cn-dropdown-menu / .cn-context-menu so the
   File / Edit / View popups read as elevation-2 floating surfaces
   instead of the pure-white `Surface` the Rust-side `.bg(...)`
   fallback was painting. */
.cn-menubar-content {
    /* Reuse the dropdown keyframes — same top-anchored slide/fade. */
    animation: cn-dropdown-menu-enter var(--duration-fast) var(--ease-state);
    transform-origin: top center;
}
/* Belt-and-braces — same as `.cn-context-menu:has(...)`. Real
   suppression now lives in `RenderTree::sweep_stale_css_animations`,
   which keeps the parent panel's ActiveCssAnimation alive across the
   submenu's OverlayStack-driven Structural rebuild so the enter
   keyframe never restarts. */
.cn-menubar-content:has(.cn-menubar-item--has-submenu:hover) {
    animation: none;
}
.cn-menubar-item {
    padding: var(--space-2) var(--space-3);
}

/* ============================================================================
   Popover
   ============================================================================ */

.cn-popover-content {
    /* Floating overlay → elevation 2 */
    background: var(--surface-elevated);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    color: var(--text-primary);
    box-shadow: var(--shadow-md);
    padding: var(--space-4);
    /* CSS-driven enter — same approach as cn-tooltip while the motion FSM
       integration with the new OverlayStack is being fixed. */
    animation: cn-popover-enter var(--duration-normal) var(--ease-spring);
    transform-origin: top center;
}

@keyframes cn-popover-enter {
    from { opacity: 0; transform: scale(0.96) translateY(-4px); }
    to   { opacity: 1; transform: scale(1) translateY(0); }
}

/* ============================================================================
   Hover Card
   ============================================================================ */

.cn-hover-card-content {
    /* Floating overlay → elevation 2 */
    background: var(--surface-elevated);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    color: var(--text-primary);
    box-shadow: var(--shadow-md);
    padding: var(--space-4);
    /* CSS-driven enter — same approach as cn-tooltip / cn-popover. */
    animation: cn-hover-card-enter var(--duration-normal) var(--ease-spring);
    transform-origin: top center;
}

@keyframes cn-hover-card-enter {
    from { opacity: 0; transform: scale(0.96) translateY(-4px); }
    to   { opacity: 1; transform: scale(1) translateY(0); }
}

/* ============================================================================
   Tree View
   ============================================================================ */

/* A closed group is at no height, the change eased by its layout animation,
   and its item's chevron turns down while open. Guides show along groups
   while the tree has `data-guides`. */
.cn-tree { font-size: var(--text-sm); }
.cn-tree-row {
    border-radius: var(--radius-md);
    color: var(--text-secondary);
    background: transparent;
    cursor: pointer;
    outline: 0 solid var(--focus-ring);
    outline-offset: -2px;
    transition: background var(--duration-fast) var(--ease-state),
        color var(--duration-fast) var(--ease-state);
}
.cn-tree-row:hover { background: var(--accent-subtle); color: var(--text-primary); }
.cn-tree-row[data-selected], .cn-tree-row[data-selected]:hover {
    background: color-mix(in srgb, var(--primary) 24%, transparent) !important;
    color: var(--text-primary) !important;
}
.cn-tree-row[data-focus-visible] { outline-width: 2px; }
.cn-tree-row[data-diff="added"] { color: var(--success); }
.cn-tree-row[data-diff="removed"] { color: var(--error); }
.cn-tree-row[data-diff="modified"] { color: var(--warning); }
.cn-tree-chevron {
    color: var(--text-tertiary);
    transition: transform var(--duration-normal) var(--ease-state);
}
.cn-tree-item[data-state="open"] > .cn-tree-row > .cn-tree-chevron { transform: rotate(90deg); }
.cn-tree-icon { color: var(--text-tertiary); }
.cn-tree-row[data-selected] > .cn-tree-icon { color: var(--primary) !important; }
.cn-tree-group { overflow: hidden; }
.cn-tree-group[data-state="closed"] { height: 0; }
.cn-tree-guide { background: transparent; }
.cn-tree[data-guides] .cn-tree-guide { background: var(--border); }

/* ============================================================================
   Overlay motion
   ============================================================================ */

/* Dialogs, sheets, drawers and toasts enter and leave by these rules. Each one's
   wrapper carries `data-motion="enter"`, then `"exit"` while it closes, and
   stays until its exit has played; the backdrop behind it, `.overlay-backdrop`,
   fades with it. A dialog rises into place; a sheet or drawer slides from
   beyond its edge by its own size. */
@keyframes cn-rise-in {
    from { opacity: 0; transform: translateY(-4px) scale(0.96); }
    to { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes cn-rise-out {
    from { opacity: 1; transform: translateY(0) scale(1); }
    to { opacity: 0; transform: translateY(-4px) scale(0.96); }
}
@keyframes cn-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes cn-fade-out { from { opacity: 1; } to { opacity: 0; } }
@keyframes cn-slide-from-right {
    from { transform: translateX(100%); }
    to { transform: translateX(0); }
}
@keyframes cn-slide-to-right {
    from { transform: translateX(0); }
    to { transform: translateX(100%); }
}
@keyframes cn-slide-from-left {
    from { transform: translateX(-100%); }
    to { transform: translateX(0); }
}
@keyframes cn-slide-to-left {
    from { transform: translateX(0); }
    to { transform: translateX(-100%); }
}
@keyframes cn-slide-from-bottom {
    from { transform: translateY(100%); }
    to { transform: translateY(0); }
}
@keyframes cn-slide-to-bottom {
    from { transform: translateY(0); }
    to { transform: translateY(100%); }
}
@keyframes cn-slide-from-top {
    from { transform: translateY(-100%); }
    to { transform: translateY(0); }
}
@keyframes cn-slide-to-top {
    from { transform: translateY(0); }
    to { transform: translateY(-100%); }
}
.cn-dialog-motion[data-motion="enter"] { animation: cn-rise-in var(--duration-normal) var(--ease-sheet); }
.cn-dialog-motion[data-motion="exit"] { animation: cn-rise-out var(--duration-fast) var(--ease-in) forwards; }
.cn-sheet-motion-right[data-motion="enter"] { animation: cn-slide-from-right var(--duration-slow) var(--ease-sheet); }
.cn-sheet-motion-right[data-motion="exit"] { animation: cn-slide-to-right var(--duration-normal) var(--ease-sheet) forwards; }
.cn-sheet-motion-left[data-motion="enter"] { animation: cn-slide-from-left var(--duration-slow) var(--ease-sheet); }
.cn-sheet-motion-left[data-motion="exit"] { animation: cn-slide-to-left var(--duration-normal) var(--ease-sheet) forwards; }
.cn-sheet-motion-bottom[data-motion="enter"] { animation: cn-slide-from-bottom var(--duration-slow) var(--ease-sheet); }
.cn-sheet-motion-bottom[data-motion="exit"] { animation: cn-slide-to-bottom var(--duration-normal) var(--ease-sheet) forwards; }
.cn-sheet-motion-top[data-motion="enter"] { animation: cn-slide-from-top var(--duration-slow) var(--ease-sheet); }
.cn-sheet-motion-top[data-motion="exit"] { animation: cn-slide-to-top var(--duration-normal) var(--ease-sheet) forwards; }
.cn-drawer-motion-right[data-motion="enter"] { animation: cn-slide-from-right var(--duration-slow) var(--ease-sheet); }
.cn-drawer-motion-right[data-motion="exit"] { animation: cn-slide-to-right var(--duration-normal) var(--ease-in) forwards; }
.cn-drawer-motion-left[data-motion="enter"] { animation: cn-slide-from-left var(--duration-slow) var(--ease-sheet); }
.cn-drawer-motion-left[data-motion="exit"] { animation: cn-slide-to-left var(--duration-normal) var(--ease-in) forwards; }
/* A toast slides in from beyond its side and back out, without fading:
   its shadow would show through its fill part-way. */
.cn-toast-motion-right[data-motion="enter"] { animation: cn-slide-from-right var(--duration-normal) var(--ease-sheet); }
.cn-toast-motion-right[data-motion="exit"] { animation: cn-slide-to-right var(--duration-fast) var(--ease-in) forwards; }
.cn-toast-motion-left[data-motion="enter"] { animation: cn-slide-from-left var(--duration-normal) var(--ease-sheet); }
.cn-toast-motion-left[data-motion="exit"] { animation: cn-slide-to-left var(--duration-fast) var(--ease-in) forwards; }
.overlay-backdrop[data-motion="enter"] { animation: cn-fade-in var(--duration-normal) var(--ease-out); }
.overlay-backdrop[data-motion="exit"] { animation: cn-fade-out var(--duration-fast) var(--ease-in) forwards; }

/* ============================================================================
   Calendar
   ============================================================================ */

/* A month and year to pick between two quiet buttons, the week's days, and
   six weeks of days in a grid of seven. */
.cn-calendar {
    flex-direction: column;
    gap: 12px;
    align-self: flex-start;
    padding: 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--text-primary);
    font-family: var(--font-sans);
}
.cn-calendar-header { flex-direction: row; align-items: center; justify-content: space-between; }
.cn-calendar-caption { flex-direction: row; align-items: center; gap: 4px; }
.cn-calendar-caption .cn-select-trigger { height: 28px; padding: 0 6px; }
.cn-calendar-caption .cn-select-item { justify-content: center; }
.cn-calendar-nav {
    width: 28px;
    height: 28px;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text-secondary);
    cursor: pointer;
    transition: background var(--duration-fast) var(--ease-state),
        color var(--duration-fast) var(--ease-state);
}
.cn-calendar-nav:hover {
    background: color-mix(in srgb, var(--text-primary) 6%, transparent);
    color: var(--text-primary);
}
.cn-calendar-nav:disabled { opacity: 0.4; cursor: default; }
.cn-calendar-body { flex-direction: column; gap: 2px; }
.cn-calendar-body:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.cn-calendar-weekdays { display: grid; grid-template-columns: repeat(7, 36px); }
/* The days, clipped a little outside them so focus rings show: a month
   turning slides the new one in from its side, pushing the old out the
   other. */
.cn-calendar-months { overflow: hidden; margin: -4px; padding: 4px; }
.cn-calendar-grid { display: grid; grid-template-columns: repeat(7, 36px); row-gap: 2px; }
.cn-calendar-grid[data-enter="next"] { animation: cn-calendar-from-next var(--duration-normal) var(--ease-nav); }
.cn-calendar-grid[data-enter="prev"] { animation: cn-calendar-from-prev var(--duration-normal) var(--ease-nav); }
.cn-calendar-grid[data-leaving="next"] { animation: cn-calendar-to-prev var(--duration-normal) var(--ease-nav) forwards; }
.cn-calendar-grid[data-leaving="prev"] { animation: cn-calendar-to-next var(--duration-normal) var(--ease-nav) forwards; }
@keyframes cn-calendar-from-next {
    from { transform: translateX(260px); opacity: 0.4; }
    to { transform: translateX(0); opacity: 1; }
}
@keyframes cn-calendar-from-prev {
    from { transform: translateX(-260px); opacity: 0.4; }
    to { transform: translateX(0); opacity: 1; }
}
@keyframes cn-calendar-to-prev {
    from { transform: translateX(0); opacity: 1; }
    to { transform: translateX(-260px); opacity: 0.4; }
}
@keyframes cn-calendar-to-next {
    from { transform: translateX(0); opacity: 1; }
    to { transform: translateX(260px); opacity: 0.4; }
}
.cn-calendar-weekday { height: 28px; align-items: center; justify-content: center; color: var(--text-secondary); }
.cn-calendar-day {
    width: 36px;
    height: 36px;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-md);
    background: transparent;
    color: var(--text-primary);
    cursor: pointer;
    outline: 0 solid var(--focus-ring);
    outline-offset: 1px;
    transition: background var(--duration-fast) var(--ease-state),
        color var(--duration-fast) var(--ease-state);
}
.cn-calendar-day:hover { background: color-mix(in srgb, var(--text-primary) 7%, transparent); }
.cn-calendar-day:active { transform: scale(0.94); }
.cn-calendar-day[data-outside] { color: var(--text-tertiary); }
.cn-calendar-day[data-today] { background: var(--accent-subtle); color: var(--accent); font-weight: 600; }
.cn-calendar-day[data-selected], .cn-calendar-day[data-selected]:hover {
    background: var(--cn-calendar-selected-bg, var(--primary)) !important;
    color: var(--cn-calendar-selected-color, var(--text-inverse)) !important;
}
.cn-calendar-day[data-focus-visible] { outline-width: 2px; }
.cn-calendar-day:disabled { opacity: 0.4; cursor: default; }
.cn-calendar-event {
    width: 4px;
    height: 4px;
    border-radius: 9999px;
    background: var(--primary);
}
.cn-calendar-event--icon { width: 8px; height: 8px; border-radius: 0; background: transparent; color: var(--primary); }
.cn-calendar-day[data-selected] .cn-calendar-event { background: var(--cn-calendar-selected-color, var(--text-inverse)) !important; }
.cn-calendar-day[data-selected] .cn-calendar-event--icon { background: transparent !important; color: var(--cn-calendar-selected-color, var(--text-inverse)) !important; }

/* ============================================================================
   Resizable
   ============================================================================ */

/* `.cn-resizable-handle` is the wide HIT AREA wrapper (thickness +
   hit padding on each side). The actual visible thin handle line
   is the Rust-side inner div whose background is theme-driven —
   `--border` at rest, `--primary` while dragging. Painting the
   wrapper background would fill the entire hit zone with that
   colour, making the handle read 2-3× wider than its actual
   visual stripe. Keep the wrapper transparent. */
.cn-resizable-handle {
    background: transparent;
}
.cn-resizable-line {
    background: var(--border);
    transition: background var(--duration-fast) var(--ease-state);
}
.cn-resizable-handle:hover > .cn-resizable-line,
.cn-resizable-handle[data-state="dragging"] > .cn-resizable-line {
    background: var(--primary);
}

/* ============================================================================
   Collapsible
   ============================================================================ */

/* Closed, the content is laid out at no height; opening and closing are a
   change of size, which the content's layout animation eases. */
.cn-collapsible-content { overflow: hidden; }
.cn-collapsible-content[data-state="closed"] { height: 0; }
.cn-collapsible-section {
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
}
.cn-collapsible-trigger {
    cursor: pointer;
    color: var(--text-primary);
    border-radius: var(--radius-md);
    transition: background-color var(--duration-fast) var(--ease-state);
}
.cn-collapsible-trigger:hover,
.cn-collapsible-trigger:active {
    background: color-mix(in srgb, var(--surface-elevated) 50%, transparent);
}
.cn-collapsible-trigger > .cn-chevron { color: var(--text-secondary); }

/* ============================================================================
   Combobox
   ============================================================================ */

/* The dropdown menu's default trigger: filled as the outline button is,
   tinted on hover and press. */
.cn-dropdown-trigger {
    color: var(--text-primary);
    background: transparent;
    border-color: var(--border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
    transition: background-color var(--duration-fast) var(--ease-state);
}
.cn-dropdown-trigger:hover {
    background: color-mix(in srgb, var(--text-primary) 5%, transparent);
}
.cn-dropdown-trigger:active {
    background: color-mix(in srgb, var(--text-primary) 10%, transparent);
}

.cn-combobox-trigger {
    color: var(--text-primary);
    background: var(--surface);
    box-shadow: var(--shadow-sm);
    border-color: var(--border);
    border-radius: var(--radius-default);
    cursor: pointer;
    transition:
        background-color var(--duration-fast) var(--ease-state),
        border-color var(--duration-fast) var(--ease-state);
}
.cn-combobox-trigger:hover:not(:disabled) { border-color: var(--border-hover); }
/* Open wins over hover; the hover variant is listed because rules with a
   pointer pseudo-class apply after plain ones. */
.cn-combobox-trigger[data-state="open"]:not(:disabled),
.cn-combobox-trigger[data-state="open"]:hover:not(:disabled) { border-color: var(--border-focus); }
/* Nothing chosen, or disabled: the shown text, which inherits, dims. */
.cn-combobox-trigger[data-placeholder] { color: var(--text-tertiary); }
.cn-combobox-trigger:disabled {
    color: var(--text-tertiary);
    box-shadow: none;
    background: var(--input-bg-disabled);
    border-color: var(--border-secondary);
    cursor: not-allowed;
}
.cn-combobox-content {
    /* Shared overlay-menu chrome with select / dropdown / context.
       No outer padding — see `.cn-select-content`. */
    background: var(--surface-elevated);
    border: 1px solid var(--border);
    border-radius: var(--radius-default);
    color: var(--text-primary);
    box-shadow: var(--shadow-md);
    /* Reuse the dropdown keyframes — same top-anchored slide/fade. */
    animation: cn-dropdown-menu-enter var(--duration-fast) var(--ease-state);
    transform-origin: top center;
}
.cn-combobox-item {
    padding: var(--space-2) var(--space-3);
    /* No `border-radius` — see `.cn-select-item`. */
    cursor: pointer;
    color: var(--text-primary);
    font-size: var(--text-sm);
    /* No transition — see cn-menubar-item rationale. */
}
/* Hover uses `--accent-subtle`. The selected state uses `--selection`,
   which carries roughly 2× the alpha (~20% vs ~10%) on most themes so
   the currently-chosen row is visibly distinct against the panel
   background even when Surface is pure white — `accent-subtle` alone
   on `Surface = #FFFFFF` (macOS light) renders as a ~5 % blue tint
   that's effectively invisible. */
.cn-combobox-item:hover:not(:disabled) {
    background: var(--accent-subtle);
}
.cn-combobox-item--selected {
    background: var(--selection) !important;
    color: var(--accent) !important;
}
.cn-combobox-item--selected:disabled {
    color: var(--text-tertiary) !important;
    background: transparent !important;
}
.cn-combobox-item:disabled {
    color: var(--text-tertiary);
    background: transparent;
    cursor: not-allowed;
}
.cn-combobox-empty { color: var(--text-tertiary); }
.cn-combobox-search-row { border-bottom: 1px solid var(--border); }
.cn-combobox-trigger > .cn-chevron { color: var(--text-tertiary); }

/* ============================================================================
   Table (shadcn `<Table>` family)
   ============================================================================ */

/* The table's text is the theme's, which every cell inherits; header and
   caption text is muted, header and footer sit on the overlay surface. */
.cn-table {
    color: var(--text-primary);
    border: 1px solid var(--cn-table-border, var(--border));
    border-radius: var(--cn-table-radius, var(--radius-md));
    font-size: var(--text-sm);
}
.cn-table-header { background: var(--surface-overlay); }
.cn-table-footer {
    font-weight: 500;
    background: var(--surface-overlay);
    border-top: 1px solid var(--cn-table-border, var(--border));
}

/* Rows are separated by a border; the body's last row has none, so the
   closing edge sits flush with the outer radius. */
.cn-table-row {
    border-bottom: 1px solid var(--cn-table-border, var(--border));
    transition: background var(--duration-fast) var(--ease-state);
}
.cn-table-body .cn-table-row:last-child {
    border-bottom: none;
}
.cn-table-body > .cn-table-row:hover {
    background: var(--cn-table-row-hover, color-mix(in srgb, var(--text-primary) 4%, transparent));
}
.cn-table-row[data-state="selected"],
.cn-table-row[data-state="selected"]:hover {
    background: var(--cn-table-row-selected, var(--selection)) !important;
}

.cn-table-head {
    color: var(--text-secondary);
    font-weight: 500;
    font-size: var(--text-sm);
}
.cn-table-caption {
    color: var(--text-secondary);
    font-size: var(--text-sm);
}

/* Time and colour pickers */
:root {
    --cn-color-picker-checker-light: #ffffff;
    --cn-color-picker-checker-dark: #b8b8b8;
}
.cn-time-picker, .cn-color-picker-trigger, .cn-color-picker-panel {
    font-family: var(--font-sans);
    color: var(--text-primary);
}
.cn-time-picker {
    height: 36px; gap: 0; padding: 0 8px;
    border: 1px solid var(--cn-time-picker-border, var(--border));
    border-radius: var(--cn-time-picker-radius, var(--radius-md));
    background: var(--cn-time-picker-bg, var(--input-bg));
    transition: border-color var(--duration-fast) var(--ease-state);
}
.cn-time-picker[data-size="sm"] { height: 32px; padding: 0 6px; }
.cn-time-picker[data-size="lg"] { height: 40px; }
.cn-time-picker[data-focus-within] {
    border-color: var(--focus-ring); outline: 2px solid var(--focus-ring); outline-offset: 2px;
}
.cn-time-picker-segment {
    width: 28px; height: 28px; padding: 0 2px;
    border: 0; border-radius: 3px;
    background: transparent; color: var(--text-primary);
    font-family: var(--font-mono); font-size: 14px;
    transition: background var(--duration-fast) var(--ease-state);
}
.cn-time-picker-segment:hover {
    background: var(--cn-time-picker-field-hover, color-mix(in srgb, var(--text-primary) 5%, transparent));
}
.cn-time-picker-segment:focus {
    background: var(--cn-time-picker-field-focus, color-mix(in srgb, var(--primary) 10%, transparent));
    outline: none;
}
.cn-time-picker-segment--sm { width: 24px; height: 24px; font-size: 12px; }
.cn-time-picker-segment--lg { width: 32px; height: 32px; font-size: 16px; }
.cn-time-picker-separator { width: 6px; text-align: center; color: var(--text-tertiary); font-size: 14px; }
.cn-time-picker[data-size="sm"] .cn-time-picker-separator { font-size: 12px; }
.cn-time-picker[data-size="lg"] .cn-time-picker-separator { font-size: 16px; }
.cn-time-picker-period {
    width: 36px; height: 28px; padding: 0; margin-left: 6px;
    border-radius: 3px; background: transparent; cursor: pointer;
    font-size: 12px; font-weight: 500; color: var(--text-secondary);
    transition: background var(--duration-fast) var(--ease-state);
}
.cn-time-picker[data-size="sm"] .cn-time-picker-period { width: 32px; height: 24px; font-size: 11px; }
.cn-time-picker[data-size="lg"] .cn-time-picker-period { width: 40px; height: 32px; font-size: 14px; }
.cn-time-picker-period:hover { color: var(--text-primary); background: color-mix(in srgb, var(--text-primary) 6%, transparent); }
.cn-time-picker-period:focus-visible { outline: 1px solid var(--focus-ring); outline-offset: -1px; }
.cn-time-picker:disabled { opacity: 0.65; }
.cn-time-picker-segment:disabled,
.cn-time-picker-period:disabled { cursor: not-allowed; background: transparent; opacity: 1; }
.cn-time-picker-clock {
    width: 28px; height: 28px; margin-left: 4px; border-radius: 3px;
    color: var(--text-secondary); background: transparent; cursor: pointer;
    transition: background var(--duration-fast) var(--ease-state), color var(--duration-fast) var(--ease-state);
}
.cn-time-picker-clock:hover, .cn-time-picker-clock[data-state="open"] {
    color: var(--primary); background: color-mix(in srgb, var(--primary) 10%, transparent);
}
.cn-time-picker-clock:focus-visible { outline: 1px solid var(--focus-ring); outline-offset: -1px; }
.cn-time-picker-clock:disabled { color: var(--text-tertiary); cursor: not-allowed; background: transparent; }
.cn-time-picker[data-size="sm"] .cn-time-picker-clock { width: 24px; height: 24px; }
.cn-time-picker[data-size="lg"] .cn-time-picker-clock { width: 32px; height: 32px; }
.cn-time-picker-wheel {
    width: 232px; padding: 12px; gap: 12px; color: var(--text-primary);
    font-family: var(--font-sans);
}
.cn-time-picker-wheel[data-seconds] { width: 288px; }
.cn-time-picker-wheel-header { gap: 8px; }
.cn-time-picker-wheel-title { font-size: 14px; font-weight: 500; }
.cn-time-picker-wheels { height: calc(var(--cn-time-picker-wheel-row-height, 32px) * 5); }
.cn-time-picker-wheel-selection {
    left: 0; right: 0; top: calc(var(--cn-time-picker-wheel-row-height, 32px) * 2); height: var(--cn-time-picker-wheel-row-height, 32px);
    border: 1px solid var(--cn-time-picker-wheel-border, var(--border));
    border-radius: var(--radius-lg);
    background: var(--cn-time-picker-wheel-selection-bg, var(--input-bg));
}
.cn-time-picker-wheel-column {
    flex-grow: 1; flex-basis: 0; height: 100%; border-radius: var(--radius-sm);
    cursor: ns-resize;
}
.cn-time-picker-wheel-column:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.cn-time-picker-wheel-list { padding-top: calc(var(--cn-time-picker-wheel-row-height, 32px) * 2); padding-bottom: calc(var(--cn-time-picker-wheel-row-height, 32px) * 2); }
.cn-time-picker-wheel-column { overflow-fade: var(--cn-time-picker-wheel-fade, 64px) 0; scrollbar-width: none; }
.cn-time-picker-wheel-option {
    width: 100%; height: var(--cn-time-picker-wheel-row-height, 32px);
    font-size: var(--cn-time-picker-wheel-font-size, 22px); color: var(--text-primary);
}
.cn-time-picker-wheel-separator { width: 12px; height: 100%; font-size: 20px; color: var(--text-tertiary); }
.cn-time-picker-wheel-period { gap: 2px; padding: 2px; border-radius: var(--radius-sm); background: var(--surface-overlay); }
.cn-time-picker-wheel-period-option { width: 36px; height: 24px; border-radius: var(--radius-sm); font-size: 12px; color: var(--text-secondary); cursor: pointer; }
.cn-time-picker-wheel-period-option:hover { color: var(--text-primary); }
.cn-time-picker-wheel-period-option[data-selected] { color: var(--text-primary) !important; background: var(--surface-elevated) !important; box-shadow: var(--shadow-sm); }
.cn-time-picker-wheel-period-option:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 1px; }
.cn-time-picker-wheel-footer { gap: 8px; }

.cn-color-picker-trigger {
    gap: 8px; padding: 6px 10px;
    border: 1px solid var(--cn-color-picker-border, var(--border));
    border-radius: var(--cn-color-picker-radius, var(--radius-md));
    background: var(--cn-color-picker-bg, var(--input-bg)); cursor: pointer;
    transition: background var(--duration-fast) var(--ease-state), border-color var(--duration-fast) var(--ease-state);
}
.cn-color-picker-trigger:hover { background: var(--surface-overlay); }
.cn-color-picker-trigger:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.cn-color-picker-trigger:disabled { opacity: 0.5; cursor: not-allowed; background: var(--input-bg); }
.cn-color-picker-value { font-family: var(--font-mono); font-size: 13px; }
.cn-color-picker-swatch {
    width: 24px; height: 24px; flex-shrink: 0;
    border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.cn-color-picker-panel {
    width: 256px; padding: 16px; gap: 8px;
    border: 1px solid var(--cn-color-picker-border, var(--border));
    border-radius: var(--cn-color-picker-radius, var(--radius-md));
    background: var(--cn-color-picker-panel-bg, var(--surface-elevated));
    box-shadow: var(--shadow-md);
}
.cn-color-picker-panel:disabled { opacity: 0.5; }
.cn-color-picker-sv { height: 160px; cursor: crosshair; border-radius: var(--radius-sm); }
.cn-color-picker-white { background: linear-gradient(to right, #ffffff, #ffffff00); border-radius: var(--radius-sm); }
.cn-color-picker-black { background: linear-gradient(to bottom, #00000000, #000000); border-radius: var(--radius-sm); }
.cn-color-picker-hue {
    height: 16px; cursor: pointer; border-radius: 999px;
}
.cn-color-picker-hue-segment[data-sector="0"] { background: linear-gradient(to right, #ff0000, #ffff00); border-radius: 999px 0 0 999px; }
.cn-color-picker-hue-segment[data-sector="1"] { background: linear-gradient(to right, #ffff00, #00ff00); }
.cn-color-picker-hue-segment[data-sector="2"] { background: linear-gradient(to right, #00ff00, #00ffff); }
.cn-color-picker-hue-segment[data-sector="3"] { background: linear-gradient(to right, #00ffff, #0000ff); }
.cn-color-picker-hue-segment[data-sector="4"] { background: linear-gradient(to right, #0000ff, #ff00ff); }
.cn-color-picker-hue-segment[data-sector="5"] { background: linear-gradient(to right, #ff00ff, #ff0000); border-radius: 0 999px 999px 0; }
.cn-color-picker-alpha { height: 16px; cursor: pointer; background: var(--surface-overlay); border-radius: 999px; }
.cn-color-picker-alpha > div { border-radius: 999px; }
.cn-color-picker-sv:focus-visible, .cn-color-picker-hue:focus-visible, .cn-color-picker-alpha:focus-visible,
.cn-color-picker-sv[data-focus-visible], .cn-color-picker-hue[data-focus-visible], .cn-color-picker-alpha[data-focus-visible] {
    outline: 2px solid var(--focus-ring); outline-offset: 3px;
}
.cn-color-picker-sv:disabled, .cn-color-picker-hue:disabled, .cn-color-picker-alpha:disabled { cursor: not-allowed; }
.cn-color-picker-marker {
    width: 10px; height: 10px; border: 2px solid var(--cn-color-picker-marker, #ffffff);
    border-radius: 999px; box-shadow: 0 0 2px 1px #00000080;
    left: -5px; top: -5px;
}
.cn-color-picker-label { font-size: 12px; color: var(--text-secondary); }
.cn-color-picker-entry { gap: 8px; }
.cn-color-picker-hex {
    width: 100%; height: 32px; font-family: var(--font-mono); font-size: 13px;
    color: var(--text-primary); background: var(--input-bg);
    border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.cn-color-picker-hex:focus { border-color: var(--focus-ring); outline: 2px solid var(--focus-ring); outline-offset: -2px; }
.cn-color-picker-hex--invalid { border-color: var(--error); }
.cn-color-picker-swatches { gap: 8px; }
.cn-color-picker-preset {
    width: 24px; height: 24px; border-radius: 999px; cursor: pointer;
    border: 1px solid var(--border);
}
.cn-color-picker-preset[data-state="selected"] { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.cn-color-picker-preset:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.cn-color-picker-preset:disabled { cursor: not-allowed; }

.cn-date-picker-trigger {
    height: 40px; min-width: 180px; gap: 8px; padding: 0 12px;
    font-family: var(--font-sans); font-size: 14px; color: var(--text-primary);
    background: var(--cn-date-picker-bg, var(--input-bg));
    border: 1px solid var(--cn-date-picker-border, var(--border));
    border-radius: var(--cn-date-picker-radius, var(--radius-md)); cursor: pointer;
    transition: background var(--duration-fast) var(--ease-state), border-color var(--duration-fast) var(--ease-state);
}
.cn-date-picker-trigger[data-size="sm"] { height: 32px; font-size: 12px; }
.cn-date-picker-trigger[data-size="lg"] { height: 48px; font-size: 16px; }
.cn-date-picker-trigger[data-empty], .cn-date-picker-icon { color: var(--text-secondary); }
.cn-date-picker-trigger:hover { background: var(--surface-overlay); }
.cn-date-picker-trigger:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.cn-date-picker-trigger:disabled { opacity: 0.5; cursor: not-allowed; background: var(--input-bg); }
.cn-date-picker-content { padding: 12px; gap: 8px; }
.cn-date-picker-content .cn-calendar { padding: 0; border: 0; background: transparent; }
.cn-date-picker-clear {
    padding: 6px 10px; border-radius: var(--radius-sm);
    color: var(--text-secondary); cursor: pointer; font-size: 13px;
    transition: background var(--duration-fast) var(--ease-state);
}
.cn-date-picker-clear:hover { background: var(--surface-overlay); color: var(--text-primary); }
.cn-date-picker-clear:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 1px; }
.cn-date-picker-clear:disabled { opacity: 0.5; cursor: not-allowed; background: transparent; }


}
