actual-css 0.4.2 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +49 -2
- package/README.md +2 -2
- package/dist/actual.css +53 -14
- package/dist/actual.full.css +287 -91
- package/dist/actual.full.js +1 -1
- package/dist/actual.full.min.css +1 -1
- package/dist/actual.min.css +1 -1
- package/docs/design-notes/spacing-units.md +286 -0
- package/docs/navigation.json +1 -0
- package/docs/pages/components/alert.md +1 -1
- package/docs/pages/components/app-navigation.md +2 -0
- package/docs/pages/components/badge.md +17 -3
- package/docs/pages/components/button.md +9 -2
- package/docs/pages/components/card.md +13 -0
- package/docs/pages/components/data-list.md +72 -0
- package/docs/pages/components/dialog.md +2 -0
- package/docs/pages/components/drawer.md +2 -0
- package/docs/pages/components/fab.md +2 -0
- package/docs/pages/components/meter.md +56 -1
- package/docs/pages/components/progress.md +10 -0
- package/docs/pages/components/skeleton.md +2 -0
- package/docs/pages/components/steps.md +10 -2
- package/docs/pages/components/table.md +1 -0
- package/docs/pages/enhancements/flyout.md +2 -0
- package/docs/pages/enhancements/status-bar.md +10 -1
- package/docs/pages/examples/overview.md +2 -1
- package/docs/pages/forms/joined-controls.md +2 -0
- package/docs/pages/forms/overview.md +1 -1
- package/docs/pages/forms/range.md +2 -0
- package/docs/pages/forms/states-and-sizes.md +1 -1
- package/docs/pages/forms/validation.md +2 -0
- package/docs/pages/foundations/philosophy.md +11 -1
- package/docs/pages/foundations/tokens.md +7 -3
- package/docs/pages/foundations/typography.md +10 -2
- package/docs/pages/guides/introduction.md +1 -1
- package/docs/pages/layout/scroll-snap.md +2 -0
- package/docs/pages/layout/sidebar-layout.md +2 -0
- package/docs/pages/layout/topbar.md +2 -0
- package/docs/pages/utilities/accessibility.md +18 -0
- package/package.json +1 -1
- package/scripts/reserved-classes.json +4 -0
- package/src/css/components/data-list.css +27 -0
- package/src/css/components/drawer.css +30 -11
- package/src/css/components/flyout.css +17 -12
- package/src/css/components/index.css +1 -0
- package/src/css/components/meter.css +28 -1
- package/src/css/components/modal.css +28 -11
- package/src/css/components/progress.css +5 -0
- package/src/css/components/status-bar.css +31 -15
- package/src/css/components/steps.css +35 -9
- package/src/css/components/surface.css +5 -3
- package/src/css/components/tooltip.css +5 -8
- package/src/css/core/base.css +7 -1
- package/src/css/core/intents.css +6 -0
- package/src/css/core/tokens.css +23 -9
- package/src/css/core/variants.css +17 -4
- package/src/css/forms/form.css +4 -4
- package/src/css/typography/prose.css +2 -3
- package/src/css/utilities/base.css +16 -0
- package/src/js/selectors.js +1 -0
- package/src/js/status.js +88 -7
- package/src/js/surface.js +2 -11
- package/src/js/transition.js +20 -0
package/dist/actual.min.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
*, *::before, *::after { box-sizing: border-box; } html { -webkit-text-size-adjust: 100%; } body { margin: 0; } button, input, textarea, select { font: inherit; } [hidden]:not([hidden="until-found"]) { display: none !important; } :where(img, svg, video) { max-inline-size: 100%; block-size: auto; } @media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto !important; } *, *::before, *::after { animation-duration: 0.01ms !important; animation-delay: 0s !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; transition-delay: 0s !important; } } :root { --font-sans: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; --line-height: 1.5; --line-height-tight: 1.25; --line-height-relaxed: 1.75; --font-weight: 400; --font-weight-medium: 500; --font-weight-strong: 650; --font-weight-bold: 700; --font-size-xs: 0.8125rem; --font-size-sm: 0.875rem; --font-size-md: 1rem; --font-size-lg: 1.125rem; --gap: 0.75rem; --density-space: var(--space-40); --density-compact-size: 1.5rem; --space-10: 0.25rem; --space-20: 0.5rem; --space-30: 0.75rem; --space-40: 1rem; --space-50: 1.5rem; --space-60: 2rem; --border-width: 1px; --radius-full: 9999px; --shadow: 0 1px 3px rgb(0 0 0 / 0.05), 0 4px 12px rgb(0 0 0 / 0.04); --shadow-popout: 0 0.25rem 0.75rem rgb(0 0 0 / 0.15); --duration: 150ms; --duration-fast: 100ms; --duration-slow: 200ms; --duration-spin: 0.75s; --duration-shimmer: 1.2s; --ease: ease; --focus-outline-color: currentColor; --focus-outline: calc(var(--border-width) * 2) solid var(--focus-outline-color); --focus-outline-offset: 2px; --focus-ring-width: 3px; --indicator-offset: 14.65%; --backdrop-color: rgb(0 0 0); --backdrop-opacity: 0.45; --backdrop-fill: rgb(0 0 0 / var(--backdrop-opacity)); --bar-height: 0.65rem; --control-size-sm: 2rem; --control-size-md: 2.375rem; --control-size-lg: 2.75rem; --control-size: var(--control-size-md); --control-pad-x: 1em; --control-font-size: var(--font-size-md); --choice-control-size: 1.125em; --disabled-opacity: 0.65; } :root, [data-theme] { --state-selected: var(--primary); --state-selected-fg: var(--primary-fg); --state-disabled: var(--text-subtle); --indicator-ring: var(--surface); } :root { --soft-bg-mix: 88%; --soft-border-mix: 65%; --soft-hover-alpha: 12%; --soft-fg-mix: 100%; --icon-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%238a8594' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E"); --icon-check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E"); --icon-close: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='6' y1='6' x2='18' y2='18'/%3E%3Cline x1='18' y1='6' x2='6' y2='18'/%3E%3C/svg%3E"); --viewport-block: 100vh; --viewport-inline: 100vw; --z-sticky: 10; --z-menu: 20; --z-tooltip: 50; --z-status: 60; } @media (forced-colors: active) { :root, [data-theme] { --state-disabled: GrayText; --disabled-opacity: 1; } } @supports (block-size: 100dvh) { :root { --viewport-block: 100dvh; } } @supports (inline-size: 100vi) { :root { --viewport-inline: 100vi; } } @supports (color: color-mix(in oklch, red, white)) { :root, [data-theme] { --shadow: 0 1px 3px color-mix(in oklch, var(--shadow-color) 5%, transparent), 0 4px 12px color-mix(in oklch, var(--shadow-color) 4%, transparent); --shadow-popout: 0 0.25rem 0.75rem color-mix(in oklch, var(--shadow-color) 15%, transparent); } :root { --backdrop-fill: color-mix( in oklch, var(--backdrop-color) calc(var(--backdrop-opacity) * 100%), transparent ); } } :root { color-scheme: light dark; } [data-theme="light"] { color-scheme: light; } [data-theme="dark"] { color-scheme: dark; } @supports not (color: light-dark(red, blue)) { :root, [data-theme="light"], [data-theme="dark"] { color-scheme: light; } } :root, [data-theme="light"] { --primary: hsl(268 32% 33%); --primary-fg: hsl(0 0% 98%); --secondary: hsl(16 38% 38%); --secondary-fg: hsl(0 0% 98%); --success: hsl(150 40% 31%); --success-fg: hsl(0 0% 98%); --warning: hsl(36 68% 34%); --warning-fg: hsl(0 0% 98%); --danger: hsl(5 58% 43%); --danger-fg: hsl(0 0% 98%); --neutral: hsl(258 7% 43%); --neutral-fg: hsl(0 0% 98%); --surface: hsl(0 0% 100%); --surface-raised: hsl(0 0% 100%); --surface-subtle: hsl(262 24% 96%); --surface-solid: hsl(261 16% 13%); --text: hsl(261 20% 13%); --text-muted: hsl(259 9% 42%); --text-subtle: hsl(258 7% 57%); --border: hsl(260 15% 88%); --focus: var(--neutral); --focus-ring: hsl(258 7% 43% / 0.3); --hover-overlay: hsl(260 20% 10% / 0.04); --radius: 0.5rem; --radius-sm: 0.25rem; --radius-lg: 0.75rem; --shadow-color: hsl(260 25% 10%); --hgroup-gap: 0.25em; } :root, [data-theme] { --heading: var(--text); --selection-bg: var(--primary); --selection-fg: var(--primary-fg); --focus-ring-shadow: 0 0 0 var(--focus-ring-width) var(--focus-ring); } :root, [data-theme] { accent-color: var(--primary); } [data-tone="dark"] { --tone-fg: white; } [data-tone="light"] { --tone-fg: var(--text); } @supports (color: color-mix(in oklch, red, white)) { :root, [data-theme] { --focus-ring: color-mix(in oklch, var(--focus) 30%, transparent); } } @supports (color: light-dark(red, blue)) { :root, [data-theme="light"] { --primary: light-dark(hsl(268 32% 33%), hsl(268 42% 76%)); --primary-fg: light-dark(hsl(0 0% 98%), hsl(268 30% 12%)); --secondary: light-dark(hsl(16 38% 38%), hsl(18 45% 72%)); --secondary-fg: light-dark(hsl(0 0% 98%), hsl(18 32% 11%)); --success: light-dark(hsl(150 40% 31%), hsl(150 38% 62%)); --success-fg: light-dark(hsl(0 0% 98%), hsl(150 35% 8%)); --warning: light-dark(hsl(36 68% 34%), hsl(40 62% 64%)); --warning-fg: light-dark(hsl(0 0% 98%), hsl(38 35% 10%)); --danger: light-dark(hsl(5 58% 43%), hsl(4 60% 70%)); --danger-fg: light-dark(hsl(0 0% 98%), hsl(4 35% 10%)); --neutral: light-dark(hsl(258 7% 43%), hsl(258 10% 72%)); --neutral-fg: light-dark(hsl(0 0% 98%), hsl(260 18% 10%)); --surface: light-dark(hsl(0 0% 100%), hsl(263 17% 9%)); --surface-raised: light-dark(hsl(0 0% 100%), hsl(263 15% 12%)); --surface-subtle: light-dark(hsl(262 24% 96%), hsl(263 13% 16%)); --surface-solid: light-dark(hsl(261 16% 13%), hsl(0 0% 96%)); --text: light-dark(hsl(261 20% 13%), hsl(260 12% 95%)); --text-muted: light-dark(hsl(259 9% 42%), hsl(259 9% 67%)); --text-subtle: light-dark(hsl(258 7% 57%), hsl(258 7% 54%)); --border: light-dark(hsl(260 15% 88%), hsl(262 12% 24%)); --focus-ring: light-dark(hsl(258 7% 43% / 0.3), hsl(258 10% 72% / 0.28)); --hover-overlay: light-dark(hsl(260 20% 10% / 0.04), hsl(0 0% 100% / 0.06)); --shadow-color: light-dark(hsl(260 25% 10%), hsl(262 40% 2%)); } } @supports (color: color-mix(in oklch, red, white)) and (color: light-dark(red, blue)) { :root, [data-theme] { --focus-ring: light-dark( color-mix(in oklch, var(--focus) 30%, transparent), color-mix(in oklch, var(--focus) 28%, transparent) ); } } @media (prefers-contrast: more) { :root, [data-theme][data-theme] { --border-width: 2px; --focus-outline-offset: 3px; --focus-ring-width: 4px; --text-muted: var(--text); --text-subtle: var(--text); } } body { background: var(--surface); color: var(--text); font-family: var(--font-sans); line-height: var(--line-height); } a { color: inherit; text-underline-offset: 0.18em; } a:hover { text-decoration-thickness: 0.12em; } :where(h1, h2, h3, h4, h5, h6) { color: var(--heading, inherit); line-height: var(--line-height-tight); text-wrap: balance; } hgroup { display: grid; gap: var(--hgroup-gap); } hgroup > * { margin-block: 0; } hr { border: 0; border-block-start: var(--border-width) solid var(--border); margin-block: var(--space-60); } code, kbd, samp, pre { font-family: var(--font-mono); } small { font-size: 0.875em; } ::selection { background: var(--selection-bg, var(--primary)); color: var(--selection-fg, var(--primary-fg)); } .primary { --intent: var(--primary); --intent-fg: var(--primary-fg); } .secondary { --intent: var(--secondary); --intent-fg: var(--secondary-fg); } .success { --intent: var(--success); --intent-fg: var(--success-fg); } .warning { --intent: var(--warning); --intent-fg: var(--warning-fg); } .danger { --intent: var(--danger); --intent-fg: var(--danger-fg); } .neutral { --intent: var(--neutral); --intent-fg: var(--neutral-fg); } .solid { --ui-bg: var(--intent, var(--neutral)); --ui-fg: var(--intent-fg, var(--neutral-fg)); --ui-border: transparent; } .soft { --ui-bg: var(--surface-subtle); --ui-border: var(--border); --ui-fg: var(--intent, var(--text)); } .outline { --ui-bg: transparent; --ui-fg: var(--intent, currentColor); --ui-border: var(--intent, currentColor); } .inverted { --ui-bg: var(--surface-solid); --ui-fg: var(--surface); --ui-border: transparent; --ui-hover-bg: var(--surface-solid); --heading: var(--surface); --busy-overlay-bg: var(--surface-solid); background: var(--ui-bg); color: var(--ui-fg); border-color: var(--ui-border); } .sm { --gap: var(--space-20); --density-space: var(--space-20); --control-size: var(--control-size-sm); --density-compact-size: 1.25rem; } .lg { --gap: var(--space-50); --density-space: var(--space-50); --control-size: var(--control-size-lg); --density-compact-size: 1.875rem; } @supports (color: color-mix(in oklch, red, white)) { .soft { --ui-bg: color-mix(in oklab, var(--surface) var(--soft-bg-mix), var(--intent, var(--neutral))); --ui-border: color-mix( in oklab, var(--surface) var(--soft-border-mix), var(--intent, var(--neutral)) ); --ui-fg: color-mix(in oklab, var(--text), var(--intent, var(--text)) var(--soft-fg-mix)); } .inverted { --ui-hover-bg: color-mix(in oklch, var(--surface-solid) 88%, black); } } :focus { outline: var(--focus-outline); outline-offset: var(--focus-outline-offset); } @supports selector(:focus-visible) { :focus:not(:focus-visible) { outline: none; } } @media print { :root, body { color-scheme: light; background: #fff; color: #000; } h1, h2, h3, h4, h5, h6 { break-after: avoid; } }
|
|
1
|
+
*, *::before, *::after { box-sizing: border-box; } html { -webkit-text-size-adjust: 100%; } body { margin: 0; } button, input, textarea, select { font: inherit; } [hidden]:not([hidden="until-found"]) { display: none !important; } :where(img, svg, video) { max-inline-size: 100%; block-size: auto; } @media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto !important; } *, *::before, *::after { animation-duration: 0.01ms !important; animation-delay: 0s !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; transition-delay: 0s !important; } } :root { --font-sans: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; --line-height: 1.5; --line-height-tight: 1.25; --line-height-relaxed: 1.75; --font-weight: 400; --font-weight-medium: 500; --font-weight-strong: 650; --font-weight-bold: 700; --font-size-xs: 0.8125rem; --font-size-sm: 0.875rem; --font-size-md: 1rem; --font-size-lg: 1.125rem; --gap: 0.75rem; --density-space: var(--space-40); --density-compact-size: 1.5rem; --space-10: 0.25rem; --space-20: 0.5rem; --space-30: 0.75rem; --space-40: 1rem; --space-50: 1.5rem; --space-60: 2rem; --border-width: 1px; --radius-full: 9999px; --shadow: 0 1px 3px rgb(0 0 0 / 0.05), 0 4px 12px rgb(0 0 0 / 0.04); --shadow-popout: 0 0.25rem 0.75rem rgb(0 0 0 / 0.15); --duration: 150ms; --duration-fast: 100ms; --duration-slow: 200ms; --duration-spin: 0.75s; --duration-shimmer: 1.2s; --ease-enter: cubic-bezier(0.2, 0, 0, 1); --ease-exit: cubic-bezier(0.4, 0, 1, 1); --focus-outline-color: currentColor; --focus-outline: calc(var(--border-width) * 2) solid var(--focus-outline-color); --focus-outline-offset: 2px; --focus-ring-width: 3px; --indicator-offset: 14.65%; --backdrop-color: rgb(0 0 0); --backdrop-opacity: 0.45; --backdrop-fill: rgb(0 0 0 / var(--backdrop-opacity)); --bar-height: 0.65rem; --control-size-sm: 2rem; --control-size-md: 2.375rem; --control-size-lg: 2.75rem; --control-size: var(--control-size-md); --control-pad-x: 1em; --control-font-size: var(--font-size-md); --choice-control-size: 1.125em; --disabled-opacity: 0.65; } :root, [data-theme] { --state-selected: var(--primary); --state-selected-fg: var(--primary-fg); --state-disabled: var(--text-subtle); --indicator-ring: var(--surface); } :root { --soft-bg-mix: 88%; --soft-border-mix: 65%; --soft-hover-alpha: 12%; --soft-fg-mix: 100%; --icon-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%238a8594' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E"); --icon-check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E"); --icon-close: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='6' y1='6' x2='18' y2='18'/%3E%3Cline x1='18' y1='6' x2='6' y2='18'/%3E%3C/svg%3E"); --viewport-block: 100vh; --viewport-inline: 100vw; --z-sticky: 10; --z-menu: 20; --z-tooltip: 50; --z-status: 60; } @media (forced-colors: active) { :root, [data-theme] { --state-disabled: GrayText; --disabled-opacity: 1; } } @supports (block-size: 100dvh) { :root { --viewport-block: 100dvh; } } @supports (inline-size: 100vi) { :root { --viewport-inline: 100vi; } } @supports (color: color-mix(in oklch, red, white)) { :root, [data-theme] { --shadow: 0 1px 3px color-mix(in oklch, var(--shadow-color) 5%, transparent), 0 4px 12px color-mix(in oklch, var(--shadow-color) 4%, transparent); --shadow-popout: 0 0.25rem 0.75rem color-mix(in oklch, var(--shadow-color) 15%, transparent); } :root { --backdrop-fill: color-mix( in oklch, var(--backdrop-color) calc(var(--backdrop-opacity) * 100%), transparent ); } } :root { color-scheme: light dark; } [data-theme="light"] { color-scheme: light; } [data-theme="dark"] { color-scheme: dark; } @supports not (color: light-dark(red, blue)) { :root, [data-theme="light"], [data-theme="dark"] { color-scheme: light; } } :root, [data-theme="light"] { --primary: hsl(268 32% 33%); --primary-fg: hsl(0 0% 98%); --secondary: hsl(16 38% 38%); --secondary-fg: hsl(0 0% 98%); --success: hsl(150 40% 31%); --success-fg: hsl(0 0% 98%); --warning: hsl(36 68% 34%); --warning-fg: hsl(0 0% 98%); --danger: hsl(5 58% 43%); --danger-fg: hsl(0 0% 98%); --neutral: hsl(258 7% 43%); --neutral-fg: hsl(0 0% 98%); --surface: hsl(0 0% 100%); --surface-raised: hsl(0 0% 100%); --surface-subtle: hsl(262 24% 96%); --surface-solid: hsl(261 16% 13%); --text: hsl(261 20% 13%); --text-muted: hsl(259 9% 42%); --text-subtle: hsl(258 7% 57%); --border: hsl(260 15% 88%); --focus: var(--neutral); --focus-ring: hsl(258 7% 43% / 0.3); --hover-overlay: hsl(260 20% 10% / 0.04); --radius: 0.5rem; --radius-sm: 0.25rem; --radius-lg: 0.75rem; --shadow-color: hsl(260 25% 10%); --hgroup-gap: 0.25em; } :root, [data-theme] { --heading: var(--text); --selection-bg: var(--primary); --selection-fg: var(--primary-fg); --focus-ring-shadow: 0 0 0 var(--focus-ring-width) var(--focus-ring); } :root, [data-theme] { accent-color: var(--primary); } [data-tone="dark"] { --tone-fg: white; } [data-tone="light"] { --tone-fg: var(--text); } @supports (color: color-mix(in oklch, red, white)) { :root, [data-theme] { --focus-ring: color-mix(in oklch, var(--focus) 30%, transparent); } } @supports (color: light-dark(red, blue)) { :root, [data-theme="light"] { --primary: light-dark(hsl(268 32% 33%), hsl(268 42% 76%)); --primary-fg: light-dark(hsl(0 0% 98%), hsl(268 30% 12%)); --secondary: light-dark(hsl(16 38% 38%), hsl(18 45% 72%)); --secondary-fg: light-dark(hsl(0 0% 98%), hsl(18 32% 11%)); --success: light-dark(hsl(150 40% 31%), hsl(150 38% 62%)); --success-fg: light-dark(hsl(0 0% 98%), hsl(150 35% 8%)); --warning: light-dark(hsl(36 68% 34%), hsl(40 62% 64%)); --warning-fg: light-dark(hsl(0 0% 98%), hsl(38 35% 10%)); --danger: light-dark(hsl(5 58% 43%), hsl(4 60% 70%)); --danger-fg: light-dark(hsl(0 0% 98%), hsl(4 35% 10%)); --neutral: light-dark(hsl(258 7% 43%), hsl(258 10% 72%)); --neutral-fg: light-dark(hsl(0 0% 98%), hsl(260 18% 10%)); --surface: light-dark(hsl(0 0% 100%), hsl(263 17% 9%)); --surface-raised: light-dark(hsl(0 0% 100%), hsl(263 15% 12%)); --surface-subtle: light-dark(hsl(262 24% 96%), hsl(263 13% 16%)); --surface-solid: light-dark(hsl(261 16% 13%), hsl(0 0% 96%)); --text: light-dark(hsl(261 20% 13%), hsl(260 12% 95%)); --text-muted: light-dark(hsl(259 9% 42%), hsl(259 9% 67%)); --text-subtle: light-dark(hsl(258 7% 57%), hsl(258 7% 54%)); --border: light-dark(hsl(260 15% 88%), hsl(262 12% 24%)); --focus-ring: light-dark(hsl(258 7% 43% / 0.3), hsl(258 10% 72% / 0.28)); --hover-overlay: light-dark(hsl(260 20% 10% / 0.04), hsl(0 0% 100% / 0.06)); --shadow-color: light-dark(hsl(260 25% 10%), hsl(262 40% 2%)); } } @supports (color: color-mix(in oklch, red, white)) and (color: light-dark(red, blue)) { :root, [data-theme] { --focus-ring: light-dark( color-mix(in oklch, var(--focus) 30%, transparent), color-mix(in oklch, var(--focus) 28%, transparent) ); } } @media (prefers-contrast: more) { :root, [data-theme][data-theme] { --border-width: 2px; --focus-outline-offset: 3px; --focus-ring-width: 4px; --text-muted: var(--text); --text-subtle: var(--text); } } body { background: var(--surface); color: var(--text); font-family: var(--font-sans); line-height: var(--line-height); } a { color: var(--link, inherit); text-underline-offset: 0.18em; } a:hover { text-decoration-thickness: 0.12em; } :where(h1, h2, h3, h4, h5, h6) { color: var(--heading, inherit); line-height: var(--line-height-tight); text-wrap: balance; } hgroup { display: grid; gap: var(--hgroup-gap); } hgroup > * { margin-block: 0; } hr { border: 0; border-block-start: var(--border-width) solid var(--border); margin-block: var(--space-60); } code, kbd, samp, pre { font-family: var(--font-mono); } small { font-size: 0.875em; } ::selection { background: var(--selection-bg, var(--primary)); color: var(--selection-fg, var(--primary-fg)); } .primary { --intent: var(--primary); --intent-fg: var(--primary-fg); } .secondary { --intent: var(--secondary); --intent-fg: var(--secondary-fg); } .success { --intent: var(--success); --intent-fg: var(--success-fg); } .warning { --intent: var(--warning); --intent-fg: var(--warning-fg); } .danger { --intent: var(--danger); --intent-fg: var(--danger-fg); } .neutral { --intent: var(--neutral); --intent-fg: var(--neutral-fg); } .intent-color { color: var(--intent); } .solid { --ui-bg: var(--intent, var(--neutral)); --ui-fg: var(--intent-fg, var(--neutral-fg)); --ui-border: transparent; } .soft { --ui-bg: var(--surface-subtle); --ui-border: var(--border); --ui-fg: var(--intent, var(--text)); } .outline { --ui-bg: transparent; --ui-fg: var(--intent, currentColor); --ui-border: var(--intent, currentColor); } .surface { --ui-bg: var(--surface); --ui-fg: var(--intent, var(--text)); --ui-border: var(--border); } .inverted { --ui-bg: var(--surface-solid); --ui-fg: var(--surface); --ui-border: transparent; --ui-hover-bg: var(--surface-solid); --heading: var(--surface); --busy-overlay-bg: var(--surface-solid); background: var(--ui-bg); color: var(--ui-fg); border-color: var(--ui-border); } .sm { --gap: var(--space-20); --density-space: var(--space-20); --control-size: var(--control-size-sm); --density-compact-size: 1.25rem; } .lg { --gap: var(--space-50); --density-space: var(--space-50); --control-size: var(--control-size-lg); --density-compact-size: 1.875rem; } @supports (color: color-mix(in oklch, red, white)) { .soft { --ui-bg: color-mix(in oklab, var(--surface) var(--soft-bg-mix), var(--intent, var(--neutral))); --ui-border: color-mix( in oklab, var(--surface) var(--soft-border-mix), var(--intent, var(--neutral)) ); --ui-fg: color-mix(in oklab, var(--text), var(--intent, var(--text)) var(--soft-fg-mix)); } .inverted { --ui-hover-bg: color-mix(in oklch, var(--surface-solid) 88%, black); } } :focus { outline: var(--focus-outline); outline-offset: var(--focus-outline-offset); } @supports selector(:focus-visible) { :focus:not(:focus-visible) { outline: none; } } @media print { :root, body { color-scheme: light; background: #fff; color: #000; } h1, h2, h3, h4, h5, h6 { break-after: avoid; } }
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
# Spacing Units: When to Use `em`, `rem`, `ch`, `lh`, or `--space-*`
|
|
2
|
+
|
|
3
|
+
Actual does not require every relative length to come from a design token.
|
|
4
|
+
|
|
5
|
+
CSS relative units already carry useful semantics. A literal `0.5em`, `1lh`, `20rem`, or `65ch` can be more meaningful than replacing it with an unrelated spacing token.
|
|
6
|
+
|
|
7
|
+
The goal is not to eliminate literal values. The goal is to choose the unit that best expresses the relationship.
|
|
8
|
+
|
|
9
|
+
## Core rule
|
|
10
|
+
|
|
11
|
+
Use `--space-*` when the value belongs to the **shared interface rhythm**.
|
|
12
|
+
|
|
13
|
+
Use a CSS relative unit when the value belongs to the **intrinsic geometry or typography of the component**.
|
|
14
|
+
|
|
15
|
+
A useful question is:
|
|
16
|
+
|
|
17
|
+
> If this value changes, is that a design-system decision or a local relationship inside the component?
|
|
18
|
+
|
|
19
|
+
If it is a design-system decision, prefer a token.
|
|
20
|
+
|
|
21
|
+
If it is a local relationship, prefer the appropriate CSS unit.
|
|
22
|
+
|
|
23
|
+
## `--space-*`: interface rhythm
|
|
24
|
+
|
|
25
|
+
Use spacing tokens for layout distances that should remain consistent across components and respond to Actual's density system.
|
|
26
|
+
|
|
27
|
+
Typical cases:
|
|
28
|
+
|
|
29
|
+
```css
|
|
30
|
+
.card {
|
|
31
|
+
padding: var(--space-40);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.cluster {
|
|
35
|
+
gap: var(--space-20);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.data-list {
|
|
39
|
+
gap: var(--space-20) var(--space-40);
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Good candidates include:
|
|
44
|
+
|
|
45
|
+
* component padding
|
|
46
|
+
* gaps between peer controls
|
|
47
|
+
* spacing between sections
|
|
48
|
+
* list and grid gaps
|
|
49
|
+
* toolbar spacing
|
|
50
|
+
* application layout rhythm
|
|
51
|
+
|
|
52
|
+
Using a spacing token also communicates that the value is expected to participate in density changes.
|
|
53
|
+
|
|
54
|
+
Do not use `--space-*` merely to avoid writing a literal relative unit.
|
|
55
|
+
|
|
56
|
+
## `em`: relative to the local text
|
|
57
|
+
|
|
58
|
+
Use `em` when a dimension should scale with the font size of the element or component.
|
|
59
|
+
|
|
60
|
+
Typical cases:
|
|
61
|
+
|
|
62
|
+
```css
|
|
63
|
+
.prose dd {
|
|
64
|
+
margin-inline-start: 1.5em;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.inline-icon {
|
|
68
|
+
margin-inline-end: 0.4em;
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Good candidates include:
|
|
73
|
+
|
|
74
|
+
* typographic indentation
|
|
75
|
+
* small offsets around inline icons
|
|
76
|
+
* decorative elements sized relative to text
|
|
77
|
+
* local relationships that should scale when the component font size changes
|
|
78
|
+
|
|
79
|
+
`em` is especially useful when the relationship is best understood as:
|
|
80
|
+
|
|
81
|
+
> some fraction or multiple of this text size
|
|
82
|
+
|
|
83
|
+
Do not use `em` for general application spacing when local font-size changes should not affect the layout.
|
|
84
|
+
|
|
85
|
+
## `rem`: relative to the root scale
|
|
86
|
+
|
|
87
|
+
Use `rem` when a dimension should follow the user's/root font size but remain independent of a component's local typography.
|
|
88
|
+
|
|
89
|
+
Typical cases:
|
|
90
|
+
|
|
91
|
+
```css
|
|
92
|
+
.sidebar {
|
|
93
|
+
inline-size: 18rem;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.dialog {
|
|
97
|
+
max-inline-size: 36rem;
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Good candidates include:
|
|
102
|
+
|
|
103
|
+
* component size constraints
|
|
104
|
+
* layout thresholds
|
|
105
|
+
* widths and heights tied to the overall UI scale
|
|
106
|
+
* values that should remain stable when nested inside differently sized text
|
|
107
|
+
|
|
108
|
+
A literal `18rem` does not need a custom property unless the value itself is part of the public API, reused significantly, or expected to be configured.
|
|
109
|
+
|
|
110
|
+
## `ch`: text-measure relationships
|
|
111
|
+
|
|
112
|
+
Use `ch` when a dimension is naturally related to the approximate width of characters.
|
|
113
|
+
|
|
114
|
+
Typical cases:
|
|
115
|
+
|
|
116
|
+
```css
|
|
117
|
+
.prose {
|
|
118
|
+
max-inline-size: 65ch;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.search-field {
|
|
122
|
+
inline-size: 24ch;
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Good candidates include:
|
|
127
|
+
|
|
128
|
+
* readable text measures
|
|
129
|
+
* text-oriented input widths
|
|
130
|
+
* content regions whose useful size is determined by expected text length
|
|
131
|
+
|
|
132
|
+
Do not use `ch` as a generic substitute for `rem`; its value depends on font metrics.
|
|
133
|
+
|
|
134
|
+
## `lh`: line-height relationships
|
|
135
|
+
|
|
136
|
+
Use `lh` when a dimension should be directly related to the computed line height.
|
|
137
|
+
|
|
138
|
+
Typical cases:
|
|
139
|
+
|
|
140
|
+
```css
|
|
141
|
+
.floating-label {
|
|
142
|
+
inset-block-start: calc(0.5lh + var(--border-width));
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Good candidates include:
|
|
147
|
+
|
|
148
|
+
* vertical positioning relative to a line of text
|
|
149
|
+
* text-area or field geometry
|
|
150
|
+
* offsets that conceptually represent one or part of one line
|
|
151
|
+
|
|
152
|
+
`lh` is preferable to reconstructing line height indirectly from font size when line height is the actual relationship being expressed.
|
|
153
|
+
|
|
154
|
+
## Choosing between them
|
|
155
|
+
|
|
156
|
+
| Intent | Prefer |
|
|
157
|
+
| --------------------------------------- | ---------------- |
|
|
158
|
+
| Shared application spacing | `var(--space-*)` |
|
|
159
|
+
| Density-aware spacing | `var(--space-*)` |
|
|
160
|
+
| Local relationship to component text | `em` |
|
|
161
|
+
| Stable size relative to root typography | `rem` |
|
|
162
|
+
| Width related to text length | `ch` |
|
|
163
|
+
| Geometry related to line height | `lh` |
|
|
164
|
+
|
|
165
|
+
## Examples
|
|
166
|
+
|
|
167
|
+
### System rhythm
|
|
168
|
+
|
|
169
|
+
```css
|
|
170
|
+
.alert {
|
|
171
|
+
padding: var(--space-30) var(--space-40);
|
|
172
|
+
gap: var(--space-30);
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
The spacing is part of the visual density and should stay aligned with other components.
|
|
177
|
+
|
|
178
|
+
### Intrinsic typography
|
|
179
|
+
|
|
180
|
+
```css
|
|
181
|
+
.prose dd {
|
|
182
|
+
margin-inline-start: 1.5em;
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
The indentation belongs to the description text itself. A spacing token would add no useful meaning.
|
|
187
|
+
|
|
188
|
+
### Stable component width
|
|
189
|
+
|
|
190
|
+
```css
|
|
191
|
+
.sidebar {
|
|
192
|
+
flex-basis: 18rem;
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
The width belongs to the component geometry, not to the spacing scale.
|
|
197
|
+
|
|
198
|
+
### Readable prose
|
|
199
|
+
|
|
200
|
+
```css
|
|
201
|
+
.prose {
|
|
202
|
+
max-inline-size: 65ch;
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
The width exists to control line length, so `ch` expresses the intention directly.
|
|
207
|
+
|
|
208
|
+
### Line-relative positioning
|
|
209
|
+
|
|
210
|
+
```css
|
|
211
|
+
.field-label {
|
|
212
|
+
inset-block-start: 0.5lh;
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
The position is defined relative to the text line, not to global spacing.
|
|
217
|
+
|
|
218
|
+
## Avoid token laundering
|
|
219
|
+
|
|
220
|
+
Do not replace meaningful CSS units with spacing tokens simply to make a stylesheet appear more tokenized.
|
|
221
|
+
|
|
222
|
+
Avoid patterns such as:
|
|
223
|
+
|
|
224
|
+
```css
|
|
225
|
+
.icon {
|
|
226
|
+
translate: 0 var(--space-10);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
.prose {
|
|
230
|
+
max-inline-size: var(--space-900);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.label {
|
|
234
|
+
margin-inline-end: var(--space-20);
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
when the real relationships would be better expressed as:
|
|
239
|
+
|
|
240
|
+
```css
|
|
241
|
+
.icon {
|
|
242
|
+
translate: 0 -0.1em;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
.prose {
|
|
246
|
+
max-inline-size: 65ch;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
.label {
|
|
250
|
+
margin-inline-end: 0.5em;
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
Tokens should add meaning, not hide it.
|
|
255
|
+
|
|
256
|
+
## Literal relative values are not a code smell
|
|
257
|
+
|
|
258
|
+
A well-chosen literal relative value is valid framework CSS.
|
|
259
|
+
|
|
260
|
+
Values such as:
|
|
261
|
+
|
|
262
|
+
```css
|
|
263
|
+
0.25em
|
|
264
|
+
1.5em
|
|
265
|
+
1lh
|
|
266
|
+
18rem
|
|
267
|
+
65ch
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
can be more stable and understandable than introducing a custom property or mapping them artificially onto the spacing scale.
|
|
271
|
+
|
|
272
|
+
Promote a value to a token when at least one of these becomes true:
|
|
273
|
+
|
|
274
|
+
* it represents a shared design decision
|
|
275
|
+
* multiple components need the same semantic value
|
|
276
|
+
* themes or density modes should modify it
|
|
277
|
+
* users are expected to configure it
|
|
278
|
+
* naming the value improves understanding of the API
|
|
279
|
+
|
|
280
|
+
Otherwise, keep the direct CSS unit.
|
|
281
|
+
|
|
282
|
+
## Guideline
|
|
283
|
+
|
|
284
|
+
> Use tokens for shared design rhythm. Use CSS relative units for intrinsic relationships.
|
|
285
|
+
|
|
286
|
+
Actual favors semantic CSS over tokenization for its own sake.
|
package/docs/navigation.json
CHANGED
|
@@ -31,7 +31,7 @@ itself needs to change, not `.soft`.
|
|
|
31
31
|
| `.alert-title` | Composition | Admonition title bar; hosts the dismiss button. |
|
|
32
32
|
| `.alert-body` | Composition | Admonition body resting on the page surface. |
|
|
33
33
|
| Shared intents | Intent | `.primary`, `.secondary`, `.success`, `.warning`, `.danger`. |
|
|
34
|
-
| Shared variants | Variant | `.solid
|
|
34
|
+
| Shared variants | Variant | `.solid`, `.outline`, and `.surface` emphasis. |
|
|
35
35
|
| `.sm` / `.lg` | Size | Density; inline padding stays stable. |
|
|
36
36
|
|
|
37
37
|
## Basic usage
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
Use one `.app-nav` landmark for the application's primary destinations. Links
|
|
6
6
|
remain links, and `aria-current="page"` is the only current-page state.
|
|
7
7
|
|
|
8
|
+
**Related terms:** tab bar, bottom navigation, bottom nav, navigation rail, side navigation.
|
|
9
|
+
|
|
8
10
|
```html demo
|
|
9
11
|
<nav class="app-nav" aria-label="Primary">
|
|
10
12
|
<a href="#today" aria-current="page">
|
|
@@ -16,6 +16,8 @@ direct child of `.stack` (where flex children otherwise stretch). Use
|
|
|
16
16
|
`inline-size: 100%` — or the optional `.inline-size-full` utility — when a
|
|
17
17
|
full-width badge is intentional.
|
|
18
18
|
|
|
19
|
+
**Related terms:** chip, tag, pill, removable tag.
|
|
20
|
+
|
|
19
21
|
## Class reference
|
|
20
22
|
|
|
21
23
|
| Class | Kind | Description |
|
|
@@ -23,7 +25,7 @@ full-width badge is intentional.
|
|
|
23
25
|
| `.badge` | Component | Compact label; soft by default. |
|
|
24
26
|
| `.badge:empty` | Composition | Truly-empty badge renders as a solid dot. |
|
|
25
27
|
| Shared intents | Intent | `.primary`, `.secondary`, `.success`, `.warning`, `.danger`. |
|
|
26
|
-
| Shared variants | Variant | `.solid` (filled)
|
|
28
|
+
| Shared variants | Variant | `.solid` (filled), `.outline` (bordered), `.surface` (untinted) emphasis. |
|
|
27
29
|
| `.sm` / `.lg` | Size | Compact density. |
|
|
28
30
|
|
|
29
31
|
## Basic usage
|
|
@@ -58,13 +60,25 @@ full-width badge is intentional.
|
|
|
58
60
|
</button>
|
|
59
61
|
```
|
|
60
62
|
|
|
61
|
-
##
|
|
63
|
+
## Status dot
|
|
62
64
|
|
|
63
65
|
```html demo
|
|
64
66
|
<span class="badge success" aria-label="Online"></span>
|
|
65
67
|
```
|
|
66
68
|
|
|
67
|
-
|
|
69
|
+
An autonomous dot conveys state without visible text, so give it an accessible
|
|
70
|
+
name.
|
|
71
|
+
|
|
72
|
+
## Color marker
|
|
73
|
+
|
|
74
|
+
Use an empty badge as a compact intent-colored marker in legends and status
|
|
75
|
+
labels. When adjacent text carries the same information, keep the marker
|
|
76
|
+
decorative.
|
|
77
|
+
|
|
78
|
+
```html demo
|
|
79
|
+
<span class="badge primary" aria-hidden="true"></span>
|
|
80
|
+
Regular
|
|
81
|
+
```
|
|
68
82
|
|
|
69
83
|
## Size variants
|
|
70
84
|
|
|
@@ -16,6 +16,7 @@ Actions and navigation with shared intents, variants, sizes, and loading, presse
|
|
|
16
16
|
| `.soft` | Variant | Muted intent-tinted surface. |
|
|
17
17
|
| `.outline` | Variant | Transparent with an intent-colored border. |
|
|
18
18
|
| `.solid` | Variant | Filled intent background — the `.btn` default. |
|
|
19
|
+
| `.surface` | Variant | Page surface with a neutral border; the intent colors the label only. |
|
|
19
20
|
| `.ghost` | Variant | Borderless text button (button-only). |
|
|
20
21
|
| `.link` | Variant | Underlined text button (button-only). |
|
|
21
22
|
| `.sm` / `.lg` | Size | Compact or large control height. |
|
|
@@ -53,8 +54,12 @@ Shared intent classes set color meaning. They compose with every variant.
|
|
|
53
54
|
|
|
54
55
|
## Variants
|
|
55
56
|
|
|
56
|
-
`.ghost` and `.link` are button-only; `.soft`, `.outline`,
|
|
57
|
-
shared with other components.
|
|
57
|
+
`.ghost` and `.link` are button-only; `.soft`, `.outline`, `.solid`, and
|
|
58
|
+
`.surface` are shared with other components.
|
|
59
|
+
|
|
60
|
+
Reach for `.surface` when a secondary action must sit on an opaque, neutral
|
|
61
|
+
chip: `.outline` lets whatever is behind it show through, and `.soft` is the
|
|
62
|
+
intent-tinted treatment (its baseline fallback uses `--surface-subtle`).
|
|
58
63
|
|
|
59
64
|
Transparent treatments (`.outline`, `.ghost`, `.link`) follow the surrounding
|
|
60
65
|
foreground by default, including on a contrasting `.inverted` surface. A local
|
|
@@ -79,6 +84,8 @@ container. For a plain text link, use a bare `<a>` with no class.
|
|
|
79
84
|
<button class="btn danger outline" type="button">Danger outline</button>
|
|
80
85
|
<button class="btn soft" type="button">Soft</button>
|
|
81
86
|
<button class="btn danger soft" type="button">Danger soft</button>
|
|
87
|
+
<button class="btn surface" type="button">Surface</button>
|
|
88
|
+
<button class="btn danger surface" type="button">Danger surface</button>
|
|
82
89
|
<button class="btn ghost" type="button">Ghost</button>
|
|
83
90
|
<button class="btn link" type="button">Button as link</button>
|
|
84
91
|
</div>
|
|
@@ -9,6 +9,7 @@ Flexible content container with optional header, body, and footer regions, plus
|
|
|
9
9
|
| `.card` | Component | Neutral raised surface for grouped content. |
|
|
10
10
|
| `.raised` | Variant | Elevated surface with a soft shadow. |
|
|
11
11
|
| `.subtle` | Variant | Lower contrast against the page surface. |
|
|
12
|
+
| `.surface` | Variant | Shared variant: the page surface instead of `--surface-raised`, with the intent in the text only. |
|
|
12
13
|
| `.inverted` | Surface modifier | Inverse surface treatment: paints `--surface-solid` and swaps the foreground to `--surface`, so it inverts in dark themes instead of always reading as dark. Apply as `class="card inverted"`, or on any block. |
|
|
13
14
|
| `.compact` | Variant | Tighter padding for dense contexts. |
|
|
14
15
|
|
|
@@ -162,6 +163,11 @@ the surface tokens, so `.card.subtle.inverted` renders a subtle background with
|
|
|
162
163
|
inverted foreground. Treat them as mutually exclusive, like two competing
|
|
163
164
|
variants.
|
|
164
165
|
|
|
166
|
+
`.surface` is the shared variant on a card: it drops the card to the page
|
|
167
|
+
surface instead of `--surface-raised`, keeps the theme border, and lets an
|
|
168
|
+
intent class color the text only. `.raised` and `.subtle` are the card-local
|
|
169
|
+
treatments on either side of it.
|
|
170
|
+
|
|
165
171
|
```html demo
|
|
166
172
|
<section class="grid">
|
|
167
173
|
<article class="card raised">
|
|
@@ -178,6 +184,13 @@ variants.
|
|
|
178
184
|
</hgroup>
|
|
179
185
|
</article>
|
|
180
186
|
|
|
187
|
+
<article class="card surface">
|
|
188
|
+
<hgroup>
|
|
189
|
+
<h3>Surface</h3>
|
|
190
|
+
<p class="muted">The page surface with the theme border.</p>
|
|
191
|
+
</hgroup>
|
|
192
|
+
</article>
|
|
193
|
+
|
|
181
194
|
<article class="card inverted stack">
|
|
182
195
|
<hgroup>
|
|
183
196
|
<h3>Inverted</h3>
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Data list
|
|
2
|
+
|
|
3
|
+
> A compact key/value layout for object properties.
|
|
4
|
+
|
|
5
|
+
Use `.data-list` to present the properties of a single object as simple
|
|
6
|
+
term–value pairs on a `<dl>`. It expects alternating `<dt>` and `<dd>` children
|
|
7
|
+
— one term, one value per property. Use a plain description list for
|
|
8
|
+
relationships that involve multiple terms or descriptions, and a `<table>` to
|
|
9
|
+
compare the same property across several objects.
|
|
10
|
+
|
|
11
|
+
```html demo
|
|
12
|
+
<dl class="data-list">
|
|
13
|
+
<dt>Name</dt>
|
|
14
|
+
<dd>Alice Martin</dd>
|
|
15
|
+
|
|
16
|
+
<dt>Email</dt>
|
|
17
|
+
<dd>alice@example.com</dd>
|
|
18
|
+
|
|
19
|
+
<dt>Role</dt>
|
|
20
|
+
<dd>Administrator</dd>
|
|
21
|
+
</dl>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Rich values
|
|
25
|
+
|
|
26
|
+
Values accept inline content such as badges, links, dates, or a `.cluster` of
|
|
27
|
+
related items. Terms and values remain baseline-aligned.
|
|
28
|
+
|
|
29
|
+
```html demo
|
|
30
|
+
<dl class="data-list">
|
|
31
|
+
<dt>Status</dt>
|
|
32
|
+
<dd><span class="badge success">Active</span></dd>
|
|
33
|
+
|
|
34
|
+
<dt>Plan</dt>
|
|
35
|
+
<dd>Professional</dd>
|
|
36
|
+
|
|
37
|
+
<dt>Renewal</dt>
|
|
38
|
+
<dd><time datetime="2026-09-14">14 Sep 2026</time></dd>
|
|
39
|
+
</dl>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## In a card
|
|
43
|
+
|
|
44
|
+
`.data-list` composes with `.card` and other layout primitives for business
|
|
45
|
+
metadata.
|
|
46
|
+
|
|
47
|
+
```html demo
|
|
48
|
+
<article class="card stack">
|
|
49
|
+
<h3>Storage details</h3>
|
|
50
|
+
|
|
51
|
+
<dl class="data-list">
|
|
52
|
+
<dt>Used</dt>
|
|
53
|
+
<dd>6.7 GB</dd>
|
|
54
|
+
|
|
55
|
+
<dt>Available</dt>
|
|
56
|
+
<dd>1.3 GB</dd>
|
|
57
|
+
|
|
58
|
+
<dt>Files</dt>
|
|
59
|
+
<dd>12,492</dd>
|
|
60
|
+
</dl>
|
|
61
|
+
</article>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Contract
|
|
65
|
+
|
|
66
|
+
`.data-list` styles one `<dt>` followed by one `<dd>` per property. A valid
|
|
67
|
+
`<dl>` may group several terms with one description or the reverse, but that
|
|
68
|
+
markup does not belong in `.data-list` — use a plain description list instead,
|
|
69
|
+
where `.prose` already covers the editorial cases.
|
|
70
|
+
|
|
71
|
+
Use `.data-list` for the properties of a single object. Use a `<table>` when
|
|
72
|
+
comparing the same properties across multiple objects.
|
|
@@ -7,6 +7,8 @@ The existing button component owns its size, shape, intent, and interaction.
|
|
|
7
7
|
As a direct child of `.app-layout`, it instead overlays the main grid area so
|
|
8
8
|
the layout keeps it clear of adaptive application navigation and safe areas.
|
|
9
9
|
|
|
10
|
+
**Related terms:** fab.
|
|
11
|
+
|
|
10
12
|
```html
|
|
11
13
|
<div class="fab">
|
|
12
14
|
<button class="btn circle primary lg icon-only" type="button" aria-label="Create">
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
> Scalar measurement within a known range, not a progress indicator.
|
|
4
4
|
|
|
5
5
|
- Use native `<meter class="meter">`.
|
|
6
|
+
- Use a segmented `<div class="meter" role="meter">` when the measurement
|
|
7
|
+
needs a category breakdown.
|
|
6
8
|
- Shares progress styling DNA.
|
|
7
9
|
- Represents a scalar measurement within a known range, not task completion.
|
|
8
10
|
- Use explicit bar height to avoid padding issues.
|
|
@@ -18,6 +20,59 @@
|
|
|
18
20
|
The three standard meter zones (optimum, suboptimum, even-less-good) map to the
|
|
19
21
|
shared `--success`, `--warning`, and `--danger` colors.
|
|
20
22
|
|
|
21
|
-
|
|
23
|
+
Segmented meters keep the overall measurement on the meter itself and expose
|
|
24
|
+
the category breakdown as composition. A segmented `.meter` is a flex container
|
|
25
|
+
whose direct children are weighted by `--meter-value`; child intent classes
|
|
26
|
+
define segment colors. The values are relative weights, so they do not need to
|
|
27
|
+
be converted to percentages. Keep the segments decorative with
|
|
28
|
+
`aria-hidden="true"` and provide category names and values in a nearby legend.
|
|
29
|
+
An unintentional child remains transparent, so the meter background can
|
|
30
|
+
represent an available or otherwise unclassified portion. Match its legend
|
|
31
|
+
marker to that background rather than to the neutral intent.
|
|
32
|
+
|
|
33
|
+
```html demo
|
|
34
|
+
<div class="stack">
|
|
35
|
+
<div
|
|
36
|
+
class="meter"
|
|
37
|
+
role="meter"
|
|
38
|
+
aria-label="Storage usage"
|
|
39
|
+
aria-valuemin="0"
|
|
40
|
+
aria-valuemax="8192"
|
|
41
|
+
aria-valuenow="6854.45"
|
|
42
|
+
aria-valuetext="6854.45 MB used of 8 GB"
|
|
43
|
+
>
|
|
44
|
+
<span class="primary" style="--meter-value: 4600" aria-hidden="true"></span>
|
|
45
|
+
<span class="secondary" style="--meter-value: 1350" aria-hidden="true"></span>
|
|
46
|
+
<span class="success" style="--meter-value: 904.45" aria-hidden="true"></span>
|
|
47
|
+
<span style="--meter-value: 1337.55" aria-hidden="true"></span>
|
|
48
|
+
</div>
|
|
49
|
+
|
|
50
|
+
<div class="cluster">
|
|
51
|
+
<span>
|
|
52
|
+
<span class="badge primary" aria-hidden="true"></span>
|
|
53
|
+
Regular <span class="muted">4600 MB</span>
|
|
54
|
+
</span>
|
|
55
|
+
<span>
|
|
56
|
+
<span class="badge secondary" aria-hidden="true"></span>
|
|
57
|
+
System <span class="muted">1350 MB</span>
|
|
58
|
+
</span>
|
|
59
|
+
<span>
|
|
60
|
+
<span class="badge success" aria-hidden="true"></span>
|
|
61
|
+
Shared <span class="muted">904.45 MB</span>
|
|
62
|
+
</span>
|
|
63
|
+
<span>
|
|
64
|
+
<span class="badge" style="--intent: var(--surface-subtle)" aria-hidden="true"></span>
|
|
65
|
+
Free <span class="muted">1337.55 MB</span>
|
|
66
|
+
</span>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Hooks
|
|
22
72
|
|
|
23
73
|
- `--bar-height` — bar thickness, shared with `.progress`.
|
|
74
|
+
- `--meter-value` — relative weight of a direct child in a segmented meter.
|
|
75
|
+
|
|
76
|
+
`.sm` / `.lg` are intentionally not supported: a bar keeps its inline size and only changes
|
|
77
|
+
thickness, and a design asks for a 4px or a 12px bar, not for a "small" one. Set the hook
|
|
78
|
+
on the element, or better, on an application class.
|
|
@@ -27,3 +27,13 @@
|
|
|
27
27
|
- `--progress-track` — unfilled track color.
|
|
28
28
|
- `--progress-value` — filled bar color. Prefer an intent class over setting this directly.
|
|
29
29
|
- `--bar-height` — bar thickness, shared with `.meter`.
|
|
30
|
+
|
|
31
|
+
`.sm` / `.lg` are intentionally not supported: a bar keeps its inline size and only changes
|
|
32
|
+
thickness, and a design asks for a 4px or a 12px bar, not for a "small" one. Set the hook
|
|
33
|
+
on the element, or better, on an application class.
|
|
34
|
+
|
|
35
|
+
```css
|
|
36
|
+
.storage-meter {
|
|
37
|
+
--bar-height: 0.375rem;
|
|
38
|
+
}
|
|
39
|
+
```
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
- Use layout utilities for placeholder arrangement.
|
|
9
9
|
- Only relevant for simple placeholders - use more structural solutions like phantom-ui for complex cases.
|
|
10
10
|
|
|
11
|
+
**Related terms:** skeleton screen, shimmer, loading placeholder.
|
|
12
|
+
|
|
11
13
|
## Class reference
|
|
12
14
|
|
|
13
15
|
| Class | Kind | Description |
|