@rowkit/tokens 0.4.0 → 1.0.0-beta.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/README.md +16 -12
- package/dist/color.d.ts +134 -495
- package/dist/css.d.ts +2 -4
- package/dist/index.d.ts +142 -352
- package/dist/index.js +212 -369
- package/dist/index.js.map +1 -1
- package/dist/radius.d.ts +15 -17
- package/dist/shadow.d.ts +42 -20
- package/dist/tokens.css +111 -232
- package/dist/typography.d.ts +63 -46
- package/package.json +3 -4
- package/dist/blur.d.ts +0 -18
- package/dist/reference.html +0 -1275
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../package.json","../src/blur.ts","../src/color.ts","../src/motion.ts","../src/radius.ts","../src/shadow.ts","../src/spacing.ts","../src/typography.ts","../src/z-index.ts","../src/css.ts","../src/index.ts"],"sourcesContent":["{\n \"name\": \"@rowkit/tokens\",\n \"version\": \"0.4.0\",\n \"description\": \"Design tokens for rowkit — consumable without importing components.\",\n \"license\": \"MIT\",\n \"author\": \"Nikolai Kushner\",\n \"homepage\": \"https://rowkit.dev\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/NikolaiKushner/rowkit.git\",\n \"directory\": \"packages/tokens\"\n },\n \"bugs\": \"https://github.com/NikolaiKushner/rowkit/issues\",\n \"keywords\": [\n \"design-tokens\",\n \"design-system\",\n \"rowkit\"\n ],\n \"type\": \"module\",\n \"sideEffects\": false,\n \"files\": [\n \"dist\"\n ],\n \"main\": \"./dist/index.js\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\"\n },\n \"./css\": \"./dist/tokens.css\",\n \"./package.json\": \"./package.json\"\n },\n \"publishConfig\": {\n \"access\": \"public\",\n \"provenance\": true\n },\n \"engines\": {\n \"node\": \">=20.19.0\"\n },\n \"scripts\": {\n \"build\": \"vue-tsc -b tsconfig.lib.json --force && vite build && node scripts/fix-dts-specifiers.mjs && node scripts/emit-css.mjs && node scripts/emit-reference.mjs\",\n \"typecheck\": \"vue-tsc -b --force\",\n \"reference\": \"pnpm build && open dist/reference.html\"\n }\n}\n","/**\n * Backdrop blur radii.\n *\n * One entry, and named for its job rather than a t-shirt size. Blur is not a\n * scale rowkit designs with — it appears in exactly one place, behind a modal,\n * and a second value would be a decision nobody has had to make yet.\n *\n * Deliberately small. The scrim separates the planes; the blur only stops the\n * page behind from competing for the eye. Anything heavier reads as an effect\n * and makes the content behind unrecognisable, which defeats the reason a\n * modal shows its context at all.\n */\nexport const blur = {\n /** The dialog scrim. The reference `backdrop-blur-xs`. */\n overlay: '4px',\n} as const\n\n/** Names of every blur token. */\nexport type BlurName = keyof typeof blur\n","/**\n * Colour primitives and semantic mappings.\n *\n * ## How the scales were derived\n *\n * Every chromatic family shares one lightness ramp and one chroma envelope, so\n * `primary-600`, `danger-600` and `success-600` are the same perceptual weight\n * and can be swapped without relayering the design. Families differ only by\n * hue and a chroma factor.\n *\n * Chroma at each step is clamped to the sRGB gamut boundary. OKLCH can express\n * colours outside sRGB, and browsers gamut-map them per their own rules — that\n * makes a token render differently on a P3 laptop than on an sRGB monitor.\n * Clamping trades a little vividness for identical output everywhere.\n *\n * `warning` carries a lightness bump through its midtones: at a shared\n * lightness, yellow is far less saturated than blue or red, so the unbumped\n * steps read as muddy brown rather than amber.\n *\n * Contrast for every semantic pair is asserted in `contrast.test.ts` — the\n * ratios are a build gate, not a claim in a comment.\n */\n\n/** The eleven steps every colour family provides. */\nexport const colorSteps = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950] as const\n\n/** One step of a colour family. */\nexport type ColorStep = (typeof colorSteps)[number]\n\n/**\n * Cool-slate neutral (hue 264). Roughly 70% of the pixels in a data table:\n * page background, row borders, muted labels, table chrome.\n */\nexport const neutral = {\n 50: 'oklch(0.984 0.003 264)',\n 100: 'oklch(0.968 0.004 264)',\n 200: 'oklch(0.928 0.006 264)',\n 300: 'oklch(0.869 0.01 264)',\n 400: 'oklch(0.704 0.018 264)',\n 500: 'oklch(0.551 0.024 264)',\n 600: 'oklch(0.446 0.027 264)',\n 700: 'oklch(0.373 0.028 264)',\n 800: 'oklch(0.279 0.03 264)',\n 900: 'oklch(0.21 0.033 264)',\n 950: 'oklch(0.13 0.036 264)',\n} as const\n\n/**\n * Ink blue (hue 255).\n *\n * Cool and current — the step after warm espresso. Chroma stays low so a\n * solid button is ink, not a brand shout, and the selected-row wash\n * (`primary-50`) reads as a cool mist instead of a pink one.\n */\nexport const primary = {\n 50: 'oklch(0.975 0.011 255)',\n 100: 'oklch(0.948 0.022 255)',\n 200: 'oklch(0.90 0.034 255)',\n 300: 'oklch(0.80 0.05 255)',\n 400: 'oklch(0.68 0.07 255)',\n 500: 'oklch(0.52 0.09 255)',\n 600: 'oklch(0.44 0.095 255)',\n 700: 'oklch(0.38 0.095 255)',\n /** Solid actions — ink blue, deep enough for white labels. */\n 800: 'oklch(0.32 0.09 255)',\n 900: 'oklch(0.27 0.075 255)',\n 950: 'oklch(0.19 0.05 255)',\n} as const\n\n/** Green (hue 152). Reserved for successful outcomes, never for brand accent. */\nexport const success = {\n 50: 'oklch(0.97 0.014 152)',\n 100: 'oklch(0.936 0.036 152)',\n 200: 'oklch(0.885 0.064 152)',\n 300: 'oklch(0.809 0.097 152)',\n 400: 'oklch(0.715 0.145 152)',\n 500: 'oklch(0.623 0.162 152)',\n 600: 'oklch(0.546 0.142 152)',\n 700: 'oklch(0.488 0.127 152)',\n 800: 'oklch(0.442 0.115 152)',\n 900: 'oklch(0.396 0.103 152)',\n 950: 'oklch(0.282 0.073 152)',\n} as const\n\n/** Amber (hue 75), lightness-bumped through the midtones. See the module note. */\nexport const warning = {\n 50: 'oklch(0.97 0.016 75)',\n 100: 'oklch(0.936 0.04 75)',\n 200: 'oklch(0.885 0.071 75)',\n 300: 'oklch(0.849 0.108 75)',\n 400: 'oklch(0.785 0.162 75)',\n 500: 'oklch(0.723 0.15 75)',\n 600: 'oklch(0.616 0.128 75)',\n 700: 'oklch(0.528 0.11 75)',\n 800: 'oklch(0.442 0.092 75)',\n 900: 'oklch(0.396 0.082 75)',\n 950: 'oklch(0.282 0.059 75)',\n} as const\n\n/** Red (hue 25). Destructive actions and error states. */\nexport const danger = {\n 50: 'oklch(0.97 0.014 25)',\n 100: 'oklch(0.936 0.032 25)',\n 200: 'oklch(0.885 0.06 25)',\n 300: 'oklch(0.809 0.107 25)',\n 400: 'oklch(0.715 0.17 25)',\n 500: 'oklch(0.623 0.214 25)',\n 600: 'oklch(0.546 0.218 25)',\n 700: 'oklch(0.488 0.195 25)',\n 800: 'oklch(0.442 0.165 25)',\n 900: 'oklch(0.396 0.135 25)',\n 950: 'oklch(0.282 0.086 25)',\n} as const\n\n/**\n * Greys keyed by OKLCH lightness × 1000, so `gray-922` is lightness 0.922.\n *\n * Most steps stay zero-chroma — the reference design's quiet base. A few carry\n * a cool cast (hue 264, the same as {@link neutral}): lighter hairlines and\n * soft recessed surfaces. That is rowkit's own signal inside an otherwise\n * clean, reference-shaped palette — enough to read as itself on a long session,\n * not enough to look like a tinted theme.\n */\nexport const gray = {\n /** Soft cool page. Slightly off pure white so a day of table work is less glare. */\n 988: 'oklch(0.988 0.002 264)',\n /** the reference `--primary-foreground`, `--foreground` (dark). */\n 985: 'oklch(0.985 0 0)',\n /**\n * Cool recessed surface — muted toolbars, row hover, quiet chips.\n *\n * Lighter and cooler than the reference `--muted` (0.97 0 0): same job, less\n * ink on the page.\n */\n 972: 'oklch(0.972 0.003 264)',\n /** the reference `--secondary`, `--muted`, `--accent` — kept for dark primary fill. */\n 970: 'oklch(0.97 0 0)',\n /**\n * Cool decorative hairline / recessed fill step. Lighter than the reference\n * `--border` (0.922) — table rules, card outlines, and secondary button fill\n * (`surface-active`) that must read as a surface next to white outline chrome.\n */\n 940: 'oklch(0.940 0.004 264)',\n /** the reference `--border`. Kept for pressed fills that still need a step of weight. */\n 922: 'oklch(0.922 0 0)',\n /**\n * Cool emphasised hairline. rowkit's; the reference design has no \"strong border\".\n * Softer than the old 0.87 step so structure reads without shouting.\n */\n 905: 'oklch(0.905 0.006 264)',\n /** Emphasised hairline (legacy weight). Prefer {@link gray[905]} for new chrome. */\n 870: 'oklch(0.87 0 0)',\n /** the reference `--muted-foreground` (dark), where it clears AA at 7.63:1. */\n 708: 'oklch(0.708 0 0)',\n /**\n * rowkit's correction to the reference `--ring` and `--input` in light mode.\n *\n * the reference design puts them at 0.708 and 0.922, which measure 2.59:1 and 1.26:1\n * against a white page — a focus ring and a control boundary that both fail\n * WCAG 1.4.11.\n *\n * Not the mathematical minimum. Solving in floating point gave 0.669 and a\n * tidy 3.00:1; the browser paints `#959595` and axe measured **2.995:1**,\n * because a colour is quantised to eight bits per channel before anyone sees\n * it. Anything solved exactly onto a threshold lands on whichever side the\n * rounding chooses. 0.635 is 3.45:1 against the page and 3.17:1 against\n * `surface-subtle`, which clears the bar on both sides of the rounding.\n */\n 635: 'oklch(0.635 0 0)',\n /**\n * Cool control boundary. Softer and cooler than the a11y floor at 0.635, still\n * clears 3:1 on the page, a card and a recessed toolbar — so inputs speak the\n * same language as the cool hairlines without failing WCAG 1.4.11.\n */\n 642: 'oklch(0.642 0.012 264)',\n /** the reference `--ring` (dark), 4.18:1 against the dark page. */\n 556: 'oklch(0.556 0 0)',\n /**\n * rowkit's correction to the reference `--muted-foreground` in light mode.\n *\n * The reference design's 0.556 is 4.73:1 on white but only 4.34:1 on `--muted`, the\n * recessed surface a table header sits on — and a table header is the single\n * most common use this token has.\n *\n * 0.547 was the first attempt and shipped 4.51:1 in floating point; axe,\n * reading the painted `#717171`, called it 4.47:1 and failed twenty-four\n * stories. See {@link gray[635]} — same lesson, same cause. 0.535 measures\n * 4.75:1 on `--muted` and 5.17:1 on the page.\n */\n 535: 'oklch(0.535 0 0)',\n /** Pressed row in dark mode. */\n 371: 'oklch(0.371 0 0)',\n /** the reference `--secondary`, `--muted`, `--accent` (dark). */\n 269: 'oklch(0.269 0 0)',\n /** the reference `--primary` (light), `--card` and `--popover` (dark). */\n 205: 'oklch(0.205 0 0)',\n /** the reference `--foreground` (light), `--background` (dark). */\n 145: 'oklch(0.145 0 0)',\n} as const\n\n/**\n * The reference design's destructive red, clamped into sRGB. Keyed by lightness, like `gray`.\n *\n * the reference design publishes `oklch(0.577 0.245 27.325)`, and that chroma **does not fit\n * in sRGB** — 0.235 is the maximum at this lightness and hue. The difference is\n * invisible; what it buys is a colour that renders identically on an sRGB\n * monitor and a P3 laptop, instead of one each browser gamut-maps by its own\n * rules. rowkit clamps every chromatic primitive for this reason, and\n * `color.test.ts` enforces it.\n *\n * One red serves both themes. The reference design's dark `--destructive` is a lighter\n * `oklch(0.704 …)`, which carries its white label at **2.86:1** — the single\n * worst failure in the reference design's default set. Reusing the light value gives 4.90:1\n * on the label in both themes and still clears 4.04:1 against the dark page.\n */\nexport const red = {\n /** Soft text on a dark subtle wash. Chroma clamped for sRGB. */\n 850: 'oklch(0.85 0.08 25)',\n /** Destructive fill. The reference design's lightness, chroma clamped. */\n 577: 'oklch(0.577 0.235 27.325)',\n /** Destructive hover — darkens in both themes, so the white label improves. */\n 520: 'oklch(0.52 0.212 27.325)',\n /** Soft border on a dark subtle wash. */\n 350: 'oklch(0.38 0.055 25)',\n /** Soft fill in dark mode — quiet red wash, not a solid brick. */\n 260: 'oklch(0.32 0.045 25)',\n} as const\n\n/**\n * Success and warning, at the reference design's weight. Keyed by lightness, like `gray`.\n *\n * the reference design has no equivalent to copy, so the rule is consistency rather than\n * fidelity: the solid step sits at the same lightness band as `red-577` and\n * carries a white label, so a success, a warning and a destructive button are\n * the same perceptual weight and only differ in hue.\n *\n * That is a real change for warning, which used to be bright amber with dark\n * text. Bright amber is the loudest thing on a the reference design page — the language is\n * built on restraint, and one saturated chip undoes it. Chroma is clamped to\n * the sRGB boundary at every step, as everywhere else.\n */\nexport const green = {\n /** Badge fill, light. */\n 950: 'oklch(0.95 0.05 152)',\n /** Badge border, light. */\n 880: 'oklch(0.88 0.05 152)',\n /** Badge text, dark. */\n 850: 'oklch(0.85 0.12 152)',\n /** Solid fill, both themes. White label at 4.56:1. */\n 550: 'oklch(0.55 0.144 152)',\n /** Solid hover — darkens, so the white label improves. */\n 520: 'oklch(0.52 0.136 152)',\n /** Badge text, light. */\n 400: 'oklch(0.4 0.105 152)',\n /** Badge border, dark. */\n 350: 'oklch(0.35 0.092 152)',\n /** Badge fill, dark. */\n 260: 'oklch(0.26 0.068 152)',\n} as const\n\n/** Warning, mirroring {@link green} step for step. */\nexport const amber = {\n 950: 'oklch(0.95 0.04 75)',\n 880: 'oklch(0.88 0.05 75)',\n 850: 'oklch(0.85 0.12 75)',\n /** Solid fill, both themes. White label at 4.96:1. */\n 550: 'oklch(0.55 0.116 75)',\n 520: 'oklch(0.52 0.109 75)',\n 400: 'oklch(0.4 0.084 75)',\n 350: 'oklch(0.35 0.074 75)',\n 260: 'oklch(0.26 0.055 75)',\n} as const\n\n/**\n * White at a fraction of opacity, for dark-mode borders.\n *\n * Alpha, not a solid grey: a grey tuned for `--background` draws too hard a\n * line once the same border sits on `--card`. The reference uses 10% / 15%;\n * rowkit softens the decorative hairline to 8% so dense tables stay quiet in\n * dark mode the same way the cool light hairline does.\n */\nexport const whiteAlpha = {\n /** Soft decorative hairline in dark mode. */\n 8: 'oklch(1 0 0 / 8%)',\n /** the reference dark `--border`. */\n 10: 'oklch(1 0 0 / 10%)',\n /** Emphasised dark hairline / the reference dark `--input`. */\n 15: 'oklch(1 0 0 / 15%)',\n} as const\n\n/**\n * Every primitive colour, keyed by the CSS custom property it becomes.\n *\n * These are the only place a literal colour value appears in rowkit. Everything\n * else — semantic tokens, component variants — references one of these.\n */\nexport const colorPrimitives = {\n white: 'oklch(1 0 0)',\n black: 'oklch(0 0 0)',\n ...prefixKeys('gray', gray),\n ...prefixKeys('red', red),\n ...prefixKeys('green', green),\n ...prefixKeys('amber', amber),\n ...prefixKeys('white-alpha', whiteAlpha),\n ...prefix('neutral', neutral),\n ...prefix('primary', primary),\n ...prefix('success', success),\n ...prefix('warning', warning),\n ...prefix('danger', danger),\n} as const\n\nfunction prefix<N extends string>(\n name: N,\n scale: Record<ColorStep, string>\n): Record<`${N}-${ColorStep}`, string> {\n const out: Record<string, string> = {}\n for (const step of colorSteps) out[`${name}-${step}`] = scale[step]\n return out\n}\n\n/**\n * The same, for a scale that is not an eleven-step ramp.\n *\n * `gray` and `whiteAlpha` are keyed by lightness and by opacity, so they cannot\n * go through {@link prefix}, which walks {@link colorSteps}.\n */\nfunction prefixKeys<N extends string, S extends Record<string | number, string>>(\n name: N,\n scale: S\n): { [K in keyof S & (string | number) as `${N}-${K}`]: string } {\n const out: Record<string, string> = {}\n for (const [key, value] of Object.entries(scale)) out[`${name}-${key}`] = value\n return out as { [K in keyof S & (string | number) as `${N}-${K}`]: string }\n}\n\n/** A reference to a primitive colour, as a CSS `var()` expression. */\nexport type ColorRef = `var(--color-${string})`\n\nconst ref = (token: keyof typeof colorPrimitives): ColorRef => `var(--color-${token})`\n\n/**\n * Light-mode semantic colours.\n *\n * Semantic tokens never hold a literal colour — each one points at a primitive\n * through `var()`, so re-theming means repointing references rather than\n * hunting down hex codes. `semantic.test.ts` enforces this.\n */\nexport const semanticColorLight = {\n /**\n * Page background, behind all surfaces.\n *\n * Soft cool off-white rather than the reference pure white — less glare over\n * a long session, and enough lift that a white `card` still reads as a plane.\n */\n background: ref('gray-988'),\n /** Cards, panels, table bodies — the plane content sits on. The reference `--card`. */\n card: ref('white'),\n /**\n * Table headers, toolbars: a surface that recedes slightly.\n *\n * Cool and a touch lighter than the reference `--muted`. Same role as\n * `accent` out of the box — separate override points, not different colours.\n */\n muted: ref('gray-972'),\n /** Row hover. */\n accent: ref('gray-972'),\n /** Row press / active. One step past hover; the reference design has no press token. */\n 'surface-active': ref('gray-940'),\n /**\n * Selected table row. Quiet primary wash — distinct from hover, not a shout.\n */\n 'surface-selected': ref('primary-50'),\n /** Disabled control background. */\n 'surface-disabled': ref('gray-972'),\n /**\n * Loading placeholder fill.\n *\n * Its own token rather than a reuse of `surface-active`, which means \"this\n * row is being pressed\". A skeleton is never interactive, so borrowing an\n * interaction token would tie the two together for any future re-theme.\n *\n * Exempt from contrast rules: skeletons are `aria-hidden` decoration\n * standing in for content that has not arrived, so there is nothing for a\n * reader to perceive and WCAG 1.4.11 does not apply.\n */\n skeleton: ref('gray-972'),\n\n /** Primary body and heading text. The reference `--foreground`. */\n foreground: ref('gray-145'),\n /**\n * Secondary text, column labels, help text. The reference `--muted-foreground`.\n *\n * `gray-535`, not the reference design's 0.556. The same trap the old `neutral-500` fell\n * into: a table header is muted text on `surface-subtle`, and the reference design's value\n * reaches 4.73:1 on white but only 4.34:1 on the recessed surface this token\n * is most often used against. Nine thousandths of lightness buy the pass.\n */\n 'muted-foreground': ref('gray-535'),\n /** Placeholders and de-emphasised metadata. */\n 'text-subtle': ref('gray-635'),\n /** Text on a disabled control. */\n 'text-disabled': ref('gray-708'),\n\n /**\n * Decorative hairline: row separators, card outlines.\n *\n * Cool and lighter than the reference 0.922. Deliberately below 3:1 — do not\n * use it for the boundary of an interactive control; see\n * {@link semanticColorLight['input']}.\n */\n border: ref('gray-940'),\n /** Emphasised decorative border: dividers that need to read as structure. */\n 'border-strong': ref('gray-905'),\n /** Barely-there separation inside a dense group. */\n 'border-subtle': ref('gray-972'),\n /**\n * Boundary of an interactive control — text inputs, selects, outlined\n * buttons.\n *\n * Quiet on purpose (structure without severity). Resting edges sit near the\n * decorative hairline; the focus treatment (`border-ring` + ring) is what\n * carries WCAG 1.4.11. Matching the reference design's soft resting edge\n * rather than a 3:1 ink outline that shouted next to every field.\n */\n input: ref('gray-870'),\n /**\n * Focus ring. Never remove the ring — recolour it.\n *\n * Soft silver — the payment-form / shadcn weight (`gray-708`), not ink.\n * Intentionally under 3:1 as a solid; the visible treatment is\n * `border-ring` plus a translucent outer ring, not a black halo.\n * Every control that focuses (Button, Input, Select, Dialog close,\n * Pagination, FilterBar chips, DataTable, Toast) reads this same token.\n */\n ring: ref('gray-708'),\n\n /** Base colour shadows are mixed from. */\n shadow: ref('black'),\n\n // `neutral` completes the status family so a component's variant matrix has\n // no special case: a neutral Badge reads the same token names as a danger\n // one. It is the default state — \"no status\" — not an absence of styling.\n 'neutral-solid': ref('gray-972'),\n 'neutral-solid-hover': ref('gray-940'),\n 'neutral-on-solid': ref('gray-205'),\n 'neutral-subtle': ref('gray-972'),\n 'neutral-on-subtle': ref('gray-205'),\n 'neutral-border': ref('gray-940'),\n\n /**\n * Ink-blue solid — cool, not a black brick and not a saturated brand blue.\n * `primary-800` ≈ `oklch(0.32 0.09 255)`.\n */\n 'primary-solid': ref('primary-800'),\n 'primary-solid-hover': ref('primary-900'),\n 'primary-on-solid': ref('gray-985'),\n 'primary-subtle': ref('primary-50'),\n 'primary-on-subtle': ref('primary-900'),\n 'primary-border': ref('primary-200'),\n\n 'success-solid': ref('green-550'),\n 'success-solid-hover': ref('green-520'),\n 'success-on-solid': ref('white'),\n 'success-subtle': ref('green-950'),\n 'success-on-subtle': ref('green-400'),\n 'success-border': ref('green-880'),\n\n // Amber is squeezed from both sides in light mode. It cannot carry white text\n // at any usable weight (white on warning-600 is 3.78:1), and a bright amber\n // fill has no discernible edge against a near-white page (warning-400 vs\n // background is 1.92:1, failing WCAG 1.4.11). warning-600 is the only step\n // that satisfies both: 3.61:1 against the page, 4.69:1 for dark text.\n //\n // Hover therefore brightens rather than darkens — warning-700 would drop dark\n // text to 3.27:1.\n 'warning-solid': ref('amber-550'),\n 'warning-solid-hover': ref('amber-520'),\n 'warning-on-solid': ref('white'),\n 'warning-subtle': ref('amber-950'),\n 'warning-on-subtle': ref('amber-400'),\n 'warning-border': ref('amber-880'),\n\n 'danger-solid': ref('red-577'),\n 'danger-solid-hover': ref('red-520'),\n 'danger-on-solid': ref('white'),\n // Soft destructive wash — pink enough to read as danger, not a solid brick.\n 'danger-subtle': ref('danger-100'),\n 'danger-on-subtle': ref('danger-700'),\n 'danger-border': ref('danger-200'),\n} as const\n\n/**\n * Dark-mode semantic colours, applied under `.dark`.\n *\n * Soft ink fills invert on dark pages: a near-white solid with dark type,\n * rather than a mid-grey that disappears into the chrome.\n */\nexport const semanticColorDark = {\n background: ref('gray-145'),\n card: ref('gray-205'),\n muted: ref('gray-269'),\n accent: ref('gray-269'),\n 'surface-active': ref('gray-371'),\n 'surface-selected': ref('gray-269'),\n 'surface-disabled': ref('gray-269'),\n // Lifts off `surface` rather than receding. On a dark page a placeholder\n // darker than its card reads as a hole in the layout.\n skeleton: ref('gray-269'),\n\n foreground: ref('gray-985'),\n // The reference design's own value, kept: 7.63:1 on the page and 5.83:1 on `--muted`, so\n // dark mode needs none of the correction light mode did.\n 'muted-foreground': ref('gray-708'),\n 'text-subtle': ref('gray-556'),\n 'text-disabled': ref('gray-556'),\n\n // White at alpha, not a solid grey — see `whiteAlpha`. Decorative hairline\n // softens to 8% so dense tables stay quiet; controls keep 15% for 1.4.11.\n border: ref('white-alpha-8'),\n 'border-strong': ref('white-alpha-15'),\n 'border-subtle': ref('white-alpha-8'),\n // The reference `--input`, unchanged: composited over the page it measures\n // 3.82:1, and 3.54:1 over a card, so both clear 1.4.11 without help.\n input: ref('white-alpha-15'),\n /**\n * Soft focus — white at the same quiet weight as the control border, not a\n * bright primary wash. Reads as a silver edge on dark surfaces.\n */\n ring: ref('white-alpha-15'),\n\n shadow: ref('black'),\n\n 'neutral-solid': ref('gray-269'),\n 'neutral-solid-hover': ref('gray-371'),\n 'neutral-on-solid': ref('gray-985'),\n 'neutral-subtle': ref('gray-269'),\n 'neutral-on-subtle': ref('gray-985'),\n 'neutral-border': ref('gray-371'),\n\n // Soft near-white fill with dark label — ink inverted for dark pages.\n 'primary-solid': ref('primary-100'),\n 'primary-solid-hover': ref('primary-50'),\n 'primary-on-solid': ref('primary-900'),\n 'primary-subtle': ref('primary-900'),\n 'primary-on-subtle': ref('primary-200'),\n 'primary-border': ref('primary-700'),\n\n 'success-solid': ref('green-550'),\n 'success-solid-hover': ref('green-520'),\n 'success-on-solid': ref('white'),\n 'success-subtle': ref('green-260'),\n 'success-on-subtle': ref('green-850'),\n 'success-border': ref('green-350'),\n\n 'warning-solid': ref('amber-550'),\n 'warning-solid-hover': ref('amber-520'),\n 'warning-on-solid': ref('white'),\n 'warning-subtle': ref('amber-260'),\n 'warning-on-subtle': ref('amber-850'),\n 'warning-border': ref('amber-350'),\n\n // The same red as light mode, with a white label. See `red`.\n 'danger-solid': ref('red-577'),\n 'danger-solid-hover': ref('red-520'),\n 'danger-on-solid': ref('white'),\n // Soft destructive wash in dark — same philosophy as light (pink wash +\n // coloured label), mirroring success/warning dark subtle steps.\n 'danger-subtle': ref('red-260'),\n 'danger-on-subtle': ref('red-850'),\n 'danger-border': ref('red-350'),\n} as const\n\n/** Names of every semantic colour token. */\nexport type SemanticColorName = keyof typeof semanticColorLight\n","/**\n * Motion durations and easing curves.\n *\n * Durations are short. In a working interface an animation is feedback, not\n * decoration: the user is scanning rows, and anything past ~200ms reads as the\n * interface lagging rather than responding.\n *\n * Every consumer of these tokens is still responsible for honouring\n * `prefers-reduced-motion` — a token cannot express that.\n */\nexport const duration = {\n /** No transition. */\n instant: '0ms',\n /** Hover and focus states — must feel immediate. */\n fast: '120ms',\n /** Dropdowns, popovers, most enter/exit transitions. */\n normal: '200ms',\n /** Dialogs and large surfaces, where more travel needs more time. */\n slow: '320ms',\n} as const\n\n/** Easing curves. */\nexport const easing = {\n /** Linear. Progress indicators only. */\n linear: 'linear',\n /**\n * The default for anything that both enters and leaves. Fast out of the\n * gate, gentle at rest.\n */\n standard: 'cubic-bezier(0.2, 0, 0, 1)',\n /** Entering the screen: decelerate into place. */\n enter: 'cubic-bezier(0, 0, 0.2, 1)',\n /** Leaving the screen: accelerate away. */\n exit: 'cubic-bezier(0.4, 0, 1, 1)',\n} as const\n\n/** Names of every duration token. */\nexport type DurationName = keyof typeof duration\n/** Names of every easing token. */\nexport type EasingName = keyof typeof easing\n","/**\n * Corner radii, derived from one variable.\n *\n * Every step is a multiple of `--radius`, following the reference scale. One\n * declaration retunes every corner in the library:\n *\n * ```css\n * :root { --radius: 0.5rem; }\n * ```\n *\n * The factors are the source of truth, not the resulting lengths. Two things\n * are generated from them and cannot drift: {@link radius}, which resolves to\n * real `rem` values so a TypeScript consumer gets a number it can use, and\n * {@link radiusCss}, which keeps the `calc()` so a consumer's override of\n * `--radius` still cascades through the whole scale.\n */\n\n/**\n * The single length the scale multiplies.\n *\n * `0.5rem` (8px) keeps corners decisive rather than soft — the silhouette that\n * reads as a data tool, not a marketing page. Override `--radius` in a\n * consumer to retune every corner without touching components.\n */\nexport const radiusBase = '0.5rem'\n\n/**\n * Multiples of `--radius`.\n *\n * `sm`/`md`/`lg`/`xl` keep the same factors as the reference scale. `xs` is\n * rowkit's, and lands on ~3px — the radius used on checkboxes and chip remove\n * targets inside dense table chrome.\n */\nexport const radiusFactor = {\n /** Square. Table cells, and anything that tiles edge to edge. */\n none: 0,\n /** ~3px — checkboxes, tags inside a cell. */\n xs: 0.4,\n /** ~5px — badges, small controls. */\n sm: 0.6,\n /** ~6px — buttons, inputs, cards. The rowkit default. */\n md: 0.8,\n /** 8px — dialogs, popovers. */\n lg: 1,\n /** ~11px — large empty-state panels. */\n xl: 1.4,\n} as const\n\n/** A radius that is not a multiple of the base. */\nconst PILL = '9999px'\n\n/**\n * Resolved lengths, for TypeScript consumers and for the contrast of reading\n * an actual size in the docs table.\n */\nexport const radius = {\n ...(Object.fromEntries(\n Object.entries(radiusFactor).map(([name, factor]) => [name, resolve(factor)])\n ) as { [K in keyof typeof radiusFactor]: string }),\n /** Pill. Status chips and avatars. */\n full: PILL,\n} as const\n\n/**\n * The same scale as CSS expressions, for the emitted `@theme` block.\n *\n * `lg` is bare `var(--radius)` rather than `calc(var(--radius) * 1)` because\n * the multiplication is noise at a factor of one.\n */\nexport const radiusCss = {\n ...(Object.fromEntries(\n Object.entries(radiusFactor).map(([name, factor]) => [name, expression(factor)])\n ) as { [K in keyof typeof radiusFactor]: string }),\n full: PILL,\n} as const\n\n/** Names of every radius token. */\nexport type RadiusName = keyof typeof radius\n\nfunction resolve(factor: number): string {\n if (factor === 0) return '0rem'\n const base = Number.parseFloat(radiusBase)\n // Six places, then trailing zeros stripped: 0.5 * 1.4 is clean in decimal\n // but floating point still needs the round-trip so docs stay readable.\n return `${Number((base * factor).toFixed(6))}rem`\n}\n\nfunction expression(factor: number): string {\n if (factor === 0) return '0rem'\n if (factor === 1) return 'var(--radius)'\n return `calc(var(--radius) * ${factor})`\n}\n","/**\n * Elevation shadows.\n *\n * Each shadow mixes from `--color-shadow`, a semantic token, rather than\n * hardcoding a colour — so dark mode swaps the base to pure black by\n * repointing one variable.\n *\n * Dark mode leans on surface lightness for elevation rather than on shadows.\n * A shadow is a darker region, and on a near-black page there is very little\n * headroom left to darken; the raised surface colour does the work instead.\n */\nexport const shadow = {\n /** No elevation. */\n none: 'none',\n /** Hairline lift — sticky table headers, input focus. */\n xs: '0 1px 2px 0 color-mix(in oklab, var(--color-shadow) 6%, transparent)',\n /** Resting cards. */\n sm: '0 1px 3px 0 color-mix(in oklab, var(--color-shadow) 8%, transparent), 0 1px 2px -1px color-mix(in oklab, var(--color-shadow) 8%, transparent)',\n /** Dropdowns, popovers. */\n md: '0 4px 6px -1px color-mix(in oklab, var(--color-shadow) 9%, transparent), 0 2px 4px -2px color-mix(in oklab, var(--color-shadow) 9%, transparent)',\n /** Menus over content. */\n lg: '0 10px 15px -3px color-mix(in oklab, var(--color-shadow) 10%, transparent), 0 4px 6px -4px color-mix(in oklab, var(--color-shadow) 10%, transparent)',\n /** Modal dialogs. */\n xl: '0 20px 25px -5px color-mix(in oklab, var(--color-shadow) 12%, transparent), 0 8px 10px -6px color-mix(in oklab, var(--color-shadow) 12%, transparent)',\n /** Horizontal-scroll affordance on a sticky table column. */\n 'scroll-x': '12px 0 16px -8px color-mix(in oklab, var(--color-shadow) 22%, transparent)',\n /**\n * The rule under a sticky table header, drawn as a shadow rather than a\n * border.\n *\n * Under `border-collapse` a border belongs to the table's grid, not to any\n * cell, so a `position: sticky` header leaves its border behind and scrolls\n * away from it — the rows then slide under a header with nothing between\n * them, which is the one thing a sticky header exists to prevent. A shadow\n * belongs to the element and travels with it.\n */\n 'sticky-header': 'inset 0 -1px 0 var(--color-border)',\n} as const\n\n/** Names of every shadow token. */\nexport type ShadowName = keyof typeof shadow\n","/**\n * Spacing scale.\n *\n * Keys are multiples of the 4px base unit, matching the convention most Vue and\n * Tailwind developers already carry in their heads: `4` is 1rem, `2` is 8px.\n * Fractional steps are deliberately absent — they would need escaped CSS custom\n * property names (`--spacing-0\\.5`), and Tailwind v4 already derives arbitrary\n * fractions from {@link spacingBase}.\n *\n * The low end is dense on purpose. A table cell padded at `2`/`3` is the\n * difference between a grid that shows twenty rows and one that shows twelve.\n */\nexport const spacing = {\n /** Zero. */\n 0: '0rem',\n /** 1px — hairline offsets and optical nudges, not layout. */\n px: '1px',\n /** 4px — icon-to-label gap. */\n 1: '0.25rem',\n /** 8px — dense table cell padding. */\n 2: '0.5rem',\n /** 12px — default table cell padding, compact control padding. */\n 3: '0.75rem',\n /** 16px — default control padding, tight card padding. */\n 4: '1rem',\n /** 20px */\n 5: '1.25rem',\n /** 24px — card padding, gap between form fields. */\n 6: '1.5rem',\n /** 32px — section spacing. */\n 8: '2rem',\n /** 40px */\n 10: '2.5rem',\n /** 48px — gap between major page regions. */\n 12: '3rem',\n /** 64px — page gutters. */\n 16: '4rem',\n /** 80px */\n 20: '5rem',\n /** 96px — empty-state vertical padding. */\n 24: '6rem',\n} as const\n\n/**\n * The base unit Tailwind v4 multiplies for dynamic spacing utilities.\n *\n * Emitting this as `--spacing` keeps `p-7` and `mt-3.5` working even though\n * neither has a named token above.\n */\nexport const spacingBase = '0.25rem'\n\n/** Names of every spacing token. */\nexport type SpacingName = keyof typeof spacing\n","/**\n * Typography scale.\n *\n * Weighted toward the small end: a dashboard spends most of its type budget\n * between 12px and 16px, and the sizes above `xl` exist for empty states and\n * page titles rather than for data.\n */\n\n/**\n * Font families.\n *\n * rowkit's face is **Geist** — designed for tools, not marketing pages. The\n * stack names the webfont first; system fallbacks keep layout honest before\n * the file lands. Loading the font is the app's job (one import from\n * `@fontsource-variable/geist`); without it, the stack falls through cleanly.\n */\nexport const fontFamily = {\n /** UI and body text. */\n sans: [\n '\"Geist Variable\"',\n 'Geist',\n 'ui-sans-serif',\n 'system-ui',\n '-apple-system',\n 'Segoe UI',\n 'Roboto',\n 'Helvetica Neue',\n 'Arial',\n 'sans-serif',\n ].join(', '),\n /** IDs, hashes, numeric columns that must align vertically. */\n mono: [\n '\"Geist Mono Variable\"',\n 'Geist Mono',\n 'ui-monospace',\n 'SFMono-Regular',\n 'Menlo',\n 'Consolas',\n 'Liberation Mono',\n 'monospace',\n ].join(', '),\n} as const\n\n/**\n * Font sizes, each paired with the line height it should almost always use.\n *\n * Pairing them prevents the most common typographic bug in a dense table:\n * shrinking the font without shrinking leading, so rows stay tall and the\n * density gain evaporates.\n */\nexport const fontSize = {\n /** 12px — table metadata, badges, column headers. */\n xs: { size: '0.75rem', lineHeight: '1rem' },\n /** 14px — the default for table cells and form controls. */\n sm: { size: '0.875rem', lineHeight: '1.25rem' },\n /** 16px — body copy outside of data views. */\n base: { size: '1rem', lineHeight: '1.5rem' },\n /** 18px — card titles. */\n lg: { size: '1.125rem', lineHeight: '1.75rem' },\n /** 20px — section headings. */\n xl: { size: '1.25rem', lineHeight: '1.75rem' },\n /** 24px — page titles, empty-state headings. */\n '2xl': { size: '1.5rem', lineHeight: '2rem' },\n /** 30px — the largest size rowkit ships. */\n '3xl': { size: '1.875rem', lineHeight: '2.25rem' },\n} as const\n\n/** Font weights. */\nexport const fontWeight = {\n /** Body text. */\n normal: '400',\n /** Buttons, labels, card titles — prefer this over semibold in dense UI. */\n medium: '500',\n /** Page titles and dialog headings. */\n semibold: '600',\n /** Display only. Rarely needed in data views. */\n bold: '700',\n} as const\n\n/** Letter spacing. Tightening only pays off at display sizes. */\nexport const letterSpacing = {\n tight: '-0.015em',\n normal: '0em',\n /** For uppercase micro-labels, which need air to stay readable. */\n wide: '0.04em',\n} as const\n\n/** Standalone line heights, for when text is not using a paired {@link fontSize}. */\nexport const lineHeight = {\n none: '1',\n tight: '1.25',\n snug: '1.375',\n normal: '1.5',\n relaxed: '1.625',\n} as const\n\n/** Names of every font size token. */\nexport type FontSizeName = keyof typeof fontSize\n","/**\n * Stacking layers.\n *\n * Spaced by 100 so a consumer can slot their own chrome — an app header, a\n * cookie banner — between two rowkit layers without editing rowkit or starting\n * a `z-index: 99999` arms race.\n *\n * The ordering is not arbitrary. A tooltip must outrank a toast, because a\n * toast can carry an action button that itself has a tooltip. A popover must\n * outrank a modal, because a select inside a dialog opens a popover.\n */\nexport const zIndex = {\n /** Default flow. */\n base: '0',\n /** Sticky table header and pinned columns. */\n sticky: '100',\n /** Dropdown menus attached to page-level content. */\n dropdown: '200',\n /** Backdrop behind a modal. */\n overlay: '300',\n /** Dialog surface. */\n modal: '400',\n /** Popovers and selects — must sit above a dialog to work inside one. */\n popover: '500',\n /** Toast queue. */\n toast: '600',\n /** Tooltips outrank everything, including toasts. */\n tooltip: '700',\n} as const\n\n/** Names of every z-index token. */\nexport type ZIndexName = keyof typeof zIndex\n","import { blur } from './blur'\nimport { colorPrimitives, semanticColorDark, semanticColorLight } from './color'\nimport { duration, easing } from './motion'\nimport { radiusBase, radiusCss } from './radius'\nimport { shadow } from './shadow'\nimport { spacing, spacingBase } from './spacing'\nimport { fontFamily, fontSize, fontWeight, letterSpacing, lineHeight } from './typography'\nimport { zIndex } from './z-index'\n\n/**\n * Emits the Tailwind v4 `@theme` block for the rowkit token set.\n *\n * The TypeScript objects are the single source of truth; this function derives\n * the stylesheet from them, so the two cannot drift. `css.test.ts` asserts that\n * every token in every scale reaches the output.\n *\n * Dark mode works by repointing *semantic* tokens under `.dark`. Primitives are\n * emitted once and never change — `--color-primary-600` is the same colour in\n * both themes; what changes is which primitive `--color-primary-solid` points\n * at. That is why the theme can flip without a single hardcoded colour moving.\n *\n * @returns The complete stylesheet, ready to write to disk.\n */\nexport function buildThemeCss(): string {\n return [\n header(),\n '',\n // Tailwind v4 defaults the `dark:` variant to prefers-color-scheme. rowkit\n // uses a class so an app can offer an explicit theme switch.\n '@custom-variant dark (&:where(.dark, .dark *));',\n '',\n '@theme {',\n section('colour primitives — the only literal colours in rowkit'),\n ...entries(colorPrimitives, (k) => `--color-${k}`),\n '',\n section('semantic colours — light (defaults)'),\n ...entries(semanticColorLight, (k) => `--color-${k}`),\n '',\n section('spacing'),\n ` --spacing: ${spacingBase};`,\n ...entries(spacing, (k) => `--spacing-${k}`),\n '',\n section('typography'),\n ...entries(fontFamily, (k) => `--font-${k}`),\n ...fontSizeEntries(),\n ...entries(fontWeight, (k) => `--font-weight-${k}`),\n ...entries(letterSpacing, (k) => `--tracking-${k}`),\n ...entries(lineHeight, (k) => `--leading-${k}`),\n '',\n section('radii — multiples of --radius, declared in :root below'),\n ...entries(radiusCss, (k) => `--radius-${k}`),\n '',\n section('blur'),\n ...entries(blur, (k) => `--blur-${k}`),\n '',\n section('shadows'),\n ...entries(shadow, (k) => `--shadow-${k}`),\n '',\n section('motion'),\n // Tailwind v4's namespaces are `--transition-duration-*` and `--ease-*`.\n // A name outside a namespace it recognises is not an error — it simply\n // generates no utility, which is why `duration-fast` silently produced\n // nothing until the compile test in packages/ui went looking for it.\n ...entries(duration, (k) => `--transition-duration-${k}`),\n ...entries(easing, (k) => `--ease-${k}`),\n '',\n section('stacking layers'),\n ...entries(zIndex, (k) => `--z-index-${k}`),\n '}',\n '',\n /*\n * Outside `@theme` on purpose.\n *\n * The radius scale is `calc(var(--radius) * f)`, so `--radius` has to\n * resolve wherever a `rounded-*` utility lands. Tailwind only emits the\n * theme variables its generated utilities reference, and nothing generates\n * a utility from a bare `--radius` — left inside `@theme` it can be dropped,\n * and every `calc()` above then references an undefined variable. That is\n * not an error in CSS: `border-radius` simply computes to nothing and every\n * corner in the library goes square, with no warning anywhere.\n *\n * Declaring it here also makes it the documented override point: a consumer\n * sets `--radius` once and the whole scale follows.\n */\n '/* The one length the radius scale multiplies. Override to retune every corner. */',\n ':root {',\n ` --radius: ${radiusBase};`,\n '}',\n '',\n '/* Dark mode repoints semantic tokens only. Primitives are theme-agnostic. */',\n '.dark {',\n ...entries(semanticColorDark, (k) => `--color-${k}`),\n '}',\n '',\n ].join('\\n')\n}\n\nfunction header(): string {\n return [\n '/*',\n ' * rowkit design tokens.',\n ' *',\n ' * GENERATED FILE — DO NOT EDIT.',\n ' * Source of truth: packages/tokens/src/*.ts',\n ' * Regenerate with: pnpm --filter @rowkit/tokens build',\n ' */',\n ].join('\\n')\n}\n\nfunction section(label: string): string {\n return ` /* ${label} */`\n}\n\n/** Renders `key: value` pairs as indented custom property declarations. */\nfunction entries(scale: Record<string, string>, toVar: (key: string) => string): string[] {\n return Object.entries(scale).map(([key, value]) => ` ${toVar(key)}: ${value};`)\n}\n\n/**\n * Font sizes use Tailwind v4's paired form, where `--text-sm--line-height`\n * supplies the leading that ships with `text-sm`.\n */\nfunction fontSizeEntries(): string[] {\n return Object.entries(fontSize).flatMap(([key, value]) => [\n ` --text-${key}: ${value.size};`,\n ` --text-${key}--line-height: ${value.lineHeight};`,\n ])\n}\n","/**\n * `@rowkit/tokens` — the design token layer behind rowkit.\n *\n * Consumable on its own: import {@link tokens} for a fully typed object, or\n * `@rowkit/tokens/css` for the Tailwind v4 `@theme` block. Nothing here depends\n * on Vue, so a design tool, a docs site, or a chart library can read the same\n * values the components use.\n *\n * @example Typed access to a primitive\n * ```ts\n * import { tokens } from '@rowkit/tokens'\n * tokens.color.primary[800] // 'oklch(0.32 0.09 255)' — ink blue\n * ```\n *\n * @example The stylesheet\n * ```css\n * @import 'tailwindcss';\n * @import '@rowkit/tokens/css';\n * ```\n */\n\nimport { version as pkgVersion } from '../package.json' with { type: 'json' }\nimport { blur } from './blur'\nimport {\n amber,\n colorPrimitives,\n danger,\n gray,\n green,\n neutral,\n primary,\n red,\n semanticColorDark,\n semanticColorLight,\n success,\n warning,\n whiteAlpha,\n} from './color'\nimport { duration, easing } from './motion'\nimport { radius, radiusBase } from './radius'\nimport { shadow } from './shadow'\nimport { spacing, spacingBase } from './spacing'\nimport { fontFamily, fontSize, fontWeight, letterSpacing, lineHeight } from './typography'\nimport { zIndex } from './z-index'\n\nexport {\n amber,\n colorPrimitives,\n colorSteps,\n danger,\n gray,\n green,\n neutral,\n primary,\n red,\n semanticColorDark,\n semanticColorLight,\n success,\n warning,\n whiteAlpha,\n} from './color'\nexport type { ColorRef, ColorStep, SemanticColorName } from './color'\n\nexport { blur } from './blur'\nexport type { BlurName } from './blur'\n\nexport { duration, easing } from './motion'\nexport type { DurationName, EasingName } from './motion'\n\nexport { radius, radiusBase } from './radius'\nexport type { RadiusName } from './radius'\n\nexport { shadow } from './shadow'\nexport type { ShadowName } from './shadow'\n\nexport { spacing, spacingBase } from './spacing'\nexport type { SpacingName } from './spacing'\n\nexport { fontFamily, fontSize, fontWeight, letterSpacing, lineHeight } from './typography'\nexport type { FontSizeName } from './typography'\n\nexport { zIndex } from './z-index'\nexport type { ZIndexName } from './z-index'\n\nexport { buildThemeCss } from './css'\n\n/**\n * Every rowkit token in one object.\n *\n * Grouped by scale rather than flattened, so `tokens.color.primary[600]`\n * narrows to its literal type and autocompletes each level.\n */\nexport const tokens = {\n color: {\n gray,\n green,\n amber,\n whiteAlpha,\n neutral,\n primary,\n red,\n success,\n warning,\n danger,\n /** Flat map of every primitive, keyed by CSS custom property suffix. */\n primitives: colorPrimitives,\n /** Semantic tokens, which reference primitives via `var()`. */\n semantic: {\n light: semanticColorLight,\n dark: semanticColorDark,\n },\n },\n spacing,\n spacingBase,\n font: {\n family: fontFamily,\n size: fontSize,\n weight: fontWeight,\n letterSpacing,\n lineHeight,\n },\n radius,\n radiusBase,\n blur,\n shadow,\n zIndex,\n motion: {\n duration,\n easing,\n },\n} as const\n\n/** The shape of {@link tokens}. */\nexport type Tokens = typeof tokens\n\n/**\n * The `@rowkit/tokens` version this build was produced from.\n *\n * Read from `package.json` rather than written out. A literal here went stale\n * the moment Changesets bumped the manifest — it edits `package.json` and\n * nothing was updating the constant, so the first release broke its own test.\n * Rollup tree-shakes the JSON down to this one string, so nothing else ships.\n */\nexport const version: string = pkgVersion\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../package.json","../src/color.ts","../src/motion.ts","../src/radius.ts","../src/shadow.ts","../src/spacing.ts","../src/typography.ts","../src/z-index.ts","../src/css.ts","../src/index.ts"],"sourcesContent":["{\n \"name\": \"@rowkit/tokens\",\n \"version\": \"1.0.0-beta.0\",\n \"description\": \"Design tokens for rowkit — consumable without importing components.\",\n \"license\": \"MIT\",\n \"author\": \"Nikolai Kushner\",\n \"homepage\": \"https://rowkit.dev\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/NikolaiKushner/rowkit.git\",\n \"directory\": \"packages/tokens\"\n },\n \"bugs\": \"https://github.com/NikolaiKushner/rowkit/issues\",\n \"keywords\": [\n \"design-tokens\",\n \"design-system\",\n \"rowkit\"\n ],\n \"type\": \"module\",\n \"sideEffects\": false,\n \"files\": [\n \"dist\"\n ],\n \"main\": \"./dist/index.js\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\"\n },\n \"./css\": \"./dist/tokens.css\",\n \"./package.json\": \"./package.json\"\n },\n \"publishConfig\": {\n \"access\": \"public\",\n \"provenance\": true\n },\n \"engines\": {\n \"node\": \">=20.19.0\"\n },\n \"scripts\": {\n \"build\": \"vue-tsc -b tsconfig.lib.json --force && vite build && node scripts/fix-dts-specifiers.mjs && node scripts/emit-css.mjs\",\n \"typecheck\": \"vue-tsc -b --force\"\n }\n}\n","/**\n * Colour primitives and semantic mappings — the Windows 98 palette.\n *\n * ## Where the values come from\n *\n * The primitives are the sixteen-colour VGA palette Windows 98 was drawn in,\n * plus the handful of system colours the default \"Windows Standard\" scheme\n * added on top of it: the light bevel grey, the title-bar gradient ends and\n * the tooltip yellow. They are written as the exact sRGB hex values, not\n * converted to another space: these colours are defined by their eight-bit\n * channels, and a round trip through OKLCH would only add rounding to values\n * that are already exact.\n *\n * The names and values mirror the Figma file's `primitives` collection, and\n * the semantic map mirrors its `semantic` collection token for token, so a\n * colour picked in the design is the colour the component paints.\n *\n * Contrast for every semantic pair a component produces is asserted in\n * `contrast.test.ts` — the ratios are a build gate, not a claim in a comment.\n */\n\n/** The sixteen-colour VGA palette, as Windows 98 used it. Only the twelve the design uses are listed. */\nexport const vga = {\n black: '#000000',\n white: '#ffffff',\n /** The face of every window, button and dialog. */\n silver: '#c0c0c0',\n /** Bevel shadows, disabled text, the borders of a field. */\n gray: '#808080',\n /** Selection, the active title bar, the default primary. */\n navy: '#000080',\n /** Hyperlinks. */\n blue: '#0000ff',\n /** The desktop. */\n teal: '#008080',\n green: '#008000',\n olive: '#808000',\n yellow: '#ffff00',\n maroon: '#800000',\n red: '#ff0000',\n} as const\n\n/** The system colours Windows 98 added on top of VGA. */\nexport const win98 = {\n /** The inner light edge of a raised bevel (`3D Light`). */\n light: '#dfdfdf',\n /** Secondary text a step lighter than black. */\n 'dark-gray': '#404040',\n /** The light end of the active title-bar gradient. */\n 'title-blue': '#1084d0',\n /** The light end of the inactive title-bar gradient. */\n 'title-gray': '#b5b5b5',\n /** Tooltip background (`Info`). */\n info: '#ffffe1',\n} as const\n\n/**\n * Every primitive colour, keyed by the CSS custom property it becomes:\n * `--color-vga-silver`, `--color-win98-info`.\n *\n * These are the only place a literal colour value appears in rowkit. Everything\n * else — semantic tokens, component variants — references one of these.\n */\nexport const colorPrimitives = {\n ...prefixKeys('vga', vga),\n ...prefixKeys('win98', win98),\n} as const\n\n/** Prefixes every key of a palette with its family name. */\nfunction prefixKeys<N extends string, S extends Record<string, string>>(\n name: N,\n scale: S\n): { [K in keyof S & string as `${N}-${K}`]: S[K] } {\n const out: Record<string, string> = {}\n for (const [key, value] of Object.entries(scale)) out[`${name}-${key}`] = value\n return out as { [K in keyof S & string as `${N}-${K}`]: S[K] }\n}\n\n/** A reference to a primitive colour, as a CSS `var()` expression. */\nexport type ColorRef = `var(--color-${string})`\n\nconst ref = (token: keyof typeof colorPrimitives): ColorRef => `var(--color-${token})`\n\n/**\n * Semantic colours.\n *\n * Semantic tokens never hold a literal colour — each one points at a primitive\n * through `var()`, so re-theming means repointing references rather than\n * hunting down hex codes. `color.test.ts` enforces this.\n *\n * Windows 98 is a grey world: most surfaces are the same silver, and depth\n * comes from bevels rather than from a lighter or darker fill. So several\n * surface tokens below share a value. They stay separate tokens because they\n * are separate override points — a theme that wants a hovered row to change\n * colour repoints `accent` without touching `muted`.\n */\nexport const semanticColor = {\n // Surfaces\n\n /** The face of a window: the page behind the content. */\n background: ref('vga-silver'),\n /** The desktop a window sits on. Docs and demo backdrops. */\n desktop: ref('vga-teal'),\n /** Panels and dialogs. Same face as the window; the bevel separates them. */\n card: ref('vga-silver'),\n /** Toolbars and table headers. */\n muted: ref('vga-silver'),\n /** Row hover. Windows 98 has none — the token is here to be repointed. */\n accent: ref('vga-silver'),\n /** A pressed row or toggle. The pressed bevel carries the state, not the fill. */\n 'surface-active': ref('vga-silver'),\n /** A selected row or list item: navy, with `on-selected` text. */\n 'surface-selected': ref('vga-navy'),\n /** A disabled control keeps the face colour; its text goes grey and embossed. */\n 'surface-disabled': ref('vga-silver'),\n /**\n * Loading placeholder fill.\n *\n * Exempt from contrast rules: skeletons are `aria-hidden` decoration standing\n * in for content that has not arrived, so WCAG 1.4.11 does not apply.\n */\n skeleton: ref('vga-gray'),\n /** The inside of a text field, list or table body: white inside a sunken bevel. */\n input: ref('vga-white'),\n /** Tooltip bubble. */\n 'tooltip-bg': ref('win98-info'),\n\n // Text\n\n /** Body and heading text. */\n foreground: ref('vga-black'),\n /**\n * Secondary text. Black, like body text: Windows 98 never greys out text\n * that can still be read and acted on — grey means disabled.\n */\n 'muted-foreground': ref('vga-black'),\n /** Placeholders and de-emphasised metadata. */\n 'text-subtle': ref('win98-dark-gray'),\n /** Disabled text, always drawn with {@link semanticColor['text-disabled-emboss']} under it. */\n 'text-disabled': ref('vga-gray'),\n /** The white copy, one pixel right and down, that embosses disabled text. */\n 'text-disabled-emboss': ref('vga-white'),\n /** Text on a selected row. */\n 'on-selected': ref('vga-white'),\n /** Hyperlinks. */\n link: ref('vga-blue'),\n\n // Borders and bevels\n\n /** Separators and the frame of a group. Decorative, below 3:1 on purpose. */\n border: ref('vga-gray'),\n /** A frame that has to read as an edge: the outline of a default button. */\n 'border-strong': ref('vga-black'),\n /** The faintest rule, inside a dense group. */\n 'border-subtle': ref('win98-light'),\n /**\n * Focus. Drawn as a 1px dotted ring inside the control, around its label.\n * Black, so it clears 3:1 on every surface rowkit paints.\n */\n ring: ref('vga-black'),\n /** Base colour for shadows. */\n shadow: ref('vga-black'),\n\n /** Outer light edge of a raised bevel, inner one of a sunken bevel. */\n 'bevel-highlight': ref('vga-white'),\n /** Inner light edge of a raised bevel. */\n 'bevel-light': ref('win98-light'),\n /** Inner dark edge of a raised bevel. */\n 'bevel-shadow': ref('vga-gray'),\n /**\n * Outer dark edge of a raised bevel. Being black, it is what gives every\n * control a boundary of well over 3:1 against the face (WCAG 1.4.11).\n */\n 'bevel-dark': ref('vga-black'),\n\n // Window title bar\n\n /** Active title bar, left end of the gradient. The title text sits on this end. */\n 'titlebar-from': ref('vga-navy'),\n /** Active title bar, right end of the gradient. */\n 'titlebar-to': ref('win98-title-blue'),\n /** Inactive title bar, left end of the gradient. */\n 'titlebar-inactive-from': ref('vga-gray'),\n /** Inactive title bar, right end of the gradient. */\n 'titlebar-inactive-to': ref('win98-title-gray'),\n /** Active title text. */\n 'titlebar-foreground': ref('vga-white'),\n /**\n * Inactive title text. Black, not Windows 98's silver: silver on the grey\n * gradient is about 2:1 and fails 4.5:1; black is 5.3:1 on `#808080` and\n * 11:1 on `#b5b5b5`.\n */\n 'titlebar-inactive-foreground': ref('vga-black'),\n\n // Status families. A solid is a filled badge or a button; a subtle is a\n // white chip with coloured text. No status colour is ever used without an\n // icon or a word that says the same thing.\n //\n // `neutral` completes the family so a component's variant matrix has no\n // special case: a neutral Badge reads the same token names as a danger one.\n 'neutral-solid': ref('vga-black'),\n 'neutral-solid-hover': ref('vga-black'),\n 'neutral-on-solid': ref('vga-white'),\n 'neutral-subtle': ref('vga-white'),\n 'neutral-on-subtle': ref('vga-black'),\n 'neutral-border': ref('vga-gray'),\n\n 'primary-solid': ref('vga-navy'),\n 'primary-solid-hover': ref('vga-navy'),\n 'primary-on-solid': ref('vga-white'),\n 'primary-subtle': ref('vga-white'),\n 'primary-on-subtle': ref('vga-navy'),\n 'primary-border': ref('vga-navy'),\n\n 'success-solid': ref('vga-green'),\n 'success-solid-hover': ref('vga-green'),\n 'success-on-solid': ref('vga-white'),\n 'success-subtle': ref('vga-white'),\n 'success-on-subtle': ref('vga-green'),\n 'success-border': ref('vga-green'),\n\n /**\n * Yellow carries black, never white: white on `#ffff00` is 1.07:1. Its edge\n * is olive, because yellow on silver has almost no edge of its own.\n */\n 'warning-solid': ref('vga-yellow'),\n 'warning-solid-hover': ref('vga-yellow'),\n 'warning-on-solid': ref('vga-black'),\n 'warning-subtle': ref('vga-white'),\n 'warning-on-subtle': ref('vga-black'),\n 'warning-border': ref('vga-olive'),\n\n 'danger-solid': ref('vga-maroon'),\n 'danger-solid-hover': ref('vga-maroon'),\n 'danger-on-solid': ref('vga-white'),\n 'danger-subtle': ref('vga-white'),\n 'danger-on-subtle': ref('vga-maroon'),\n 'danger-border': ref('vga-maroon'),\n} as const\n\n/** Names of every semantic colour token. */\nexport type SemanticColorName = keyof typeof semanticColor\n","/**\n * Motion durations and easing curves.\n *\n * Durations are short. In a working interface an animation is feedback, not\n * decoration: the user is scanning rows, and anything past ~200ms reads as the\n * interface lagging rather than responding.\n *\n * Every consumer of these tokens is still responsible for honouring\n * `prefers-reduced-motion` — a token cannot express that.\n */\nexport const duration = {\n /** No transition. */\n instant: '0ms',\n /** Hover and focus states — must feel immediate. */\n fast: '120ms',\n /** Dropdowns, popovers, most enter/exit transitions. */\n normal: '200ms',\n /** Dialogs and large surfaces, where more travel needs more time. */\n slow: '320ms',\n} as const\n\n/** Easing curves. */\nexport const easing = {\n /** Linear. Progress indicators only. */\n linear: 'linear',\n /**\n * The default for anything that both enters and leaves. Fast out of the\n * gate, gentle at rest.\n */\n standard: 'cubic-bezier(0.2, 0, 0, 1)',\n /** Entering the screen: decelerate into place. */\n enter: 'cubic-bezier(0, 0, 0.2, 1)',\n /** Leaving the screen: accelerate away. */\n exit: 'cubic-bezier(0.4, 0, 1, 1)',\n} as const\n\n/** Names of every duration token. */\nexport type DurationName = keyof typeof duration\n/** Names of every easing token. */\nexport type EasingName = keyof typeof easing\n","/**\n * Corner radii, derived from one variable.\n *\n * Every step is a multiple of `--radius`, following the reference scale. One\n * declaration retunes every corner in the library:\n *\n * ```css\n * :root { --radius: 0.25rem; }\n * ```\n *\n * The factors are the source of truth, not the resulting lengths. Two things\n * are generated from them and cannot drift: {@link radius}, which resolves to\n * real `rem` values so a TypeScript consumer gets a number it can use, and\n * {@link radiusCss}, which keeps the `calc()` so a consumer's override of\n * `--radius` still cascades through the whole scale.\n */\n\n/**\n * The single length the scale multiplies.\n *\n * Zero: Windows 98 has no rounded corners, and every `radius/*` token in the\n * design is 0. The scale is kept rather than deleted so that corners stay one\n * decision away — set `--radius` in a consumer and every control follows,\n * without touching a component.\n */\nexport const radiusBase = '0rem'\n\n/**\n * Multiples of `--radius`. All of them compute to 0 with the default base;\n * the factors decide how a consumer's own `--radius` spreads across controls.\n */\nexport const radiusFactor = {\n /** Always square, whatever `--radius` is: table cells, anything that tiles. */\n none: 0,\n /** Checkboxes and tags inside a cell. */\n xs: 0.4,\n /** Badges and small controls. */\n sm: 0.6,\n /** Buttons, inputs and panels. */\n md: 0.8,\n /** Windows, dialogs and popovers. */\n lg: 1,\n /** Large empty-state panels. */\n xl: 1.4,\n} as const\n\n/** A radius that is not a multiple of the base. */\nconst PILL = '9999px'\n\n/**\n * Resolved lengths, for TypeScript consumers and for the contrast of reading\n * an actual size in the docs table.\n */\nexport const radius = {\n ...(Object.fromEntries(\n Object.entries(radiusFactor).map(([name, factor]) => [name, resolve(factor)])\n ) as { [K in keyof typeof radiusFactor]: string }),\n /** Circle. The only rounded shape Windows 98 draws: radio buttons, and a round skeleton. */\n full: PILL,\n} as const\n\n/**\n * The same scale as CSS expressions, for the emitted `@theme` block.\n *\n * `lg` is bare `var(--radius)` rather than `calc(var(--radius) * 1)` because\n * the multiplication is noise at a factor of one.\n */\nexport const radiusCss = {\n ...(Object.fromEntries(\n Object.entries(radiusFactor).map(([name, factor]) => [name, expression(factor)])\n ) as { [K in keyof typeof radiusFactor]: string }),\n full: PILL,\n} as const\n\n/** Names of every radius token. */\nexport type RadiusName = keyof typeof radius\n\nfunction resolve(factor: number): string {\n if (factor === 0) return '0rem'\n const base = Number.parseFloat(radiusBase)\n // Six places, then trailing zeros stripped: 0.5 * 1.4 is clean in decimal\n // but floating point still needs the round-trip so docs stay readable.\n return `${Number((base * factor).toFixed(6))}rem`\n}\n\nfunction expression(factor: number): string {\n if (factor === 0) return '0rem'\n if (factor === 1) return 'var(--radius)'\n return `calc(var(--radius) * ${factor})`\n}\n","/**\n * Bevels, and the two structural shadows a data table needs.\n *\n * Windows 98 has no elevation. Depth is drawn with bevels: two 1px lines on\n * each side of a box, light on the top-left and dark on the bottom-right for a\n * raised surface, the other way round for a sunken one. Each bevel here is a\n * stack of hard inset shadows — no blur, no spread — built from the four\n * `bevel-*` colours, so the frame lives inside the box and never changes its\n * size.\n *\n * The first shadow in the list paints on top, so the 1px outer edge is listed\n * before the 2px inner one it overlaps. The values match the effect styles in\n * the Figma file one for one.\n */\n\nconst hl = 'var(--color-bevel-highlight)'\nconst light = 'var(--color-bevel-light)'\nconst sh = 'var(--color-bevel-shadow)'\nconst dark = 'var(--color-bevel-dark)'\n\n/** Builds an inset bevel from its outer and inner edge colours. */\nfunction bevel(outer: [string, string], inner?: [string, string]): string {\n const [outerTopLeft, outerBottomRight] = outer\n const layers = [`inset -1px -1px ${outerBottomRight}`, `inset 1px 1px ${outerTopLeft}`]\n if (inner) {\n const [innerTopLeft, innerBottomRight] = inner\n layers.push(`inset -2px -2px ${innerBottomRight}`, `inset 2px 2px ${innerTopLeft}`)\n }\n return layers.join(', ')\n}\n\nexport const shadow = {\n /** No bevel. */\n none: 'none',\n /** Buttons and raised panels. */\n raised: bevel([hl, dark], [light, sh]),\n /** A window's frame: like `raised`, with the bright white on the inner edge. */\n window: bevel([light, dark], [hl, sh]),\n /**\n * The default button of a dialog: a 1px black frame around a raised bevel,\n * so Enter's target is visible before anyone presses it.\n */\n 'raised-default': [\n `inset -1px -1px ${dark}`,\n `inset 1px 1px ${dark}`,\n `inset -2px -2px ${dark}`,\n `inset 2px 2px ${hl}`,\n `inset -3px -3px ${sh}`,\n `inset 3px 3px ${light}`,\n ].join(', '),\n /** A button held down, or a toggle that is on. */\n pressed: bevel([dark, hl], [sh, light]),\n /** Text fields, lists and table bodies: the white well a value sits in. */\n sunken: bevel([sh, hl], [dark, light]),\n /** A thin sunken edge: status-bar sections, counters, Badge. */\n status: bevel([sh, hl]),\n /** An etched groove: group boxes and separators. */\n etched: bevel([sh, hl], [hl, sh]),\n /** A thin raised edge: a flat toolbar button while hovered. */\n 'raised-thin': bevel([hl, sh]),\n\n /** The edge of a sticky table column while rows scroll under it. */\n 'scroll-x': `inset -1px 0 ${sh}`,\n /**\n * The rule under a sticky table header, drawn as a shadow rather than a\n * border.\n *\n * Under `border-collapse` a border belongs to the table's grid, not to any\n * cell, so a `position: sticky` header leaves its border behind and scrolls\n * away from it — the rows then slide under a header with nothing between\n * them, which is the one thing a sticky header exists to prevent. A shadow\n * belongs to the element and travels with it.\n */\n 'sticky-header': 'inset 0 -1px 0 var(--color-border)',\n} as const\n\n/** Names of every shadow token. */\nexport type ShadowName = keyof typeof shadow\n\n/**\n * Text shadows. One: the emboss that makes disabled text read as disabled\n * rather than as faint — grey text with a white copy one pixel right and\n * down. Windows 98 never fades a disabled control with opacity.\n */\nexport const textShadow = {\n disabled: '1px 1px 0 var(--color-text-disabled-emboss)',\n} as const\n\n/** Names of every text shadow token. */\nexport type TextShadowName = keyof typeof textShadow\n","/**\n * Spacing scale.\n *\n * Keys are multiples of the 4px base unit, matching the convention most Vue and\n * Tailwind developers already carry in their heads: `4` is 1rem, `2` is 8px.\n * Fractional steps are deliberately absent — they would need escaped CSS custom\n * property names (`--spacing-0\\.5`), and Tailwind v4 already derives arbitrary\n * fractions from {@link spacingBase}.\n *\n * The low end is dense on purpose. A table cell padded at `2`/`3` is the\n * difference between a grid that shows twenty rows and one that shows twelve.\n */\nexport const spacing = {\n /** Zero. */\n 0: '0rem',\n /** 1px — hairline offsets and optical nudges, not layout. */\n px: '1px',\n /** 4px — icon-to-label gap. */\n 1: '0.25rem',\n /** 8px — dense table cell padding. */\n 2: '0.5rem',\n /** 12px — default table cell padding, compact control padding. */\n 3: '0.75rem',\n /** 16px — default control padding, tight card padding. */\n 4: '1rem',\n /** 20px */\n 5: '1.25rem',\n /** 24px — card padding, gap between form fields. */\n 6: '1.5rem',\n /** 32px — section spacing. */\n 8: '2rem',\n /** 40px */\n 10: '2.5rem',\n /** 48px — gap between major page regions. */\n 12: '3rem',\n /** 64px — page gutters. */\n 16: '4rem',\n /** 80px */\n 20: '5rem',\n /** 96px — empty-state vertical padding. */\n 24: '6rem',\n} as const\n\n/**\n * The base unit Tailwind v4 multiplies for dynamic spacing utilities.\n *\n * Emitting this as `--spacing` keeps `p-7` and `mt-3.5` working even though\n * neither has a named token above.\n */\nexport const spacingBase = '0.25rem'\n\n/** Names of every spacing token. */\nexport type SpacingName = keyof typeof spacing\n","/**\n * Typography.\n *\n * Two registers, as in the design: the interface, and long text for\n * documentation. The interface is set at 13px — Windows 98's 8pt in its\n * \"Large Fonts\" mode (120 DPI), which the system offered for exactly this\n * reason: at 96 DPI 8pt is 11px, and on today's screens, whose pixels are far\n * smaller than a 1998 monitor's, 11px is too small to read for long. The sizes\n * are named after the Figma text styles (`ui/body` is `text-ui`, `doc/h1` is\n * `text-doc-h1`), so a style picked in the design maps to one utility.\n *\n * Sizes are in `rem`, so a reader who raised their browser's base size gets\n * larger text; at the default 16px base they land on the design's pixels.\n */\n\n/**\n * Font families.\n *\n * The interface face is **PT Sans** (ParaType, OFL): the closest open match\n * to Tahoma, which succeeded MS Sans Serif, and compact enough for dense\n * tables. It covers Latin and Cyrillic in regular and bold. The fixed-width\n * face is **VT323** (OFL), drawn after the Fixedsys terminal font.\n *\n * rowkit does not ship either font file: the app loads them, one import each\n * from `@fontsource/pt-sans` and `@fontsource/vt323`. Without them the stacks\n * fall through to Tahoma and the faces operating systems already ship.\n */\nexport const fontFamily = {\n /** UI and body text. */\n sans: [\n '\"PT Sans\"',\n 'Tahoma',\n '\"Microsoft Sans Serif\"',\n '\"MS Sans Serif\"',\n 'Verdana',\n 'Arial',\n 'sans-serif',\n ].join(', '),\n /** Code, IDs and numbers that must align in a column. */\n mono: ['VT323', '\"Lucida Console\"', '\"Courier New\"', 'ui-monospace', 'monospace'].join(', '),\n} as const\n\n/**\n * Font sizes, each paired with the line height the design sets it in.\n *\n * Pairing them prevents the most common typographic bug in a dense table:\n * changing the size without the leading, so rows stay tall and the density\n * the size was meant to buy evaporates.\n */\nexport const fontSize = {\n /** 13/16 — every control, label, menu and table cell. Bold for titles and the default button. */\n ui: { size: '0.8125rem', lineHeight: '1rem' },\n /** 16/20, bold — the heading of an empty state or a group. */\n heading: { size: '1rem', lineHeight: '1.25rem' },\n /**\n * 16/16 — the fixed-width face beside interface text. VT323's x-height is\n * 0.4em to PT Sans's 0.5em, so 16px VT323 stands exactly as tall as 13px\n * PT Sans.\n */\n mono: { size: '1rem', lineHeight: '1rem' },\n /** 16/26 — documentation paragraphs, about seventy characters to a line. */\n doc: { size: '1rem', lineHeight: '1.625rem' },\n /** 20/20 — code beside documentation text: as tall as 16px PT Sans, for the same reason as `mono`. */\n 'doc-mono': { size: '1.25rem', lineHeight: '1.25rem' },\n /** 26/30, bold — a documentation page title. */\n 'doc-h1': { size: '1.625rem', lineHeight: '1.875rem' },\n /** 19/24, bold — a documentation section. */\n 'doc-h2': { size: '1.1875rem', lineHeight: '1.5rem' },\n /** 15/20, bold — a documentation subsection. */\n 'doc-h3': { size: '0.9375rem', lineHeight: '1.25rem' },\n} as const\n\n/**\n * Font weights. Two, because PT Sans has two: anything in between would be\n * synthesised by the browser, and a faked weight is blurrier than either real\n * one.\n */\nexport const fontWeight = {\n /** Body text. */\n normal: '400',\n /** Window titles, headings, the default button. */\n bold: '700',\n} as const\n\n/** Letter spacing. Windows 98 sets every size at the face's own spacing. */\nexport const letterSpacing = {\n normal: '0em',\n} as const\n\n/** Standalone line heights, for when text is not using a paired {@link fontSize}. */\nexport const lineHeight = {\n none: '1',\n tight: '1.25',\n snug: '1.375',\n normal: '1.5',\n relaxed: '1.625',\n} as const\n\n/** Names of every font size token. */\nexport type FontSizeName = keyof typeof fontSize\n","/**\n * Stacking layers.\n *\n * Spaced by 100 so a consumer can slot their own chrome — an app header, a\n * cookie banner — between two rowkit layers without editing rowkit or starting\n * a `z-index: 99999` arms race.\n *\n * The ordering is not arbitrary. A tooltip must outrank a toast, because a\n * toast can carry an action button that itself has a tooltip. A popover must\n * outrank a modal, because a select inside a dialog opens a popover.\n */\nexport const zIndex = {\n /** Default flow. */\n base: '0',\n /** Sticky table header and pinned columns. */\n sticky: '100',\n /** Dropdown menus attached to page-level content. */\n dropdown: '200',\n /** Backdrop behind a modal. */\n overlay: '300',\n /** Dialog surface. */\n modal: '400',\n /** Popovers and selects — must sit above a dialog to work inside one. */\n popover: '500',\n /** Toast queue. */\n toast: '600',\n /** Tooltips outrank everything, including toasts. */\n tooltip: '700',\n} as const\n\n/** Names of every z-index token. */\nexport type ZIndexName = keyof typeof zIndex\n","import { colorPrimitives, semanticColor } from './color'\nimport { duration, easing } from './motion'\nimport { radiusBase, radiusCss } from './radius'\nimport { shadow, textShadow } from './shadow'\nimport { spacing, spacingBase } from './spacing'\nimport { fontFamily, fontSize, fontWeight, letterSpacing, lineHeight } from './typography'\nimport { zIndex } from './z-index'\n\n/**\n * Emits the Tailwind v4 `@theme` block for the rowkit token set.\n *\n * The TypeScript objects are the single source of truth; this function derives\n * the stylesheet from them, so the two cannot drift. `css.test.ts` asserts that\n * every token in every scale reaches the output.\n *\n * There is one theme. Semantic tokens point at primitives, so a consumer\n * rebrands by repointing a semantic token rather than editing a literal colour.\n *\n * @returns The complete stylesheet, ready to write to disk.\n */\nexport function buildThemeCss(): string {\n return [\n header(),\n '',\n '@theme {',\n section('colour primitives — the only literal colours in rowkit'),\n ...entries(colorPrimitives, (k) => `--color-${k}`),\n '',\n section('semantic colours'),\n ...entries(semanticColor, (k) => `--color-${k}`),\n '',\n section('spacing'),\n ` --spacing: ${spacingBase};`,\n ...entries(spacing, (k) => `--spacing-${k}`),\n '',\n section('typography'),\n ...entries(fontFamily, (k) => `--font-${k}`),\n ...fontSizeEntries(),\n ...entries(fontWeight, (k) => `--font-weight-${k}`),\n ...entries(letterSpacing, (k) => `--tracking-${k}`),\n ...entries(lineHeight, (k) => `--leading-${k}`),\n '',\n section('radii — multiples of --radius, declared in :root below'),\n ...entries(radiusCss, (k) => `--radius-${k}`),\n '',\n section('bevels — box shadows'),\n ...entries(shadow, (k) => `--shadow-${k}`),\n ...entries(textShadow, (k) => `--text-shadow-${k}`),\n '',\n section('motion'),\n // Tailwind v4's namespaces are `--transition-duration-*` and `--ease-*`.\n // A name outside a namespace it recognises is not an error — it simply\n // generates no utility, which is why `duration-fast` silently produced\n // nothing until the compile test in packages/ui went looking for it.\n ...entries(duration, (k) => `--transition-duration-${k}`),\n ...entries(easing, (k) => `--ease-${k}`),\n '',\n section('stacking layers'),\n ...entries(zIndex, (k) => `--z-index-${k}`),\n '}',\n '',\n /*\n * Outside `@theme` on purpose.\n *\n * The radius scale is `calc(var(--radius) * f)`, so `--radius` has to\n * resolve wherever a `rounded-*` utility lands. Tailwind only emits the\n * theme variables its generated utilities reference, and nothing generates\n * a utility from a bare `--radius` — left inside `@theme` it can be dropped,\n * and every `calc()` above then references an undefined variable. That is\n * not an error in CSS: `border-radius` simply computes to nothing and every\n * corner in the library goes square, with no warning anywhere.\n *\n * Declaring it here also makes it the documented override point: a consumer\n * sets `--radius` once and the whole scale follows.\n */\n '/* The one length the radius scale multiplies. Override to retune every corner. */',\n ':root {',\n ` --radius: ${radiusBase};`,\n '}',\n '',\n ].join('\\n')\n}\n\nfunction header(): string {\n return [\n '/*',\n ' * rowkit design tokens.',\n ' *',\n ' * GENERATED FILE — DO NOT EDIT.',\n ' * Source of truth: packages/tokens/src/*.ts',\n ' * Regenerate with: pnpm --filter @rowkit/tokens build',\n ' */',\n ].join('\\n')\n}\n\nfunction section(label: string): string {\n return ` /* ${label} */`\n}\n\n/** Renders `key: value` pairs as indented custom property declarations. */\nfunction entries(scale: Record<string, string>, toVar: (key: string) => string): string[] {\n return Object.entries(scale).map(([key, value]) => ` ${toVar(key)}: ${value};`)\n}\n\n/**\n * Font sizes use Tailwind v4's paired form, where `--text-sm--line-height`\n * supplies the leading that ships with `text-sm`.\n */\nfunction fontSizeEntries(): string[] {\n return Object.entries(fontSize).flatMap(([key, value]) => [\n ` --text-${key}: ${value.size};`,\n ` --text-${key}--line-height: ${value.lineHeight};`,\n ])\n}\n","/**\n * `@rowkit/tokens` — the design token layer behind rowkit.\n *\n * Consumable on its own: import {@link tokens} for a fully typed object, or\n * `@rowkit/tokens/css` for the Tailwind v4 `@theme` block. Nothing here depends\n * on Vue, so a design tool, a docs site, or a chart library can read the same\n * values the components use.\n *\n * @example Typed access to a primitive\n * ```ts\n * import { tokens } from '@rowkit/tokens'\n * tokens.color.vga.silver // '#c0c0c0' — the face of every window\n * ```\n *\n * @example The stylesheet\n * ```css\n * @import 'tailwindcss';\n * @import '@rowkit/tokens/css';\n * ```\n */\n\nimport { version as pkgVersion } from '../package.json' with { type: 'json' }\nimport { colorPrimitives, semanticColor, vga, win98 } from './color'\nimport { duration, easing } from './motion'\nimport { radius, radiusBase } from './radius'\nimport { shadow, textShadow } from './shadow'\nimport { spacing, spacingBase } from './spacing'\nimport { fontFamily, fontSize, fontWeight, letterSpacing, lineHeight } from './typography'\nimport { zIndex } from './z-index'\n\nexport { colorPrimitives, semanticColor, vga, win98 } from './color'\nexport type { ColorRef, SemanticColorName } from './color'\n\nexport { duration, easing } from './motion'\nexport type { DurationName, EasingName } from './motion'\n\nexport { radius, radiusBase } from './radius'\nexport type { RadiusName } from './radius'\n\nexport { shadow, textShadow } from './shadow'\nexport type { ShadowName, TextShadowName } from './shadow'\n\nexport { spacing, spacingBase } from './spacing'\nexport type { SpacingName } from './spacing'\n\nexport { fontFamily, fontSize, fontWeight, letterSpacing, lineHeight } from './typography'\nexport type { FontSizeName } from './typography'\n\nexport { zIndex } from './z-index'\nexport type { ZIndexName } from './z-index'\n\nexport { buildThemeCss } from './css'\n\n/**\n * Every rowkit token in one object.\n *\n * Grouped by scale rather than flattened, so `tokens.color.vga.navy` narrows\n * to its literal type and autocompletes each level.\n */\nexport const tokens = {\n color: {\n /** The VGA palette Windows 98 is drawn in. */\n vga,\n /** The system colours Windows 98 added to it. */\n win98,\n /** Flat map of every primitive, keyed by CSS custom property suffix. */\n primitives: colorPrimitives,\n /** Semantic tokens, which reference primitives via `var()`. */\n semantic: semanticColor,\n },\n spacing,\n spacingBase,\n font: {\n family: fontFamily,\n size: fontSize,\n weight: fontWeight,\n letterSpacing,\n lineHeight,\n },\n radius,\n radiusBase,\n shadow,\n textShadow,\n zIndex,\n motion: {\n duration,\n easing,\n },\n} as const\n\n/** The shape of {@link tokens}. */\nexport type Tokens = typeof tokens\n\n/**\n * The `@rowkit/tokens` version this build was produced from.\n *\n * Read from `package.json` rather than written out. A literal here went stale\n * the moment Changesets bumped the manifest — it edits `package.json` and\n * nothing was updating the constant, so the first release broke its own test.\n * Rollup tree-shakes the JSON down to this one string, so nothing else ships.\n */\nexport const version: string = pkgVersion\n"],"mappings":"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"}
|
package/dist/radius.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* declaration retunes every corner in the library:
|
|
6
6
|
*
|
|
7
7
|
* ```css
|
|
8
|
-
* :root { --radius: 0.
|
|
8
|
+
* :root { --radius: 0.25rem; }
|
|
9
9
|
* ```
|
|
10
10
|
*
|
|
11
11
|
* The factors are the source of truth, not the resulting lengths. Two things
|
|
@@ -17,30 +17,28 @@
|
|
|
17
17
|
/**
|
|
18
18
|
* The single length the scale multiplies.
|
|
19
19
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
20
|
+
* Zero: Windows 98 has no rounded corners, and every `radius/*` token in the
|
|
21
|
+
* design is 0. The scale is kept rather than deleted so that corners stay one
|
|
22
|
+
* decision away — set `--radius` in a consumer and every control follows,
|
|
23
|
+
* without touching a component.
|
|
23
24
|
*/
|
|
24
|
-
export declare const radiusBase = "
|
|
25
|
+
export declare const radiusBase = "0rem";
|
|
25
26
|
/**
|
|
26
|
-
* Multiples of `--radius`.
|
|
27
|
-
*
|
|
28
|
-
* `sm`/`md`/`lg`/`xl` keep the same factors as the reference scale. `xs` is
|
|
29
|
-
* rowkit's, and lands on ~3px — the radius used on checkboxes and chip remove
|
|
30
|
-
* targets inside dense table chrome.
|
|
27
|
+
* Multiples of `--radius`. All of them compute to 0 with the default base;
|
|
28
|
+
* the factors decide how a consumer's own `--radius` spreads across controls.
|
|
31
29
|
*/
|
|
32
30
|
export declare const radiusFactor: {
|
|
33
|
-
/**
|
|
31
|
+
/** Always square, whatever `--radius` is: table cells, anything that tiles. */
|
|
34
32
|
readonly none: 0;
|
|
35
|
-
/**
|
|
33
|
+
/** Checkboxes and tags inside a cell. */
|
|
36
34
|
readonly xs: 0.4;
|
|
37
|
-
/**
|
|
35
|
+
/** Badges and small controls. */
|
|
38
36
|
readonly sm: 0.6;
|
|
39
|
-
/**
|
|
37
|
+
/** Buttons, inputs and panels. */
|
|
40
38
|
readonly md: 0.8;
|
|
41
|
-
/**
|
|
39
|
+
/** Windows, dialogs and popovers. */
|
|
42
40
|
readonly lg: 1;
|
|
43
|
-
/**
|
|
41
|
+
/** Large empty-state panels. */
|
|
44
42
|
readonly xl: 1.4;
|
|
45
43
|
};
|
|
46
44
|
/**
|
|
@@ -48,7 +46,7 @@ export declare const radiusFactor: {
|
|
|
48
46
|
* an actual size in the docs table.
|
|
49
47
|
*/
|
|
50
48
|
export declare const radius: {
|
|
51
|
-
/**
|
|
49
|
+
/** Circle. The only rounded shape Windows 98 draws: radio buttons, and a round skeleton. */
|
|
52
50
|
readonly full: "9999px";
|
|
53
51
|
readonly none: string;
|
|
54
52
|
readonly xs: string;
|
package/dist/shadow.d.ts
CHANGED
|
@@ -1,29 +1,41 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Bevels, and the two structural shadows a data table needs.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Windows 98 has no elevation. Depth is drawn with bevels: two 1px lines on
|
|
5
|
+
* each side of a box, light on the top-left and dark on the bottom-right for a
|
|
6
|
+
* raised surface, the other way round for a sunken one. Each bevel here is a
|
|
7
|
+
* stack of hard inset shadows — no blur, no spread — built from the four
|
|
8
|
+
* `bevel-*` colours, so the frame lives inside the box and never changes its
|
|
9
|
+
* size.
|
|
7
10
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
+
* The first shadow in the list paints on top, so the 1px outer edge is listed
|
|
12
|
+
* before the 2px inner one it overlaps. The values match the effect styles in
|
|
13
|
+
* the Figma file one for one.
|
|
11
14
|
*/
|
|
12
15
|
export declare const shadow: {
|
|
13
|
-
/** No
|
|
16
|
+
/** No bevel. */
|
|
14
17
|
readonly none: "none";
|
|
15
|
-
/**
|
|
16
|
-
readonly
|
|
17
|
-
/**
|
|
18
|
-
readonly
|
|
19
|
-
/**
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
18
|
+
/** Buttons and raised panels. */
|
|
19
|
+
readonly raised: string;
|
|
20
|
+
/** A window's frame: like `raised`, with the bright white on the inner edge. */
|
|
21
|
+
readonly window: string;
|
|
22
|
+
/**
|
|
23
|
+
* The default button of a dialog: a 1px black frame around a raised bevel,
|
|
24
|
+
* so Enter's target is visible before anyone presses it.
|
|
25
|
+
*/
|
|
26
|
+
readonly 'raised-default': string;
|
|
27
|
+
/** A button held down, or a toggle that is on. */
|
|
28
|
+
readonly pressed: string;
|
|
29
|
+
/** Text fields, lists and table bodies: the white well a value sits in. */
|
|
30
|
+
readonly sunken: string;
|
|
31
|
+
/** A thin sunken edge: status-bar sections, counters, Badge. */
|
|
32
|
+
readonly status: string;
|
|
33
|
+
/** An etched groove: group boxes and separators. */
|
|
34
|
+
readonly etched: string;
|
|
35
|
+
/** A thin raised edge: a flat toolbar button while hovered. */
|
|
36
|
+
readonly 'raised-thin': string;
|
|
37
|
+
/** The edge of a sticky table column while rows scroll under it. */
|
|
38
|
+
readonly 'scroll-x': "inset -1px 0 var(--color-bevel-shadow)";
|
|
27
39
|
/**
|
|
28
40
|
* The rule under a sticky table header, drawn as a shadow rather than a
|
|
29
41
|
* border.
|
|
@@ -38,3 +50,13 @@ export declare const shadow: {
|
|
|
38
50
|
};
|
|
39
51
|
/** Names of every shadow token. */
|
|
40
52
|
export type ShadowName = keyof typeof shadow;
|
|
53
|
+
/**
|
|
54
|
+
* Text shadows. One: the emboss that makes disabled text read as disabled
|
|
55
|
+
* rather than as faint — grey text with a white copy one pixel right and
|
|
56
|
+
* down. Windows 98 never fades a disabled control with opacity.
|
|
57
|
+
*/
|
|
58
|
+
export declare const textShadow: {
|
|
59
|
+
readonly disabled: "1px 1px 0 var(--color-text-disabled-emboss)";
|
|
60
|
+
};
|
|
61
|
+
/** Names of every text shadow token. */
|
|
62
|
+
export type TextShadowName = keyof typeof textShadow;
|