@juwel-development/design-system 3.3.0 → 3.4.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/dist/design-system.js +184 -113
- package/dist/index.css +1 -1
- package/dist/types/Display/Meter/Meter.d.ts +59 -0
- package/dist/types/Display/Meter/MeterConfigurationError.d.ts +3 -0
- package/dist/types/Interaction/Slider/Slider.d.ts +41 -0
- package/dist/types/Interaction/Slider/SliderConfigurationError.d.ts +3 -0
- package/dist/types/Theme/Palette.d.ts +13 -0
- package/dist/types/index.d.ts +2 -0
- package/package.json +1 -1
- package/src/Display/Meter/Meter.tsx +136 -0
- package/src/Display/Meter/MeterConfigurationError.ts +6 -0
- package/src/Interaction/Slider/Slider.tsx +125 -0
- package/src/Interaction/Slider/SliderConfigurationError.ts +6 -0
- package/src/Theme/Palette.ts +20 -0
- package/src/Theme/renderTokens.ts +23 -0
- package/src/index.ts +2 -0
- package/src/tokens.css +16 -0
- package/src/tokens.dark.css +14 -0
- package/src/tokens.light.css +14 -0
package/dist/index.css
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
|
|
2
|
-
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;--tw-content:""}}}@layer theme{:root,:host{--font-sans:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-serif:ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-slate-200:oklch(92.9% .013 255.508);--color-slate-900:oklch(20.8% .042 265.755);--color-stone-50:oklch(98.5% .001 106.423);--color-white:#fff;--spacing:.25rem;--container-5xl:64rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-9xl:8rem;--text-9xl--line-height:1;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-wider:.05em;--radius-md:.375rem;--radius-lg:.5rem;--aspect-video:16 / 9;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-surface:var(--color-surface);--color-foreground:var(--color-foreground);--color-muted:var(--color-muted);--color-border:var(--color-border);--color-control-border:var(--color-control-border);--color-rule:var(--color-rule);--color-backing:var(--color-backing);--color-primary:var(--color-primary);--color-primary-hover:var(--color-primary-hover);--color-primary-foreground:var(--color-primary-foreground);--color-secondary:var(--color-secondary);--color-secondary-hover:var(--color-secondary-hover);--color-secondary-foreground:var(--color-secondary-foreground);--color-disabled:var(--color-disabled);--color-disabled-hover:var(--color-disabled-hover);--color-focus-ring:var(--color-focus-ring);--color-link:var(--color-link);--color-success:var(--color-success);--color-warning:var(--color-warning);--color-error:var(--color-error);--color-info:var(--color-info);--font-primary:inherit;--font-secondary:inherit;--text-display:clamp(3rem, 7vw, 6rem);--leading-display:1.05;--text-title:clamp(2.25rem, 5vw, 4.25rem);--leading-title:1.1;--text-subtitle:clamp(1.5rem, 3vw, 2.25rem);--leading-subtitle:1.2;--text-lede:1.25rem;--leading-lede:1.4;--text-body:1.0625rem;--leading-body:1.6;--text-small:.9375rem;--text-label:.8125rem;--leading-label:1.5;--tracking-label:.14em;--tracking-optical:-.02em;--aspect-portrait:4 / 5;--aspect-square:1 / 1;--aspect-landscape:3 / 2;--aspect-wide:16 / 9}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.isolate{isolation:isolate}.z-10{z-index:10}.container{width:100%}@media (width>=40rem){.container{max-width:40rem}}@media (width>=48rem){.container{max-width:48rem}}@media (width>=64rem){.container{max-width:64rem}}@media (width>=80rem){.container{max-width:80rem}}@media (width>=96rem){.container{max-width:96rem}}.m-0{margin:0}.m-\[calc\(-1\*\(var\(--focus-ring-width\)\+var\(--focus-ring-offset\)\)\)\]{margin:calc(-1 * (var(--focus-ring-width) + var(--focus-ring-offset)))}.mx-auto{margin-inline:auto}.my-auto{margin-block:auto}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.table{display:table}.aspect-landscape{aspect-ratio:var(--aspect-landscape)}.aspect-portrait{aspect-ratio:var(--aspect-portrait)}.aspect-square{aspect-ratio:var(--aspect-square)}.aspect-wide{aspect-ratio:var(--aspect-wide)}.h-12{height:calc(var(--spacing) * 12)}.min-h-24{min-height:calc(var(--spacing) * 24)}.min-h-\[calc\(var\(--text-label\)\*var\(--leading-label\)\)\]{min-height:calc(var(--text-label) * var(--leading-label))}.min-h-\[var\(--cover-height\)\]{min-height:var(--cover-height)}.min-h-\[var\(--fold-height\)\]{min-height:var(--fold-height)}.w-\[360px\]{width:360px}.w-\[var\(--measure-action\)\]{width:var(--measure-action)}.w-full{width:100%}.\[max-width\:var\(--measure-display\)\]{max-width:var(--measure-display)}.max-w-5xl{max-width:var(--container-5xl)}.max-w-\[var\(--measure\)\]{max-width:var(--measure)}.max-w-\[var\(--measure-display\)\]{max-width:var(--measure-display)}.max-w-\[var\(--measure-wide\)\]{max-width:var(--measure-wide)}.max-w-full{max-width:100%}.min-w-0{min-width:0}.min-w-42{min-width:calc(var(--spacing) * 42)}.min-w-\[var\(--control-min-width\)\]{min-width:var(--control-min-width)}.min-w-\[var\(--standing-min-width\)\]{min-width:var(--standing-min-width)}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.resize{resize:both}.scroll-p-\[calc\(var\(--focus-ring-width\)\+var\(--focus-ring-offset\)\)\]{scroll-padding:calc(var(--focus-ring-width) + var(--focus-ring-offset))}.list-none{list-style-type:none}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-start{justify-content:flex-start}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-\[var\(--space-region\)\]{gap:var(--space-region)}.gap-\[var\(--space-stack\)\]{gap:var(--space-stack)}:where(.space-y-10>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 10) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 10) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-12>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 12) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 12) * calc(1 - var(--tw-space-y-reverse)))}.gap-x-\[var\(--space-region\)\]{column-gap:var(--space-region)}.gap-x-\[var\(--space-stack\)\]{column-gap:var(--space-stack)}.gap-y-\[var\(--space-stack\)\]{row-gap:var(--space-stack)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-x-auto{overflow-x:auto}.rounded-\[var\(--radius-control\)\]{border-radius:var(--radius-control)}.rounded-\[var\(--radius-…\)\]{border-radius:var(--radius-…)}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-\[length\:var\(--tab-marker-thickness\)\]{border-bottom-style:var(--tw-border-style);border-bottom-width:var(--tab-marker-thickness)}.border-l-4{border-left-style:var(--tw-border-style);border-left-width:4px}.border-solid{--tw-border-style:solid;border-style:solid}.border-border{border-color:var(--color-border)}.border-control-border{border-color:var(--color-control-border)}.border-primary{border-color:var(--color-primary)}.border-rule{border-color:var(--color-rule)}.border-slate-200{border-color:var(--color-slate-200)}.border-transparent{border-color:#0000}.bg-backing{background-color:var(--color-backing)}.bg-primary{background-color:var(--color-primary)}.bg-secondary{background-color:var(--color-secondary)}.bg-stone-50{background-color:var(--color-stone-50)}.bg-surface{background-color:var(--color-surface)}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.object-cover{object-fit:cover}.object-bottom{object-position:bottom}.object-center{object-position:center}.object-left{object-position:left}.object-right{object-position:right}.object-top{object-position:top}.p-0{padding:0}.p-4{padding:calc(var(--spacing) * 4)}.p-\[calc\(var\(--focus-ring-width\)\+var\(--focus-ring-offset\)\)\]{padding:calc(var(--focus-ring-width) + var(--focus-ring-offset))}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-6{padding-inline:calc(var(--spacing) * 6)}.px-\[var\(--gutter\)\]{padding-inline:var(--gutter)}.px-\[var\(--tab-inset-inline\)\]{padding-inline:var(--tab-inset-inline)}.py-1{padding-block:var(--spacing)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-12{padding-block:calc(var(--spacing) * 12)}.py-\[var\(--space-band\)\]{padding-block:var(--space-band)}.py-\[var\(--space-collection-item\)\]{padding-block:var(--space-collection-item)}.py-\[var\(--space-region\)\]{padding-block:var(--space-region)}.py-\[var\(--tab-inset-block\)\]{padding-block:var(--tab-inset-block)}.pt-1{padding-top:var(--spacing)}.pb-1{padding-bottom:var(--spacing)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.text-start{text-align:start}.font-mono{font-family:var(--font-mono)}.font-primary{font-family:var(--font-primary)}.font-sans{font-family:var(--font-sans)}.font-secondary{font-family:var(--font-secondary)}.font-serif{font-family:var(--font-serif)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-9xl{font-size:var(--text-9xl);line-height:var(--tw-leading,var(--text-9xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-body{font-size:var(--text-body)}.text-display{font-size:var(--text-display)}.text-label{font-size:var(--text-label)}.text-lede{font-size:var(--text-lede)}.text-small{font-size:var(--text-small)}.text-subtitle{font-size:var(--text-subtitle)}.text-title{font-size:var(--text-title)}.leading-body{--tw-leading:var(--leading-body);line-height:var(--leading-body)}.leading-display{--tw-leading:var(--leading-display);line-height:var(--leading-display)}.leading-label{--tw-leading:var(--leading-label);line-height:var(--leading-label)}.leading-lede{--tw-leading:var(--leading-lede);line-height:var(--leading-lede)}.leading-subtitle{--tw-leading:var(--leading-subtitle);line-height:var(--leading-subtitle)}.leading-title{--tw-leading:var(--leading-title);line-height:var(--leading-title)}.font-\[500\]{--tw-font-weight:500;font-weight:500}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-label{--tw-tracking:var(--tracking-label);letter-spacing:var(--tracking-label)}.tracking-optical{--tw-tracking:var(--tracking-optical);letter-spacing:var(--tracking-optical)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.text-nowrap{text-wrap:nowrap}.text-\[var\(--text-small\)\]{color:var(--text-small)}.text-error{color:var(--color-error)}.text-foreground{color:var(--color-foreground)}.text-inherit{color:inherit}.text-link{color:var(--color-link)}.text-muted{color:var(--color-muted)}.text-primary-foreground{color:var(--color-primary-foreground)}.text-secondary-foreground{color:var(--color-secondary-foreground)}.text-slate-900{color:var(--color-slate-900)}.text-success{color:var(--color-success)}.uppercase{text-transform:uppercase}.ordinal{--tw-ordinal:ordinal;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.no-underline{text-decoration-line:none}.underline{text-decoration-line:underline}.decoration-\[length\:var\(--underline-thickness\)\]{text-decoration-thickness:var(--underline-thickness)}.underline-offset-\[var\(--underline-offset\)\]{text-underline-offset:var(--underline-offset)}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.outline-offset-\[var\(--focus-ring-offset\)\]{outline-offset:var(--focus-ring-offset)}.outline-focus-ring{outline-color:var(--color-focus-ring)}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.invert{--tw-invert:invert(100%);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-\[var\(--motion-duration-color\)\]{--tw-duration:var(--motion-duration-color);transition-duration:var(--motion-duration-color)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.before\:mt-\[0\.35em\]:before{content:var(--tw-content);margin-top:.35em}.before\:size-\[calc\(var\(--tick-length\)\*0\.7\)\]:before{content:var(--tw-content);width:calc(var(--tick-length) * .7);height:calc(var(--tick-length) * .7)}.before\:shrink-0:before{content:var(--tw-content);flex-shrink:0}.before\:rotate-45:before{content:var(--tw-content);rotate:45deg}.before\:bg-\[var\(--color-rule\)\]:before{content:var(--tw-content);background-color:var(--color-rule)}.before\:content-\[\'\'\]:before{--tw-content:"";content:var(--tw-content)}.before\:\[border-right\:var\(--tick-thickness\)_solid_var\(--color-rule\)\]:before{content:var(--tw-content);border-right:var(--tick-thickness) solid var(--color-rule)}.before\:\[border-top\:var\(--tick-thickness\)_solid_var\(--color-rule\)\]:before{content:var(--tw-content);border-top:var(--tick-thickness) solid var(--color-rule)}.first\:border-t:first-child{border-top-style:var(--tw-border-style);border-top-width:1px}.first\:pl-0:first-child{padding-left:0}.last\:pr-0:last-child{padding-right:0}@media (hover:hover){.hover\:border-muted:hover{border-color:var(--color-muted)}.hover\:bg-primary-hover:hover{background-color:var(--color-primary-hover)}.hover\:bg-secondary-hover:hover{background-color:var(--color-secondary-hover)}.hover\:text-sm:hover{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.hover\:text-foreground:hover{color:var(--color-foreground)}.hover\:underline:hover{text-decoration-line:underline}.hover\:decoration-\[length\:var\(--underline-thickness\)\]:hover{text-decoration-thickness:var(--underline-thickness)}.hover\:decoration-\[length\:var\(--underline-thickness-hover\)\]:hover{text-decoration-thickness:var(--underline-thickness-hover)}.hover\:underline-offset-\[var\(--underline-offset\)\]:hover{text-underline-offset:var(--underline-offset)}.hover\:opacity-90:hover{opacity:.9}}.focus-visible\:outline:focus-visible{outline-style:var(--tw-outline-style);outline-width:1px}.focus-visible\:outline-\[length\:var\(--focus-ring-width\)\]:focus-visible{outline-style:var(--tw-outline-style);outline-width:var(--focus-ring-width)}.focus-visible\:outline-\[length\:…\]:focus-visible{outline-style:var(--tw-outline-style);outline-width:…}.focus-visible\:outline-focus-ring:focus-visible{outline-color:var(--color-focus-ring)}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:border-disabled:disabled{border-color:var(--color-disabled)}.disabled\:bg-disabled:disabled{background-color:var(--color-disabled)}.disabled\:text-muted:disabled{color:var(--color-muted)}@media (hover:hover){.disabled\:hover\:bg-disabled-hover:disabled:hover{background-color:var(--color-disabled-hover)}}.aria-selected\:border-foreground[aria-selected=true]{border-color:var(--color-foreground)}.aria-selected\:text-foreground[aria-selected=true]{color:var(--color-foreground)}.aria-\[invalid\=true\]\:border-error[aria-invalid=true]{border-color:var(--color-error)}@media (width>=40rem){.sm\:px-6{padding-inline:calc(var(--spacing) * 6)}.sm\:py-2{padding-block:calc(var(--spacing) * 2)}}@media (width>=48rem){.md\:text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}}@media (width>=64rem){.lg\:sticky{position:sticky}.lg\:top-6{top:calc(var(--spacing) * 6)}.lg\:max-w-\[var\(--measure-display\)\]{max-width:var(--measure-display)}.lg\:grid-cols-\[10rem_minmax\(0\,1fr\)\]{grid-template-columns:10rem minmax(0,1fr)}.lg\:grid-cols-\[12rem_minmax\(0\,1fr\)\]{grid-template-columns:12rem minmax(0,1fr)}.lg\:grid-cols-\[16rem_minmax\(0\,1fr\)\]{grid-template-columns:16rem minmax(0,1fr)}.lg\:flex-row{flex-direction:row}.lg\:items-baseline{align-items:baseline}.lg\:items-start{align-items:flex-start}.lg\:gap-x-12{column-gap:calc(var(--spacing) * 12)}}.\[\&_\[aria-current\=page\]\]\:text-foreground [aria-current=page]{color:var(--color-foreground)}.\[\&_caption\]\:pb-3 caption{padding-bottom:calc(var(--spacing) * 3)}.\[\&_caption\]\:text-left caption{text-align:left}.\[\&_caption\]\:font-secondary caption{font-family:var(--font-secondary)}.\[\&_caption\]\:text-label caption{font-size:var(--text-label)}.\[\&_caption\]\:tracking-label caption{--tw-tracking:var(--tracking-label);letter-spacing:var(--tracking-label)}.\[\&_caption\]\:text-muted caption{color:var(--color-muted)}.\[\&\+li\]\:border-t+li{border-top-style:var(--tw-border-style);border-top-width:1px}.\[\&\+li\]\:border-solid+li{--tw-border-style:solid;border-style:solid}.\[\&\+li\]\:border-border+li{border-color:var(--color-border)}.\[\&\:not\(\:first-child\)\]\:mt-\[var\(--space-stack\)\]:not(:first-child){margin-top:var(--space-stack)}.\[\&\:not\(\:first-child\)\]\:border-t:not(:first-child){border-top-style:var(--tw-border-style);border-top-width:1px}.\[\&\:not\(\:first-child\)\]\:border-solid:not(:first-child){--tw-border-style:solid;border-style:solid}.\[\&\:not\(\:first-child\)\]\:border-border:not(:first-child){border-color:var(--color-border)}.\[\&\:not\(\:first-child\)\]\:pt-\[var\(--space-stack\)\]:not(:first-child){padding-top:var(--space-stack)}.\[\&\:not\(\[data-notes\]\)\]\:overflow-x-auto:not([data-notes]){overflow-x:auto}.\[\&\:user-invalid\]\:border-error:user-invalid{border-color:var(--color-error)}@media (width>=64rem){.lg\:\[\&\>dd\]\:col-start-2>dd{grid-column-start:2}.lg\:\[\&\>dd\]\:row-start-1>dd{grid-row-start:1}}.\[\&\>div\:first-child\]\:border-b>div:first-child{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.\[\&\>div\:first-child\]\:border-solid>div:first-child{--tw-border-style:solid;border-style:solid}.\[\&\>div\:first-child\]\:border-border>div:first-child{border-color:var(--color-border)}.\[\&\>div\:first-child\]\:pb-\[var\(--space-stack\)\]>div:first-child{padding-bottom:var(--space-stack)}@media (width>=64rem){.lg\:\[\&\>div\:first-child\]\:border-r>div:first-child{border-right-style:var(--tw-border-style);border-right-width:1px}.lg\:\[\&\>div\:first-child\]\:border-b-0>div:first-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.lg\:\[\&\>div\:first-child\]\:pr-\[var\(--space-stack\)\]>div:first-child{padding-right:var(--space-stack)}.lg\:\[\&\>div\:first-child\]\:pb-0>div:first-child{padding-bottom:0}}.\[\&\>div\:first-child\>nav\]\:p-\[calc\(var\(--focus-ring-width\)\+var\(--focus-ring-offset\)\)\]>div:first-child>nav{padding:calc(var(--focus-ring-width) + var(--focus-ring-offset))}@media (width>=64rem){.lg\:\[\&\>div\:first-child\>nav\]\:sticky>div:first-child>nav{position:sticky}.lg\:\[\&\>div\:first-child\>nav\]\:top-0>div:first-child>nav{top:0}.lg\:\[\&\>div\:first-child\>nav\]\:max-h-\[min\(100dvh\,var\(--sidebar-scrollport-height\,100dvh\)\)\]>div:first-child>nav{max-height:min(100dvh, var(--sidebar-scrollport-height,100dvh))}.lg\:\[\&\>div\:first-child\>nav\]\:scroll-p-\[calc\(var\(--focus-ring-width\)\+var\(--focus-ring-offset\)\)\]>div:first-child>nav{scroll-padding:calc(var(--focus-ring-width) + var(--focus-ring-offset))}.lg\:\[\&\>div\:first-child\>nav\]\:overflow-y-auto>div:first-child>nav{overflow-y:auto}}.\[\&\>div\:first-child\>nav\>ul\]\:flex>div:first-child>nav>ul{display:flex}.\[\&\>div\:first-child\>nav\>ul\]\:flex-col>div:first-child>nav>ul{flex-direction:column}.\[\&\>div\:first-child\>nav\>ul\]\:gap-\[var\(--space-stack\)\]>div:first-child>nav>ul{gap:var(--space-stack)}@media (width>=64rem){.lg\:\[\&\>dt\]\:col-start-1>dt{grid-column-start:1}}.\[\&\>table\]\:w-full>table{width:100%}.\[\&\>table\]\:border-collapse>table{border-collapse:collapse}.\[\&\>table\]\:text-left>table{text-align:left}.\[\&\>table\>\*\:nth-child\(2\)\>tr\:first-child\]\:border-rule>table>:nth-child(2)>tr:first-child{border-color:var(--color-rule)}@media not all and (width>=48rem){.\[\&\[data-notes\=content\]_tbody\]\:max-md\:block[data-notes=content] tbody,.\[\&\[data-notes\=content\]_td\]\:max-md\:block[data-notes=content] td,.\[\&\[data-notes\=content\]_tfoot\]\:max-md\:block[data-notes=content] tfoot,.\[\&\[data-notes\=content\]_th\]\:max-md\:block[data-notes=content] th,.\[\&\[data-notes\=content\]_thead\]\:max-md\:block[data-notes=content] thead,.\[\&\[data-notes\=content\]_tr\]\:max-md\:block[data-notes=content] tr,.\[\&\[data-notes\=content\]\>table\]\:max-md\:block[data-notes=content]>table{display:block}.\[\&\[data-notes\=supplementary\]_\[data-variant\=note\]\]\:max-md\:hidden[data-notes=supplementary] [data-variant=note]{display:none}}[data-section]+.\[\[data-section\]\+\&\]\:z-10{z-index:10}[data-section]+.\[\[data-section\]\+\&\]\:border-t{border-top-style:var(--tw-border-style);border-top-width:1px}[data-section]+.\[\[data-section\]\+\&\]\:border-solid{--tw-border-style:solid;border-style:solid}[data-section]+.\[\[data-section\]\+\&\]\:border-rule{border-color:var(--color-rule)}}:root{--color-surface:#fff;--color-foreground:#0f172a;--color-muted:#64748b;--color-border:#e2e8f0;--color-control-border:#64748b;--color-rule:#808fa3;--color-backing:#f1f5f9;--color-primary:#7c3aed;--color-primary-hover:#6d28d9;--color-primary-foreground:#f8fafc;--color-secondary:#0369a1;--color-secondary-hover:#075985;--color-secondary-foreground:#f8fafc;--color-disabled:#94a3b8;--color-disabled-hover:#64748b;--color-focus-ring:var(--color-ring,#475569);--color-link:#2563eb;--color-success:#10b981;--color-warning:#f59e0b;--color-error:#d63384;--color-info:#06b6d4}.dark{--color-surface:#0f172a;--color-foreground:#f8fafc;--color-muted:#94a3b8;--color-border:#334155;--color-control-border:#94a3b8;--color-rule:#5b6a80;--color-backing:#1e293b;--color-primary:#8b5cf6;--color-primary-hover:#a78bfa;--color-primary-foreground:#020617;--color-secondary:#0284c7;--color-secondary-hover:#0ea5e9;--color-secondary-foreground:#020617;--color-disabled:#475569;--color-disabled-hover:#334155;--color-focus-ring:var(--color-ring,#cbd5e1);--color-link:#60a5fa;--color-success:#34d399;--color-warning:#fbbf24;--color-error:#f48fb1;--color-info:#22d3ee}:root{--motion-duration-color:.15s}@media (prefers-reduced-motion:reduce){:root{--motion-duration-color:0s}}:root{--focus-ring-width:3px;--focus-ring-offset:2px;--radius-control:.5rem;--control-min-width:10.5rem;--standing-min-width:7.5rem;--underline-offset:.18em;--underline-thickness:1px;--underline-thickness-hover:2px;--measure:66ch;--measure-display:36ch;--measure-wide:72ch;--measure-action:20rem;--space-stack:.5em;--space-region:1.5em;--space-band:4em;--space-collection-item:1em;--gutter:clamp(1.5rem, 5vw, 4rem);--fold-height:min(70vh, 40rem);--cover-height:100svh;--tick-length:.9rem;--tick-thickness:1px;--tab-marker-thickness:2px;--tab-inset-inline:1em;--tab-inset-block:.5em}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}
|
|
2
|
+
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;--tw-content:""}}}@layer theme{:root,:host{--font-sans:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-serif:ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-slate-200:oklch(92.9% .013 255.508);--color-slate-900:oklch(20.8% .042 265.755);--color-stone-50:oklch(98.5% .001 106.423);--color-white:#fff;--spacing:.25rem;--container-5xl:64rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-9xl:8rem;--text-9xl--line-height:1;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-wider:.05em;--radius-md:.375rem;--radius-lg:.5rem;--aspect-video:16 / 9;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-surface:var(--color-surface);--color-foreground:var(--color-foreground);--color-muted:var(--color-muted);--color-border:var(--color-border);--color-control-border:var(--color-control-border);--color-rule:var(--color-rule);--color-backing:var(--color-backing);--color-meter-fill:var(--color-meter-fill);--color-meter-track:var(--color-meter-track);--color-primary:var(--color-primary);--color-primary-hover:var(--color-primary-hover);--color-primary-foreground:var(--color-primary-foreground);--color-secondary:var(--color-secondary);--color-secondary-hover:var(--color-secondary-hover);--color-secondary-foreground:var(--color-secondary-foreground);--color-disabled:var(--color-disabled);--color-disabled-hover:var(--color-disabled-hover);--color-focus-ring:var(--color-focus-ring);--color-link:var(--color-link);--color-success:var(--color-success);--color-warning:var(--color-warning);--color-error:var(--color-error);--color-info:var(--color-info);--font-primary:inherit;--font-secondary:inherit;--text-display:clamp(3rem, 7vw, 6rem);--leading-display:1.05;--text-title:clamp(2.25rem, 5vw, 4.25rem);--leading-title:1.1;--text-subtitle:clamp(1.5rem, 3vw, 2.25rem);--leading-subtitle:1.2;--text-lede:1.25rem;--leading-lede:1.4;--text-body:1.0625rem;--leading-body:1.6;--text-small:.9375rem;--text-label:.8125rem;--leading-label:1.5;--tracking-label:.14em;--tracking-optical:-.02em;--aspect-portrait:4 / 5;--aspect-square:1 / 1;--aspect-landscape:3 / 2;--aspect-wide:16 / 9}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.isolate{isolation:isolate}.z-10{z-index:10}.container{width:100%}@media (width>=40rem){.container{max-width:40rem}}@media (width>=48rem){.container{max-width:48rem}}@media (width>=64rem){.container{max-width:64rem}}@media (width>=80rem){.container{max-width:80rem}}@media (width>=96rem){.container{max-width:96rem}}.m-0{margin:0}.m-\[calc\(-1\*\(var\(--focus-ring-width\)\+var\(--focus-ring-offset\)\)\)\]{margin:calc(-1 * (var(--focus-ring-width) + var(--focus-ring-offset)))}.mx-auto{margin-inline:auto}.my-auto{margin-block:auto}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.table{display:table}.aspect-landscape{aspect-ratio:var(--aspect-landscape)}.aspect-portrait{aspect-ratio:var(--aspect-portrait)}.aspect-square{aspect-ratio:var(--aspect-square)}.aspect-wide{aspect-ratio:var(--aspect-wide)}.h-12{height:calc(var(--spacing) * 12)}.h-\[var\(--meter-track-thickness\)\]{height:var(--meter-track-thickness)}.h-\[var\(--slider-thumb-size\)\]{height:var(--slider-thumb-size)}.h-full{height:100%}.min-h-24{min-height:calc(var(--spacing) * 24)}.min-h-\[calc\(var\(--text-label\)\*var\(--leading-label\)\)\]{min-height:calc(var(--text-label) * var(--leading-label))}.min-h-\[var\(--cover-height\)\]{min-height:var(--cover-height)}.min-h-\[var\(--fold-height\)\]{min-height:var(--fold-height)}.w-\[360px\]{width:360px}.w-\[calc\(var\(--meter-level\)\*100\%\)\]{width:calc(var(--meter-level) * 100%)}.w-\[var\(--measure-action\)\]{width:var(--measure-action)}.w-full{width:100%}.\[max-width\:var\(--measure-display\)\]{max-width:var(--measure-display)}.max-w-5xl{max-width:var(--container-5xl)}.max-w-\[var\(--measure\)\]{max-width:var(--measure)}.max-w-\[var\(--measure-display\)\]{max-width:var(--measure-display)}.max-w-\[var\(--measure-wide\)\]{max-width:var(--measure-wide)}.max-w-full{max-width:100%}.min-w-0{min-width:0}.min-w-42{min-width:calc(var(--spacing) * 42)}.min-w-\[var\(--control-min-width\)\]{min-width:var(--control-min-width)}.min-w-\[var\(--standing-min-width\)\]{min-width:var(--standing-min-width)}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.resize{resize:both}.scroll-p-\[calc\(var\(--focus-ring-width\)\+var\(--focus-ring-offset\)\)\]{scroll-padding:calc(var(--focus-ring-width) + var(--focus-ring-offset))}.list-none{list-style-type:none}.appearance-none{appearance:none}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-start{justify-content:flex-start}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-\[var\(--space-region\)\]{gap:var(--space-region)}.gap-\[var\(--space-stack\)\]{gap:var(--space-stack)}:where(.space-y-10>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 10) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 10) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-12>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 12) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 12) * calc(1 - var(--tw-space-y-reverse)))}.gap-x-\[var\(--space-region\)\]{column-gap:var(--space-region)}.gap-x-\[var\(--space-stack\)\]{column-gap:var(--space-stack)}.gap-y-\[var\(--space-stack\)\]{row-gap:var(--space-stack)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-x-auto{overflow-x:auto}.rounded-\[var\(--radius-control\)\]{border-radius:var(--radius-control)}.rounded-\[var\(--radius-…\)\]{border-radius:var(--radius-…)}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-\[length\:var\(--tab-marker-thickness\)\]{border-bottom-style:var(--tw-border-style);border-bottom-width:var(--tab-marker-thickness)}.border-l-4{border-left-style:var(--tw-border-style);border-left-width:4px}.border-none{--tw-border-style:none;border-style:none}.border-solid{--tw-border-style:solid;border-style:solid}.border-border{border-color:var(--color-border)}.border-control-border{border-color:var(--color-control-border)}.border-primary{border-color:var(--color-primary)}.border-rule{border-color:var(--color-rule)}.border-slate-200{border-color:var(--color-slate-200)}.border-transparent{border-color:#0000}.bg-\[color-mix\(in_oklab\,var\(--color-meter-fill\)_calc\(var\(--meter-level\)\*100\%\)\,var\(--color-error\)\)\]{background-color:var(--color-meter-fill)}@supports (color:color-mix(in lab, red, red)){.bg-\[color-mix\(in_oklab\,var\(--color-meter-fill\)_calc\(var\(--meter-level\)\*100\%\)\,var\(--color-error\)\)\]{background-color:color-mix(in oklab,var(--color-meter-fill) calc(var(--meter-level) * 100%),var(--color-error))}}.bg-backing{background-color:var(--color-backing)}.bg-meter-fill{background-color:var(--color-meter-fill)}.bg-meter-track{background-color:var(--color-meter-track)}.bg-primary{background-color:var(--color-primary)}.bg-secondary{background-color:var(--color-secondary)}.bg-stone-50{background-color:var(--color-stone-50)}.bg-surface{background-color:var(--color-surface)}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.object-cover{object-fit:cover}.object-bottom{object-position:bottom}.object-center{object-position:center}.object-left{object-position:left}.object-right{object-position:right}.object-top{object-position:top}.p-0{padding:0}.p-4{padding:calc(var(--spacing) * 4)}.p-\[calc\(var\(--focus-ring-width\)\+var\(--focus-ring-offset\)\)\]{padding:calc(var(--focus-ring-width) + var(--focus-ring-offset))}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-6{padding-inline:calc(var(--spacing) * 6)}.px-\[var\(--gutter\)\]{padding-inline:var(--gutter)}.px-\[var\(--tab-inset-inline\)\]{padding-inline:var(--tab-inset-inline)}.py-1{padding-block:var(--spacing)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-12{padding-block:calc(var(--spacing) * 12)}.py-\[var\(--space-band\)\]{padding-block:var(--space-band)}.py-\[var\(--space-collection-item\)\]{padding-block:var(--space-collection-item)}.py-\[var\(--space-region\)\]{padding-block:var(--space-region)}.py-\[var\(--tab-inset-block\)\]{padding-block:var(--tab-inset-block)}.pt-1{padding-top:var(--spacing)}.pb-1{padding-bottom:var(--spacing)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.text-start{text-align:start}.font-mono{font-family:var(--font-mono)}.font-primary{font-family:var(--font-primary)}.font-sans{font-family:var(--font-sans)}.font-secondary{font-family:var(--font-secondary)}.font-serif{font-family:var(--font-serif)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-9xl{font-size:var(--text-9xl);line-height:var(--tw-leading,var(--text-9xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-body{font-size:var(--text-body)}.text-display{font-size:var(--text-display)}.text-label{font-size:var(--text-label)}.text-lede{font-size:var(--text-lede)}.text-small{font-size:var(--text-small)}.text-subtitle{font-size:var(--text-subtitle)}.text-title{font-size:var(--text-title)}.leading-body{--tw-leading:var(--leading-body);line-height:var(--leading-body)}.leading-display{--tw-leading:var(--leading-display);line-height:var(--leading-display)}.leading-label{--tw-leading:var(--leading-label);line-height:var(--leading-label)}.leading-lede{--tw-leading:var(--leading-lede);line-height:var(--leading-lede)}.leading-subtitle{--tw-leading:var(--leading-subtitle);line-height:var(--leading-subtitle)}.leading-title{--tw-leading:var(--leading-title);line-height:var(--leading-title)}.font-\[500\]{--tw-font-weight:500;font-weight:500}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-label{--tw-tracking:var(--tracking-label);letter-spacing:var(--tracking-label)}.tracking-optical{--tw-tracking:var(--tracking-optical);letter-spacing:var(--tracking-optical)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.text-nowrap{text-wrap:nowrap}.text-\[var\(--text-small\)\]{color:var(--text-small)}.text-error{color:var(--color-error)}.text-foreground{color:var(--color-foreground)}.text-inherit{color:inherit}.text-link{color:var(--color-link)}.text-muted{color:var(--color-muted)}.text-primary-foreground{color:var(--color-primary-foreground)}.text-secondary-foreground{color:var(--color-secondary-foreground)}.text-slate-900{color:var(--color-slate-900)}.text-success{color:var(--color-success)}.uppercase{text-transform:uppercase}.ordinal{--tw-ordinal:ordinal;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.no-underline{text-decoration-line:none}.underline{text-decoration-line:underline}.decoration-\[length\:var\(--underline-thickness\)\]{text-decoration-thickness:var(--underline-thickness)}.underline-offset-\[var\(--underline-offset\)\]{text-underline-offset:var(--underline-offset)}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.outline-offset-\[var\(--focus-ring-offset\)\]{outline-offset:var(--focus-ring-offset)}.outline-focus-ring{outline-color:var(--color-focus-ring)}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.invert{--tw-invert:invert(100%);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-\[var\(--motion-duration-color\)\]{--tw-duration:var(--motion-duration-color);transition-duration:var(--motion-duration-color)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.before\:mt-\[0\.35em\]:before{content:var(--tw-content);margin-top:.35em}.before\:size-\[calc\(var\(--tick-length\)\*0\.7\)\]:before{content:var(--tw-content);width:calc(var(--tick-length) * .7);height:calc(var(--tick-length) * .7)}.before\:shrink-0:before{content:var(--tw-content);flex-shrink:0}.before\:rotate-45:before{content:var(--tw-content);rotate:45deg}.before\:bg-\[var\(--color-rule\)\]:before{content:var(--tw-content);background-color:var(--color-rule)}.before\:content-\[\'\'\]:before{--tw-content:"";content:var(--tw-content)}.before\:\[border-right\:var\(--tick-thickness\)_solid_var\(--color-rule\)\]:before{content:var(--tw-content);border-right:var(--tick-thickness) solid var(--color-rule)}.before\:\[border-top\:var\(--tick-thickness\)_solid_var\(--color-rule\)\]:before{content:var(--tw-content);border-top:var(--tick-thickness) solid var(--color-rule)}.first\:border-t:first-child{border-top-style:var(--tw-border-style);border-top-width:1px}.first\:pl-0:first-child{padding-left:0}.last\:pr-0:last-child{padding-right:0}@media (hover:hover){.hover\:border-muted:hover{border-color:var(--color-muted)}.hover\:bg-primary-hover:hover{background-color:var(--color-primary-hover)}.hover\:bg-secondary-hover:hover{background-color:var(--color-secondary-hover)}.hover\:text-sm:hover{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.hover\:text-foreground:hover{color:var(--color-foreground)}.hover\:underline:hover{text-decoration-line:underline}.hover\:decoration-\[length\:var\(--underline-thickness\)\]:hover{text-decoration-thickness:var(--underline-thickness)}.hover\:decoration-\[length\:var\(--underline-thickness-hover\)\]:hover{text-decoration-thickness:var(--underline-thickness-hover)}.hover\:underline-offset-\[var\(--underline-offset\)\]:hover{text-underline-offset:var(--underline-offset)}.hover\:opacity-90:hover{opacity:.9}}.focus-visible\:outline:focus-visible{outline-style:var(--tw-outline-style);outline-width:1px}.focus-visible\:outline-\[length\:var\(--focus-ring-width\)\]:focus-visible{outline-style:var(--tw-outline-style);outline-width:var(--focus-ring-width)}.focus-visible\:outline-\[length\:…\]:focus-visible{outline-style:var(--tw-outline-style);outline-width:…}.focus-visible\:outline-focus-ring:focus-visible{outline-color:var(--color-focus-ring)}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:border-disabled:disabled{border-color:var(--color-disabled)}.disabled\:bg-disabled:disabled{background-color:var(--color-disabled)}.disabled\:text-muted:disabled{color:var(--color-muted)}@media (hover:hover){.disabled\:hover\:bg-disabled-hover:disabled:hover{background-color:var(--color-disabled-hover)}}.aria-selected\:border-foreground[aria-selected=true]{border-color:var(--color-foreground)}.aria-selected\:text-foreground[aria-selected=true]{color:var(--color-foreground)}.aria-\[invalid\=true\]\:border-error[aria-invalid=true]{border-color:var(--color-error)}@media (width>=40rem){.sm\:px-6{padding-inline:calc(var(--spacing) * 6)}.sm\:py-2{padding-block:calc(var(--spacing) * 2)}}@media (width>=48rem){.md\:text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}}@media (width>=64rem){.lg\:sticky{position:sticky}.lg\:top-6{top:calc(var(--spacing) * 6)}.lg\:max-w-\[var\(--measure-display\)\]{max-width:var(--measure-display)}.lg\:grid-cols-\[10rem_minmax\(0\,1fr\)\]{grid-template-columns:10rem minmax(0,1fr)}.lg\:grid-cols-\[12rem_minmax\(0\,1fr\)\]{grid-template-columns:12rem minmax(0,1fr)}.lg\:grid-cols-\[16rem_minmax\(0\,1fr\)\]{grid-template-columns:16rem minmax(0,1fr)}.lg\:flex-row{flex-direction:row}.lg\:items-baseline{align-items:baseline}.lg\:items-start{align-items:flex-start}.lg\:gap-x-12{column-gap:calc(var(--spacing) * 12)}}.\[\&_\[aria-current\=page\]\]\:text-foreground [aria-current=page]{color:var(--color-foreground)}.\[\&_caption\]\:pb-3 caption{padding-bottom:calc(var(--spacing) * 3)}.\[\&_caption\]\:text-left caption{text-align:left}.\[\&_caption\]\:font-secondary caption{font-family:var(--font-secondary)}.\[\&_caption\]\:text-label caption{font-size:var(--text-label)}.\[\&_caption\]\:tracking-label caption{--tw-tracking:var(--tracking-label);letter-spacing:var(--tracking-label)}.\[\&_caption\]\:text-muted caption{color:var(--color-muted)}.\[\&\+li\]\:border-t+li{border-top-style:var(--tw-border-style);border-top-width:1px}.\[\&\+li\]\:border-solid+li{--tw-border-style:solid;border-style:solid}.\[\&\+li\]\:border-border+li{border-color:var(--color-border)}.\[\&\:\:-moz-range-thumb\]\:size-\[var\(--slider-thumb-size\)\]::-moz-range-thumb{width:var(--slider-thumb-size);height:var(--slider-thumb-size)}.\[\&\:\:-moz-range-thumb\]\:rounded-\[var\(--radius-control\)\]::-moz-range-thumb{border-radius:var(--radius-control)}.\[\&\:\:-moz-range-thumb\]\:border-none::-moz-range-thumb{--tw-border-style:none;border-style:none}.\[\&\:\:-moz-range-thumb\]\:bg-foreground::-moz-range-thumb{background-color:var(--color-foreground)}.\[\&\:\:-moz-range-track\]\:h-\[var\(--slider-track-thickness\)\]::-moz-range-track{height:var(--slider-track-thickness)}.\[\&\:\:-moz-range-track\]\:rounded-\[var\(--radius-control\)\]::-moz-range-track{border-radius:var(--radius-control)}.\[\&\:\:-moz-range-track\]\:bg-control-border::-moz-range-track{background-color:var(--color-control-border)}.\[\&\:\:-webkit-slider-runnable-track\]\:h-\[var\(--slider-track-thickness\)\]::-webkit-slider-runnable-track{height:var(--slider-track-thickness)}.\[\&\:\:-webkit-slider-runnable-track\]\:rounded-\[var\(--radius-control\)\]::-webkit-slider-runnable-track{border-radius:var(--radius-control)}.\[\&\:\:-webkit-slider-runnable-track\]\:bg-control-border::-webkit-slider-runnable-track{background-color:var(--color-control-border)}.\[\&\:\:-webkit-slider-thumb\]\:mt-\[calc\(\(var\(--slider-track-thickness\)-var\(--slider-thumb-size\)\)\/2\)\]::-webkit-slider-thumb{margin-top:calc((var(--slider-track-thickness) - var(--slider-thumb-size)) / 2)}.\[\&\:\:-webkit-slider-thumb\]\:size-\[var\(--slider-thumb-size\)\]::-webkit-slider-thumb{width:var(--slider-thumb-size);height:var(--slider-thumb-size)}.\[\&\:\:-webkit-slider-thumb\]\:appearance-none::-webkit-slider-thumb{appearance:none}.\[\&\:\:-webkit-slider-thumb\]\:rounded-\[var\(--radius-control\)\]::-webkit-slider-thumb{border-radius:var(--radius-control)}.\[\&\:\:-webkit-slider-thumb\]\:bg-foreground::-webkit-slider-thumb{background-color:var(--color-foreground)}.\[\&\:disabled\:\:-moz-range-thumb\]\:bg-disabled:disabled::-moz-range-thumb{background-color:var(--color-disabled)}.\[\&\:disabled\:\:-moz-range-track\]\:bg-disabled:disabled::-moz-range-track{background-color:var(--color-disabled)}.\[\&\:disabled\:\:-webkit-slider-runnable-track\]\:bg-disabled:disabled::-webkit-slider-runnable-track{background-color:var(--color-disabled)}.\[\&\:disabled\:\:-webkit-slider-thumb\]\:bg-disabled:disabled::-webkit-slider-thumb{background-color:var(--color-disabled)}.\[\&\:not\(\:first-child\)\]\:mt-\[var\(--space-stack\)\]:not(:first-child){margin-top:var(--space-stack)}.\[\&\:not\(\:first-child\)\]\:border-t:not(:first-child){border-top-style:var(--tw-border-style);border-top-width:1px}.\[\&\:not\(\:first-child\)\]\:border-solid:not(:first-child){--tw-border-style:solid;border-style:solid}.\[\&\:not\(\:first-child\)\]\:border-border:not(:first-child){border-color:var(--color-border)}.\[\&\:not\(\:first-child\)\]\:pt-\[var\(--space-stack\)\]:not(:first-child){padding-top:var(--space-stack)}.\[\&\:not\(\[data-notes\]\)\]\:overflow-x-auto:not([data-notes]){overflow-x:auto}.\[\&\:user-invalid\]\:border-error:user-invalid{border-color:var(--color-error)}@media (width>=64rem){.lg\:\[\&\>dd\]\:col-start-2>dd{grid-column-start:2}.lg\:\[\&\>dd\]\:row-start-1>dd{grid-row-start:1}}.\[\&\>div\:first-child\]\:border-b>div:first-child{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.\[\&\>div\:first-child\]\:border-solid>div:first-child{--tw-border-style:solid;border-style:solid}.\[\&\>div\:first-child\]\:border-border>div:first-child{border-color:var(--color-border)}.\[\&\>div\:first-child\]\:pb-\[var\(--space-stack\)\]>div:first-child{padding-bottom:var(--space-stack)}@media (width>=64rem){.lg\:\[\&\>div\:first-child\]\:border-r>div:first-child{border-right-style:var(--tw-border-style);border-right-width:1px}.lg\:\[\&\>div\:first-child\]\:border-b-0>div:first-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.lg\:\[\&\>div\:first-child\]\:pr-\[var\(--space-stack\)\]>div:first-child{padding-right:var(--space-stack)}.lg\:\[\&\>div\:first-child\]\:pb-0>div:first-child{padding-bottom:0}}.\[\&\>div\:first-child\>nav\]\:p-\[calc\(var\(--focus-ring-width\)\+var\(--focus-ring-offset\)\)\]>div:first-child>nav{padding:calc(var(--focus-ring-width) + var(--focus-ring-offset))}@media (width>=64rem){.lg\:\[\&\>div\:first-child\>nav\]\:sticky>div:first-child>nav{position:sticky}.lg\:\[\&\>div\:first-child\>nav\]\:top-0>div:first-child>nav{top:0}.lg\:\[\&\>div\:first-child\>nav\]\:max-h-\[min\(100dvh\,var\(--sidebar-scrollport-height\,100dvh\)\)\]>div:first-child>nav{max-height:min(100dvh, var(--sidebar-scrollport-height,100dvh))}.lg\:\[\&\>div\:first-child\>nav\]\:scroll-p-\[calc\(var\(--focus-ring-width\)\+var\(--focus-ring-offset\)\)\]>div:first-child>nav{scroll-padding:calc(var(--focus-ring-width) + var(--focus-ring-offset))}.lg\:\[\&\>div\:first-child\>nav\]\:overflow-y-auto>div:first-child>nav{overflow-y:auto}}.\[\&\>div\:first-child\>nav\>ul\]\:flex>div:first-child>nav>ul{display:flex}.\[\&\>div\:first-child\>nav\>ul\]\:flex-col>div:first-child>nav>ul{flex-direction:column}.\[\&\>div\:first-child\>nav\>ul\]\:gap-\[var\(--space-stack\)\]>div:first-child>nav>ul{gap:var(--space-stack)}@media (width>=64rem){.lg\:\[\&\>dt\]\:col-start-1>dt{grid-column-start:1}}.\[\&\>table\]\:w-full>table{width:100%}.\[\&\>table\]\:border-collapse>table{border-collapse:collapse}.\[\&\>table\]\:text-left>table{text-align:left}.\[\&\>table\>\*\:nth-child\(2\)\>tr\:first-child\]\:border-rule>table>:nth-child(2)>tr:first-child{border-color:var(--color-rule)}@media not all and (width>=48rem){.\[\&\[data-notes\=content\]_tbody\]\:max-md\:block[data-notes=content] tbody,.\[\&\[data-notes\=content\]_td\]\:max-md\:block[data-notes=content] td,.\[\&\[data-notes\=content\]_tfoot\]\:max-md\:block[data-notes=content] tfoot,.\[\&\[data-notes\=content\]_th\]\:max-md\:block[data-notes=content] th,.\[\&\[data-notes\=content\]_thead\]\:max-md\:block[data-notes=content] thead,.\[\&\[data-notes\=content\]_tr\]\:max-md\:block[data-notes=content] tr,.\[\&\[data-notes\=content\]\>table\]\:max-md\:block[data-notes=content]>table{display:block}.\[\&\[data-notes\=supplementary\]_\[data-variant\=note\]\]\:max-md\:hidden[data-notes=supplementary] [data-variant=note]{display:none}}[data-section]+.\[\[data-section\]\+\&\]\:z-10{z-index:10}[data-section]+.\[\[data-section\]\+\&\]\:border-t{border-top-style:var(--tw-border-style);border-top-width:1px}[data-section]+.\[\[data-section\]\+\&\]\:border-solid{--tw-border-style:solid;border-style:solid}[data-section]+.\[\[data-section\]\+\&\]\:border-rule{border-color:var(--color-rule)}}:root{--color-surface:#fff;--color-foreground:#0f172a;--color-muted:#64748b;--color-border:#e2e8f0;--color-control-border:#64748b;--color-rule:#808fa3;--color-backing:#f1f5f9;--color-meter-fill:#0f172a;--color-meter-track:#e2e8f0;--color-primary:#7c3aed;--color-primary-hover:#6d28d9;--color-primary-foreground:#f8fafc;--color-secondary:#0369a1;--color-secondary-hover:#075985;--color-secondary-foreground:#f8fafc;--color-disabled:#94a3b8;--color-disabled-hover:#64748b;--color-focus-ring:var(--color-ring,#475569);--color-link:#2563eb;--color-success:#10b981;--color-warning:#f59e0b;--color-error:#d63384;--color-info:#06b6d4}.dark{--color-surface:#0f172a;--color-foreground:#f8fafc;--color-muted:#94a3b8;--color-border:#334155;--color-control-border:#94a3b8;--color-rule:#5b6a80;--color-backing:#1e293b;--color-meter-fill:#f8fafc;--color-meter-track:#334155;--color-primary:#8b5cf6;--color-primary-hover:#a78bfa;--color-primary-foreground:#020617;--color-secondary:#0284c7;--color-secondary-hover:#0ea5e9;--color-secondary-foreground:#020617;--color-disabled:#475569;--color-disabled-hover:#334155;--color-focus-ring:var(--color-ring,#cbd5e1);--color-link:#60a5fa;--color-success:#34d399;--color-warning:#fbbf24;--color-error:#f48fb1;--color-info:#22d3ee}:root{--motion-duration-color:.15s}@media (prefers-reduced-motion:reduce){:root{--motion-duration-color:0s}}:root{--focus-ring-width:3px;--focus-ring-offset:2px;--radius-control:.5rem;--control-min-width:10.5rem;--standing-min-width:7.5rem;--underline-offset:.18em;--underline-thickness:1px;--underline-thickness-hover:2px;--measure:66ch;--measure-display:36ch;--measure-wide:72ch;--measure-action:20rem;--space-stack:.5em;--space-region:1.5em;--space-band:4em;--space-collection-item:1em;--gutter:clamp(1.5rem, 5vw, 4rem);--fold-height:min(70vh, 40rem);--cover-height:100svh;--tick-length:.9rem;--tick-thickness:1px;--tab-marker-thickness:2px;--tab-inset-inline:1em;--tab-inset-block:.5em;--slider-track-thickness:.25rem;--slider-thumb-size:1.5rem;--meter-track-thickness:.5rem}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { type VariantProps } from 'class-variance-authority';
|
|
2
|
+
import type { FunctionComponent } from 'react';
|
|
3
|
+
declare const meterFill: (props?: ({
|
|
4
|
+
treatment?: "neutral" | "depleting" | null | undefined;
|
|
5
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
6
|
+
export interface IMeterProps extends VariantProps<typeof meterFill> {
|
|
7
|
+
/** The current level. Must lie inside `[min, max]`; an outside value throws
|
|
8
|
+
* {@link MeterConfigurationError} rather than clamping - a wrong number must not render as a
|
|
9
|
+
* plausible level. */
|
|
10
|
+
value: number;
|
|
11
|
+
/** The bottom of the scale. Defaults to `0`. */
|
|
12
|
+
min?: number;
|
|
13
|
+
/** The top of the scale. Must exceed `min`. */
|
|
14
|
+
max: number;
|
|
15
|
+
/** The meter's accessible name - what the level measures. Required, and never rendered visibly:
|
|
16
|
+
* the component shows a filled track and nothing else. Its wording is the consumer's. */
|
|
17
|
+
label: string;
|
|
18
|
+
/** Optional `aria-valuetext`, so a screen reader hears the consumer's wording ("strained")
|
|
19
|
+
* instead of a bare number. Omitted, the numeric value is announced. */
|
|
20
|
+
valueText?: string;
|
|
21
|
+
testId?: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* A read-only display of one numeric level within a bounded scale, shown as a filled share of a
|
|
25
|
+
* whole: a short track, a fill from inline-start, no text. It states an amount - not an operation's
|
|
26
|
+
* completion, and unlike a Slider it cannot be operated.
|
|
27
|
+
*
|
|
28
|
+
* @Guarantees — enforced on every render
|
|
29
|
+
* - The root carries `role="meter"`, `aria-valuenow`/`aria-valuemin`/`aria-valuemax`, the `label`
|
|
30
|
+
* as its accessible name, and `aria-valuetext` exactly when `valueText` is supplied. It is not
|
|
31
|
+
* focusable, and the visual fill is hidden from the accessibility tree.
|
|
32
|
+
* - The filled share is `(value - min) / (max - min)` of the container and begins at logical
|
|
33
|
+
* inline-start under both LTR and RTL direction.
|
|
34
|
+
* - Neutral paints the fill with `meterFill`; `depleting` maps the normalized level linearly
|
|
35
|
+
* through OKLab from `meterFill` at the maximum to `error` at the minimum - no threshold, no
|
|
36
|
+
* wording, no icon (docs/adr/0010-meter-depletion-is-a-treatment.md).
|
|
37
|
+
* - A value change lands instantly: no width or colour animation.
|
|
38
|
+
* - The track fills its container, reads `--meter-track-thickness`, keeps square corners (no
|
|
39
|
+
* radius token - Meter is not a control), and draws a persistent one-pixel `rule` line that
|
|
40
|
+
* identifies the whole capacity against the surface.
|
|
41
|
+
* - Invalid numeric configuration throws {@link MeterConfigurationError}: non-finite `value`,
|
|
42
|
+
* `min` or `max`, `min >= max`, or a value outside the inclusive range. Nothing is clamped.
|
|
43
|
+
* - No visible wording of its own, no numeric readout, no caption slot, no `className`/`style`
|
|
44
|
+
* passthrough.
|
|
45
|
+
*
|
|
46
|
+
* @CallerMustEnsure — the component cannot see these and does not check them
|
|
47
|
+
* - `label` carries meaningful wording; the component renders it to assistive technology only and
|
|
48
|
+
* does not inspect it.
|
|
49
|
+
* - When `depleting` is selected, surrounding visible content explains why nearing the minimum
|
|
50
|
+
* matters - the colour walk reinforces a stated consequence and must not be its only carrier.
|
|
51
|
+
*
|
|
52
|
+
* @UXGuidelines
|
|
53
|
+
* - Place any visible caption or readout yourself with typography; the Meter deliberately carries
|
|
54
|
+
* none, so what the level measures stays the consumer's wording.
|
|
55
|
+
* - Reach for `depleting` only where a low value is genuinely more erroneous - some quantities
|
|
56
|
+
* become safer toward their minimum, which is why the treatment is opt-in.
|
|
57
|
+
*/
|
|
58
|
+
export declare const Meter: FunctionComponent<IMeterProps>;
|
|
59
|
+
export {};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { FunctionComponent } from 'react';
|
|
2
|
+
import type { Subject } from 'rxjs';
|
|
3
|
+
export interface ISliderProps {
|
|
4
|
+
/** The operating range's lower bound - interaction geometry, not a content rule (ADR 0009). */
|
|
5
|
+
min: number;
|
|
6
|
+
/** The operating range's upper bound. */
|
|
7
|
+
max: number;
|
|
8
|
+
/**
|
|
9
|
+
* The increment a movement produces. Defaults to 1: whole-step movement. Keeping `value` and
|
|
10
|
+
* `max` on the step grid is the caller's obligation - Slider neither rejects nor repairs an
|
|
11
|
+
* off-grid value, and the native control's own conduct stays observable: inside a surrounding
|
|
12
|
+
* form, misalignment counts as a `stepMismatch` against that form's validity.
|
|
13
|
+
*/
|
|
14
|
+
step?: number;
|
|
15
|
+
/** The current value. Controlled - the consumer holds it and passes it back in. */
|
|
16
|
+
value: number;
|
|
17
|
+
/**
|
|
18
|
+
* Emits the new value on every native input event. Required, not optional: the control is
|
|
19
|
+
* controlled and takes no part in form submission, so a consumer that did not listen here
|
|
20
|
+
* could never read a value at all.
|
|
21
|
+
*/
|
|
22
|
+
onInput$: Subject<number>;
|
|
23
|
+
/** The control's accessible name. */
|
|
24
|
+
label: string;
|
|
25
|
+
/**
|
|
26
|
+
* How the value is announced, in the consumer's wording ("$60 a week"). Left out, assistive
|
|
27
|
+
* technology reads the bare number: the library ships no wording of its own.
|
|
28
|
+
*/
|
|
29
|
+
valueText?: string;
|
|
30
|
+
/** The explicit non-operable state: native disabled conduct, no emissions, disabled paint. */
|
|
31
|
+
disabled?: boolean;
|
|
32
|
+
testId?: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A control that sets one numeric value by moving one thumb along a fixed, visible operating
|
|
36
|
+
* range. Controlled: the consumer holds the value and passes it back in, and a value it does not
|
|
37
|
+
* pass back is never adopted. It renders the value nowhere - the consumer sets any figures beside
|
|
38
|
+
* it with typography - and it fills its container's width the way `Input` does. `disabled` is the
|
|
39
|
+
* explicit non-operable state.
|
|
40
|
+
*/
|
|
41
|
+
export declare const Slider: FunctionComponent<ISliderProps>;
|
|
@@ -38,6 +38,19 @@ export type PaletteTokens = {
|
|
|
38
38
|
* because a failed image renders its alt text on this plate and that text must stay legible. That
|
|
39
39
|
* keeps it near `surface` rather than a mid grey. */
|
|
40
40
|
backing: string;
|
|
41
|
+
/** The colour of a Meter's filled share when it states an amount without judgment - neither an
|
|
42
|
+
* action fill nor text ink. The depletion treatment mixes it toward `error` in OKLab, so the
|
|
43
|
+
* constraint covers the whole path (WCAG 2.2 SC 1.4.11): this value, `error`, and every colour
|
|
44
|
+
* the mix produces between them stay at least 3:1 against `meterTrack` in the same theme. A
|
|
45
|
+
* distinct role even while its shipped value matches `foreground` - a consumer re-points either
|
|
46
|
+
* without moving the other. See docs/adr/0010-meter-depletion-is-a-treatment.md. */
|
|
47
|
+
meterFill: string;
|
|
48
|
+
/** The colour of a Meter's whole capacity behind its filled share. It makes the scale visible
|
|
49
|
+
* without turning it into a boundary - the persistent one-pixel `rule` outline is what
|
|
50
|
+
* identifies the capacity against `surface`, so this role carries no floor of its own; the
|
|
51
|
+
* 3:1 floor is stated from the fill side, on `meterFill`. A distinct role even while its
|
|
52
|
+
* shipped value matches `border`. See docs/adr/0010-meter-depletion-is-a-treatment.md. */
|
|
53
|
+
meterTrack: string;
|
|
41
54
|
/** The main call-to-action fill. A filled control draws no border, so the fill is the only thing
|
|
42
55
|
* separating the control from the surface - what `controlBorder` is for an unfilled one.
|
|
43
56
|
* Constraint (WCAG 2.2 SC 1.4.11): at least 3:1 against `surface` in the same theme,
|
package/dist/types/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export { Checklist } from 'Display/Checklist/Checklist';
|
|
|
6
6
|
export { Collection } from 'Display/Collection/Collection';
|
|
7
7
|
export { DefinitionList } from 'Display/DefinitionList/DefinitionList';
|
|
8
8
|
export { Figure } from 'Display/Figure/Figure';
|
|
9
|
+
export { Meter } from 'Display/Meter/Meter';
|
|
9
10
|
export { Rail } from 'Display/Rail/Rail';
|
|
10
11
|
export { Table } from 'Display/Table/Table';
|
|
11
12
|
export { Eyebrow } from 'Display/Typography/Eyebrow/Eyebrow';
|
|
@@ -21,6 +22,7 @@ export { Prose } from 'Display/Typography/Prose/Prose';
|
|
|
21
22
|
export { Button } from 'Interaction/Button/Button';
|
|
22
23
|
export { Input } from 'Interaction/Input/Input';
|
|
23
24
|
export { Link } from 'Interaction/Link/Link';
|
|
25
|
+
export { Slider } from 'Interaction/Slider/Slider';
|
|
24
26
|
export { Tabs } from 'Interaction/Tabs/Tabs';
|
|
25
27
|
export { TextArea } from 'Interaction/TextArea/TextArea';
|
|
26
28
|
export { Cover } from 'Layout/Cover/Cover';
|
package/package.json
CHANGED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
2
|
+
import type { CSSProperties, FunctionComponent } from 'react';
|
|
3
|
+
import { MeterConfigurationError } from './MeterConfigurationError';
|
|
4
|
+
|
|
5
|
+
// The track is the whole capacity: square corners, no radius token - Meter is not a control
|
|
6
|
+
// (docs/adr/0003). The one-pixel `rule` line identifies the capacity against the surface;
|
|
7
|
+
// `meterTrack` behind it makes the scale visible without boxing (docs/adr/0010). Deliberately no
|
|
8
|
+
// transition class: the library's one motion belongs to state changes on controls, not a display.
|
|
9
|
+
const meterTrack = cva(
|
|
10
|
+
'w-full h-[var(--meter-track-thickness)] bg-meter-track border border-solid border-rule',
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
// The fill is a block box sized by --meter-level, the normalized share the component computes;
|
|
14
|
+
// block layout places it at inline-start in both LTR and RTL, no physical offset. Depleting reads
|
|
15
|
+
// the same share into color-mix: `meterFill` at max, `error` at min, linearly through OKLab - a
|
|
16
|
+
// perceptual space, so no threshold (docs/adr/0010). Both endpoints stay tokens a brand re-points.
|
|
17
|
+
const meterFill = cva('h-full w-[calc(var(--meter-level)*100%)]', {
|
|
18
|
+
variants: {
|
|
19
|
+
treatment: {
|
|
20
|
+
neutral: 'bg-meter-fill',
|
|
21
|
+
depleting:
|
|
22
|
+
'bg-[color-mix(in_oklab,var(--color-meter-fill)_calc(var(--meter-level)*100%),var(--color-error))]',
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
defaultVariants: {
|
|
26
|
+
treatment: 'neutral',
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// React's CSSProperties is closed over known properties; the one custom property the recipes read
|
|
31
|
+
// is declared here so the style object stays typed without an assertion.
|
|
32
|
+
type MeterLevelStyle = CSSProperties & { '--meter-level': number };
|
|
33
|
+
|
|
34
|
+
export interface IMeterProps extends VariantProps<typeof meterFill> {
|
|
35
|
+
/** The current level. Must lie inside `[min, max]`; an outside value throws
|
|
36
|
+
* {@link MeterConfigurationError} rather than clamping - a wrong number must not render as a
|
|
37
|
+
* plausible level. */
|
|
38
|
+
value: number;
|
|
39
|
+
/** The bottom of the scale. Defaults to `0`. */
|
|
40
|
+
min?: number;
|
|
41
|
+
/** The top of the scale. Must exceed `min`. */
|
|
42
|
+
max: number;
|
|
43
|
+
/** The meter's accessible name - what the level measures. Required, and never rendered visibly:
|
|
44
|
+
* the component shows a filled track and nothing else. Its wording is the consumer's. */
|
|
45
|
+
label: string;
|
|
46
|
+
/** Optional `aria-valuetext`, so a screen reader hears the consumer's wording ("strained")
|
|
47
|
+
* instead of a bare number. Omitted, the numeric value is announced. */
|
|
48
|
+
valueText?: string;
|
|
49
|
+
testId?: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* A read-only display of one numeric level within a bounded scale, shown as a filled share of a
|
|
54
|
+
* whole: a short track, a fill from inline-start, no text. It states an amount - not an operation's
|
|
55
|
+
* completion, and unlike a Slider it cannot be operated.
|
|
56
|
+
*
|
|
57
|
+
* @Guarantees — enforced on every render
|
|
58
|
+
* - The root carries `role="meter"`, `aria-valuenow`/`aria-valuemin`/`aria-valuemax`, the `label`
|
|
59
|
+
* as its accessible name, and `aria-valuetext` exactly when `valueText` is supplied. It is not
|
|
60
|
+
* focusable, and the visual fill is hidden from the accessibility tree.
|
|
61
|
+
* - The filled share is `(value - min) / (max - min)` of the container and begins at logical
|
|
62
|
+
* inline-start under both LTR and RTL direction.
|
|
63
|
+
* - Neutral paints the fill with `meterFill`; `depleting` maps the normalized level linearly
|
|
64
|
+
* through OKLab from `meterFill` at the maximum to `error` at the minimum - no threshold, no
|
|
65
|
+
* wording, no icon (docs/adr/0010-meter-depletion-is-a-treatment.md).
|
|
66
|
+
* - A value change lands instantly: no width or colour animation.
|
|
67
|
+
* - The track fills its container, reads `--meter-track-thickness`, keeps square corners (no
|
|
68
|
+
* radius token - Meter is not a control), and draws a persistent one-pixel `rule` line that
|
|
69
|
+
* identifies the whole capacity against the surface.
|
|
70
|
+
* - Invalid numeric configuration throws {@link MeterConfigurationError}: non-finite `value`,
|
|
71
|
+
* `min` or `max`, `min >= max`, or a value outside the inclusive range. Nothing is clamped.
|
|
72
|
+
* - No visible wording of its own, no numeric readout, no caption slot, no `className`/`style`
|
|
73
|
+
* passthrough.
|
|
74
|
+
*
|
|
75
|
+
* @CallerMustEnsure — the component cannot see these and does not check them
|
|
76
|
+
* - `label` carries meaningful wording; the component renders it to assistive technology only and
|
|
77
|
+
* does not inspect it.
|
|
78
|
+
* - When `depleting` is selected, surrounding visible content explains why nearing the minimum
|
|
79
|
+
* matters - the colour walk reinforces a stated consequence and must not be its only carrier.
|
|
80
|
+
*
|
|
81
|
+
* @UXGuidelines
|
|
82
|
+
* - Place any visible caption or readout yourself with typography; the Meter deliberately carries
|
|
83
|
+
* none, so what the level measures stays the consumer's wording.
|
|
84
|
+
* - Reach for `depleting` only where a low value is genuinely more erroneous - some quantities
|
|
85
|
+
* become safer toward their minimum, which is why the treatment is opt-in.
|
|
86
|
+
*/
|
|
87
|
+
export const Meter: FunctionComponent<IMeterProps> = ({
|
|
88
|
+
value,
|
|
89
|
+
min = 0,
|
|
90
|
+
max,
|
|
91
|
+
treatment,
|
|
92
|
+
label,
|
|
93
|
+
valueText,
|
|
94
|
+
testId,
|
|
95
|
+
}) => {
|
|
96
|
+
if (
|
|
97
|
+
!Number.isFinite(value) ||
|
|
98
|
+
!Number.isFinite(min) ||
|
|
99
|
+
!Number.isFinite(max)
|
|
100
|
+
) {
|
|
101
|
+
throw new MeterConfigurationError(
|
|
102
|
+
`value, min and max must be finite numbers (got value=${value}, min=${min}, max=${max})`,
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
if (min >= max) {
|
|
106
|
+
throw new MeterConfigurationError(
|
|
107
|
+
`min must be less than max (got min=${min}, max=${max})`,
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
if (value < min || value > max) {
|
|
111
|
+
throw new MeterConfigurationError(
|
|
112
|
+
`value must lie within [min, max] (got value=${value}, min=${min}, max=${max})`,
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const style: MeterLevelStyle = {
|
|
117
|
+
'--meter-level': (value - min) / (max - min),
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
return (
|
|
121
|
+
// biome-ignore lint/a11y/useSemanticElements: the native <meter> paints its own optimum/low/high bands the token contract cannot reach, and its fill is unstylable cross-browser; the ARIA meter pattern on a div carries the same semantics with the library's paint (#105).
|
|
122
|
+
<div
|
|
123
|
+
role={'meter'}
|
|
124
|
+
aria-valuenow={value}
|
|
125
|
+
aria-valuemin={min}
|
|
126
|
+
aria-valuemax={max}
|
|
127
|
+
aria-label={label}
|
|
128
|
+
aria-valuetext={valueText}
|
|
129
|
+
data-testid={testId}
|
|
130
|
+
className={meterTrack()}
|
|
131
|
+
style={style}
|
|
132
|
+
>
|
|
133
|
+
<div aria-hidden={'true'} className={meterFill({ treatment })} />
|
|
134
|
+
</div>
|
|
135
|
+
);
|
|
136
|
+
};
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { cva } from 'class-variance-authority';
|
|
2
|
+
import type { FunctionComponent } from 'react';
|
|
3
|
+
import type { Subject } from 'rxjs';
|
|
4
|
+
import { SliderConfigurationError } from './SliderConfigurationError';
|
|
5
|
+
|
|
6
|
+
// The track and thumb are vendor pseudo-elements, so every dimension on them needs a token name -
|
|
7
|
+
// no consumer selector reaches them (ADR 0004's test; the tick precedent). The track takes
|
|
8
|
+
// `controlBorder`: the one thing separating an unfilled control from the surface, >=3:1 against it.
|
|
9
|
+
// The thumb takes `foreground`, a solid mark drawn on the surface like the tab marker; disabled
|
|
10
|
+
// paints both in the disabled role, the non-operable statement every control makes. WebKit does
|
|
11
|
+
// not centre the thumb on the track, hence the computed negative margin; Firefox does, but draws a
|
|
12
|
+
// default thumb border WebKit does not, hence border-none on its thumb alone.
|
|
13
|
+
const slider = cva(
|
|
14
|
+
[
|
|
15
|
+
'block h-[var(--slider-thumb-size)] w-full cursor-pointer appearance-none bg-transparent',
|
|
16
|
+
'disabled:cursor-not-allowed',
|
|
17
|
+
'outline-focus-ring outline-offset-[var(--focus-ring-offset)] focus-visible:outline focus-visible:outline-[length:var(--focus-ring-width)]',
|
|
18
|
+
'[&::-webkit-slider-runnable-track]:h-[var(--slider-track-thickness)] [&::-webkit-slider-runnable-track]:rounded-[var(--radius-control)] [&::-webkit-slider-runnable-track]:bg-control-border',
|
|
19
|
+
'[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:size-[var(--slider-thumb-size)] [&::-webkit-slider-thumb]:rounded-[var(--radius-control)] [&::-webkit-slider-thumb]:bg-foreground',
|
|
20
|
+
'[&::-webkit-slider-thumb]:mt-[calc((var(--slider-track-thickness)-var(--slider-thumb-size))/2)]',
|
|
21
|
+
'[&:disabled::-webkit-slider-runnable-track]:bg-disabled [&:disabled::-webkit-slider-thumb]:bg-disabled',
|
|
22
|
+
'[&::-moz-range-track]:h-[var(--slider-track-thickness)] [&::-moz-range-track]:rounded-[var(--radius-control)] [&::-moz-range-track]:bg-control-border',
|
|
23
|
+
'[&::-moz-range-thumb]:size-[var(--slider-thumb-size)] [&::-moz-range-thumb]:rounded-[var(--radius-control)] [&::-moz-range-thumb]:border-none [&::-moz-range-thumb]:bg-foreground',
|
|
24
|
+
'[&:disabled::-moz-range-track]:bg-disabled [&:disabled::-moz-range-thumb]:bg-disabled',
|
|
25
|
+
].join(' '),
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
export interface ISliderProps {
|
|
29
|
+
/** The operating range's lower bound - interaction geometry, not a content rule (ADR 0009). */
|
|
30
|
+
min: number;
|
|
31
|
+
/** The operating range's upper bound. */
|
|
32
|
+
max: number;
|
|
33
|
+
/**
|
|
34
|
+
* The increment a movement produces. Defaults to 1: whole-step movement. Keeping `value` and
|
|
35
|
+
* `max` on the step grid is the caller's obligation - Slider neither rejects nor repairs an
|
|
36
|
+
* off-grid value, and the native control's own conduct stays observable: inside a surrounding
|
|
37
|
+
* form, misalignment counts as a `stepMismatch` against that form's validity.
|
|
38
|
+
*/
|
|
39
|
+
step?: number;
|
|
40
|
+
/** The current value. Controlled - the consumer holds it and passes it back in. */
|
|
41
|
+
value: number;
|
|
42
|
+
/**
|
|
43
|
+
* Emits the new value on every native input event. Required, not optional: the control is
|
|
44
|
+
* controlled and takes no part in form submission, so a consumer that did not listen here
|
|
45
|
+
* could never read a value at all.
|
|
46
|
+
*/
|
|
47
|
+
onInput$: Subject<number>;
|
|
48
|
+
/** The control's accessible name. */
|
|
49
|
+
label: string;
|
|
50
|
+
/**
|
|
51
|
+
* How the value is announced, in the consumer's wording ("$60 a week"). Left out, assistive
|
|
52
|
+
* technology reads the bare number: the library ships no wording of its own.
|
|
53
|
+
*/
|
|
54
|
+
valueText?: string;
|
|
55
|
+
/** The explicit non-operable state: native disabled conduct, no emissions, disabled paint. */
|
|
56
|
+
disabled?: boolean;
|
|
57
|
+
testId?: string;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Structural misconfiguration is a programmer error, so it fails fast - no clamping, no
|
|
61
|
+
// normalization, no substitute emission. Step-grid alignment is deliberately not checked: that is
|
|
62
|
+
// the caller's obligation, documented on `step`, and native constraint behaviour stays observable.
|
|
63
|
+
const assertOperatingRange = (
|
|
64
|
+
range: Pick<Required<ISliderProps>, 'min' | 'max' | 'step' | 'value'>,
|
|
65
|
+
): void => {
|
|
66
|
+
for (const [name, given] of Object.entries(range)) {
|
|
67
|
+
if (!Number.isFinite(given)) {
|
|
68
|
+
throw new SliderConfigurationError(
|
|
69
|
+
`\`${name}\` must be a finite number, got ${given}`,
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (range.min >= range.max) {
|
|
74
|
+
throw new SliderConfigurationError(
|
|
75
|
+
`\`min\` (${range.min}) must be below \`max\` (${range.max})`,
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
if (range.step <= 0) {
|
|
79
|
+
throw new SliderConfigurationError(
|
|
80
|
+
`\`step\` (${range.step}) must be positive`,
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
if (range.value < range.min || range.value > range.max) {
|
|
84
|
+
throw new SliderConfigurationError(
|
|
85
|
+
`\`value\` (${range.value}) must lie within [${range.min}, ${range.max}]`,
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* A control that sets one numeric value by moving one thumb along a fixed, visible operating
|
|
92
|
+
* range. Controlled: the consumer holds the value and passes it back in, and a value it does not
|
|
93
|
+
* pass back is never adopted. It renders the value nowhere - the consumer sets any figures beside
|
|
94
|
+
* it with typography - and it fills its container's width the way `Input` does. `disabled` is the
|
|
95
|
+
* explicit non-operable state.
|
|
96
|
+
*/
|
|
97
|
+
export const Slider: FunctionComponent<ISliderProps> = ({
|
|
98
|
+
min,
|
|
99
|
+
max,
|
|
100
|
+
step = 1,
|
|
101
|
+
value,
|
|
102
|
+
onInput$,
|
|
103
|
+
label,
|
|
104
|
+
valueText,
|
|
105
|
+
disabled,
|
|
106
|
+
testId,
|
|
107
|
+
}) => {
|
|
108
|
+
assertOperatingRange({ min, max, step, value });
|
|
109
|
+
return (
|
|
110
|
+
<input
|
|
111
|
+
type={'range'}
|
|
112
|
+
className={slider()}
|
|
113
|
+
min={min}
|
|
114
|
+
max={max}
|
|
115
|
+
step={step}
|
|
116
|
+
value={value}
|
|
117
|
+
disabled={disabled}
|
|
118
|
+
aria-label={label}
|
|
119
|
+
aria-valuetext={valueText}
|
|
120
|
+
data-testid={testId}
|
|
121
|
+
// React's onChange rides the native input event, so every movement emits through here.
|
|
122
|
+
onChange={(event) => onInput$.next(event.currentTarget.valueAsNumber)}
|
|
123
|
+
/>
|
|
124
|
+
);
|
|
125
|
+
};
|