You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/web/routes/uix/uix.css

1491 lines
44 KiB

/*
* UIX docs — design tokens.
*
* Visual language: refined-geometric, dual-theme (light + dark via
* `data-theme`), single accent against neutral surfaces. Inspired by
* Linear / Radix / Stripe docs but with its own voice — tight type,
* dot-leader tables, ring-only hovers, minimal shadows.
*
* Palette decisions:
* - Neutral scale = warm zinc (slightly warmer than gray)
* - Accent = teal (distinctive, not Vercel-blue, not Tailwind-indigo)
* - One brand color, one functional accent, no rainbow
*
* Typography:
* - Display + body = Instrument Sans, loaded locally by Eidos.
* - Monospace = Azeret Mono, loaded locally by Eidos.
* These keep `/uix` deterministic in offline/dev sandboxes.
*/
[data-uix-docs] {
/* ── Type scale ────────────────────────────────────────────────── */
--uix-font-sans: 'Instrument Sans', -apple-system, system-ui, sans-serif;
--uix-font-mono: 'Azeret Mono', ui-monospace, 'SF Mono', Consolas, monospace;
--uix-text-2xs: 11px;
--uix-text-xs: 12px;
--uix-text-sm: 13px;
--uix-text-md: 14px;
--uix-text-lg: 16px;
--uix-text-xl: 18px;
--uix-text-2xl: 22px;
--uix-text-3xl: 28px;
--uix-text-4xl: 36px;
--uix-text-5xl: 48px;
--uix-leading-tight: 1.2;
--uix-leading-snug: 1.4;
--uix-leading-prose: 1.65;
--uix-weight-regular: 400;
--uix-weight-medium: 500;
--uix-weight-semibold: 600;
--uix-weight-bold: 700;
/* ── Spacing scale (4px base) ──────────────────────────────────── */
--uix-space-1: 4px;
--uix-space-2: 8px;
--uix-space-3: 12px;
--uix-space-4: 16px;
--uix-space-5: 20px;
--uix-space-6: 24px;
--uix-space-8: 32px;
--uix-space-10: 40px;
--uix-space-12: 48px;
--uix-space-16: 64px;
--uix-space-20: 80px;
/* ── Radius ────────────────────────────────────────────────────── */
--uix-radius-xs: 3px;
--uix-radius-sm: 5px;
--uix-radius-md: 8px;
--uix-radius-lg: 12px;
--uix-radius-full: 9999px;
/* ── Motion ────────────────────────────────────────────────────── */
--uix-duration-fast: 120ms;
--uix-duration-base: 200ms;
--uix-duration-slow: 320ms;
--uix-ease: cubic-bezier(0.4, 0, 0.2, 1);
--uix-ease-emphatic: cubic-bezier(0.16, 1, 0.3, 1);
/* ── Layout dims ───────────────────────────────────────────────── */
--uix-rail-w: 248px;
--uix-toc-w: 220px;
--uix-content-max: 920px;
--uix-topbar-h: 56px;
}
/* ── Palette — Light (default) ─────────────────────────────────────── */
[data-uix-docs] {
/* Neutral (warm zinc) */
--uix-bg: #fcfcfc;
--uix-surface: #ffffff;
--uix-surface-raised: #ffffff;
--uix-surface-sunken: #f6f6f5;
--uix-surface-overlay: #ffffff;
--uix-line: #ececea;
--uix-line-soft: #f1f1ef;
--uix-line-strong: #d8d8d3;
--uix-text: #18181b;
--uix-text-muted: #5a5a55;
--uix-text-subtle: #8d8d86;
--uix-text-faint: #b4b4ad;
--uix-text-inverse: #fafaf9;
/* Accent — Brand red. Slightly orange-leaning for warmth (not the
* generic Tailwind red-500 wall), with deep contrast in light mode. */
--uix-accent: #dc2626;
--uix-accent-hover: #b91c1c;
--uix-accent-soft: #fee2e2;
--uix-accent-soft-hover: #fecaca;
--uix-accent-text: #b91c1c;
--uix-accent-line: #fca5a5;
/* Layer badge palette (one per UIX layer — soma/morfo/sema/eidos) */
--uix-layer-soma: #b45309;
--uix-layer-soma-bg: #fef3c7;
--uix-layer-morfo: #1d4ed8;
--uix-layer-morfo-bg: #dbeafe;
--uix-layer-sema: #7e22ce;
--uix-layer-sema-bg: #f3e8ff;
--uix-layer-eidos: #047857;
--uix-layer-eidos-bg: #d1fae5;
--uix-layer-docs: #475569;
--uix-layer-docs-bg: #f1f5f9;
/* Code highlight subtle */
--uix-code-bg: #f6f6f5;
--uix-code-line: #ececea;
/* Focus */
--uix-ring: 0 0 0 3px color-mix(in srgb, var(--uix-accent) 24%, transparent);
}
/* ── Palette — Dark ────────────────────────────────────────────────── */
[data-uix-docs][data-theme='dark'] {
--uix-bg: #0a0a0b;
--uix-surface: #111113;
--uix-surface-raised: #16161a;
--uix-surface-sunken: #0d0d0f;
--uix-surface-overlay: #1a1a1e;
--uix-line: #232328;
--uix-line-soft: #1c1c20;
--uix-line-strong: #353539;
--uix-text: #f4f4f3;
--uix-text-muted: #a8a8a3;
--uix-text-subtle: #76766f;
--uix-text-faint: #4a4a44;
--uix-text-inverse: #18181b;
--uix-accent: #f87171;
--uix-accent-hover: #fca5a5;
--uix-accent-soft: #450a0a;
--uix-accent-soft-hover: #7f1d1d;
--uix-accent-text: #fca5a5;
--uix-accent-line: #b91c1c;
--uix-layer-soma: #fcd34d;
--uix-layer-soma-bg: #422006;
--uix-layer-morfo: #93c5fd;
--uix-layer-morfo-bg: #172554;
--uix-layer-sema: #d8b4fe;
--uix-layer-sema-bg: #3b0764;
--uix-layer-eidos: #6ee7b7;
--uix-layer-eidos-bg: #022c22;
--uix-layer-docs: #cbd5e1;
--uix-layer-docs-bg: #1e293b;
--uix-code-bg: #16161a;
--uix-code-line: #232328;
}
/* ── Reset within docs scope ──────────────────────────────────────── */
[data-uix-docs] *,
[data-uix-docs] *::before,
[data-uix-docs] *::after {
box-sizing: border-box;
}
[data-uix-docs] {
background: var(--uix-bg);
color: var(--uix-text);
font-family: var(--uix-font-sans);
font-size: var(--uix-text-md);
line-height: var(--uix-leading-snug);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
min-block-size: 100vh;
demos: theme scrollbars + add missing data-uix-radio chrome Two visible inconsistencies in dark theme that the user flagged: 1. Scrollbars in code blocks (and any other scrollable inside the demos) rendered with the user-agent default chrome — bright white track + thumb on a dark surface. Only `[data-uix-rail]` (the left navigation column) had a themed scrollbar. Added a universal WebKit scrollbar theme scoped to `[data-uix-docs]`: transparent track, `--uix-line` thumb with 2px padding-clipped border so it reads as a thin rounded handle that hovers to `--uix-line-strong`. Both axes (10px width). Firefox handled via `scrollbar-color` + `scrollbar-width: thin` on the root. 2. `[data-uix-radio]` had zero CSS rules — the date-range-picker demo's `mode` (inline / modal) selector fell back to native radio inputs and an unstyled label, while its sibling controls used the themed `[data-uix-switch]`. Two switches-as-controls + one set of native radios in the same panel. Mirrored the data-uix-switch chrome at radio size: 16x16 circle, `--uix-line` border, `--uix-surface-sunken` background, inner pill in `--uix-accent` when checked, focus ring matches the rest. Label uses the same color + size as data-uix-switch-label. Verified in browser on date-range-picker demo: the `mode` radios now read as the same control family as the surrounding switches, and the code-snippet scrollbar is dark-themed instead of bright white. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
/* Firefox scrollbar — themed thin track that reads on both light + dark. */
scrollbar-color: var(--uix-line) transparent;
scrollbar-width: thin;
}
eidos: theming fixes + size/variant parity batch + docs - theme: add surface.muted + content.muted to color contract (neutral-3 + neutral-10). Plugs 17 broken --color-content-muted and 3 broken --color-surface-muted references in recipes/components. - form.css: fix --color-neutral-element-hover typo → --color-neutral-hover. - archetypes.css + events.css: replace raw hsl/rgba indigo with color-mix(var(--color-primary-solid) …) — no raw colors left in eidos. - combobox dark scrollbar: unscope ::-webkit-scrollbar rules in uix.css and duplicate --uix-line on :root + :root[data-mode='dark'] so portaled overlays (Combobox listbox, Popover, Dialog, Drawer) inherit the theme. - sizes: 20 components expand from sm/md/lg to xs..xl (form controls, text inputs, progress/meter, field/form) or xs..lg (nav controls: breadcrumb, pagination, tag-group, toolbar). Composite panels keep sm/md/lg deliberately. - variants: field + toolbar drop arbitrary ControlVariant narrowings; both expose all 3 (surface | outline | ghost) with new outline CSS. - pagination demo: disambiguate siblingCount/boundaryCount as "per side" in label + API table (Radix/MUI convention). - docs: CHECKLIST §C-2.6 (contract token presence) + §D-7.4 (chip parity) + §D-7.5 (size category) added. DEMO_AUTHORING §12.7 (chip parity) + §12.8 (size category cheatsheet) added. eidos/README + active_architecture.md sync texts/migration nomenclature. - PENDIENTES.md: normas N-1..N-5 implantadas en esta sesión. Verification: 88/88 eidos tests, 0 type errors, 67/67 component:audit PASS. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
/* Portal-safe scrollbar palette: mirror the line tokens on :root so that
portaled overlays (combobox listbox, popover content, dialog/drawer)
— which live outside [data-uix-docs] under <body> — can still resolve
them. ActiveEidos sets data-mode on <html>, so we hook the dark
variant onto that. This stylesheet is only loaded under the /uix
layout, so the broader selectors don't bleed anywhere else. */
:root {
--uix-line: #ececea;
--uix-line-strong: #d8d8d3;
/* Firefox: inherits everywhere, including portaled overlays. */
scrollbar-color: var(--uix-line) transparent;
scrollbar-width: thin;
}
:root[data-mode='dark'] {
--uix-line: #232328;
--uix-line-strong: #353539;
}
demos: theme scrollbars + add missing data-uix-radio chrome Two visible inconsistencies in dark theme that the user flagged: 1. Scrollbars in code blocks (and any other scrollable inside the demos) rendered with the user-agent default chrome — bright white track + thumb on a dark surface. Only `[data-uix-rail]` (the left navigation column) had a themed scrollbar. Added a universal WebKit scrollbar theme scoped to `[data-uix-docs]`: transparent track, `--uix-line` thumb with 2px padding-clipped border so it reads as a thin rounded handle that hovers to `--uix-line-strong`. Both axes (10px width). Firefox handled via `scrollbar-color` + `scrollbar-width: thin` on the root. 2. `[data-uix-radio]` had zero CSS rules — the date-range-picker demo's `mode` (inline / modal) selector fell back to native radio inputs and an unstyled label, while its sibling controls used the themed `[data-uix-switch]`. Two switches-as-controls + one set of native radios in the same panel. Mirrored the data-uix-switch chrome at radio size: 16x16 circle, `--uix-line` border, `--uix-surface-sunken` background, inner pill in `--uix-accent` when checked, focus ring matches the rest. Label uses the same color + size as data-uix-switch-label. Verified in browser on date-range-picker demo: the `mode` radios now read as the same control family as the surrounding switches, and the code-snippet scrollbar is dark-themed instead of bright white. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
/* WebKit scrollbar — universal demo theme so code blocks, scroll areas,
eidos: theming fixes + size/variant parity batch + docs - theme: add surface.muted + content.muted to color contract (neutral-3 + neutral-10). Plugs 17 broken --color-content-muted and 3 broken --color-surface-muted references in recipes/components. - form.css: fix --color-neutral-element-hover typo → --color-neutral-hover. - archetypes.css + events.css: replace raw hsl/rgba indigo with color-mix(var(--color-primary-solid) …) — no raw colors left in eidos. - combobox dark scrollbar: unscope ::-webkit-scrollbar rules in uix.css and duplicate --uix-line on :root + :root[data-mode='dark'] so portaled overlays (Combobox listbox, Popover, Dialog, Drawer) inherit the theme. - sizes: 20 components expand from sm/md/lg to xs..xl (form controls, text inputs, progress/meter, field/form) or xs..lg (nav controls: breadcrumb, pagination, tag-group, toolbar). Composite panels keep sm/md/lg deliberately. - variants: field + toolbar drop arbitrary ControlVariant narrowings; both expose all 3 (surface | outline | ghost) with new outline CSS. - pagination demo: disambiguate siblingCount/boundaryCount as "per side" in label + API table (Radix/MUI convention). - docs: CHECKLIST §C-2.6 (contract token presence) + §D-7.4 (chip parity) + §D-7.5 (size category) added. DEMO_AUTHORING §12.7 (chip parity) + §12.8 (size category cheatsheet) added. eidos/README + active_architecture.md sync texts/migration nomenclature. - PENDIENTES.md: normas N-1..N-5 implantadas en esta sesión. Verification: 88/88 eidos tests, 0 type errors, 67/67 component:audit PASS. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
stage canvas etc. all read on dark mode (default is white track).
Unscoped on purpose: see the :root rule above. */
::-webkit-scrollbar {
demos: theme scrollbars + add missing data-uix-radio chrome Two visible inconsistencies in dark theme that the user flagged: 1. Scrollbars in code blocks (and any other scrollable inside the demos) rendered with the user-agent default chrome — bright white track + thumb on a dark surface. Only `[data-uix-rail]` (the left navigation column) had a themed scrollbar. Added a universal WebKit scrollbar theme scoped to `[data-uix-docs]`: transparent track, `--uix-line` thumb with 2px padding-clipped border so it reads as a thin rounded handle that hovers to `--uix-line-strong`. Both axes (10px width). Firefox handled via `scrollbar-color` + `scrollbar-width: thin` on the root. 2. `[data-uix-radio]` had zero CSS rules — the date-range-picker demo's `mode` (inline / modal) selector fell back to native radio inputs and an unstyled label, while its sibling controls used the themed `[data-uix-switch]`. Two switches-as-controls + one set of native radios in the same panel. Mirrored the data-uix-switch chrome at radio size: 16x16 circle, `--uix-line` border, `--uix-surface-sunken` background, inner pill in `--uix-accent` when checked, focus ring matches the rest. Label uses the same color + size as data-uix-switch-label. Verified in browser on date-range-picker demo: the `mode` radios now read as the same control family as the surrounding switches, and the code-snippet scrollbar is dark-themed instead of bright white. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
inline-size: 10px;
block-size: 10px;
}
eidos: theming fixes + size/variant parity batch + docs - theme: add surface.muted + content.muted to color contract (neutral-3 + neutral-10). Plugs 17 broken --color-content-muted and 3 broken --color-surface-muted references in recipes/components. - form.css: fix --color-neutral-element-hover typo → --color-neutral-hover. - archetypes.css + events.css: replace raw hsl/rgba indigo with color-mix(var(--color-primary-solid) …) — no raw colors left in eidos. - combobox dark scrollbar: unscope ::-webkit-scrollbar rules in uix.css and duplicate --uix-line on :root + :root[data-mode='dark'] so portaled overlays (Combobox listbox, Popover, Dialog, Drawer) inherit the theme. - sizes: 20 components expand from sm/md/lg to xs..xl (form controls, text inputs, progress/meter, field/form) or xs..lg (nav controls: breadcrumb, pagination, tag-group, toolbar). Composite panels keep sm/md/lg deliberately. - variants: field + toolbar drop arbitrary ControlVariant narrowings; both expose all 3 (surface | outline | ghost) with new outline CSS. - pagination demo: disambiguate siblingCount/boundaryCount as "per side" in label + API table (Radix/MUI convention). - docs: CHECKLIST §C-2.6 (contract token presence) + §D-7.4 (chip parity) + §D-7.5 (size category) added. DEMO_AUTHORING §12.7 (chip parity) + §12.8 (size category cheatsheet) added. eidos/README + active_architecture.md sync texts/migration nomenclature. - PENDIENTES.md: normas N-1..N-5 implantadas en esta sesión. Verification: 88/88 eidos tests, 0 type errors, 67/67 component:audit PASS. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
::-webkit-scrollbar-track {
demos: theme scrollbars + add missing data-uix-radio chrome Two visible inconsistencies in dark theme that the user flagged: 1. Scrollbars in code blocks (and any other scrollable inside the demos) rendered with the user-agent default chrome — bright white track + thumb on a dark surface. Only `[data-uix-rail]` (the left navigation column) had a themed scrollbar. Added a universal WebKit scrollbar theme scoped to `[data-uix-docs]`: transparent track, `--uix-line` thumb with 2px padding-clipped border so it reads as a thin rounded handle that hovers to `--uix-line-strong`. Both axes (10px width). Firefox handled via `scrollbar-color` + `scrollbar-width: thin` on the root. 2. `[data-uix-radio]` had zero CSS rules — the date-range-picker demo's `mode` (inline / modal) selector fell back to native radio inputs and an unstyled label, while its sibling controls used the themed `[data-uix-switch]`. Two switches-as-controls + one set of native radios in the same panel. Mirrored the data-uix-switch chrome at radio size: 16x16 circle, `--uix-line` border, `--uix-surface-sunken` background, inner pill in `--uix-accent` when checked, focus ring matches the rest. Label uses the same color + size as data-uix-switch-label. Verified in browser on date-range-picker demo: the `mode` radios now read as the same control family as the surrounding switches, and the code-snippet scrollbar is dark-themed instead of bright white. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
background: transparent;
}
eidos: theming fixes + size/variant parity batch + docs - theme: add surface.muted + content.muted to color contract (neutral-3 + neutral-10). Plugs 17 broken --color-content-muted and 3 broken --color-surface-muted references in recipes/components. - form.css: fix --color-neutral-element-hover typo → --color-neutral-hover. - archetypes.css + events.css: replace raw hsl/rgba indigo with color-mix(var(--color-primary-solid) …) — no raw colors left in eidos. - combobox dark scrollbar: unscope ::-webkit-scrollbar rules in uix.css and duplicate --uix-line on :root + :root[data-mode='dark'] so portaled overlays (Combobox listbox, Popover, Dialog, Drawer) inherit the theme. - sizes: 20 components expand from sm/md/lg to xs..xl (form controls, text inputs, progress/meter, field/form) or xs..lg (nav controls: breadcrumb, pagination, tag-group, toolbar). Composite panels keep sm/md/lg deliberately. - variants: field + toolbar drop arbitrary ControlVariant narrowings; both expose all 3 (surface | outline | ghost) with new outline CSS. - pagination demo: disambiguate siblingCount/boundaryCount as "per side" in label + API table (Radix/MUI convention). - docs: CHECKLIST §C-2.6 (contract token presence) + §D-7.4 (chip parity) + §D-7.5 (size category) added. DEMO_AUTHORING §12.7 (chip parity) + §12.8 (size category cheatsheet) added. eidos/README + active_architecture.md sync texts/migration nomenclature. - PENDIENTES.md: normas N-1..N-5 implantadas en esta sesión. Verification: 88/88 eidos tests, 0 type errors, 67/67 component:audit PASS. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
::-webkit-scrollbar-thumb {
demos: theme scrollbars + add missing data-uix-radio chrome Two visible inconsistencies in dark theme that the user flagged: 1. Scrollbars in code blocks (and any other scrollable inside the demos) rendered with the user-agent default chrome — bright white track + thumb on a dark surface. Only `[data-uix-rail]` (the left navigation column) had a themed scrollbar. Added a universal WebKit scrollbar theme scoped to `[data-uix-docs]`: transparent track, `--uix-line` thumb with 2px padding-clipped border so it reads as a thin rounded handle that hovers to `--uix-line-strong`. Both axes (10px width). Firefox handled via `scrollbar-color` + `scrollbar-width: thin` on the root. 2. `[data-uix-radio]` had zero CSS rules — the date-range-picker demo's `mode` (inline / modal) selector fell back to native radio inputs and an unstyled label, while its sibling controls used the themed `[data-uix-switch]`. Two switches-as-controls + one set of native radios in the same panel. Mirrored the data-uix-switch chrome at radio size: 16x16 circle, `--uix-line` border, `--uix-surface-sunken` background, inner pill in `--uix-accent` when checked, focus ring matches the rest. Label uses the same color + size as data-uix-switch-label. Verified in browser on date-range-picker demo: the `mode` radios now read as the same control family as the surrounding switches, and the code-snippet scrollbar is dark-themed instead of bright white. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
background: var(--uix-line);
border-radius: var(--uix-radius-sm);
border: 2px solid transparent;
background-clip: padding-box;
}
eidos: theming fixes + size/variant parity batch + docs - theme: add surface.muted + content.muted to color contract (neutral-3 + neutral-10). Plugs 17 broken --color-content-muted and 3 broken --color-surface-muted references in recipes/components. - form.css: fix --color-neutral-element-hover typo → --color-neutral-hover. - archetypes.css + events.css: replace raw hsl/rgba indigo with color-mix(var(--color-primary-solid) …) — no raw colors left in eidos. - combobox dark scrollbar: unscope ::-webkit-scrollbar rules in uix.css and duplicate --uix-line on :root + :root[data-mode='dark'] so portaled overlays (Combobox listbox, Popover, Dialog, Drawer) inherit the theme. - sizes: 20 components expand from sm/md/lg to xs..xl (form controls, text inputs, progress/meter, field/form) or xs..lg (nav controls: breadcrumb, pagination, tag-group, toolbar). Composite panels keep sm/md/lg deliberately. - variants: field + toolbar drop arbitrary ControlVariant narrowings; both expose all 3 (surface | outline | ghost) with new outline CSS. - pagination demo: disambiguate siblingCount/boundaryCount as "per side" in label + API table (Radix/MUI convention). - docs: CHECKLIST §C-2.6 (contract token presence) + §D-7.4 (chip parity) + §D-7.5 (size category) added. DEMO_AUTHORING §12.7 (chip parity) + §12.8 (size category cheatsheet) added. eidos/README + active_architecture.md sync texts/migration nomenclature. - PENDIENTES.md: normas N-1..N-5 implantadas en esta sesión. Verification: 88/88 eidos tests, 0 type errors, 67/67 component:audit PASS. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
::-webkit-scrollbar-thumb:hover {
demos: theme scrollbars + add missing data-uix-radio chrome Two visible inconsistencies in dark theme that the user flagged: 1. Scrollbars in code blocks (and any other scrollable inside the demos) rendered with the user-agent default chrome — bright white track + thumb on a dark surface. Only `[data-uix-rail]` (the left navigation column) had a themed scrollbar. Added a universal WebKit scrollbar theme scoped to `[data-uix-docs]`: transparent track, `--uix-line` thumb with 2px padding-clipped border so it reads as a thin rounded handle that hovers to `--uix-line-strong`. Both axes (10px width). Firefox handled via `scrollbar-color` + `scrollbar-width: thin` on the root. 2. `[data-uix-radio]` had zero CSS rules — the date-range-picker demo's `mode` (inline / modal) selector fell back to native radio inputs and an unstyled label, while its sibling controls used the themed `[data-uix-switch]`. Two switches-as-controls + one set of native radios in the same panel. Mirrored the data-uix-switch chrome at radio size: 16x16 circle, `--uix-line` border, `--uix-surface-sunken` background, inner pill in `--uix-accent` when checked, focus ring matches the rest. Label uses the same color + size as data-uix-switch-label. Verified in browser on date-range-picker demo: the `mode` radios now read as the same control family as the surrounding switches, and the code-snippet scrollbar is dark-themed instead of bright white. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
background: var(--uix-line-strong);
background-clip: padding-box;
border: 2px solid transparent;
}
eidos: theming fixes + size/variant parity batch + docs - theme: add surface.muted + content.muted to color contract (neutral-3 + neutral-10). Plugs 17 broken --color-content-muted and 3 broken --color-surface-muted references in recipes/components. - form.css: fix --color-neutral-element-hover typo → --color-neutral-hover. - archetypes.css + events.css: replace raw hsl/rgba indigo with color-mix(var(--color-primary-solid) …) — no raw colors left in eidos. - combobox dark scrollbar: unscope ::-webkit-scrollbar rules in uix.css and duplicate --uix-line on :root + :root[data-mode='dark'] so portaled overlays (Combobox listbox, Popover, Dialog, Drawer) inherit the theme. - sizes: 20 components expand from sm/md/lg to xs..xl (form controls, text inputs, progress/meter, field/form) or xs..lg (nav controls: breadcrumb, pagination, tag-group, toolbar). Composite panels keep sm/md/lg deliberately. - variants: field + toolbar drop arbitrary ControlVariant narrowings; both expose all 3 (surface | outline | ghost) with new outline CSS. - pagination demo: disambiguate siblingCount/boundaryCount as "per side" in label + API table (Radix/MUI convention). - docs: CHECKLIST §C-2.6 (contract token presence) + §D-7.4 (chip parity) + §D-7.5 (size category) added. DEMO_AUTHORING §12.7 (chip parity) + §12.8 (size category cheatsheet) added. eidos/README + active_architecture.md sync texts/migration nomenclature. - PENDIENTES.md: normas N-1..N-5 implantadas en esta sesión. Verification: 88/88 eidos tests, 0 type errors, 67/67 component:audit PASS. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
::-webkit-scrollbar-corner {
demos: theme scrollbars + add missing data-uix-radio chrome Two visible inconsistencies in dark theme that the user flagged: 1. Scrollbars in code blocks (and any other scrollable inside the demos) rendered with the user-agent default chrome — bright white track + thumb on a dark surface. Only `[data-uix-rail]` (the left navigation column) had a themed scrollbar. Added a universal WebKit scrollbar theme scoped to `[data-uix-docs]`: transparent track, `--uix-line` thumb with 2px padding-clipped border so it reads as a thin rounded handle that hovers to `--uix-line-strong`. Both axes (10px width). Firefox handled via `scrollbar-color` + `scrollbar-width: thin` on the root. 2. `[data-uix-radio]` had zero CSS rules — the date-range-picker demo's `mode` (inline / modal) selector fell back to native radio inputs and an unstyled label, while its sibling controls used the themed `[data-uix-switch]`. Two switches-as-controls + one set of native radios in the same panel. Mirrored the data-uix-switch chrome at radio size: 16x16 circle, `--uix-line` border, `--uix-surface-sunken` background, inner pill in `--uix-accent` when checked, focus ring matches the rest. Label uses the same color + size as data-uix-switch-label. Verified in browser on date-range-picker demo: the `mode` radios now read as the same control family as the surrounding switches, and the code-snippet scrollbar is dark-themed instead of bright white. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
background: transparent;
}
/* ── Shell layout ──────────────────────────────────────────────────── */
[data-uix-shell] {
display: grid;
grid-template-columns: var(--uix-rail-w) minmax(0, 1fr);
min-block-size: 100vh;
}
/* ── Topbar ───────────────────────────────────────────────────────── */
[data-uix-topbar] {
grid-column: 1 / -1;
position: sticky;
top: 0;
z-index: 50;
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--uix-space-4);
padding: 0 var(--uix-space-6);
height: var(--uix-topbar-h);
background: color-mix(in srgb, var(--uix-bg) 88%, transparent);
border-bottom: 1px solid var(--uix-line);
backdrop-filter: saturate(1.6) blur(10px);
-webkit-backdrop-filter: saturate(1.6) blur(10px);
}
[data-uix-brand] {
display: inline-flex;
align-items: center;
gap: var(--uix-space-2);
text-decoration: none;
color: inherit;
font-family: var(--uix-font-sans);
font-weight: var(--uix-weight-semibold);
font-size: var(--uix-text-md);
letter-spacing: -0.015em;
}
[data-uix-brand-mark] {
inline-size: 22px;
block-size: 22px;
border-radius: var(--uix-radius-xs);
background: var(--uix-text);
color: var(--uix-bg);
display: inline-flex;
align-items: center;
justify-content: center;
font-family: var(--uix-font-mono);
font-weight: var(--uix-weight-bold);
font-size: 11px;
letter-spacing: -0.05em;
}
[data-uix-brand-version] {
font-family: var(--uix-font-mono);
font-size: 11px;
color: var(--uix-text-subtle);
font-weight: var(--uix-weight-regular);
margin-inline-start: var(--uix-space-1);
}
[data-uix-topbar-nav] {
display: inline-flex;
gap: var(--uix-space-1);
margin-inline-start: var(--uix-space-6);
}
[data-uix-topbar-nav] a {
display: inline-flex;
align-items: center;
padding: 0 var(--uix-space-3);
height: 30px;
border-radius: var(--uix-radius-sm);
color: var(--uix-text-muted);
text-decoration: none;
font-size: var(--uix-text-sm);
font-weight: var(--uix-weight-medium);
transition:
color var(--uix-duration-fast) var(--uix-ease),
background var(--uix-duration-fast) var(--uix-ease);
}
[data-uix-topbar-nav] a:hover {
color: var(--uix-text);
background: var(--uix-surface-sunken);
}
[data-uix-topbar-nav] a[data-active='true'] {
color: var(--uix-text);
background: var(--uix-surface-sunken);
}
[data-uix-topbar-tools] {
display: inline-flex;
align-items: center;
gap: var(--uix-space-2);
margin-inline-start: auto;
}
[data-uix-icon-btn] {
inline-size: 32px;
block-size: 32px;
display: inline-flex;
align-items: center;
justify-content: center;
border: 1px solid var(--uix-line);
border-radius: var(--uix-radius-sm);
background: var(--uix-surface);
color: var(--uix-text-muted);
cursor: pointer;
padding: 0;
transition:
border-color var(--uix-duration-fast) var(--uix-ease),
color var(--uix-duration-fast) var(--uix-ease),
background var(--uix-duration-fast) var(--uix-ease);
}
[data-uix-icon-btn]:hover {
border-color: var(--uix-line-strong);
color: var(--uix-text);
}
[data-uix-icon-btn] svg {
inline-size: 14px;
block-size: 14px;
}
/* Label button — same envelope as icon-btn but accommodates a short
* mono label (e.g. lang code "ES"). Used by lang/dir/formats/semantics
* triggers in the topbar. */
[data-uix-label-btn] {
display: inline-flex;
align-items: center;
gap: 6px;
height: 32px;
padding: 0 var(--uix-space-3);
border: 1px solid var(--uix-line);
border-radius: var(--uix-radius-sm);
background: var(--uix-surface);
color: var(--uix-text-muted);
font: inherit;
font-family: var(--uix-font-mono);
font-size: var(--uix-text-xs);
letter-spacing: 0.02em;
cursor: pointer;
transition:
border-color var(--uix-duration-fast) var(--uix-ease),
color var(--uix-duration-fast) var(--uix-ease),
background var(--uix-duration-fast) var(--uix-ease);
}
[data-uix-label-btn]:hover,
[data-uix-label-btn][aria-expanded='true'] {
border-color: var(--uix-line-strong);
color: var(--uix-text);
}
[data-uix-label-btn] svg {
inline-size: 12px;
block-size: 12px;
}
[data-uix-label-btn] [data-caret] {
color: var(--uix-text-faint);
}
/* Popover menu — dropdown shape used by lang / formats / semantics.
* Gives a clean Radix-feel card around a stack of menu items. */
[data-uix-menu] {
min-inline-size: 200px;
display: flex;
flex-direction: column;
padding: 6px;
border: 1px solid var(--uix-line);
border-radius: var(--uix-radius-md);
background: var(--uix-surface-overlay);
box-shadow: 0 10px 32px -12px rgba(0, 0, 0, 0.18), 0 2px 6px rgba(0, 0, 0, 0.05);
color: var(--uix-text);
font-size: var(--uix-text-sm);
}
[data-uix-menu-section] + [data-uix-menu-section] {
margin-block-start: 4px;
padding-block-start: 4px;
border-block-start: 1px solid var(--uix-line);
}
[data-uix-menu-label] {
padding: 4px 10px 6px;
font-family: var(--uix-font-mono);
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--uix-text-faint);
font-weight: var(--uix-weight-medium);
}
[data-uix-menu-item] {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--uix-space-3);
inline-size: 100%;
padding: 6px 10px;
border: 0;
border-radius: var(--uix-radius-xs);
background: transparent;
color: var(--uix-text);
font: inherit;
font-size: var(--uix-text-sm);
cursor: pointer;
text-align: start;
transition: background var(--uix-duration-fast) var(--uix-ease);
}
[data-uix-menu-item]:hover {
background: var(--uix-surface-sunken);
}
[data-uix-menu-item][data-checked='true'] {
color: var(--uix-accent-text);
font-weight: var(--uix-weight-medium);
}
[data-uix-menu-item][data-checked='true']::after {
content: '✓';
color: var(--uix-accent);
font-family: var(--uix-font-mono);
font-weight: var(--uix-weight-bold);
}
[data-uix-menu-item-meta] {
font-family: var(--uix-font-mono);
font-size: 10px;
color: var(--uix-text-faint);
letter-spacing: 0.04em;
}
[data-uix-menu-toggle] {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 6px 10px;
font-size: var(--uix-text-sm);
color: var(--uix-text);
cursor: pointer;
border-radius: var(--uix-radius-xs);
transition: background var(--uix-duration-fast) var(--uix-ease);
}
[data-uix-menu-toggle]:hover {
background: var(--uix-surface-sunken);
}
[data-uix-menu-toggle] input[type='checkbox'] {
appearance: none;
-webkit-appearance: none;
inline-size: 30px;
block-size: 16px;
padding: 0;
border: 1px solid var(--uix-line);
border-radius: var(--uix-radius-full);
background: var(--uix-surface-sunken);
cursor: pointer;
position: relative;
transition:
background var(--uix-duration-fast) var(--uix-ease),
border-color var(--uix-duration-fast) var(--uix-ease);
}
[data-uix-menu-toggle] input[type='checkbox']::after {
content: '';
position: absolute;
inset-inline-start: 1px;
inset-block-start: 1px;
inline-size: 12px;
block-size: 12px;
border-radius: var(--uix-radius-full);
background: var(--uix-text);
transition: transform var(--uix-duration-fast) var(--uix-ease);
}
[data-uix-menu-toggle] input[type='checkbox']:checked {
background: var(--uix-accent);
border-color: var(--uix-accent);
}
[data-uix-menu-toggle] input[type='checkbox']:checked::after {
transform: translateX(14px);
background: white;
}
[data-uix-menu-toggle] [data-uix-menu-toggle-meta] {
margin-inline-start: auto;
font-family: var(--uix-font-mono);
font-size: 10px;
color: var(--uix-text-faint);
letter-spacing: 0.04em;
text-transform: uppercase;
}
/* ── Sidebar (rail) ───────────────────────────────────────────────── */
[data-uix-rail] {
position: sticky;
top: var(--uix-topbar-h);
height: calc(100vh - var(--uix-topbar-h));
overflow-y: auto;
padding: var(--uix-space-6) var(--uix-space-4) var(--uix-space-8);
border-right: 1px solid var(--uix-line);
background: var(--uix-surface-sunken);
}
[data-uix-rail]::-webkit-scrollbar {
inline-size: 8px;
}
[data-uix-rail]::-webkit-scrollbar-thumb {
background: var(--uix-line);
border-radius: var(--uix-radius-sm);
}
[data-uix-rail]::-webkit-scrollbar-thumb:hover {
background: var(--uix-line-strong);
}
[data-uix-rail-search] {
margin-block-end: var(--uix-space-5);
}
[data-uix-rail-search] input {
inline-size: 100%;
height: 32px;
padding: 0 var(--uix-space-3);
border: 1px solid var(--uix-line);
border-radius: var(--uix-radius-sm);
background: var(--uix-surface);
color: var(--uix-text);
font: inherit;
font-size: var(--uix-text-sm);
transition: border-color var(--uix-duration-fast) var(--uix-ease);
}
[data-uix-rail-search] input::placeholder {
color: var(--uix-text-faint);
}
[data-uix-rail-search] input:focus {
outline: none;
border-color: var(--uix-accent-line);
box-shadow: var(--uix-ring);
}
[data-uix-rail-group] {
margin-block-end: var(--uix-space-5);
}
[data-uix-rail-group-head] {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 var(--uix-space-3) var(--uix-space-2);
font-family: var(--uix-font-mono);
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--uix-text-faint);
font-weight: var(--uix-weight-medium);
}
[data-uix-rail-group-count] {
color: var(--uix-text-faint);
}
[data-uix-rail-group] ul {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-direction: column;
gap: 1px;
}
[data-uix-rail-link] {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--uix-space-2);
padding: 6px var(--uix-space-3);
border-radius: var(--uix-radius-sm);
color: var(--uix-text-muted);
text-decoration: none;
font-size: var(--uix-text-sm);
font-weight: var(--uix-weight-medium);
transition:
color var(--uix-duration-fast) var(--uix-ease),
background var(--uix-duration-fast) var(--uix-ease);
}
[data-uix-rail-link]:hover {
color: var(--uix-text);
background: var(--uix-surface);
}
[data-uix-rail-link][data-active='true'] {
color: var(--uix-text);
background: var(--uix-surface);
font-weight: var(--uix-weight-semibold);
}
[data-uix-rail-link][data-active='true']::before {
content: '';
inline-size: 3px;
block-size: 14px;
border-radius: 2px;
background: var(--uix-accent);
margin-inline-end: var(--uix-space-2);
margin-inline-start: -8px;
}
[data-uix-rail-link-tag] {
font-family: var(--uix-font-mono);
font-size: 10px;
letter-spacing: 0.04em;
color: var(--uix-text-faint);
text-transform: uppercase;
}
/* ── Canvas (content area) ────────────────────────────────────────── */
[data-uix-canvas] {
min-inline-size: 0;
padding: var(--uix-space-10) var(--uix-space-8) var(--uix-space-16);
}
[data-uix-canvas-inner] {
max-inline-size: var(--uix-content-max);
margin: 0 auto;
}
/* When a TOC is needed, the canvas-inner becomes a 2-column grid. */
[data-uix-canvas-inner][data-with-toc='true'] {
display: grid;
grid-template-columns: minmax(0, 1fr) var(--uix-toc-w);
gap: var(--uix-space-12);
max-inline-size: calc(var(--uix-content-max) + var(--uix-toc-w) + var(--uix-space-12));
}
[data-uix-toc] {
position: sticky;
top: calc(var(--uix-topbar-h) + var(--uix-space-6));
align-self: start;
max-block-size: calc(100vh - var(--uix-topbar-h) - var(--uix-space-12));
overflow-y: auto;
font-size: var(--uix-text-xs);
}
[data-uix-toc-head] {
font-family: var(--uix-font-mono);
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--uix-text-faint);
font-weight: var(--uix-weight-medium);
padding-block-end: var(--uix-space-3);
}
[data-uix-toc] ul {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-direction: column;
gap: 4px;
border-inline-start: 1px solid var(--uix-line);
}
[data-uix-toc] a {
display: block;
padding: 4px var(--uix-space-3);
margin-inline-start: -1px;
border-inline-start: 1px solid transparent;
color: var(--uix-text-subtle);
text-decoration: none;
font-size: var(--uix-text-xs);
transition: color var(--uix-duration-fast) var(--uix-ease);
}
[data-uix-toc] a:hover {
color: var(--uix-text);
}
[data-uix-toc] a[data-active='true'] {
color: var(--uix-accent-text);
border-inline-start-color: var(--uix-accent);
font-weight: var(--uix-weight-medium);
}
/* ── Page header ──────────────────────────────────────────────────── */
[data-uix-eyebrow] {
display: inline-flex;
align-items: center;
gap: var(--uix-space-2);
font-family: var(--uix-font-mono);
font-size: var(--uix-text-2xs);
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--uix-accent-text);
font-weight: var(--uix-weight-semibold);
margin-block-end: var(--uix-space-4);
}
[data-uix-eyebrow]::before {
content: '';
inline-size: 14px;
block-size: 1px;
background: var(--uix-accent);
}
[data-uix-page-title] {
font-size: var(--uix-text-5xl);
line-height: var(--uix-leading-tight);
font-weight: var(--uix-weight-semibold);
letter-spacing: -0.025em;
margin: 0 0 var(--uix-space-4);
color: var(--uix-text);
}
[data-uix-page-lede] {
font-size: var(--uix-text-xl);
line-height: var(--uix-leading-prose);
color: var(--uix-text-muted);
margin: 0 0 var(--uix-space-6);
max-inline-size: 64ch;
font-weight: var(--uix-weight-regular);
}
[data-uix-page-meta] {
display: flex;
flex-wrap: wrap;
gap: var(--uix-space-2);
margin-block-end: var(--uix-space-10);
}
[data-uix-meta-pill] {
display: inline-flex;
align-items: baseline;
gap: var(--uix-space-2);
padding: 4px var(--uix-space-3);
border: 1px solid var(--uix-line);
border-radius: var(--uix-radius-full);
background: var(--uix-surface);
font-family: var(--uix-font-mono);
font-size: var(--uix-text-xs);
color: var(--uix-text);
}
[data-uix-meta-pill] [data-uix-meta-key] {
color: var(--uix-text-faint);
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.06em;
font-weight: var(--uix-weight-medium);
}
/* ── Layer badge ──────────────────────────────────────────────────── */
[data-uix-layer-badge] {
display: inline-flex;
align-items: center;
padding: 2px 6px;
border-radius: var(--uix-radius-xs);
font-family: var(--uix-font-mono);
font-size: 10px;
font-weight: var(--uix-weight-semibold);
letter-spacing: 0.04em;
text-transform: uppercase;
}
[data-uix-layer-badge='soma'] {
color: var(--uix-layer-soma);
background: var(--uix-layer-soma-bg);
}
[data-uix-layer-badge='morfo'] {
color: var(--uix-layer-morfo);
background: var(--uix-layer-morfo-bg);
}
[data-uix-layer-badge='sema'] {
color: var(--uix-layer-sema);
background: var(--uix-layer-sema-bg);
}
[data-uix-layer-badge='eidos'] {
color: var(--uix-layer-eidos);
background: var(--uix-layer-eidos-bg);
}
[data-uix-layer-badge='docs'] {
color: var(--uix-layer-docs);
background: var(--uix-layer-docs-bg);
}
/* ── Code (inline + block) ────────────────────────────────────────── */
[data-uix-docs] code {
font-family: var(--uix-font-mono);
font-size: 0.92em;
padding: 1px 5px;
border-radius: var(--uix-radius-xs);
background: var(--uix-code-bg);
border: 1px solid var(--uix-code-line);
color: var(--uix-text);
}
[data-uix-docs] pre {
margin: 0;
padding: var(--uix-space-4) var(--uix-space-5);
border: 1px solid var(--uix-line);
border-radius: var(--uix-radius-md);
background: var(--uix-code-bg);
overflow-x: auto;
font-family: var(--uix-font-mono);
font-size: var(--uix-text-sm);
line-height: var(--uix-leading-snug);
color: var(--uix-text);
}
[data-uix-docs] pre code {
padding: 0;
background: transparent;
border: 0;
color: inherit;
font-size: inherit;
}
/* ── Generic prose styles inside docs sections ─────────────────────── */
[data-uix-prose] {
color: var(--uix-text);
font-size: var(--uix-text-md);
line-height: var(--uix-leading-prose);
}
[data-uix-prose] > * + * {
margin-block-start: var(--uix-space-4);
}
[data-uix-prose] h2 {
font-size: var(--uix-text-2xl);
letter-spacing: -0.015em;
font-weight: var(--uix-weight-semibold);
margin-block-start: var(--uix-space-12);
margin-block-end: var(--uix-space-3);
padding-block-end: var(--uix-space-3);
border-block-end: 1px solid var(--uix-line);
}
[data-uix-prose] h3 {
font-size: var(--uix-text-lg);
letter-spacing: -0.01em;
font-weight: var(--uix-weight-semibold);
margin-block-start: var(--uix-space-8);
margin-block-end: var(--uix-space-2);
}
[data-uix-prose] p {
margin: 0;
color: var(--uix-text-muted);
max-inline-size: 70ch;
}
[data-uix-prose] strong {
color: var(--uix-text);
font-weight: var(--uix-weight-semibold);
}
[data-uix-prose] a {
color: var(--uix-accent-text);
text-decoration: underline;
text-decoration-color: color-mix(in srgb, var(--uix-accent) 35%, transparent);
text-underline-offset: 3px;
}
[data-uix-prose] a:hover {
text-decoration-color: var(--uix-accent);
}
/* ════════════════════════════════════════════════════════════════════
* Component page primitives — shared across every /uix/components/*
* page. Tabs · stage · control panel · props table · anatomy · code
* block · play button · kbd. Strict: every component page composes
* the same primitives in the same order so the visitor gets uniformity.
* ════════════════════════════════════════════════════════════════════ */
/* ── Tabs ──────────────────────────────────────────────────────────── */
[data-uix-tabs] {
display: flex;
gap: 2px;
padding: 4px;
background: var(--uix-surface-sunken);
border: 1px solid var(--uix-line);
border-radius: var(--uix-radius-md);
margin-block-end: var(--uix-space-6);
}
[data-uix-tab] {
display: inline-flex;
align-items: center;
gap: 6px;
height: 30px;
padding: 0 var(--uix-space-3);
border: 0;
border-radius: var(--uix-radius-sm);
background: transparent;
color: var(--uix-text-muted);
font: inherit;
font-size: var(--uix-text-sm);
font-weight: var(--uix-weight-medium);
cursor: pointer;
transition: color var(--uix-duration-fast) var(--uix-ease), background var(--uix-duration-fast) var(--uix-ease);
}
[data-uix-tab]:hover { color: var(--uix-text); }
[data-uix-tab][data-active="true"] {
color: var(--uix-text);
background: var(--uix-surface);
box-shadow: 0 1px 2px rgba(0,0,0,0.04);
}
[data-uix-tab-count] {
font-family: var(--uix-font-mono);
font-size: 10px;
color: var(--uix-text-faint);
background: var(--uix-surface-sunken);
padding: 1px 5px;
border-radius: var(--uix-radius-xs);
}
[data-uix-tab][data-active="true"] [data-uix-tab-count] {
background: var(--uix-accent-soft);
color: var(--uix-accent-text);
}
/* ── Stage (live preview canvas) ──────────────────────────────────── */
[data-uix-stage] {
margin-block-end: var(--uix-space-6);
border: 1px solid var(--uix-line);
border-radius: var(--uix-radius-md);
background: var(--uix-surface);
overflow: hidden;
}
[data-uix-stage-area] {
position: relative;
min-block-size: clamp(11rem, 28vh, 16rem);
display: grid;
place-items: center;
padding: clamp(var(--uix-space-4), 3vw, var(--uix-space-6));
background:
radial-gradient(circle at 50% 0%, var(--uix-surface-sunken), var(--uix-surface) 60%),
repeating-linear-gradient(45deg, transparent 0, transparent 11px, color-mix(in srgb, var(--uix-line-soft) 60%, transparent) 11px, color-mix(in srgb, var(--uix-line-soft) 60%, transparent) 12px);
}
[data-uix-stage-trace] {
display: flex;
align-items: center;
gap: var(--uix-space-3);
flex-wrap: wrap;
padding: var(--uix-space-3) var(--uix-space-4);
border-block-start: 1px solid var(--uix-line);
background: var(--uix-surface-sunken);
font-family: var(--uix-font-mono);
font-size: var(--uix-text-xs);
color: var(--uix-text-muted);
}
[data-uix-stage-trace-key] {
color: var(--uix-text-faint);
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.06em;
}
[data-uix-stage-trace-event] {
color: var(--uix-accent-text);
font-weight: var(--uix-weight-medium);
}
/* ── Section ──────────────────────────────────────────────────────── */
[data-uix-section] { margin-block-end: var(--uix-space-10); }
[data-uix-section-title] {
font-size: var(--uix-text-xl);
letter-spacing: -0.01em;
font-weight: var(--uix-weight-semibold);
margin: 0 0 var(--uix-space-3);
color: var(--uix-text);
}
[data-uix-section-desc] {
font-size: var(--uix-text-md);
color: var(--uix-text-muted);
max-inline-size: 70ch;
margin: 0 0 var(--uix-space-5);
line-height: var(--uix-leading-prose);
}
[data-uix-subsection-head] {
font-family: var(--uix-font-mono);
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--uix-text-faint);
font-weight: var(--uix-weight-medium);
margin-block-start: var(--uix-space-6);
margin-block-end: var(--uix-space-3);
}
/* ── Control panel ────────────────────────────────────────────────── */
[data-uix-controls] {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
gap: var(--uix-space-4);
padding: var(--uix-space-5);
border: 1px solid var(--uix-line);
border-radius: var(--uix-radius-md);
background: var(--uix-surface);
margin-block-end: var(--uix-space-5);
}
[data-uix-control] {
display: flex;
flex-direction: column;
gap: 6px;
min-inline-size: 0;
}
[data-uix-control-label] {
display: flex;
align-items: center;
gap: 6px;
font-family: var(--uix-font-mono);
font-size: 11px;
font-weight: var(--uix-weight-medium);
color: var(--uix-text-muted);
}
[data-uix-control-hint] {
color: var(--uix-text-faint);
font-weight: var(--uix-weight-regular);
font-size: 10px;
}
demos: homogenize input chrome across all demo Controls The `[data-uix-control] input[type='text|number']` rule only covered two input types, so demos that used `<input type='date'>` (date- and date-range pickers' min/max/start/end inputs, calendar bounds, etc.) or `<input type='email|search|tel|url|password|time|month|week| datetime-local'>` (form/field demos) fell back to the user-agent chrome — different padding, borders, fonts, and the native calendar/clock indicator with no theme alignment. Replaced the type-specific selector with an exclusion list: [data-uix-control] input:not([type='checkbox']):not([type='radio']):not([type='range']) Every text-like input now picks up the demo's standard chrome (6px / 32px / `--uix-line` border / `--uix-surface` bg / focus ring). Checkbox + radio keep their bespoke toggle treatments; range keeps its native track with the demo accent. Added: - Consistent `min-block-size: 32px` + `box-sizing: border-box` so inputs line up vertically with the demo's button-style pill controls. - Disabled state: 0.55 opacity + `not-allowed` cursor. - `::-webkit-calendar-picker-indicator` recolored for date/datetime-local/month/time/week inputs — inverted 70% so the calendar/clock icon reads on dark theme and matches the field text tone, with full opacity on hover. - `::-webkit-search-cancel-button` recolored. Verified in browser: date-range-picker demo's start/end/minValue/ maxValue inputs now match minDays/maxDays (number) and label/name (text) inputs. Form demo Field-rendered inputs and the controls panel both read as one consistent surface. date-field controls panel (locale select + name text + min/max date inputs) matches. Closes #47 in the task list. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
/* Generic chrome for every text-like input + select + textarea inside a
demo control. The selector explicitly excludes the input types that
have their own bespoke affordances (checkbox + radio → custom toggle
chrome; range → native track + accent-color). Anything else — text,
number, email, search, date, time, datetime-local, month, week, tel,
url, password, etc. — gets the same neutral chrome so the controls
panel reads as one consistent thing across all demos. */
[data-uix-control] input:not([type='checkbox']):not([type='radio']):not([type='range']),
[data-uix-control] select,
[data-uix-control] textarea {
padding: 6px var(--uix-space-3);
border: 1px solid var(--uix-line);
border-radius: var(--uix-radius-sm);
background: var(--uix-surface);
color: var(--uix-text);
font: inherit;
font-size: var(--uix-text-sm);
demos: homogenize input chrome across all demo Controls The `[data-uix-control] input[type='text|number']` rule only covered two input types, so demos that used `<input type='date'>` (date- and date-range pickers' min/max/start/end inputs, calendar bounds, etc.) or `<input type='email|search|tel|url|password|time|month|week| datetime-local'>` (form/field demos) fell back to the user-agent chrome — different padding, borders, fonts, and the native calendar/clock indicator with no theme alignment. Replaced the type-specific selector with an exclusion list: [data-uix-control] input:not([type='checkbox']):not([type='radio']):not([type='range']) Every text-like input now picks up the demo's standard chrome (6px / 32px / `--uix-line` border / `--uix-surface` bg / focus ring). Checkbox + radio keep their bespoke toggle treatments; range keeps its native track with the demo accent. Added: - Consistent `min-block-size: 32px` + `box-sizing: border-box` so inputs line up vertically with the demo's button-style pill controls. - Disabled state: 0.55 opacity + `not-allowed` cursor. - `::-webkit-calendar-picker-indicator` recolored for date/datetime-local/month/time/week inputs — inverted 70% so the calendar/clock icon reads on dark theme and matches the field text tone, with full opacity on hover. - `::-webkit-search-cancel-button` recolored. Verified in browser: date-range-picker demo's start/end/minValue/ maxValue inputs now match minDays/maxDays (number) and label/name (text) inputs. Form demo Field-rendered inputs and the controls panel both read as one consistent surface. date-field controls panel (locale select + name text + min/max date inputs) matches. Closes #47 in the task list. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
line-height: var(--uix-leading-ui, 1.4);
min-inline-size: 0;
demos: homogenize input chrome across all demo Controls The `[data-uix-control] input[type='text|number']` rule only covered two input types, so demos that used `<input type='date'>` (date- and date-range pickers' min/max/start/end inputs, calendar bounds, etc.) or `<input type='email|search|tel|url|password|time|month|week| datetime-local'>` (form/field demos) fell back to the user-agent chrome — different padding, borders, fonts, and the native calendar/clock indicator with no theme alignment. Replaced the type-specific selector with an exclusion list: [data-uix-control] input:not([type='checkbox']):not([type='radio']):not([type='range']) Every text-like input now picks up the demo's standard chrome (6px / 32px / `--uix-line` border / `--uix-surface` bg / focus ring). Checkbox + radio keep their bespoke toggle treatments; range keeps its native track with the demo accent. Added: - Consistent `min-block-size: 32px` + `box-sizing: border-box` so inputs line up vertically with the demo's button-style pill controls. - Disabled state: 0.55 opacity + `not-allowed` cursor. - `::-webkit-calendar-picker-indicator` recolored for date/datetime-local/month/time/week inputs — inverted 70% so the calendar/clock icon reads on dark theme and matches the field text tone, with full opacity on hover. - `::-webkit-search-cancel-button` recolored. Verified in browser: date-range-picker demo's start/end/minValue/ maxValue inputs now match minDays/maxDays (number) and label/name (text) inputs. Form demo Field-rendered inputs and the controls panel both read as one consistent surface. date-field controls panel (locale select + name text + min/max date inputs) matches. Closes #47 in the task list. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
min-block-size: 32px;
box-sizing: border-box;
}
demos: homogenize input chrome across all demo Controls The `[data-uix-control] input[type='text|number']` rule only covered two input types, so demos that used `<input type='date'>` (date- and date-range pickers' min/max/start/end inputs, calendar bounds, etc.) or `<input type='email|search|tel|url|password|time|month|week| datetime-local'>` (form/field demos) fell back to the user-agent chrome — different padding, borders, fonts, and the native calendar/clock indicator with no theme alignment. Replaced the type-specific selector with an exclusion list: [data-uix-control] input:not([type='checkbox']):not([type='radio']):not([type='range']) Every text-like input now picks up the demo's standard chrome (6px / 32px / `--uix-line` border / `--uix-surface` bg / focus ring). Checkbox + radio keep their bespoke toggle treatments; range keeps its native track with the demo accent. Added: - Consistent `min-block-size: 32px` + `box-sizing: border-box` so inputs line up vertically with the demo's button-style pill controls. - Disabled state: 0.55 opacity + `not-allowed` cursor. - `::-webkit-calendar-picker-indicator` recolored for date/datetime-local/month/time/week inputs — inverted 70% so the calendar/clock icon reads on dark theme and matches the field text tone, with full opacity on hover. - `::-webkit-search-cancel-button` recolored. Verified in browser: date-range-picker demo's start/end/minValue/ maxValue inputs now match minDays/maxDays (number) and label/name (text) inputs. Form demo Field-rendered inputs and the controls panel both read as one consistent surface. date-field controls panel (locale select + name text + min/max date inputs) matches. Closes #47 in the task list. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
[data-uix-control] input:not([type='checkbox']):not([type='radio']):not([type='range']):focus,
[data-uix-control] select:focus,
[data-uix-control] textarea:focus {
outline: none;
border-color: var(--uix-accent-line);
box-shadow: var(--uix-ring);
}
demos: homogenize input chrome across all demo Controls The `[data-uix-control] input[type='text|number']` rule only covered two input types, so demos that used `<input type='date'>` (date- and date-range pickers' min/max/start/end inputs, calendar bounds, etc.) or `<input type='email|search|tel|url|password|time|month|week| datetime-local'>` (form/field demos) fell back to the user-agent chrome — different padding, borders, fonts, and the native calendar/clock indicator with no theme alignment. Replaced the type-specific selector with an exclusion list: [data-uix-control] input:not([type='checkbox']):not([type='radio']):not([type='range']) Every text-like input now picks up the demo's standard chrome (6px / 32px / `--uix-line` border / `--uix-surface` bg / focus ring). Checkbox + radio keep their bespoke toggle treatments; range keeps its native track with the demo accent. Added: - Consistent `min-block-size: 32px` + `box-sizing: border-box` so inputs line up vertically with the demo's button-style pill controls. - Disabled state: 0.55 opacity + `not-allowed` cursor. - `::-webkit-calendar-picker-indicator` recolored for date/datetime-local/month/time/week inputs — inverted 70% so the calendar/clock icon reads on dark theme and matches the field text tone, with full opacity on hover. - `::-webkit-search-cancel-button` recolored. Verified in browser: date-range-picker demo's start/end/minValue/ maxValue inputs now match minDays/maxDays (number) and label/name (text) inputs. Form demo Field-rendered inputs and the controls panel both read as one consistent surface. date-field controls panel (locale select + name text + min/max date inputs) matches. Closes #47 in the task list. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
[data-uix-control] input:not([type='checkbox']):not([type='radio']):not([type='range']):disabled,
[data-uix-control] select:disabled,
[data-uix-control] textarea:disabled {
opacity: 0.55;
cursor: not-allowed;
}
[data-uix-control] input[type="range"] {
inline-size: 100%;
accent-color: var(--uix-accent);
}
demos: homogenize input chrome across all demo Controls The `[data-uix-control] input[type='text|number']` rule only covered two input types, so demos that used `<input type='date'>` (date- and date-range pickers' min/max/start/end inputs, calendar bounds, etc.) or `<input type='email|search|tel|url|password|time|month|week| datetime-local'>` (form/field demos) fell back to the user-agent chrome — different padding, borders, fonts, and the native calendar/clock indicator with no theme alignment. Replaced the type-specific selector with an exclusion list: [data-uix-control] input:not([type='checkbox']):not([type='radio']):not([type='range']) Every text-like input now picks up the demo's standard chrome (6px / 32px / `--uix-line` border / `--uix-surface` bg / focus ring). Checkbox + radio keep their bespoke toggle treatments; range keeps its native track with the demo accent. Added: - Consistent `min-block-size: 32px` + `box-sizing: border-box` so inputs line up vertically with the demo's button-style pill controls. - Disabled state: 0.55 opacity + `not-allowed` cursor. - `::-webkit-calendar-picker-indicator` recolored for date/datetime-local/month/time/week inputs — inverted 70% so the calendar/clock icon reads on dark theme and matches the field text tone, with full opacity on hover. - `::-webkit-search-cancel-button` recolored. Verified in browser: date-range-picker demo's start/end/minValue/ maxValue inputs now match minDays/maxDays (number) and label/name (text) inputs. Form demo Field-rendered inputs and the controls panel both read as one consistent surface. date-field controls panel (locale select + name text + min/max date inputs) matches. Closes #47 in the task list. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
/* Native date/time pickers ship a calendar/clock indicator icon that
shows in browser-default tone. Force inherit so it matches our chrome. */
[data-uix-control] input[type='date']::-webkit-calendar-picker-indicator,
[data-uix-control] input[type='datetime-local']::-webkit-calendar-picker-indicator,
[data-uix-control] input[type='month']::-webkit-calendar-picker-indicator,
[data-uix-control] input[type='time']::-webkit-calendar-picker-indicator,
[data-uix-control] input[type='week']::-webkit-calendar-picker-indicator {
filter: invert(0.7);
cursor: pointer;
opacity: 0.7;
transition: opacity var(--uix-duration-fast, 120ms) ease;
}
[data-uix-control] input[type='date']::-webkit-calendar-picker-indicator:hover,
[data-uix-control] input[type='datetime-local']::-webkit-calendar-picker-indicator:hover,
[data-uix-control] input[type='month']::-webkit-calendar-picker-indicator:hover,
[data-uix-control] input[type='time']::-webkit-calendar-picker-indicator:hover,
[data-uix-control] input[type='week']::-webkit-calendar-picker-indicator:hover {
opacity: 1;
}
/* Search has a browser-default cancel button that may not match the theme. */
[data-uix-control] input[type='search']::-webkit-search-cancel-button {
filter: invert(0.7);
cursor: pointer;
}
/* Switch (boolean) */
[data-uix-switch] {
display: inline-flex;
align-items: center;
gap: 8px;
cursor: pointer;
user-select: none;
}
[data-uix-switch] input[type="checkbox"] {
appearance: none;
-webkit-appearance: none;
inline-size: 30px;
block-size: 16px;
padding: 0;
border: 1px solid var(--uix-line);
border-radius: var(--uix-radius-full);
background: var(--uix-surface-sunken);
cursor: pointer;
position: relative;
transition: background var(--uix-duration-fast) var(--uix-ease), border-color var(--uix-duration-fast) var(--uix-ease);
}
[data-uix-switch] input[type="checkbox"]::after {
content: "";
position: absolute;
inset-inline-start: 1px;
inset-block-start: 1px;
inline-size: 12px;
block-size: 12px;
border-radius: var(--uix-radius-full);
background: var(--uix-text);
transition: transform var(--uix-duration-fast) var(--uix-ease);
}
[data-uix-switch] input[type="checkbox"]:checked {
background: var(--uix-accent);
border-color: var(--uix-accent);
}
[data-uix-switch] input[type="checkbox"]:checked::after {
transform: translateX(14px);
background: white;
}
[data-uix-switch-label] { font-size: var(--uix-text-sm); color: var(--uix-text); }
demos: theme scrollbars + add missing data-uix-radio chrome Two visible inconsistencies in dark theme that the user flagged: 1. Scrollbars in code blocks (and any other scrollable inside the demos) rendered with the user-agent default chrome — bright white track + thumb on a dark surface. Only `[data-uix-rail]` (the left navigation column) had a themed scrollbar. Added a universal WebKit scrollbar theme scoped to `[data-uix-docs]`: transparent track, `--uix-line` thumb with 2px padding-clipped border so it reads as a thin rounded handle that hovers to `--uix-line-strong`. Both axes (10px width). Firefox handled via `scrollbar-color` + `scrollbar-width: thin` on the root. 2. `[data-uix-radio]` had zero CSS rules — the date-range-picker demo's `mode` (inline / modal) selector fell back to native radio inputs and an unstyled label, while its sibling controls used the themed `[data-uix-switch]`. Two switches-as-controls + one set of native radios in the same panel. Mirrored the data-uix-switch chrome at radio size: 16x16 circle, `--uix-line` border, `--uix-surface-sunken` background, inner pill in `--uix-accent` when checked, focus ring matches the rest. Label uses the same color + size as data-uix-switch-label. Verified in browser on date-range-picker demo: the `mode` radios now read as the same control family as the surrounding switches, and the code-snippet scrollbar is dark-themed instead of bright white. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
/* Radio (enum, single-select) — sibling chrome to data-uix-switch so demos
that use radios for picker-style choices read as the same control family. */
[data-uix-radio] {
display: inline-flex;
align-items: center;
gap: 8px;
cursor: pointer;
user-select: none;
}
[data-uix-radio] input[type="radio"] {
appearance: none;
-webkit-appearance: none;
inline-size: 16px;
block-size: 16px;
margin: 0;
padding: 0;
border: 1px solid var(--uix-line);
border-radius: var(--uix-radius-full);
background: var(--uix-surface-sunken);
cursor: pointer;
position: relative;
transition:
background var(--uix-duration-fast) var(--uix-ease),
border-color var(--uix-duration-fast) var(--uix-ease);
}
[data-uix-radio] input[type="radio"]::after {
content: "";
position: absolute;
inset: 3px;
border-radius: var(--uix-radius-full);
background: transparent;
transition: background var(--uix-duration-fast) var(--uix-ease);
}
[data-uix-radio] input[type="radio"]:checked {
border-color: var(--uix-accent);
}
[data-uix-radio] input[type="radio"]:checked::after {
background: var(--uix-accent);
}
[data-uix-radio] input[type="radio"]:focus-visible {
outline: none;
box-shadow: var(--uix-ring);
}
[data-uix-radio-label] { font-size: var(--uix-text-sm); color: var(--uix-text); }
/* Chip group (enum) */
[data-uix-chips] {
display: inline-flex;
flex-wrap: wrap;
gap: 2px;
padding: 3px;
border: 1px solid var(--uix-line);
border-radius: var(--uix-radius-sm);
background: var(--uix-surface-sunken);
}
[data-uix-chip] {
display: inline-flex;
align-items: center;
height: 26px;
padding: 0 10px;
border: 0;
border-radius: var(--uix-radius-xs);
background: transparent;
color: var(--uix-text-muted);
font: inherit;
font-family: var(--uix-font-mono);
font-size: 11px;
cursor: pointer;
transition: color var(--uix-duration-fast) var(--uix-ease), background var(--uix-duration-fast) var(--uix-ease);
}
[data-uix-chip]:hover:not([data-active="true"]) {
color: var(--uix-text);
background: var(--uix-surface);
}
[data-uix-chip][data-active="true"] {
background: var(--uix-surface);
color: var(--uix-accent-text);
box-shadow: 0 1px 2px rgba(0,0,0,0.04);
}
/* ── Props table ──────────────────────────────────────────────────── */
[data-uix-table-wrap] {
border: 1px solid var(--uix-line);
border-radius: var(--uix-radius-md);
background: var(--uix-surface);
overflow-x: auto;
margin-block-end: var(--uix-space-5);
}
[data-uix-table] {
inline-size: 100%;
border-collapse: collapse;
font-size: var(--uix-text-sm);
}
[data-uix-table] thead th {
text-align: start;
padding: var(--uix-space-3) var(--uix-space-4);
background: var(--uix-surface-sunken);
border-block-end: 1px solid var(--uix-line);
font-family: var(--uix-font-mono);
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--uix-text-faint);
font-weight: var(--uix-weight-medium);
}
[data-uix-table] tbody td {
padding: var(--uix-space-3) var(--uix-space-4);
border-block-end: 1px solid var(--uix-line-soft);
vertical-align: top;
color: var(--uix-text-muted);
}
[data-uix-table] tbody tr:last-child td { border-block-end: 0; }
[data-uix-table] td.name {
color: var(--uix-text);
font-family: var(--uix-font-mono);
font-size: var(--uix-text-xs);
white-space: nowrap;
}
[data-uix-table] td.type {
font-family: var(--uix-font-mono);
font-size: var(--uix-text-xs);
color: var(--uix-accent-text);
max-inline-size: 24rem;
}
[data-uix-table] td.default {
font-family: var(--uix-font-mono);
font-size: var(--uix-text-xs);
color: var(--uix-text-subtle);
}
[data-uix-table] td.default.empty { color: var(--uix-text-faint); }
[data-uix-table] td code {
background: transparent;
border: 0;
padding: 0;
color: inherit;
}
[data-uix-tag] {
display: inline-block;
padding: 1px 6px;
margin-inline-start: 4px;
border-radius: var(--uix-radius-xs);
font-family: var(--uix-font-mono);
font-size: 9px;
letter-spacing: 0.06em;
text-transform: uppercase;
background: var(--uix-surface-sunken);
color: var(--uix-text-faint);
}
[data-uix-tag][data-kind="bindable"] { background: var(--uix-accent-soft); color: var(--uix-accent-text); }
[data-uix-tag][data-kind="eidos"] { background: var(--uix-layer-eidos-bg); color: var(--uix-layer-eidos); }
[data-uix-tag][data-kind="soma"] { background: var(--uix-layer-soma-bg); color: var(--uix-layer-soma); }
/* ── Anatomy diagram ──────────────────────────────────────────────── */
[data-uix-anatomy] {
display: flex;
flex-direction: column;
padding: var(--uix-space-3) var(--uix-space-5);
border: 1px solid var(--uix-line);
border-radius: var(--uix-radius-md);
background: var(--uix-surface);
}
[data-uix-part] {
display: grid;
grid-template-columns: 8rem 1fr;
gap: var(--uix-space-4);
align-items: baseline;
padding: var(--uix-space-3) 0;
border-block-end: 1px dashed var(--uix-line);
}
[data-uix-part]:last-child { border-block-end: 0; }
[data-uix-part-name] {
font-family: var(--uix-font-mono);
font-size: var(--uix-text-sm);
color: var(--uix-text);
font-weight: var(--uix-weight-semibold);
}
[data-uix-part-marker] {
font-family: var(--uix-font-mono);
font-size: var(--uix-text-xs);
color: var(--uix-accent-text);
}
[data-uix-part-meta] {
font-family: var(--uix-font-mono);
font-size: 10px;
color: var(--uix-text-faint);
letter-spacing: 0.04em;
text-transform: uppercase;
margin-inline-start: 8px;
}
/* ── Code block (with header) ─────────────────────────────────────── */
[data-uix-code] {
border: 1px solid var(--uix-line);
border-radius: var(--uix-radius-md);
background: var(--uix-code-bg);
overflow: hidden;
margin-block-end: var(--uix-space-5);
}
[data-uix-code-head] {
display: flex;
align-items: center;
gap: var(--uix-space-3);
padding: 8px var(--uix-space-4);
border-block-end: 1px solid var(--uix-line);
background: var(--uix-surface-sunken);
font-family: var(--uix-font-mono);
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--uix-text-faint);
font-weight: var(--uix-weight-medium);
}
[data-uix-code-lang] { margin-inline-start: auto; }
[data-uix-code] pre {
border: 0;
border-radius: 0;
background: transparent;
margin: 0;
}
/* ── Play button (sema) ───────────────────────────────────────────── */
[data-uix-play] {
display: inline-flex;
align-items: center;
gap: 6px;
height: 24px;
padding: 0 10px;
border: 1px solid var(--uix-line);
border-radius: var(--uix-radius-sm);
background: var(--uix-surface);
color: var(--uix-text-muted);
font: inherit;
font-family: var(--uix-font-mono);
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.06em;
cursor: pointer;
}
[data-uix-play]:hover { color: var(--uix-accent-text); border-color: var(--uix-accent-line); }
/* ── Keyboard shortcut ─────────────────────────────────────────────── */
[data-uix-kbd] {
display: inline-flex;
align-items: center;
min-block-size: 22px;
padding: 1px 8px;
border: 1px solid var(--uix-line);
border-block-end-width: 2px;
border-radius: var(--uix-radius-xs);
background: var(--uix-surface);
color: var(--uix-text);
font-family: var(--uix-font-mono);
font-size: 11px;
font-weight: var(--uix-weight-medium);
}
feat(eidos): add Skeleton and Spinner loader primitives Two pure-eidos loader components with morfos at scope `['eidos']` (no soma backing, no semantic events). Skeleton — content placeholder: - 3 shapes: rect (default), circle, text (multi-line with staggered widths) - 5 sizes (xs..xl), 8 color accents - Optional shimmer animation via CSS `background-position` keyframes - Single `<div role="status" aria-busy="true">` with translated aria-label - Reduced-motion freezes animation, keeps visual Spinner — indeterminate progress: - 3 variants: ring (rotating arc), dots (bouncing), bars (stretching) - 5 sizes, 8 colors - Optional inline label via children snippet - `role="status"` + `aria-live="polite"` for SR announcements - Reduced-motion freezes animation, keeps visual Files: - morfo: skeleton.ts, spinner.ts (scope eidos, no events) - eidos: full component + types + css + langs + index per component - langs: skeleton/spinner under componentLangs barrel - demos: canonical 6-tab depth + composition examples (avatar+text card) - layout: sidebar additions under Status group Note: also includes responsive shell additions to web/routes/uix/uix.css that surfaced from an external session — same file, leaving them in. Reference libraries reviewed (Mantine, Chakra v3, Radix Themes, MUI): all expose the same shape/variant/size/color surface. shadcn Skeleton uses the same pulse animation. No surprises in our API. svelte-check: 0 errors in skeleton/spinner files. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
feat: build PasswordField (full stack) Dedicated password input component — matches the Ark UI / Chakra v3 / Mantine / PrimeReact / Ant Design pattern of treating PasswordField as its own first-class component (not a TextField variant). Includes one feature that NO surveyed library ships: a CapsLock indicator driven by KeyboardEvent.getModifierState('CapsLock'). Anatomy (5 parts, 4 events): - Provider (root, value + visibility state) - Input (the textbox; type flips between password / text) - VisibilityTrigger (eye toggle button; aria-pressed + aria-controls) - CapsLockIndicator (status live region; data-active toggles via soma listening to keydown/keyup on Input) - StrengthMeter (composable; consumer provides 0-4 score; UIX bundles no zxcvbn-style algorithm — dependency-free by design) Events: - commit-input (every keystroke) - commit-submit (Enter) - shift-toggle-visibility (eye click) - shift-caps-state (Caps Lock state flips while focused) Key behaviors: - `purpose: 'current' | 'new'` drives native autocomplete attribute ('current-password' for login / 'new-password' for registration). - Field integration: disabled/readonly/required/invalid OR-merged. - VisibilityTrigger gets tabindex=-1 so it doesn't break the form's natural tab order — mouse / programmatic focus only, matching Ark UI. - Caps Lock indicator is aria-live="polite" — announces on activation while focused, silent when inactive. - Letter-spacing increased on the input for legibility while masked. Reference library survey performed (10 libraries) before implementation — all consensus around dedicated component, all have built-in toggle, ZERO have caps lock warning. Documented in the demo's API tab with a feature comparison table. Demo follows DEMO_AUTHORING_GUIDE canonical 6-tab depth: Live (controls grouped by layer + code snippets at the bottom), API (props + reference comparison), Morfo (field/value + Parts + Events tables), Sema (events table with ▶ play), Recipe (selectors with morfo/eidos owner tags), A11y (concern/contract table). Also includes external work in words/ from a separate session (unrelated to PasswordField) — not touching Words is the standing rule, but the diff was already in the working tree. svelte-check: 0 errors in PasswordField files (Words errors are tracked by its own development branch). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
/* ── Responsive docs shell: driven by ActiveDom breakpoints ────────── */
[data-uix-docs][data-uix-compact='true'] [data-uix-shell] {
grid-template-columns: minmax(0, 1fr);
}
[data-uix-docs][data-uix-compact='true'] [data-uix-topbar] {
max-inline-size: 100vi;
overflow: hidden;
padding-inline: var(--uix-space-3);
gap: var(--uix-space-2);
}
[data-uix-docs][data-uix-compact='true'] [data-uix-brand],
[data-uix-docs][data-uix-compact='true'] [data-uix-topbar-nav],
[data-uix-docs][data-uix-compact='true'] [data-uix-topbar-tools] {
min-inline-size: 0;
}
[data-uix-docs][data-uix-compact='true'] [data-uix-brand-version] {
display: none;
}
[data-uix-docs][data-uix-compact='true'] [data-uix-topbar-nav] {
margin-inline-start: 0;
}
[data-uix-docs][data-uix-compact='true'] [data-uix-topbar-nav] a {
padding-inline: var(--uix-space-2);
}
[data-uix-docs][data-uix-compact='true'] [data-uix-topbar-tools] {
flex: 1 1 auto;
justify-content: flex-end;
overflow-x: auto;
overscroll-behavior-inline: contain;
scrollbar-width: none;
}
[data-uix-docs][data-uix-compact='true'] [data-uix-topbar-tools]::-webkit-scrollbar {
display: none;
}
[data-uix-docs][data-uix-compact='true'] [data-uix-rail] {
display: none;
}
[data-uix-docs][data-uix-compact='true'] [data-uix-canvas] {
grid-column: 1;
padding: var(--uix-space-8) var(--uix-space-4) var(--uix-space-12);
}
[data-uix-docs][data-uix-compact='true'] [data-uix-canvas-inner],
[data-uix-docs][data-uix-compact='true'] [data-uix-canvas-inner][data-with-toc='true'] {
display: block;
max-inline-size: none;
}
[data-uix-docs][data-uix-compact='true'] [data-uix-toc] {
display: none;
}
[data-uix-docs][data-uix-phone='true'] [data-uix-topbar-nav] a[href='https://github.com/'] {
display: none;
}
[data-uix-docs][data-uix-phone='true'] [data-uix-canvas] {
padding: var(--uix-space-6) var(--uix-space-3) var(--uix-space-10);
}
[data-uix-docs][data-uix-phone='true'] [data-uix-page-title] {
font-size: var(--uix-text-4xl);
}
[data-uix-docs][data-uix-phone='true'] [data-uix-page-lede] {
font-size: var(--uix-text-lg);
}
[data-uix-docs][data-uix-phone='true'] [data-uix-page-meta],
[data-uix-docs][data-uix-phone='true'] [data-uix-tabs],
[data-uix-docs][data-uix-phone='true'] [data-uix-code-head] {
overflow-x: auto;
overscroll-behavior-inline: contain;
}
[data-uix-docs][data-uix-phone='true'] [data-uix-tabs] {
flex-wrap: nowrap;
}
[data-uix-docs][data-uix-phone='true'] [data-uix-tab],
[data-uix-docs][data-uix-phone='true'] [data-uix-meta-pill],
[data-uix-docs][data-uix-phone='true'] [data-uix-code-head] > * {
flex: 0 0 auto;
}
[data-uix-docs][data-uix-phone='true'] [data-uix-stage-area] {
place-items: stretch;
}
[data-uix-docs][data-uix-phone='true'] [data-uix-stage-trace] {
align-items: flex-start;
gap: var(--uix-space-2);
}
[data-uix-docs][data-uix-phone='true'] [data-uix-controls] {
grid-template-columns: minmax(0, 1fr);
padding: var(--uix-space-4);
}
[data-uix-docs][data-uix-phone='true'] [data-uix-part] {
grid-template-columns: minmax(0, 1fr);
gap: var(--uix-space-2);
feat(eidos): add Skeleton and Spinner loader primitives Two pure-eidos loader components with morfos at scope `['eidos']` (no soma backing, no semantic events). Skeleton — content placeholder: - 3 shapes: rect (default), circle, text (multi-line with staggered widths) - 5 sizes (xs..xl), 8 color accents - Optional shimmer animation via CSS `background-position` keyframes - Single `<div role="status" aria-busy="true">` with translated aria-label - Reduced-motion freezes animation, keeps visual Spinner — indeterminate progress: - 3 variants: ring (rotating arc), dots (bouncing), bars (stretching) - 5 sizes, 8 colors - Optional inline label via children snippet - `role="status"` + `aria-live="polite"` for SR announcements - Reduced-motion freezes animation, keeps visual Files: - morfo: skeleton.ts, spinner.ts (scope eidos, no events) - eidos: full component + types + css + langs + index per component - langs: skeleton/spinner under componentLangs barrel - demos: canonical 6-tab depth + composition examples (avatar+text card) - layout: sidebar additions under Status group Note: also includes responsive shell additions to web/routes/uix/uix.css that surfaced from an external session — same file, leaving them in. Reference libraries reviewed (Mantine, Chakra v3, Radix Themes, MUI): all expose the same shape/variant/size/color surface. shadcn Skeleton uses the same pulse animation. No surprises in our API. svelte-check: 0 errors in skeleton/spinner files. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
}

Powered by TurnKey Linux.