plass-ui 0.0.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 CDGet
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,111 @@
1
+ # Plass UI
2
+
3
+ [![license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/jooy2/plass-ui/blob/main/LICENSE) [![npm latest package](https://img.shields.io/npm/v/plass-ui/latest.svg)](https://www.npmjs.com/package/plass-ui) [![npm downloads](https://img.shields.io/npm/dm/plass-ui.svg)](https://www.npmjs.com/package/plass-ui)
4
+
5
+ ### 📘 [**plass-ui.cdget.com**](https://plass-ui.cdget.com)
6
+
7
+ Live previews and full props for every component. This README is just the quick start.
8
+
9
+ ---
10
+
11
+ **Plass UI is a React component library with a material rather than a theme.** Every surface answers one question — is this pressed, or does it hold something? — and the answer decides everything else.
12
+
13
+ A thing that is pressed is **plastic**: a gradient fill at 135°, a specular highlight along its top edge, and a drop shadow tinted with its own colour. A thing that holds something is **glass**: translucent, heavily blurred, a white hairline round it, and never dyed. There is no third answer.
14
+
15
+ - **Two materials, one language** — `solid`, `glass`, `ghost`. Not `filled`, `outlined`, `text`.
16
+ - **One shared vocabulary** — `size`, `color`, `variant`, `density`, `elevation`. An `md` is 40px on every control; `primary` is the same family everywhere.
17
+ - **Accessible by construction** — real roles, labels, focus management and keyboard support, not `div`s with click handlers.
18
+ - **Contrast that was checked** — every gradient stop clears 4.5:1 against its own label, the lightest corner included.
19
+ - **Dark mode with no work** — follows the system, and can be forced either way per subtree.
20
+ - **ESM only**, TypeScript declarations included, tree-shakeable.
21
+ - **One runtime dependency.** React 18 or 19, Node.js 20.19 or later.
22
+
23
+ > **0.0.1 is a preview.** Two components are released — `Button` and `TextField`. The prop vocabulary, the tokens and the build are the shape everything after this will be poured into; the component list is not yet worth building a product on.
24
+
25
+ ## Documentation
26
+
27
+ | Page | What you will find |
28
+ | --- | --- |
29
+ | [**Getting started**](https://plass-ui.cdget.com/guide/getting-started) | Install and setup, end to end. |
30
+ | [**All components**](https://plass-ui.cdget.com/components/) | Every component, one page each: live previews and the full props table. |
31
+ | [**Design language**](https://plass-ui.cdget.com/design/design-language) | Why a Plass surface looks and behaves the way it does. |
32
+ | [**Prop conventions**](https://plass-ui.cdget.com/design/prop-conventions) | The shared vocabulary every component draws from. |
33
+ | [**Colour**](https://plass-ui.cdget.com/design/color) | The token families, the measured contrast, and how to theme them. |
34
+ | [**Changelog**](https://plass-ui.cdget.com/changelog) | What changed in each release. |
35
+
36
+ ## Installation
37
+
38
+ ```bash
39
+ npm install plass-ui
40
+ ```
41
+
42
+ `react` and `react-dom` are peer dependencies — React 18 or 19.
43
+
44
+ ### Setup
45
+
46
+ Add one line to your app's CSS entry point:
47
+
48
+ ```css
49
+ @import 'plass-ui/styles.css';
50
+ ```
51
+
52
+ `plass-ui/styles.css` is finished CSS — the design tokens, the compiled rules for every utility class the components use, and a small reset whose every rule is specificity 0 so your own styles always win. [Tailwind CSS](https://tailwindcss.com) v4 builds this package; it does not have to be installed in yours.
53
+
54
+ If your project already runs Tailwind v4, import the token sheet instead:
55
+
56
+ ```css
57
+ @import 'tailwindcss';
58
+ @import 'plass-ui/tailwind.css';
59
+ ```
60
+
61
+ ### One more line, and it matters here
62
+
63
+ Plass does not paint your `<body>`, but a sheet of glass over a flat white page has nothing to be in front of. Two tokens exist for exactly this:
64
+
65
+ ```css
66
+ body {
67
+ background: linear-gradient(160deg, var(--plass-bg-from) 0%, var(--plass-bg-to) 100%);
68
+ background-attachment: fixed;
69
+ color: var(--plass-fg);
70
+ }
71
+ ```
72
+
73
+ ## Usage
74
+
75
+ ```tsx
76
+ import { Button, TextField } from 'plass-ui';
77
+
78
+ export default function SignIn() {
79
+ return (
80
+ <form onSubmit={submit}>
81
+ <TextField label="Email" type="email" fullWidth />
82
+ <Button type="submit">Sign in</Button>
83
+ <Button variant="glass" color="secondary">
84
+ Cancel
85
+ </Button>
86
+ </form>
87
+ );
88
+ }
89
+ ```
90
+
91
+ ## Components
92
+
93
+ ### Inputs
94
+
95
+ `Button` · `TextField`
96
+
97
+ ## Development
98
+
99
+ ```bash
100
+ npm test # Vitest, single run (headless Chromium)
101
+ npm run typecheck # tsc --noEmit over all three TS projects
102
+ npm run docs:dev # VitePress docs site — the develop-and-eyeball loop
103
+ npm run build # tsc + terser + build-styles → dist/
104
+ npm run lint # ESLint
105
+ ```
106
+
107
+ The docs render the real components from `src/` through a Vite alias, so `npm run docs:dev` is the develop-and-eyeball loop; there is no separate demo app.
108
+
109
+ ## License
110
+
111
+ MIT © [CDGet](https://cdget.com)
@@ -0,0 +1,42 @@
1
+ import * as React from 'react';
2
+ import { useRender } from '@base-ui/react/use-render';
3
+ import type { PlassElevation, PlassStyleProps } from '../../types';
4
+ export interface ButtonProps extends PlassStyleProps, Omit<React.ComponentPropsWithoutRef<'button'>, 'color'> {
5
+ /**
6
+ * Drop shadow depth. `1` is the default, because a moulded key **rests on**
7
+ * the sheet rather than lying flush with it. Hover adds a level and pressing
8
+ * removes one, which is what puts the key down against the glass under the
9
+ * finger.
10
+ * @default 1
11
+ */
12
+ elevation?: PlassElevation;
13
+ /** Content placed before the label. Sized in `em`, so it tracks the label. */
14
+ startIcon?: React.ReactNode;
15
+ /** Content placed after the label. */
16
+ endIcon?: React.ReactNode;
17
+ /**
18
+ * Shows a spinner in place of `startIcon` and stops the button from
19
+ * activating, while keeping it focusable and visually unchanged otherwise.
20
+ */
21
+ loading?: boolean;
22
+ /** Inert but not dimmed — the action exists, it just is not available here. */
23
+ readOnly?: boolean;
24
+ /** Stretches to the width of the container. */
25
+ fullWidth?: boolean;
26
+ /**
27
+ * Renders something other than a `<button>` — an `<a href>` for an action that
28
+ * is really a navigation, or the `Link` a router brings. Base UI's own escape
29
+ * hatch.
30
+ *
31
+ * The surface, the sizes and the press signature are unchanged; what changes
32
+ * is the element they are drawn on, and what it *is* to everything reading the
33
+ * page. A link stays a link: it is announced as one, it is in the list a
34
+ * screen reader can pull up, and a crawler follows it.
35
+ *
36
+ * An `<a>` has no `disabled`, so a button that has to be unavailable stays a
37
+ * `<button>`.
38
+ */
39
+ render?: useRender.RenderProp;
40
+ children?: React.ReactNode;
41
+ }
42
+ export declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
@@ -0,0 +1 @@
1
+ import{jsx as s,Fragment as o,jsxs as a}from"react/jsx-runtime";import*as r from"react";import{Button as e}from"@base-ui/react/button";import{useRender as l}from"@base-ui/react/use-render";import{Spinner as t}from"../../internal/icons";import{controlHeightClasses as i,controlSlots as n,controlSquareClasses as d,controlTextClasses as p,disabledClasses as g,focusRingClasses as v,gapClasses as c,glassClasses as m,hasContent as x,iconClasses as b,paddingXClasses as h,radiusClasses as f,readOnlyFilterClasses as $,transitionClasses as u}from"../../internal/styles";const w={xs:`${i.xs} ${c.xs} ${f.xs} ${p.xs}`,sm:`${i.sm} ${c.sm} ${f.sm} ${p.sm}`,md:`${i.md} ${c.md} ${f.md} ${p.md}`,lg:`${i.lg} ${c.lg} ${f.lg} ${p.lg}`,xl:`${i.xl} ${c.xl} ${f.xl} ${p.xl}`},j={xs:`${d.xs} px-0`,sm:`${d.sm} px-0`,md:`${d.md} px-0`,lg:`${d.lg} px-0`,xl:`${d.xl} px-0`},y=["relative inline-flex shrink-0 select-none items-center justify-center","whitespace-nowrap align-middle font-semibold leading-none","[-webkit-tap-highlight-color:transparent] [touch-action:manipulation]",u,v,b].join(" "),k={solid:["text-(--p-on-solid) [background-image:var(--p-fill)]","[box-shadow:var(--p-elev),var(--p-lift),var(--plass-gloss-solid)]"].join(" "),glass:[m,"border text-(--p-accent) bg-(--plass-glass)","[border-color:var(--plass-glass-line)]","[box-shadow:var(--p-elev),var(--plass-gloss-glass)]"].join(" "),ghost:"text-(--p-accent) bg-transparent"},B={solid:["hover:brightness-105","hover:[box-shadow:var(--p-elev-hover),var(--p-lift-hover),var(--plass-gloss-solid)]","active:brightness-95","active:[box-shadow:var(--p-elev-press),var(--p-lift-press),var(--plass-gloss-solid)]"].join(" "),glass:["hover:bg-(--plass-glass-hover) hover:[border-color:var(--p-line)]","hover:[box-shadow:var(--p-elev-hover),var(--plass-gloss-glass)]","active:bg-(--plass-glass-press)","active:[box-shadow:var(--p-elev-press),var(--plass-gloss-glass)]"].join(" "),ghost:"hover:bg-(--p-soft) active:bg-(--p-soft-hover)"},C={solid:["cursor-default text-(--p-on-solid) [background-image:var(--p-fill)]",`[box-shadow:var(--plass-gloss-solid)] ${$}`].join(" "),glass:[m,"cursor-default border text-(--p-accent) bg-(--plass-glass)","[border-color:var(--plass-glass-line)]",`[box-shadow:var(--plass-gloss-glass)] ${$}`].join(" "),ghost:`cursor-default text-(--p-accent) bg-transparent ${$}`};export const Button=r.forwardRef(function({variant:r="solid",size:i="md",color:d="primary",density:p="default",elevation:v=1,startIcon:c,endIcon:m,loading:b=!1,readOnly:f=!1,fullWidth:$=!1,disabled:u=!1,render:I,className:N,style:z,children:D,onClick:F,...O},P){const R=!x(D),W=b||f,q=!u&&!W,A=[y,w[i],R?j[i]:h[p][i],u?g[r]:f?C[r]:k[r],q?`${B[r]} cursor-pointer`:"",q&&"solid"===r?"plass-gloss":"",b?"cursor-progress":"",$?"w-full":"",N??""].filter(Boolean).join(" ");return l({render:I??s(e,{disabled:u}),ref:P,props:{className:A,style:{...n(d,v),...z},"aria-disabled":W||void 0,"aria-busy":b||void 0,"data-loading":b||void 0,"data-readonly":f||void 0,onClick:s=>{if(W)return s.preventDefault(),void s.stopPropagation();F?.(s)},...O,children:a(o,{children:[b?s(t,{}):c,D,m]})}})});
@@ -0,0 +1,2 @@
1
+ export { Button } from './Button';
2
+ export type { ButtonProps } from './Button';
@@ -0,0 +1 @@
1
+ export{Button}from"./Button";
@@ -0,0 +1,65 @@
1
+ import * as React from 'react';
2
+ import type { PlassElevation, PlassStyleProps } from '../../types';
3
+ /** How the multiline control may be resized by the user. Ignored when single line. */
4
+ export type TextFieldResize = 'none' | 'vertical' | 'horizontal' | 'both';
5
+ /**
6
+ * Native `<input>` attributes, minus the three that collide with the shared
7
+ * vocabulary: `color` and `size` are Plass props here, and `onChange` is widened
8
+ * below so the same handler types against a `<textarea>` in multiline mode.
9
+ */
10
+ type NativeControlProps = Omit<React.ComponentPropsWithoutRef<'input'>, 'color' | 'size' | 'onChange' | 'children'>;
11
+ export interface TextFieldProps extends PlassStyleProps, NativeControlProps {
12
+ /**
13
+ * Drop shadow depth. `0` is the default — a field is a well cut into the
14
+ * sheet, not a key resting on it, and the one place in the library where a
15
+ * shadow points *inward*.
16
+ * @default 0
17
+ */
18
+ elevation?: PlassElevation;
19
+ /**
20
+ * Renders a `<textarea>` instead of an `<input>`. Everything else — sizing,
21
+ * density, variants, states — stays identical, so switching a field to
22
+ * multiline never changes how it sits in a form.
23
+ * @default false
24
+ */
25
+ multiline?: boolean;
26
+ /** Visible rows in multiline mode. One row is exactly the single-line height. */
27
+ rows?: number;
28
+ /**
29
+ * Which way the user may drag the multiline control. Horizontal resizing
30
+ * breaks a form's column, so only the vertical axis is on by default.
31
+ * @default 'vertical'
32
+ */
33
+ resize?: TextFieldResize;
34
+ /**
35
+ * Label above the control, wired to it by Base UI's Field. There is no
36
+ * floating variant on purpose: a floating label needs a `transform` on the
37
+ * thing being typed into, and a label that moves under the caret is the one
38
+ * effect this library rules out on a control.
39
+ */
40
+ label?: React.ReactNode;
41
+ /** Helper text below the control. */
42
+ description?: React.ReactNode;
43
+ /** Error message below the control. Its presence also turns the field invalid. */
44
+ error?: React.ReactNode;
45
+ /**
46
+ * Forces the invalid state without a message — for when an external form
47
+ * library owns the validity. Defaults to whether `error` has content.
48
+ */
49
+ invalid?: boolean;
50
+ /** Content placed before the control. Sized in `em`, so it tracks the text. */
51
+ startIcon?: React.ReactNode;
52
+ /** Content placed after the control. */
53
+ endIcon?: React.ReactNode;
54
+ /**
55
+ * Shows a spinner in place of `endIcon` and marks the field busy. Typing is
56
+ * deliberately still allowed — a field is usually loading *because of* what
57
+ * was typed into it.
58
+ */
59
+ loading?: boolean;
60
+ /** Stretches to the width of the container. */
61
+ fullWidth?: boolean;
62
+ onChange?: React.ChangeEventHandler<HTMLInputElement | HTMLTextAreaElement>;
63
+ }
64
+ export declare const TextField: React.ForwardRefExoticComponent<TextFieldProps & React.RefAttributes<HTMLInputElement | HTMLTextAreaElement>>;
65
+ export {};
@@ -0,0 +1 @@
1
+ import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as l from"react";import{Field as n}from"@base-ui/react/field";import{Input as r}from"@base-ui/react/input";import{Spinner as s}from"../../internal/icons";import{controlHeightClasses as i,controlTextLeadingClasses as a,disabledClasses as o,fieldReadOnlyClasses as c,fieldRestClasses as m,focusWithinRingClasses as d,gapClasses as p,hasContent as u,iconClasses as f,metaTextClasses as x,paddingXClasses as h,radiusClasses as g,stackGapClasses as $,surfaceSlots as y,transitionClasses as b}from"../../internal/styles";const j={xs:`${p.xs} ${g.xs} ${a.xs}`,sm:`${p.sm} ${g.sm} ${a.sm}`,md:`${p.md} ${g.md} ${a.md}`,lg:`${p.lg} ${g.lg} ${a.lg}`,xl:`${p.xl} ${g.xl} ${a.xl}`},v={xs:"min-h-6 py-[3px]",sm:"min-h-8 py-[6px]",md:"min-h-10 py-[9px]",lg:"min-h-12 py-[11px]",xl:"min-h-14 py-[13px]"},w={none:"resize-none",vertical:"resize-y",horizontal:"resize-x",both:"resize"},N=["group relative flex w-full cursor-text","[-webkit-tap-highlight-color:transparent]",b,d,f].join(" "),z=m,k=c;export const TextField=l.forwardRef(function({variant:a="glass",size:c="md",color:m="primary",density:d="default",elevation:p=0,multiline:f=!1,rows:g=3,resize:b="vertical",label:D,description:R,error:B,invalid:I,startIcon:O,endIcon:T,loading:C=!1,fullWidth:E=!1,readOnly:F=!1,disabled:L=!1,type:P="text",className:W,style:q,...A},G){const H=u(B),J=I??H,K=J?"danger":m,M=l.useRef(null),Q=l.useCallback(e=>{M.current=e,"function"==typeof G?G(e):G&&(G.current=e)},[G]),S=[N,j[c],f?`${v[c]} items-start`:`${i[c]} items-center`,h[d][c],L?o[a]:F?k[a]:z[a]].filter(Boolean).join(" "),U=["min-w-0 flex-1 bg-transparent [font:inherit] text-inherit","[outline:none]","placeholder:text-(--plass-muted-fg)","caret-(--p-accent) selection:bg-(--p-soft-press)","disabled:cursor-not-allowed",f?`block ${w[b]}`:"self-stretch"].join(" "),V="inline-flex h-[1lh] shrink-0 items-center text-(--plass-muted-fg) transition-[color] duration-(--plass-duration) group-focus-within:text-(--p-accent)";return t(n.Root,{disabled:L,invalid:J,className:["flex-col align-top",$[c],E?"flex w-full":"inline-flex",W??""].filter(Boolean).join(" "),style:{...y(K,p),...q},children:[D?e(n.Label,{className:[x[c],"font-semibold",L?"text-(--plass-muted-fg)":"text-(--plass-fg)"].join(" "),children:D}):null,t("span",{className:S,onPointerDown:e=>{e.target!==e.currentTarget||L||(e.preventDefault(),M.current?.focus())},children:[O?e("span",{className:V,children:O}):null,e(r,{ref:Q,className:U,disabled:L,readOnly:F,"aria-busy":C||void 0,"data-loading":C||void 0,...f?{render:e("textarea",{rows:g})}:{type:P},...A}),C?e("span",{className:V,children:e(s,{})}):T?e("span",{className:V,children:T}):null]}),R?e(n.Description,{className:[x[c],"text-(--plass-muted-fg)"].join(" "),children:R}):null,H?e(n.Error,{match:!0,className:[x[c],"text-(--p-accent)"].join(" "),children:B}):null]})});
@@ -0,0 +1,2 @@
1
+ export { TextField } from './TextField';
2
+ export type { TextFieldProps, TextFieldResize } from './TextField';
@@ -0,0 +1 @@
1
+ export{TextField}from"./TextField";
@@ -0,0 +1,3 @@
1
+ export * from './types';
2
+ export * from './components/button';
3
+ export * from './components/text-field';
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export*from"./types";export*from"./components/button";export*from"./components/text-field";
@@ -0,0 +1,18 @@
1
+ /**
2
+ * The glyphs more than one component draws.
3
+ *
4
+ * A component that needs a shape nobody else needs draws it in its own file.
5
+ * What lands here is what two components would otherwise each have a copy of —
6
+ * and the reason that matters is not the duplication, it is that two copies
7
+ * drift: a spinner in a Button and a spinner in a TextField have to be the same
8
+ * object in motion, or a form that is saving looks like two things loading.
9
+ */
10
+ import * as React from 'react';
11
+ /**
12
+ * The one thing in the library that moves on its own, and the only place that
13
+ * is allowed: an indeterminate indicator that does not move is a decoration.
14
+ *
15
+ * Sized in `em` by `iconClasses`, like every other glyph inside a control, so
16
+ * it tracks the label rather than carrying a size of its own.
17
+ */
18
+ export declare function Spinner(): React.ReactElement;
@@ -0,0 +1 @@
1
+ import{jsx as r,jsxs as e}from"react/jsx-runtime";export function Spinner(){return e("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",className:"animate-spin",children:[r("circle",{cx:"8",cy:"8",r:"6.5",stroke:"currentColor",strokeOpacity:"0.25",strokeWidth:"2"}),r("path",{d:"M14.5 8A6.5 6.5 0 0 0 8 1.5",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round"})]})}
@@ -0,0 +1,181 @@
1
+ /**
2
+ * The pieces every Plass component is built out of.
3
+ *
4
+ * None of this is exported from `src/index.ts` — it is the library talking to
5
+ * itself. It lives here for one reason: a `size` of `md` has to be 40px on a
6
+ * Button, a TextField, a Select and a Chip, and a table copied into eleven
7
+ * files is a table that will disagree with itself by the twelfth.
8
+ *
9
+ * The two things that cannot move out of a component are its variant classes
10
+ * and its layout — those genuinely differ. Heights, radii, type scale, padding
11
+ * tracks, the glass surface, the transition and the colour slots do not.
12
+ *
13
+ * Tailwind only sees class names written out literally, so everything here is a
14
+ * complete class string rather than something assembled at runtime. `@source
15
+ * '.'` in `styles.css` covers this folder in the repository and in `dist/`.
16
+ */
17
+ import type * as React from 'react';
18
+ import type { PlassColor, PlassDensity, PlassElevation, PlassSize, PlassVariant } from '../types';
19
+ /**
20
+ * Corner radius — a moulded fillet rather than a chamfer or a pill.
21
+ *
22
+ * It grows far more slowly than the height does: 33% of an `xs` control, 29% at
23
+ * `md`, 29% at `xl`. That near-constant radius is what makes two controls of
24
+ * different sizes read as two pieces cast in the same mould, which a radius
25
+ * pinned to a percentage of the height does not.
26
+ */
27
+ export declare const radiusClasses: Record<PlassSize, string>;
28
+ /**
29
+ * The height of a control, and the one number the whole library lines up on:
30
+ * a Button, a TextField, a Select and a Chip of the same `size` sit on the same
31
+ * baseline in the same row.
32
+ *
33
+ * The ladder is 8px per step, and it starts higher than a dense desktop toolkit
34
+ * would: `md` is 40px, not 32px. A moulded surface needs room to be one — a
35
+ * gradient, a specular highlight and a hairline inside 32px is three effects
36
+ * fighting over eleven pixels of fill. `xs` exists for a table row and is the
37
+ * one step where the gloss is deliberately faint.
38
+ *
39
+ * `lg` at 48px and `xl` at 56px both clear the 44px mobile touch target.
40
+ *
41
+ * Density never touches these.
42
+ */
43
+ export declare const controlHeightClasses: Record<PlassSize, string>;
44
+ /** The same numbers as a width, for a control with nothing to pad against. */
45
+ export declare const controlSquareClasses: Record<PlassSize, string>;
46
+ /** A control's label. One line, so the leading comes from `leading-none`. */
47
+ export declare const controlTextClasses: Record<PlassSize, string>;
48
+ /**
49
+ * The same type scale with an explicit leading, for the controls that hold text
50
+ * which may wrap — a textarea, a select option, a table cell. The line heights
51
+ * have to agree with `controlHeightClasses` or a one-row control would stop
52
+ * lining up with a single-line one.
53
+ */
54
+ export declare const controlTextLeadingClasses: Record<PlassSize, string>;
55
+ /** Labels, descriptions and error messages: one step below the control's text. */
56
+ export declare const metaTextClasses: Record<PlassSize, string>;
57
+ /**
58
+ * Horizontal padding, and the only thing `density` is allowed to touch. The two
59
+ * tracks are roughly 2:1 so the difference is legible at a glance rather than a
60
+ * two-pixel nudge.
61
+ */
62
+ export declare const paddingXClasses: Record<PlassDensity, Record<PlassSize, string>>;
63
+ /** Between a control's own parts — an icon and its label. */
64
+ export declare const gapClasses: Record<PlassSize, string>;
65
+ /** Between a label, the control under it and the text under that. */
66
+ export declare const stackGapClasses: Record<PlassSize, string>;
67
+ /**
68
+ * Glass: a translucent fill over a heavily blurred backdrop.
69
+ *
70
+ * The blur is the whole material. Plass is not trying to let you read what is
71
+ * behind a sheet — it is trying to make the sheet look thick, which is why the
72
+ * radius is 22px and not the 8–10px a frosted-acrylic language would use.
73
+ * Below about 14px the surface stops being glass and becomes a white box with
74
+ * an alpha on it.
75
+ *
76
+ * `-webkit-backdrop-filter` is written alongside the standard property because
77
+ * Safari still needs it, and Tailwind will not add it for an arbitrary value.
78
+ */
79
+ export declare const glassClasses = "[backdrop-filter:var(--plass-blur)] [-webkit-backdrop-filter:var(--plass-blur)]";
80
+ /**
81
+ * The house transition.
82
+ *
83
+ * One duration and one curve, applied the same way in both directions — a key
84
+ * going down and a key coming back up are the same spring. `background-image`
85
+ * is in the list because a gradient fill is the thing being changed on a solid
86
+ * surface, and `filter` because that is what hover and press actually move.
87
+ *
88
+ * There is no `transform` in the list and none should be added to a *control*:
89
+ * scaling a key resamples its label, and text that shimmers under the cursor
90
+ * undoes the restraint everything else is spending effort on. A surface that
91
+ * holds content rather than being pressed — a Card — may lift, and does.
92
+ */
93
+ export declare const transitionClasses: string;
94
+ /**
95
+ * The focus ring, written as the `outline` shorthand rather than Tailwind's
96
+ * `outline-2` + colour pair: the utilities route the style through
97
+ * `--tw-outline-style`, which any `outline-none` on the element (ours or a
98
+ * consumer's) would zero out.
99
+ *
100
+ * An `outline` and not a `ring`, which is the other way this could be drawn:
101
+ * Tailwind's `ring-*` is a `box-shadow`, and every Plass surface already spends
102
+ * its `box-shadow` on the elevation, the tinted glow and the gloss line. A ring
103
+ * would have to be spliced into that chain in each of the three variants, and
104
+ * the first one that forgot would silently lose its focus ring.
105
+ */
106
+ export declare const focusRingClasses = "focus-visible:[outline:2px_solid_var(--p-ring)] focus-visible:outline-offset-2";
107
+ /** The same ring, drawn by whichever descendant actually takes focus. */
108
+ export declare const focusWithinRingClasses = "has-[:focus-visible]:[outline:2px_solid_var(--p-ring)] has-[:focus-visible]:outline-offset-2";
109
+ /** Icons track their label rather than carrying a size of their own. */
110
+ export declare const iconClasses = "[&_svg]:pointer-events-none [&_svg]:size-[1.2em] [&_svg]:shrink-0";
111
+ /**
112
+ * Text for a screen reader and nobody else.
113
+ *
114
+ * Not `hidden`, not `display:none` and not `opacity:0` — the first two take the
115
+ * text off the accessibility tree along with the screen, and the third leaves a
116
+ * clickable ghost the size of the words. A 1px clipped box is the one form that
117
+ * is invisible to a sighted reader and present to every other kind.
118
+ */
119
+ export declare const srOnlyClasses = "absolute size-px overflow-hidden whitespace-nowrap [clip-path:inset(50%)]";
120
+ /**
121
+ * Every slot a control reads.
122
+ *
123
+ * The three elevation slots are resolved here rather than in CSS because
124
+ * hovering adds a level and pressing removes one, and doing that arithmetic in
125
+ * a stylesheet would mean four ladders instead of one.
126
+ */
127
+ export declare function controlSlots(color: PlassColor, elevation: PlassElevation): React.CSSProperties;
128
+ /**
129
+ * The same slots for a surface that **holds** content rather than being
130
+ * pressed: a Box, a Card, a TextField's shell, a popup.
131
+ *
132
+ * There is no `--p-fill` and no `--p-lift` here, and that is the point. A
133
+ * container's sheet is the undyed glass, because what it holds arrives with its
134
+ * own colours and tinting the sheet under them puts every one on a background
135
+ * it was not chosen against. The family shows up in the hairline, the focus
136
+ * ring and the caret, and the glass stays clear.
137
+ */
138
+ export declare function surfaceSlots(color: PlassColor, elevation: PlassElevation): React.CSSProperties;
139
+ /**
140
+ * Disabled is **the light going out.** The key keeps its shape, its colour and
141
+ * its place in the layout, and stops catching any light: no gloss, no tinted
142
+ * lift, no shadow, most of the saturation gone and half the opacity with it.
143
+ *
144
+ * Opacity is doing real work here rather than standing in for a decision, which
145
+ * is the usual complaint against it. On a page made of translucent sheets, a
146
+ * surface that has gone part-transparent is a surface the page is showing
147
+ * *through* — it has stopped being an object. That reads as unavailable in a
148
+ * way a grey swatch does not, and it is the one state in the library that uses
149
+ * the axis.
150
+ */
151
+ export declare const disabledClasses: Record<PlassVariant, string>;
152
+ /**
153
+ * Read-only keeps the colour and the edge, goes flat and drains most of the
154
+ * saturation — a label that happens to be control-shaped. It is not dimmed:
155
+ * the value is still there to be read and copied, which is the whole difference
156
+ * from `disabled`.
157
+ *
158
+ * The cursor is left to the component. A read-only button stops being something
159
+ * you click; a read-only field is still something you select text out of.
160
+ */
161
+ export declare const readOnlyFilterClasses = "saturate-[0.55]";
162
+ /**
163
+ * The shell a field-shaped control is drawn on — a TextField's box and a
164
+ * Select's trigger, which have to be indistinguishable or a form looks like two
165
+ * different forms stacked on each other.
166
+ *
167
+ * The three variants say what they say everywhere else, with one deliberate
168
+ * difference: `solid` is not a moulded key. What a field holds is user data,
169
+ * and a caret, a text selection and a placeholder all have to stay legible on
170
+ * top of it, which they are not on a gradient fill. So a `solid` field is the
171
+ * **well** — the glass at its most opaque with an inset shadow falling into it,
172
+ * the one shadow in the library that points downward — and the colour family
173
+ * shows up in the hairline, the ring and the caret instead.
174
+ */
175
+ export declare const fieldRestClasses: Record<PlassVariant, string>;
176
+ /** The same three, held still. */
177
+ export declare const fieldReadOnlyClasses: Record<PlassVariant, string>;
178
+ /** `false`, `null`, `undefined` and `''` all mean "this slot is not filled". */
179
+ export declare function hasContent(node: React.ReactNode): boolean;
180
+ /** Joins class name fragments, dropping the empty ones. */
181
+ export declare function cx(...parts: Array<string | false | null | undefined>): string;
@@ -0,0 +1 @@
1
+ export const radiusClasses={xs:"rounded-(--plass-radius-xs)",sm:"rounded-(--plass-radius-sm)",md:"rounded-(--plass-radius-md)",lg:"rounded-(--plass-radius-lg)",xl:"rounded-(--plass-radius-xl)"};export const controlHeightClasses={xs:"h-6",sm:"h-8",md:"h-10",lg:"h-12",xl:"h-14"};export const controlSquareClasses={xs:"w-6",sm:"w-8",md:"w-10",lg:"w-12",xl:"w-14"};export const controlTextClasses={xs:"text-[0.6875rem]",sm:"text-[0.8125rem]",md:"text-[0.875rem]",lg:"text-[1rem]",xl:"text-[1.125rem]"};export const controlTextLeadingClasses={xs:"text-[0.6875rem]/[1rem]",sm:"text-[0.8125rem]/[1.125rem]",md:"text-[0.875rem]/[1.25rem]",lg:"text-[1rem]/[1.5rem]",xl:"text-[1.125rem]/[1.75rem]"};export const metaTextClasses={xs:"text-[0.625rem]",sm:"text-[0.6875rem]",md:"text-[0.75rem]",lg:"text-[0.8125rem]",xl:"text-[0.875rem]"};export const paddingXClasses={default:{xs:"px-2.5",sm:"px-3",md:"px-4",lg:"px-6",xl:"px-7"},compact:{xs:"px-1.5",sm:"px-2",md:"px-2.5",lg:"px-3.5",xl:"px-4"}};export const gapClasses={xs:"gap-1",sm:"gap-1.5",md:"gap-2",lg:"gap-2.5",xl:"gap-3"};export const stackGapClasses={xs:"gap-1",sm:"gap-1.5",md:"gap-1.5",lg:"gap-2",xl:"gap-2"};export const glassClasses="[backdrop-filter:var(--plass-blur)] [-webkit-backdrop-filter:var(--plass-blur)]";export const transitionClasses=["[transition-property:background-color,background-image,border-color,box-shadow,color,filter]","[transition-duration:var(--plass-duration)]","[transition-timing-function:var(--plass-ease)]"].join(" ");export const focusRingClasses="focus-visible:[outline:2px_solid_var(--p-ring)] focus-visible:outline-offset-2";export const focusWithinRingClasses="has-[:focus-visible]:[outline:2px_solid_var(--p-ring)] has-[:focus-visible]:outline-offset-2";export const iconClasses="[&_svg]:pointer-events-none [&_svg]:size-[1.2em] [&_svg]:shrink-0";export const srOnlyClasses="absolute size-px overflow-hidden whitespace-nowrap [clip-path:inset(50%)]";export function controlSlots(s,a){return{"--p-fill":`var(--plass-${s}-fill)`,"--p-on-solid":`var(--plass-${s}-on-solid)`,"--p-accent":`var(--plass-${s}-accent)`,"--p-glow":`var(--plass-${s}-glow)`,"--p-soft":`var(--plass-${s}-soft)`,"--p-soft-hover":`var(--plass-${s}-soft-hover)`,"--p-soft-press":`var(--plass-${s}-soft-press)`,"--p-line":`var(--plass-${s}-line)`,"--p-line-hover":`var(--plass-${s}-line-hover)`,"--p-ring":`var(--plass-${s}-ring)`,"--p-elev":`var(--plass-shadow-${a})`,"--p-elev-hover":`var(--plass-shadow-${Math.min(a+1,4)})`,"--p-elev-press":`var(--plass-shadow-${Math.max(a-1,0)})`,"--p-lift":"0 6px 16px -4px var(--p-glow)","--p-lift-hover":"0 10px 24px -6px var(--p-glow)","--p-lift-press":"0 2px 6px -2px var(--p-glow)"}}export function surfaceSlots(s,a){return{"--p-accent":`var(--plass-${s}-accent)`,"--p-soft":`var(--plass-${s}-soft)`,"--p-soft-hover":`var(--plass-${s}-soft-hover)`,"--p-soft-press":`var(--plass-${s}-soft-press)`,"--p-line":`var(--plass-${s}-line)`,"--p-line-hover":`var(--plass-${s}-line-hover)`,"--p-ring":`var(--plass-${s}-ring)`,"--p-elev":`var(--plass-shadow-${a})`,"--p-elev-hover":`var(--plass-shadow-${Math.min(a+1,4)})`,"--p-elev-press":`var(--plass-shadow-${Math.max(a-1,0)})`}}export const disabledClasses={solid:["cursor-not-allowed text-(--p-on-solid) [background-image:var(--p-fill)]","opacity-50 saturate-[0.35] shadow-none"].join(" "),glass:[glassClasses,"cursor-not-allowed border text-(--plass-fg) bg-(--plass-glass)","[border-color:var(--plass-border)]","opacity-50 saturate-[0.35] shadow-none"].join(" "),ghost:"cursor-not-allowed bg-transparent text-(--p-accent) opacity-50 saturate-[0.35]"};export const readOnlyFilterClasses="saturate-[0.55]";export const fieldRestClasses={solid:[glassClasses,"text-(--plass-fg) bg-(--plass-glass-press)","[box-shadow:var(--p-elev),var(--plass-well)]","hover:bg-(--plass-glass-hover)","focus-within:bg-(--plass-glass-press)"].join(" "),glass:[glassClasses,"border text-(--plass-fg) bg-(--plass-glass-hover)","[border-color:var(--plass-glass-line)]","[box-shadow:var(--p-elev),var(--plass-gloss-glass)]","hover:bg-(--plass-glass-press)","focus-within:bg-(--plass-glass-press) focus-within:[border-color:var(--p-line-hover)]"].join(" "),ghost:["text-(--plass-fg) bg-transparent","hover:bg-(--p-soft)","focus-within:bg-(--p-soft-hover)"].join(" ")};export const fieldReadOnlyClasses={solid:[glassClasses,"text-(--plass-fg) bg-(--plass-glass-press)","[box-shadow:var(--plass-well)] saturate-[0.55]"].join(" "),glass:[glassClasses,"border text-(--plass-fg) bg-(--plass-glass-hover)","[border-color:var(--plass-glass-line)]","[box-shadow:var(--plass-gloss-glass)] saturate-[0.55]"].join(" "),ghost:"text-(--plass-fg) bg-transparent saturate-[0.55]"};export function hasContent(s){return null!=s&&!1!==s&&""!==s}export function cx(...s){return s.filter(Boolean).join(" ")}
@@ -0,0 +1,2 @@
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-border-style:solid;--tw-leading:initial;--tw-font-weight: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}}}*,:before,:after,::backdrop{box-sizing:border-box;border:0 solid}::file-selector-button{box-sizing:border-box;border:0 solid}:where(html,:host){-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--font-sans,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");-webkit-tap-highlight-color:transparent}:where(blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre){margin:0}:where(menu,ol,ul){margin:0;padding:0;list-style:none}:where(h1,h2,h3,h4,h5,h6){font-size:inherit;font-weight:inherit}:where(button,input,optgroup,select,textarea){font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(button,input:where([type=button],[type=reset],[type=submit])){appearance:button}::placeholder{opacity:1}:where(textarea){resize:vertical}:where(audio,canvas,embed,iframe,img,object,svg,video){vertical-align:middle;display:block}:where(img,video){max-width:100%;height:auto}:where(code,kbd,pre,samp){font-family:var(--font-mono,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-size:1em}@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-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--spacing:.25rem;--font-weight-semibold:600;--animate-spin:spin 1s linear infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1)}}.invisible{visibility:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.block{display:block}.flex{display:flex}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.table{display:table}.size-px{width:1px;height:1px}.h-6{height:calc(var(--spacing) * 6)}.h-8{height:calc(var(--spacing) * 8)}.h-10{height:calc(var(--spacing) * 10)}.h-12{height:calc(var(--spacing) * 12)}.h-14{height:calc(var(--spacing) * 14)}.h-\[1lh\]{height:1lh}.min-h-6{min-height:calc(var(--spacing) * 6)}.min-h-8{min-height:calc(var(--spacing) * 8)}.min-h-10{min-height:calc(var(--spacing) * 10)}.min-h-12{min-height:calc(var(--spacing) * 12)}.min-h-14{min-height:calc(var(--spacing) * 14)}.w-6{width:calc(var(--spacing) * 6)}.w-8{width:calc(var(--spacing) * 8)}.w-10{width:calc(var(--spacing) * 10)}.w-12{width:calc(var(--spacing) * 12)}.w-14{width:calc(var(--spacing) * 14)}.w-full{width:100%}.min-w-0{min-width:0}.flex-1{flex:1}.shrink-0{flex-shrink:0}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-spin{animation:var(--animate-spin)}.cursor-default{cursor:default}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.cursor-progress{cursor:progress}.cursor-text{cursor:text}.\[touch-action\:manipulation\]{touch-action:manipulation}.resize{resize:both}.resize-none{resize:none}.resize-x{resize:horizontal}.resize-y{resize:vertical}.flex-col{flex-direction:column}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-center{justify-content:center}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.self-stretch{align-self:stretch}.overflow-hidden{overflow:hidden}.rounded-\(--plass-radius-lg\){border-radius:var(--plass-radius-lg)}.rounded-\(--plass-radius-md\){border-radius:var(--plass-radius-md)}.rounded-\(--plass-radius-sm\){border-radius:var(--plass-radius-sm)}.rounded-\(--plass-radius-xl\){border-radius:var(--plass-radius-xl)}.rounded-\(--plass-radius-xs\){border-radius:var(--plass-radius-xs)}.border{border-style:var(--tw-border-style);border-width:1px}.\[border-color\:var\(--plass-border\)\]{border-color:var(--plass-border)}.\[border-color\:var\(--plass-glass-line\)\]{border-color:var(--plass-glass-line)}.bg-\(--plass-glass\){background-color:var(--plass-glass)}.bg-\(--plass-glass-hover\){background-color:var(--plass-glass-hover)}.bg-\(--plass-glass-press\){background-color:var(--plass-glass-press)}.bg-transparent{background-color:#0000}.\[background-image\:var\(--p-fill\)\]{background-image:var(--p-fill)}.px-0{padding-inline:0}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-3\.5{padding-inline:calc(var(--spacing) * 3.5)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-6{padding-inline:calc(var(--spacing) * 6)}.px-7{padding-inline:calc(var(--spacing) * 7)}.py-\[3px\]{padding-block:3px}.py-\[6px\]{padding-block:6px}.py-\[9px\]{padding-block:9px}.py-\[11px\]{padding-block:11px}.py-\[13px\]{padding-block:13px}.align-middle{vertical-align:middle}.align-top{vertical-align:top}.text-\[0\.875rem\]\/\[1\.25rem\]{font-size:.875rem;line-height:1.25rem}.text-\[0\.6875rem\]\/\[1rem\]{font-size:.6875rem;line-height:1rem}.text-\[0\.8125rem\]\/\[1\.125rem\]{font-size:.8125rem;line-height:1.125rem}.text-\[1\.125rem\]\/\[1\.75rem\]{font-size:1.125rem;line-height:1.75rem}.text-\[1rem\]\/\[1\.5rem\]{font-size:1rem;line-height:1.5rem}.text-\[0\.75rem\]{font-size:.75rem}.text-\[0\.625rem\]{font-size:.625rem}.text-\[0\.875rem\]{font-size:.875rem}.text-\[0\.6875rem\]{font-size:.6875rem}.text-\[0\.8125rem\]{font-size:.8125rem}.text-\[1\.125rem\]{font-size:1.125rem}.text-\[1rem\]{font-size:1rem}.leading-none{--tw-leading:1;line-height:1}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.whitespace-nowrap{white-space:nowrap}.text-\(--p-accent\){color:var(--p-accent)}.text-\(--p-on-solid\){color:var(--p-on-solid)}.text-\(--plass-fg\){color:var(--plass-fg)}.text-\(--plass-muted-fg\){color:var(--plass-muted-fg)}.text-inherit{color:inherit}.caret-\(--p-accent\){caret-color:var(--p-accent)}.opacity-50{opacity:.5}.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)}.shadow-none{--tw-shadow:0 0 #0000;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)}.\[box-shadow\:var\(--p-elev\)\,var\(--p-lift\)\,var\(--plass-gloss-solid\)\]{box-shadow:var(--p-elev),var(--p-lift),var(--plass-gloss-solid)}.\[box-shadow\:var\(--p-elev\)\,var\(--plass-gloss-glass\)\]{box-shadow:var(--p-elev),var(--plass-gloss-glass)}.\[box-shadow\:var\(--p-elev\)\,var\(--plass-well\)\]{box-shadow:var(--p-elev),var(--plass-well)}.\[box-shadow\:var\(--plass-gloss-glass\)\]{box-shadow:var(--plass-gloss-glass)}.\[box-shadow\:var\(--plass-gloss-solid\)\]{box-shadow:var(--plass-gloss-solid)}.\[box-shadow\:var\(--plass-well\)\]{box-shadow:var(--plass-well)}.\[outline\:none\]{outline:none}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.outline-2{outline-style:var(--tw-outline-style);outline-width:2px}.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,)}.saturate-\[0\.35\]{--tw-saturate:saturate(.35);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,)}.saturate-\[0\.55\]{--tw-saturate:saturate(.55);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,)}.\[backdrop-filter\:var\(--plass-blur\)\]{-webkit-backdrop-filter:var(--plass-blur);backdrop-filter:var(--plass-blur)}.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-\[color\]{transition-property:color;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.\[transition-property\:background-color\,background-image\,border-color\,box-shadow\,color\,filter\]{transition-property:background-color,background-image,border-color,box-shadow,color,filter}.duration-\(--plass-duration\){--tw-duration:var(--plass-duration);transition-duration:var(--plass-duration)}.\[transition-duration\:var\(--plass-duration\)\]{transition-duration:var(--plass-duration)}.\[transition-timing-function\:var\(--plass-ease\)\]{transition-timing-function:var(--plass-ease)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.\[--p-fill\:var\(--plass-primary-fill\)\]{--p-fill:var(--plass-primary-fill)}.\[-webkit-backdrop-filter\:var\(--plass-blur\)\]{-webkit-backdrop-filter:var(--plass-blur)}.\[-webkit-tap-highlight-color\:transparent\]{-webkit-tap-highlight-color:transparent}.\[clip-path\:inset\(50\%\)\]{clip-path:inset(50%)}.\[font\:inherit\]{font:inherit}.group-focus-within\:text-\(--p-accent\):is(:where(.group):focus-within *){color:var(--p-accent)}.selection\:bg-\(--p-soft-press\) ::selection{background-color:var(--p-soft-press)}.selection\:bg-\(--p-soft-press\)::selection{background-color:var(--p-soft-press)}.placeholder\:text-\(--plass-muted-fg\)::placeholder{color:var(--plass-muted-fg)}.focus-within\:\[border-color\:var\(--p-line-hover\)\]:focus-within{border-color:var(--p-line-hover)}.focus-within\:bg-\(--p-soft-hover\):focus-within{background-color:var(--p-soft-hover)}.focus-within\:bg-\(--plass-glass-press\):focus-within{background-color:var(--plass-glass-press)}@media (hover:hover){.hover\:\[border-color\:var\(--p-line\)\]:hover{border-color:var(--p-line)}.hover\:bg-\(--p-soft\):hover{background-color:var(--p-soft)}.hover\:bg-\(--plass-glass-hover\):hover{background-color:var(--plass-glass-hover)}.hover\:bg-\(--plass-glass-press\):hover{background-color:var(--plass-glass-press)}.hover\:\[box-shadow\:var\(--p-elev-hover\)\,var\(--p-lift-hover\)\,var\(--plass-gloss-solid\)\]:hover{box-shadow:var(--p-elev-hover),var(--p-lift-hover),var(--plass-gloss-solid)}.hover\:\[box-shadow\:var\(--p-elev-hover\)\,var\(--plass-gloss-glass\)\]:hover{box-shadow:var(--p-elev-hover),var(--plass-gloss-glass)}.hover\:brightness-105:hover{--tw-brightness:brightness(105%);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,)}}.focus-visible\:\[outline\:2px_solid_var\(--p-ring\)\]:focus-visible{outline:2px solid var(--p-ring)}.focus-visible\:outline-offset-2:focus-visible{outline-offset:2px}.active\:bg-\(--p-soft-hover\):active{background-color:var(--p-soft-hover)}.active\:bg-\(--plass-glass-press\):active{background-color:var(--plass-glass-press)}.active\:\[box-shadow\:var\(--p-elev-press\)\,var\(--p-lift-press\)\,var\(--plass-gloss-solid\)\]:active{box-shadow:var(--p-elev-press),var(--p-lift-press),var(--plass-gloss-solid)}.active\:\[box-shadow\:var\(--p-elev-press\)\,var\(--plass-gloss-glass\)\]:active{box-shadow:var(--p-elev-press),var(--plass-gloss-glass)}.active\:brightness-95:active{--tw-brightness:brightness(95%);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,)}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.has-\[\:focus-visible\]\:\[outline\:2px_solid_var\(--p-ring\)\]:has(:focus-visible){outline:2px solid var(--p-ring)}.has-\[\:focus-visible\]\:outline-offset-2:has(:focus-visible){outline-offset:2px}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:size-\[1\.2em\] svg{width:1.2em;height:1.2em}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}:root{--plass-primary-solid:#3558ef;--plass-primary-on-solid:#fff;--plass-secondary-solid:#4f5a70;--plass-secondary-on-solid:#fff;--plass-success-solid:#157845;--plass-success-on-solid:#fff;--plass-warning-solid:#e2921c;--plass-warning-on-solid:#3b2405;--plass-danger-solid:#c4383e;--plass-danger-on-solid:#fff;--plass-info-solid:#186cb3;--plass-info-on-solid:#fff}:root,.light,[data-theme=light]{--plass-surface:#fff;--plass-fg:#1b1e27;--plass-muted-fg:#5b6376;--plass-border:#d5deef;--plass-bg-from:#eef2fb;--plass-bg-to:#dfe8f8;--plass-glass:#ffffff9e;--plass-glass-hover:#ffffffc2;--plass-glass-press:#ffffffe0;--plass-glass-line:#fff9;--plass-blur:blur(22px) saturate(160%);--plass-gloss-glass:inset 0 1px 0 #ffffff8c;--plass-gloss-solid:inset 0 1px 0 #ffffff57;--plass-well:inset 0 1px 2px #14285a1a;--plass-specular:linear-gradient(180deg, #ffffff4d 0%, #ffffff0f 46%, #fff0 62%);--plass-shadow-ambient:#14285a29;--plass-glow-strength:35%;--plass-scrim:#10182866;--plass-radius-xs:.5rem;--plass-radius-sm:.625rem;--plass-radius-md:.75rem;--plass-radius-lg:.875rem;--plass-radius-xl:1rem;--plass-ease:cubic-bezier(.16, .9, .3, 1);--plass-duration:.15s;--plass-duration-slow:.26s;--plass-primary-accent:#2c49d6;--plass-secondary-accent:#46506a;--plass-success-accent:#146b41;--plass-warning-accent:#96600c;--plass-danger-accent:#bb3339;--plass-info-accent:#1668ae}@media (prefers-color-scheme:dark){:root:not(.light):not([data-theme=light]){--plass-surface:#141b30;--plass-fg:#e7eaf3;--plass-muted-fg:#99a2ba;--plass-border:#ffffff1f;--plass-bg-from:#111731;--plass-bg-to:#0a0e1c;--plass-glass:#ffffff12;--plass-glass-hover:#ffffff1c;--plass-glass-press:#ffffff26;--plass-glass-line:#ffffff1f;--plass-blur:blur(22px) saturate(150%);--plass-gloss-glass:inset 0 1px 0 #ffffff1a;--plass-gloss-solid:inset 0 1px 0 #ffffff38;--plass-well:inset 0 1px 2px #00000073;--plass-specular:linear-gradient(180deg, #ffffff2e 0%, #ffffff0a 46%, #fff0 62%);--plass-shadow-ambient:#00000080;--plass-glow-strength:55%;--plass-scrim:#0009;--plass-primary-accent:#93a8ff;--plass-secondary-accent:#aab3c6;--plass-success-accent:#4fd08d;--plass-warning-accent:#f2b74e;--plass-danger-accent:#ff8a8f;--plass-info-accent:#5fb4ee}}.dark,[data-theme=dark]{--plass-surface:#141b30;--plass-fg:#e7eaf3;--plass-muted-fg:#99a2ba;--plass-border:#ffffff1f;--plass-bg-from:#111731;--plass-bg-to:#0a0e1c;--plass-glass:#ffffff12;--plass-glass-hover:#ffffff1c;--plass-glass-press:#ffffff26;--plass-glass-line:#ffffff1f;--plass-blur:blur(22px) saturate(150%);--plass-gloss-glass:inset 0 1px 0 #ffffff1a;--plass-gloss-solid:inset 0 1px 0 #ffffff38;--plass-well:inset 0 1px 2px #00000073;--plass-specular:linear-gradient(180deg, #ffffff2e 0%, #ffffff0a 46%, #fff0 62%);--plass-shadow-ambient:#00000080;--plass-glow-strength:55%;--plass-scrim:#0009;--plass-primary-accent:#93a8ff;--plass-secondary-accent:#aab3c6;--plass-success-accent:#4fd08d;--plass-warning-accent:#f2b74e;--plass-danger-accent:#ff8a8f;--plass-info-accent:#5fb4ee}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-shadow-0:0 0 #0000;--plass-shadow-1:0 2px 8px -2px var(--plass-shadow-ambient);--plass-shadow-2:0 6px 20px -4px var(--plass-shadow-ambient);--plass-shadow-3:0 12px 32px -8px var(--plass-shadow-ambient);--plass-shadow-4:0 20px 48px -12px var(--plass-shadow-ambient);--plass-primary-fill:linear-gradient(135deg, var(--plass-primary-solid) 0%, var(--plass-primary-solid) 46%, var(--plass-primary-solid) 100%)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-primary-fill:linear-gradient(135deg, color-mix(in srgb, var(--plass-primary-solid) 95%, white) 0%, var(--plass-primary-solid) 46%, color-mix(in srgb, var(--plass-primary-solid) 90%, black) 100%)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-primary-glow:var(--plass-primary-solid)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-primary-glow:color-mix(in srgb, var(--plass-primary-solid) var(--plass-glow-strength), transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-primary-soft:var(--plass-primary-accent)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-primary-soft:color-mix(in srgb, var(--plass-primary-accent) 10%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-primary-soft-hover:var(--plass-primary-accent)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-primary-soft-hover:color-mix(in srgb, var(--plass-primary-accent) 18%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-primary-soft-press:var(--plass-primary-accent)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-primary-soft-press:color-mix(in srgb, var(--plass-primary-accent) 26%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-primary-line:var(--plass-primary-accent)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-primary-line:color-mix(in srgb, var(--plass-primary-accent) 30%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-primary-line-hover:var(--plass-primary-accent)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-primary-line-hover:color-mix(in srgb, var(--plass-primary-accent) 48%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-primary-ring:var(--plass-primary-solid)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-primary-ring:color-mix(in srgb, var(--plass-primary-solid) 55%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-secondary-fill:linear-gradient(135deg, var(--plass-secondary-solid) 0%, var(--plass-secondary-solid) 46%, var(--plass-secondary-solid) 100%)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-secondary-fill:linear-gradient(135deg, color-mix(in srgb, var(--plass-secondary-solid) 95%, white) 0%, var(--plass-secondary-solid) 46%, color-mix(in srgb, var(--plass-secondary-solid) 90%, black) 100%)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-secondary-glow:var(--plass-secondary-solid)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-secondary-glow:color-mix(in srgb, var(--plass-secondary-solid) var(--plass-glow-strength), transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-secondary-soft:var(--plass-secondary-accent)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-secondary-soft:color-mix(in srgb, var(--plass-secondary-accent) 10%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-secondary-soft-hover:var(--plass-secondary-accent)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-secondary-soft-hover:color-mix(in srgb, var(--plass-secondary-accent) 18%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-secondary-soft-press:var(--plass-secondary-accent)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-secondary-soft-press:color-mix(in srgb, var(--plass-secondary-accent) 26%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-secondary-line:var(--plass-secondary-accent)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-secondary-line:color-mix(in srgb, var(--plass-secondary-accent) 30%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-secondary-line-hover:var(--plass-secondary-accent)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-secondary-line-hover:color-mix(in srgb, var(--plass-secondary-accent) 48%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-secondary-ring:var(--plass-secondary-solid)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-secondary-ring:color-mix(in srgb, var(--plass-secondary-solid) 55%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-success-fill:linear-gradient(135deg, var(--plass-success-solid) 0%, var(--plass-success-solid) 46%, var(--plass-success-solid) 100%)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-success-fill:linear-gradient(135deg, color-mix(in srgb, var(--plass-success-solid) 95%, white) 0%, var(--plass-success-solid) 46%, color-mix(in srgb, var(--plass-success-solid) 90%, black) 100%)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-success-glow:var(--plass-success-solid)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-success-glow:color-mix(in srgb, var(--plass-success-solid) var(--plass-glow-strength), transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-success-soft:var(--plass-success-accent)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-success-soft:color-mix(in srgb, var(--plass-success-accent) 10%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-success-soft-hover:var(--plass-success-accent)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-success-soft-hover:color-mix(in srgb, var(--plass-success-accent) 18%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-success-soft-press:var(--plass-success-accent)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-success-soft-press:color-mix(in srgb, var(--plass-success-accent) 26%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-success-line:var(--plass-success-accent)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-success-line:color-mix(in srgb, var(--plass-success-accent) 30%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-success-line-hover:var(--plass-success-accent)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-success-line-hover:color-mix(in srgb, var(--plass-success-accent) 48%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-success-ring:var(--plass-success-solid)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-success-ring:color-mix(in srgb, var(--plass-success-solid) 55%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-warning-fill:linear-gradient(135deg, var(--plass-warning-solid) 0%, var(--plass-warning-solid) 46%, var(--plass-warning-solid) 100%)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-warning-fill:linear-gradient(135deg, color-mix(in srgb, var(--plass-warning-solid) 95%, white) 0%, var(--plass-warning-solid) 46%, color-mix(in srgb, var(--plass-warning-solid) 90%, black) 100%)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-warning-glow:var(--plass-warning-solid)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-warning-glow:color-mix(in srgb, var(--plass-warning-solid) var(--plass-glow-strength), transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-warning-soft:var(--plass-warning-accent)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-warning-soft:color-mix(in srgb, var(--plass-warning-accent) 12%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-warning-soft-hover:var(--plass-warning-accent)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-warning-soft-hover:color-mix(in srgb, var(--plass-warning-accent) 20%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-warning-soft-press:var(--plass-warning-accent)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-warning-soft-press:color-mix(in srgb, var(--plass-warning-accent) 28%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-warning-line:var(--plass-warning-accent)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-warning-line:color-mix(in srgb, var(--plass-warning-accent) 34%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-warning-line-hover:var(--plass-warning-accent)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-warning-line-hover:color-mix(in srgb, var(--plass-warning-accent) 52%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-warning-ring:var(--plass-warning-solid)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-warning-ring:color-mix(in srgb, var(--plass-warning-solid) 55%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-danger-fill:linear-gradient(135deg, var(--plass-danger-solid) 0%, var(--plass-danger-solid) 46%, var(--plass-danger-solid) 100%)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-danger-fill:linear-gradient(135deg, color-mix(in srgb, var(--plass-danger-solid) 95%, white) 0%, var(--plass-danger-solid) 46%, color-mix(in srgb, var(--plass-danger-solid) 90%, black) 100%)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-danger-glow:var(--plass-danger-solid)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-danger-glow:color-mix(in srgb, var(--plass-danger-solid) var(--plass-glow-strength), transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-danger-soft:var(--plass-danger-accent)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-danger-soft:color-mix(in srgb, var(--plass-danger-accent) 10%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-danger-soft-hover:var(--plass-danger-accent)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-danger-soft-hover:color-mix(in srgb, var(--plass-danger-accent) 18%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-danger-soft-press:var(--plass-danger-accent)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-danger-soft-press:color-mix(in srgb, var(--plass-danger-accent) 26%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-danger-line:var(--plass-danger-accent)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-danger-line:color-mix(in srgb, var(--plass-danger-accent) 30%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-danger-line-hover:var(--plass-danger-accent)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-danger-line-hover:color-mix(in srgb, var(--plass-danger-accent) 48%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-danger-ring:var(--plass-danger-solid)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-danger-ring:color-mix(in srgb, var(--plass-danger-solid) 55%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-info-fill:linear-gradient(135deg, var(--plass-info-solid) 0%, var(--plass-info-solid) 46%, var(--plass-info-solid) 100%)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-info-fill:linear-gradient(135deg, color-mix(in srgb, var(--plass-info-solid) 95%, white) 0%, var(--plass-info-solid) 46%, color-mix(in srgb, var(--plass-info-solid) 90%, black) 100%)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-info-glow:var(--plass-info-solid)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-info-glow:color-mix(in srgb, var(--plass-info-solid) var(--plass-glow-strength), transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-info-soft:var(--plass-info-accent)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-info-soft:color-mix(in srgb, var(--plass-info-accent) 10%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-info-soft-hover:var(--plass-info-accent)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-info-soft-hover:color-mix(in srgb, var(--plass-info-accent) 18%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-info-soft-press:var(--plass-info-accent)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-info-soft-press:color-mix(in srgb, var(--plass-info-accent) 26%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-info-line:var(--plass-info-accent)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-info-line:color-mix(in srgb, var(--plass-info-accent) 30%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-info-line-hover:var(--plass-info-accent)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-info-line-hover:color-mix(in srgb, var(--plass-info-accent) 48%, transparent)}}:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-info-ring:var(--plass-info-solid)}@supports (color:color-mix(in lab, red, red)){:root,.dark,.light,[data-theme=dark],[data-theme=light]{--plass-info-ring:color-mix(in srgb, var(--plass-info-solid) 55%, transparent)}}.plass-title :where(h1,h2,h3,h4,h5,h6){font:inherit;margin:0}.plass-gloss:before{content:"";border-radius:inherit;pointer-events:none;background-image:var(--plass-specular);opacity:1;transition:opacity var(--plass-duration) var(--plass-ease);position:absolute;inset:0}.plass-gloss:active:before{opacity:.3}@media (prefers-reduced-motion:reduce){.plass-gloss:before{transition-duration:1ms}}@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-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{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}@keyframes spin{to{transform:rotate(360deg)}}