@nomosui/react 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +65 -0
  3. package/SKILL.md +166 -0
  4. package/dist/index.js +4591 -0
  5. package/dist/mcp/bin.js +46371 -0
  6. package/dist/types/catalogue/contract.d.ts +78 -0
  7. package/dist/types/catalogue/registry.d.ts +33 -0
  8. package/dist/types/components/alert/alert.d.ts +30 -0
  9. package/dist/types/components/alert/manifest.d.ts +3 -0
  10. package/dist/types/components/badge/badge.d.ts +25 -0
  11. package/dist/types/components/badge/manifest.d.ts +7 -0
  12. package/dist/types/components/button/button.d.ts +38 -0
  13. package/dist/types/components/button/manifest.d.ts +7 -0
  14. package/dist/types/components/card/card.d.ts +12 -0
  15. package/dist/types/components/card/manifest.d.ts +3 -0
  16. package/dist/types/components/checkbox/checkbox.d.ts +4 -0
  17. package/dist/types/components/checkbox/manifest.d.ts +3 -0
  18. package/dist/types/components/chip/chip.d.ts +36 -0
  19. package/dist/types/components/chip/manifest.d.ts +3 -0
  20. package/dist/types/components/counter/counter.d.ts +14 -0
  21. package/dist/types/components/counter/manifest.d.ts +3 -0
  22. package/dist/types/components/data-table-pagination/data-table-pagination.d.ts +20 -0
  23. package/dist/types/components/data-table-pagination/manifest.d.ts +3 -0
  24. package/dist/types/components/data-table-toolbar/data-table-toolbar.d.ts +34 -0
  25. package/dist/types/components/data-table-toolbar/manifest.d.ts +3 -0
  26. package/dist/types/components/empty-state/empty-state.d.ts +23 -0
  27. package/dist/types/components/empty-state/manifest.d.ts +3 -0
  28. package/dist/types/components/facet-filter/facet-filter.d.ts +23 -0
  29. package/dist/types/components/facet-filter/manifest.d.ts +6 -0
  30. package/dist/types/components/field/field.d.ts +15 -0
  31. package/dist/types/components/field/manifest.d.ts +3 -0
  32. package/dist/types/components/fieldset/fieldset.d.ts +3 -0
  33. package/dist/types/components/fieldset/manifest.d.ts +3 -0
  34. package/dist/types/components/form/form.d.ts +14 -0
  35. package/dist/types/components/form/manifest.d.ts +3 -0
  36. package/dist/types/components/freshness/freshness.d.ts +18 -0
  37. package/dist/types/components/freshness/manifest.d.ts +7 -0
  38. package/dist/types/components/input/input.d.ts +6 -0
  39. package/dist/types/components/input/manifest.d.ts +6 -0
  40. package/dist/types/components/label/label.d.ts +3 -0
  41. package/dist/types/components/label/manifest.d.ts +3 -0
  42. package/dist/types/components/meter/manifest.d.ts +6 -0
  43. package/dist/types/components/meter/meter.d.ts +23 -0
  44. package/dist/types/components/number-field/manifest.d.ts +3 -0
  45. package/dist/types/components/number-field/number-field.d.ts +7 -0
  46. package/dist/types/components/progress-bar/manifest.d.ts +3 -0
  47. package/dist/types/components/progress-bar/progress-bar.d.ts +12 -0
  48. package/dist/types/components/radio/manifest.d.ts +3 -0
  49. package/dist/types/components/radio/radio.d.ts +5 -0
  50. package/dist/types/components/rating/manifest.d.ts +3 -0
  51. package/dist/types/components/rating/rating.d.ts +19 -0
  52. package/dist/types/components/search-field/manifest.d.ts +3 -0
  53. package/dist/types/components/search-field/search-field.d.ts +14 -0
  54. package/dist/types/components/separator/manifest.d.ts +3 -0
  55. package/dist/types/components/separator/separator.d.ts +7 -0
  56. package/dist/types/components/skeleton/manifest.d.ts +3 -0
  57. package/dist/types/components/skeleton/skeleton.d.ts +3 -0
  58. package/dist/types/components/switch/manifest.d.ts +3 -0
  59. package/dist/types/components/switch/switch.d.ts +4 -0
  60. package/dist/types/components/table/manifest.d.ts +7 -0
  61. package/dist/types/components/table/table.d.ts +14 -0
  62. package/dist/types/components/textarea/manifest.d.ts +3 -0
  63. package/dist/types/components/textarea/textarea.d.ts +3 -0
  64. package/dist/types/components/timeline/manifest.d.ts +3 -0
  65. package/dist/types/components/timeline/timeline.d.ts +19 -0
  66. package/dist/types/components/toast/manifest.d.ts +3 -0
  67. package/dist/types/components/toast/toast.d.ts +35 -0
  68. package/dist/types/components/toggle/manifest.d.ts +3 -0
  69. package/dist/types/components/toggle/toggle.d.ts +31 -0
  70. package/dist/types/components/toggle-group/manifest.d.ts +6 -0
  71. package/dist/types/components/toggle-group/toggle-group.d.ts +8 -0
  72. package/dist/types/components/tree/manifest.d.ts +7 -0
  73. package/dist/types/components/tree/tree.d.ts +42 -0
  74. package/dist/types/features/data-table-features.d.ts +29 -0
  75. package/dist/types/features/faceted-data-table.d.ts +99 -0
  76. package/dist/types/features/toast.d.ts +33 -0
  77. package/dist/types/index.d.ts +112 -0
  78. package/dist/types/internal/dropdown-menu.d.ts +27 -0
  79. package/dist/types/internal/select.d.ts +13 -0
  80. package/dist/types/internal/sheet.d.ts +25 -0
  81. package/dist/types/internal/tooltip.d.ts +7 -0
  82. package/dist/types/lib/cn.d.ts +6 -0
  83. package/dist/types/lib/tone.d.ts +12 -0
  84. package/dist/types/tokens/build.d.mts +68 -0
  85. package/dist/types/tokens/resource.d.ts +8 -0
  86. package/dist/types/tokens/skin.d.ts +9 -0
  87. package/package.json +107 -0
  88. package/scripts/install-skill.mjs +28 -0
  89. package/tokens/theme.css +63 -0
  90. package/tokens/tokens.generated.css +271 -0
  91. package/tokens/tokens.json +225 -0
  92. package/tokens/tokens.resource.json +138 -0
@@ -0,0 +1,25 @@
1
+ import * as React from "react";
2
+ import * as SheetPrimitive from "@radix-ui/react-dialog";
3
+ import { type VariantProps } from "class-variance-authority";
4
+ declare const Sheet: React.FC<SheetPrimitive.DialogProps>;
5
+ declare const SheetTrigger: React.ForwardRefExoticComponent<SheetPrimitive.DialogTriggerProps & React.RefAttributes<HTMLButtonElement>>;
6
+ declare const SheetClose: React.ForwardRefExoticComponent<SheetPrimitive.DialogCloseProps & React.RefAttributes<HTMLButtonElement>>;
7
+ declare const SheetPortal: React.FC<SheetPrimitive.DialogPortalProps>;
8
+ declare const SheetOverlay: React.ForwardRefExoticComponent<Omit<SheetPrimitive.DialogOverlayProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
9
+ declare const sheetVariants: (props?: ({
10
+ side?: "top" | "right" | "bottom" | "left" | null | undefined;
11
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
12
+ interface SheetContentProps extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>, VariantProps<typeof sheetVariants> {
13
+ }
14
+ declare const SheetContent: React.ForwardRefExoticComponent<SheetContentProps & React.RefAttributes<HTMLDivElement>>;
15
+ declare const SheetHeader: {
16
+ ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): React.JSX.Element;
17
+ displayName: string;
18
+ };
19
+ declare const SheetFooter: {
20
+ ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): React.JSX.Element;
21
+ displayName: string;
22
+ };
23
+ declare const SheetTitle: React.ForwardRefExoticComponent<Omit<SheetPrimitive.DialogTitleProps & React.RefAttributes<HTMLHeadingElement>, "ref"> & React.RefAttributes<HTMLHeadingElement>>;
24
+ declare const SheetDescription: React.ForwardRefExoticComponent<Omit<SheetPrimitive.DialogDescriptionProps & React.RefAttributes<HTMLParagraphElement>, "ref"> & React.RefAttributes<HTMLParagraphElement>>;
25
+ export { Sheet, SheetPortal, SheetOverlay, SheetTrigger, SheetClose, SheetContent, SheetHeader, SheetFooter, SheetTitle, SheetDescription, };
@@ -0,0 +1,7 @@
1
+ import * as React from "react";
2
+ import * as TooltipPrimitive from "@radix-ui/react-tooltip";
3
+ declare const TooltipProvider: React.FC<TooltipPrimitive.TooltipProviderProps>;
4
+ declare const Tooltip: React.FC<TooltipPrimitive.TooltipProps>;
5
+ declare const TooltipTrigger: React.ForwardRefExoticComponent<TooltipPrimitive.TooltipTriggerProps & React.RefAttributes<HTMLButtonElement>>;
6
+ declare const TooltipContent: React.ForwardRefExoticComponent<Omit<TooltipPrimitive.TooltipContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
7
+ export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
@@ -0,0 +1,6 @@
1
+ import { type ClassValue } from 'clsx';
2
+ /**
3
+ * Le `cn` du cœur. Il vit ici et pas dans l'app : un composant du design system ne
4
+ * peut pas dépendre d'un utilitaire qui appartient au dashboard.
5
+ */
6
+ export declare const cn: (...inputs: ClassValue[]) => string;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Le vocabulaire de tons du cœur : sept **intentions**, pas sept couleurs. Un badge de
3
+ * statut choisit l'intention (« danger », « succès »), et c'est le cœur qui sait la
4
+ * rendre — l'app ne manipule plus un nom de couleur.
5
+ *
6
+ * Chaque ton lit deux emplacements sémantiques (`status-<ton>` pour la surface, lue à
7
+ * faible opacité, et `status-<ton>-ink` pour l'encre) : c'est le token qui porte le
8
+ * mode, pas la classe, donc le cœur ne connaît jamais le mode (ADR 0004, garde des tokens).
9
+ */
10
+ export declare const TONES: readonly ["neutral", "info", "progress", "attention", "warning", "danger", "success"];
11
+ export type Tone = (typeof TONES)[number];
12
+ export declare const toneClasses: Record<Tone, string>;
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Les types de la dérivation des tokens (ADR 0004). Le module lui-même est en
3
+ * JavaScript (`.mjs`) : il est exécuté par le CLI en Node sans étape de compilation,
4
+ * donc ses types vivent ici, à côté — même convention que `scripts/api-lib.d.mts`.
5
+ */
6
+
7
+ /** Un token DTCG tel qu'il vit dans `tokens.json`. */
8
+ export interface Token {
9
+ $type: string
10
+ $value: unknown
11
+ $description?: string
12
+ }
13
+
14
+ export interface TokensDocument {
15
+ $description?: string
16
+ $extensions?: Record<string, Record<string, unknown>>
17
+ primitive?: Record<string, unknown>
18
+ semantic?: Record<string, unknown>
19
+ }
20
+
21
+ export interface TokensResource {
22
+ $description: string
23
+ namespace: string
24
+ defaultMode: string
25
+ modes: string[]
26
+ densities: Record<string, number>
27
+ defaultDensity: string
28
+ slots: Record<string, Record<string, string>>
29
+ }
30
+
31
+ /** Les modes déclarés par la source (`$extensions["org.nomos"].modes`). */
32
+ export function modes(doc: TokensDocument): string[]
33
+
34
+ /** Le mode par défaut, qui doit être l'un des modes déclarés. */
35
+ export function defaultMode(doc: TokensDocument): string
36
+
37
+ /** Les densités déclarées (ADR 0008) : un nom et son multiplicateur d'espacement. */
38
+ export function densities(doc: TokensDocument): Record<string, number>
39
+
40
+ /** La densité par défaut, qui doit être l'une des densités déclarées. */
41
+ export function defaultDensity(doc: TokensDocument): string
42
+
43
+ /** Les primitives aplaties, `chemin -> token`. */
44
+ export function primitives(doc: TokensDocument): Map<string, Token>
45
+
46
+ /** Les emplacements sémantiques aplatis, `chemin -> token`. */
47
+ export function semanticTokens(doc: TokensDocument): Map<string, Token>
48
+
49
+ /** Tous les tokens du document, aplatis depuis sa racine (résolution des alias). */
50
+ export function allTokens(doc: TokensDocument): Map<string, Token>
51
+
52
+ /** Résout un emplacement pour un mode, en suivant les alias jusqu'au bout. */
53
+ export function resolve(doc: TokensDocument, path: string, mode: string): unknown
54
+
55
+ /** Rend une valeur DTCG en texte CSS. Le type n'est requis que pour un tableau. */
56
+ export function cssValue(value: unknown, type?: string): string
57
+
58
+ /** Le nom de la custom property d'un emplacement sémantique. */
59
+ export function cssName(path: string, namespace: string): string
60
+
61
+ /** Les emplacements d'un mode, `nom CSS -> valeur`. */
62
+ export function slotsFor(doc: TokensDocument, mode: string): Record<string, string>
63
+
64
+ /** L'inventaire plat que le serveur MCP du design system servira. */
65
+ export function buildResource(doc: TokensDocument): TokensResource
66
+
67
+ /** Le CSS dérivé, en entier. */
68
+ export function renderCss(doc: TokensDocument): string
@@ -0,0 +1,8 @@
1
+ import type { TokensResource } from './build.mjs';
2
+ /**
3
+ * La ressource de tokens, servie telle quelle à la page de style (et, plus tard, au
4
+ * serveur MCP). C'est le rendu dérivé de `tokens/tokens.json` par
5
+ * `npm run tokens` — ne pas l'éditer à la main : le test des tokens échoue si le
6
+ * fichier committé n'est plus celui que la source produit.
7
+ */
8
+ export declare const tokensResource: TokensResource;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Le contrat de skin (ADR 0022) : un skin est un **overlay sémantique** posé par-dessus le
3
+ * défaut du cœur. La fusion est pure et bruyante — un emplacement **absent** hérite du
4
+ * défaut, un emplacement **inconnu** lève (l'interface de thème est celle du défaut), et un
5
+ * skin qui porterait une `primitive` lève aussi : le cœur garde les valeurs brutes.
6
+ */
7
+ type Doc = Record<string, unknown>;
8
+ export declare function resolveSkin(defaultDoc: Doc, overlay?: Doc): Doc;
9
+ export {};
package/package.json ADDED
@@ -0,0 +1,107 @@
1
+ {
2
+ "name": "@nomosui/react",
3
+ "private": false,
4
+ "version": "0.4.0",
5
+ "type": "module",
6
+ "description": "An app-agnostic design system, built in public: a core of tokens and components exposed to humans and agents.",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/PierreTsia/nomos.git"
10
+ },
11
+ "publishConfig": {
12
+ "registry": "https://registry.npmjs.org",
13
+ "access": "public"
14
+ },
15
+ "exports": {
16
+ ".": {
17
+ "types": "./dist/types/index.d.ts",
18
+ "source": "./src/index.ts",
19
+ "import": "./dist/index.js",
20
+ "default": "./dist/index.js"
21
+ },
22
+ "./tokens/theme.css": "./tokens/theme.css",
23
+ "./tokens/tokens.generated.css": "./tokens/tokens.generated.css",
24
+ "./tokens/tokens.json": "./tokens/tokens.json"
25
+ },
26
+ "files": [
27
+ "dist",
28
+ "tokens",
29
+ "SKILL.md",
30
+ "README.md",
31
+ "scripts/install-skill.mjs"
32
+ ],
33
+ "bin": {
34
+ "nomos-mcp": "./dist/mcp/bin.js",
35
+ "nomos-skill": "./scripts/install-skill.mjs"
36
+ },
37
+ "scripts": {
38
+ "mcp": "tsx src/mcp/bin.ts",
39
+ "test": "vitest run",
40
+ "test:watch": "vitest",
41
+ "lint": "eslint .",
42
+ "typecheck": "tsc -p tsconfig.json --noEmit",
43
+ "tokens": "node scripts/build-tokens.mjs",
44
+ "tokens:check": "node scripts/build-tokens.mjs --check",
45
+ "build:view": "node scripts/build-view.mjs",
46
+ "view:check": "node scripts/build-view.mjs --check",
47
+ "build:view-css": "node scripts/build-view-css.mjs",
48
+ "view-css:check": "node scripts/build-view-css.mjs --check",
49
+ "build:surface": "tsx scripts/build-surface.ts",
50
+ "surface:check": "tsx scripts/build-surface.ts --check",
51
+ "build:package": "node scripts/build-package.mjs",
52
+ "prepublishOnly": "npm run build:package",
53
+ "smoke:consumer": "node scripts/smoke-consumer.mjs",
54
+ "changeset": "changeset",
55
+ "release": "changeset publish"
56
+ },
57
+ "dependencies": {
58
+ "@modelcontextprotocol/sdk": "^1.31.0",
59
+ "@radix-ui/react-checkbox": "^1.3.11",
60
+ "@radix-ui/react-dialog": "^1.1.23",
61
+ "@radix-ui/react-dropdown-menu": "^2.1.24",
62
+ "@radix-ui/react-radio-group": "^1.4.7",
63
+ "@radix-ui/react-select": "^2.3.7",
64
+ "@radix-ui/react-separator": "^1.1.15",
65
+ "@radix-ui/react-slot": "^1.3.3",
66
+ "@radix-ui/react-switch": "^1.3.7",
67
+ "@radix-ui/react-toggle": "^1.1.18",
68
+ "@radix-ui/react-toggle-group": "^1.1.19",
69
+ "@radix-ui/react-tooltip": "^1.2.16",
70
+ "@tanstack/react-table": "^9.2.4",
71
+ "class-variance-authority": "^0.7.1",
72
+ "clsx": "^2.1.1",
73
+ "lucide-react": "^0.548.0",
74
+ "tailwind-merge": "^3.7.0",
75
+ "zod": "^4.6.5"
76
+ },
77
+ "devDependencies": {
78
+ "@changesets/cli": "^3.0.3",
79
+ "@eslint/js": "^10.0.1",
80
+ "@tailwindcss/postcss": "^4.3.3",
81
+ "@testing-library/jest-dom": "^7.0.1",
82
+ "@testing-library/react": "^16.3.3",
83
+ "@testing-library/user-event": "^14.6.7",
84
+ "@types/node": "^26.6.2",
85
+ "@types/react": "^19.3.0",
86
+ "@types/react-dom": "^19.3.0",
87
+ "@vitejs/plugin-react": "^6.1.1",
88
+ "eslint": "^10.11.0",
89
+ "eslint-plugin-react-hooks": "^7.1.1",
90
+ "eslint-plugin-react-refresh": "^0.5.6",
91
+ "globals": "^17.12.0",
92
+ "jsdom": "^30.1.1",
93
+ "postcss": "^8.5.28",
94
+ "react": "^19.3.0",
95
+ "react-dom": "^19.3.0",
96
+ "tailwindcss": "^4.3.3",
97
+ "tsx": "^4.23.15",
98
+ "typescript": "~6.0.3",
99
+ "typescript-eslint": "~8.70.0",
100
+ "vite": "^8.3.0",
101
+ "vitest": "^5.0.1"
102
+ },
103
+ "peerDependencies": {
104
+ "react": "^19.0.0",
105
+ "react-dom": "^19.0.0"
106
+ }
107
+ }
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Installe la skill « nomos » livrée avec le paquet (#54) : copie son `SKILL.md` là où un
4
+ * hôte lit ses skills. Par défaut `~/.claude/skills/nomos` ; `--dir <dossier>` pour un
5
+ * autre hôte (opencode, etc.).
6
+ */
7
+ import { copyFileSync, mkdirSync } from 'node:fs'
8
+ import os from 'node:os'
9
+ import path from 'node:path'
10
+ import { fileURLToPath } from 'node:url'
11
+
12
+ const here = path.dirname(fileURLToPath(import.meta.url))
13
+ const source = path.resolve(here, '..', 'SKILL.md')
14
+
15
+ const args = process.argv.slice(2)
16
+ const dirIndex = args.indexOf('--dir')
17
+ const targetDir =
18
+ dirIndex >= 0 ? args[dirIndex + 1] : path.join(os.homedir(), '.claude', 'skills', 'nomos')
19
+
20
+ if (!targetDir) {
21
+ console.error('usage : nomos-skill [--dir <dossier>]')
22
+ process.exit(1)
23
+ }
24
+
25
+ mkdirSync(targetDir, { recursive: true })
26
+ const dest = path.join(targetDir, 'SKILL.md')
27
+ copyFileSync(source, dest)
28
+ console.log(`Skill « nomos » installée : ${dest}`)
@@ -0,0 +1,63 @@
1
+ /*
2
+ * Le raccord Tailwind → tokens du cœur (ADR 0003, 0022) : des noms, aucune valeur.
3
+ * Les valeurs vivent dans `tokens.generated.css`, dérivé de `tokens.json` (ADR 0004).
4
+ * App-agnostique : un skin (ADR 0022) change les **valeurs**, jamais ces noms.
5
+ *
6
+ * L'app l'importe (`src/styles/globals.css`) et le build des vues l'inline
7
+ * (`src/mcp/view.css`) : une seule définition du raccord, deux rendus.
8
+ */
9
+ @theme {
10
+ /*
11
+ La densité (ADR 0008) multiplie l'échelle d'espacement : toutes les marges, tous les
12
+ paddings, toutes les hauteurs et les tailles d'icône que Tailwind dérive de
13
+ `--spacing` suivent `--nomos-density`. Les composants n'ont aucun nombre propre à
14
+ changer, et le mode se pose sur la racine (`data-density`), donc il est scopable.
15
+ */
16
+ --spacing: calc(0.25rem * var(--nomos-density, 1));
17
+
18
+ --color-border: hsl(var(--nomos-color-border));
19
+ --color-input: hsl(var(--nomos-color-input));
20
+ --color-ring: hsl(var(--nomos-color-ring));
21
+ --color-background: hsl(var(--nomos-color-background));
22
+ --color-foreground: hsl(var(--nomos-color-foreground));
23
+
24
+ --color-primary: hsl(var(--nomos-color-primary));
25
+ --color-primary-foreground: hsl(var(--nomos-color-primary-foreground));
26
+
27
+ --color-secondary: hsl(var(--nomos-color-secondary));
28
+ --color-secondary-foreground: hsl(var(--nomos-color-secondary-foreground));
29
+
30
+ --color-destructive: hsl(var(--nomos-color-destructive));
31
+ --color-destructive-foreground: hsl(var(--nomos-color-destructive-foreground));
32
+
33
+ --color-muted: hsl(var(--nomos-color-muted));
34
+ --color-muted-foreground: hsl(var(--nomos-color-muted-foreground));
35
+
36
+ --color-accent: hsl(var(--nomos-color-accent));
37
+ --color-accent-foreground: hsl(var(--nomos-color-accent-foreground));
38
+
39
+ --color-popover: hsl(var(--nomos-color-popover));
40
+ --color-popover-foreground: hsl(var(--nomos-color-popover-foreground));
41
+
42
+ --color-card: hsl(var(--nomos-color-card));
43
+ --color-card-foreground: hsl(var(--nomos-color-card-foreground));
44
+
45
+ --color-brand: var(--nomos-color-brand);
46
+
47
+ --color-status-info: hsl(var(--nomos-color-status-info));
48
+ --color-status-info-ink: hsl(var(--nomos-color-status-info-ink));
49
+ --color-status-progress: hsl(var(--nomos-color-status-progress));
50
+ --color-status-progress-ink: hsl(var(--nomos-color-status-progress-ink));
51
+ --color-status-attention: hsl(var(--nomos-color-status-attention));
52
+ --color-status-attention-ink: hsl(var(--nomos-color-status-attention-ink));
53
+ --color-status-warning: hsl(var(--nomos-color-status-warning));
54
+ --color-status-warning-ink: hsl(var(--nomos-color-status-warning-ink));
55
+ --color-status-danger: hsl(var(--nomos-color-status-danger));
56
+ --color-status-danger-ink: hsl(var(--nomos-color-status-danger-ink));
57
+ --color-status-success: hsl(var(--nomos-color-status-success));
58
+ --color-status-success-ink: hsl(var(--nomos-color-status-success-ink));
59
+
60
+ --radius-lg: var(--nomos-radius-control);
61
+ --radius-md: var(--nomos-radius-field);
62
+ --radius-sm: var(--nomos-radius-chip);
63
+ }
@@ -0,0 +1,271 @@
1
+ /*
2
+ * Généré par scripts/build-tokens.mjs — ne pas éditer à la main.
3
+ * Source unique : tokens/tokens.json (format DTCG, ADR 0004).
4
+ * Rejouer : npm run tokens
5
+ */
6
+
7
+ @layer base {
8
+ :root {
9
+ color-scheme: dark;
10
+ --nomos-color-background: 240 7% 8%;
11
+ --nomos-color-foreground: 240 10% 94%;
12
+ --nomos-color-card: 240 17% 12%;
13
+ --nomos-color-card-foreground: 240 10% 94%;
14
+ --nomos-color-popover: 240 17% 12%;
15
+ --nomos-color-popover-foreground: 240 10% 94%;
16
+ --nomos-color-primary: 174 100% 39%;
17
+ --nomos-color-primary-foreground: 0 0% 0%;
18
+ --nomos-color-secondary: 240 8% 16%;
19
+ --nomos-color-secondary-foreground: 240 10% 94%;
20
+ --nomos-color-muted: 240 8% 19%;
21
+ --nomos-color-muted-foreground: 0 0% 60%;
22
+ --nomos-color-accent: 240 8% 16%;
23
+ --nomos-color-accent-foreground: 240 10% 94%;
24
+ --nomos-color-destructive: 0 72% 71%;
25
+ --nomos-color-destructive-foreground: 0 0% 0%;
26
+ --nomos-color-border: 240 8% 19%;
27
+ --nomos-color-input: 240 8% 19%;
28
+ --nomos-color-ring: 174 100% 39%;
29
+ --nomos-color-brand: #00c9b1;
30
+ --nomos-color-status-info: 199 89% 48%;
31
+ --nomos-color-status-info-ink: 198 93% 74%;
32
+ --nomos-color-status-progress: 258 90% 66%;
33
+ --nomos-color-status-progress-ink: 255 92% 85%;
34
+ --nomos-color-status-attention: 38 92% 50%;
35
+ --nomos-color-status-attention-ink: 46 97% 65%;
36
+ --nomos-color-status-warning: 25 95% 53%;
37
+ --nomos-color-status-warning-ink: 31 97% 72%;
38
+ --nomos-color-status-danger: 0 84% 60%;
39
+ --nomos-color-status-danger-ink: 0 94% 82%;
40
+ --nomos-color-status-success: 160 84% 39%;
41
+ --nomos-color-status-success-ink: 156 72% 67%;
42
+ --nomos-radius-pill: 9999px;
43
+ --nomos-radius-control: 0.625rem;
44
+ --nomos-radius-field: 0.5rem;
45
+ --nomos-radius-chip: 0.375rem;
46
+ --nomos-space-hairline: 2px;
47
+ --nomos-space-tight: 4px;
48
+ --nomos-space-snug: 8px;
49
+ --nomos-space-base: 12px;
50
+ --nomos-space-comfy: 16px;
51
+ --nomos-space-loose: 24px;
52
+ --nomos-space-section: 32px;
53
+ --nomos-type-size-micro: 0.6875rem;
54
+ --nomos-type-size-caption: 0.75rem;
55
+ --nomos-type-size-body: 0.875rem;
56
+ --nomos-type-size-lead: 1rem;
57
+ --nomos-type-size-title: 1.125rem;
58
+ --nomos-type-size-display: 1.5rem;
59
+ --nomos-type-leading-micro: 0.875rem;
60
+ --nomos-type-leading-caption: 1rem;
61
+ --nomos-type-leading-body: 1.25rem;
62
+ --nomos-type-leading-lead: 1.5rem;
63
+ --nomos-type-leading-title: 1.75rem;
64
+ --nomos-type-leading-display: 2rem;
65
+ --nomos-type-weight-regular: 400;
66
+ --nomos-type-weight-medium: 500;
67
+ --nomos-type-weight-strong: 600;
68
+ --nomos-type-family-sans: ui-sans-serif, system-ui, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
69
+ }
70
+
71
+ /* Aucun mode posé sur la racine : c’est le système qui décide (ADR 0009). */
72
+ @media (prefers-color-scheme: light) {
73
+ :root:not(.dark):not(.light) {
74
+ color-scheme: light;
75
+ --nomos-color-background: 0 0% 100%;
76
+ --nomos-color-foreground: 240 10% 10%;
77
+ --nomos-color-card: 0 0% 98%;
78
+ --nomos-color-card-foreground: 240 10% 10%;
79
+ --nomos-color-popover: 0 0% 100%;
80
+ --nomos-color-popover-foreground: 240 10% 10%;
81
+ --nomos-color-primary: 174 100% 35%;
82
+ --nomos-color-primary-foreground: 0 0% 100%;
83
+ --nomos-color-secondary: 240 5% 92%;
84
+ --nomos-color-secondary-foreground: 240 10% 10%;
85
+ --nomos-color-muted: 240 5% 92%;
86
+ --nomos-color-muted-foreground: 240 4% 46%;
87
+ --nomos-color-accent: 240 5% 92%;
88
+ --nomos-color-accent-foreground: 240 10% 10%;
89
+ --nomos-color-destructive: 0 72% 51%;
90
+ --nomos-color-destructive-foreground: 0 0% 100%;
91
+ --nomos-color-border: 240 6% 85%;
92
+ --nomos-color-input: 240 6% 85%;
93
+ --nomos-color-ring: 174 100% 35%;
94
+ --nomos-color-brand: #00c9b1;
95
+ --nomos-color-status-info: 199 89% 48%;
96
+ --nomos-color-status-info-ink: 201 96% 32%;
97
+ --nomos-color-status-progress: 258 90% 66%;
98
+ --nomos-color-status-progress-ink: 263 70% 50%;
99
+ --nomos-color-status-attention: 38 92% 50%;
100
+ --nomos-color-status-attention-ink: 26 90% 37%;
101
+ --nomos-color-status-warning: 25 95% 53%;
102
+ --nomos-color-status-warning-ink: 17 88% 40%;
103
+ --nomos-color-status-danger: 0 84% 60%;
104
+ --nomos-color-status-danger-ink: 0 74% 42%;
105
+ --nomos-color-status-success: 160 84% 39%;
106
+ --nomos-color-status-success-ink: 161 94% 25%;
107
+ --nomos-radius-pill: 9999px;
108
+ --nomos-radius-control: 0.625rem;
109
+ --nomos-radius-field: 0.5rem;
110
+ --nomos-radius-chip: 0.375rem;
111
+ --nomos-space-hairline: 2px;
112
+ --nomos-space-tight: 4px;
113
+ --nomos-space-snug: 8px;
114
+ --nomos-space-base: 12px;
115
+ --nomos-space-comfy: 16px;
116
+ --nomos-space-loose: 24px;
117
+ --nomos-space-section: 32px;
118
+ --nomos-type-size-micro: 0.6875rem;
119
+ --nomos-type-size-caption: 0.75rem;
120
+ --nomos-type-size-body: 0.875rem;
121
+ --nomos-type-size-lead: 1rem;
122
+ --nomos-type-size-title: 1.125rem;
123
+ --nomos-type-size-display: 1.5rem;
124
+ --nomos-type-leading-micro: 0.875rem;
125
+ --nomos-type-leading-caption: 1rem;
126
+ --nomos-type-leading-body: 1.25rem;
127
+ --nomos-type-leading-lead: 1.5rem;
128
+ --nomos-type-leading-title: 1.75rem;
129
+ --nomos-type-leading-display: 2rem;
130
+ --nomos-type-weight-regular: 400;
131
+ --nomos-type-weight-medium: 500;
132
+ --nomos-type-weight-strong: 600;
133
+ --nomos-type-family-sans: ui-sans-serif, system-ui, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
134
+ }
135
+ }
136
+
137
+ .dark, [data-theme='dark'] {
138
+ color-scheme: dark;
139
+ --nomos-color-background: 240 7% 8%;
140
+ --nomos-color-foreground: 240 10% 94%;
141
+ --nomos-color-card: 240 17% 12%;
142
+ --nomos-color-card-foreground: 240 10% 94%;
143
+ --nomos-color-popover: 240 17% 12%;
144
+ --nomos-color-popover-foreground: 240 10% 94%;
145
+ --nomos-color-primary: 174 100% 39%;
146
+ --nomos-color-primary-foreground: 0 0% 0%;
147
+ --nomos-color-secondary: 240 8% 16%;
148
+ --nomos-color-secondary-foreground: 240 10% 94%;
149
+ --nomos-color-muted: 240 8% 19%;
150
+ --nomos-color-muted-foreground: 0 0% 60%;
151
+ --nomos-color-accent: 240 8% 16%;
152
+ --nomos-color-accent-foreground: 240 10% 94%;
153
+ --nomos-color-destructive: 0 72% 71%;
154
+ --nomos-color-destructive-foreground: 0 0% 0%;
155
+ --nomos-color-border: 240 8% 19%;
156
+ --nomos-color-input: 240 8% 19%;
157
+ --nomos-color-ring: 174 100% 39%;
158
+ --nomos-color-brand: #00c9b1;
159
+ --nomos-color-status-info: 199 89% 48%;
160
+ --nomos-color-status-info-ink: 198 93% 74%;
161
+ --nomos-color-status-progress: 258 90% 66%;
162
+ --nomos-color-status-progress-ink: 255 92% 85%;
163
+ --nomos-color-status-attention: 38 92% 50%;
164
+ --nomos-color-status-attention-ink: 46 97% 65%;
165
+ --nomos-color-status-warning: 25 95% 53%;
166
+ --nomos-color-status-warning-ink: 31 97% 72%;
167
+ --nomos-color-status-danger: 0 84% 60%;
168
+ --nomos-color-status-danger-ink: 0 94% 82%;
169
+ --nomos-color-status-success: 160 84% 39%;
170
+ --nomos-color-status-success-ink: 156 72% 67%;
171
+ --nomos-radius-pill: 9999px;
172
+ --nomos-radius-control: 0.625rem;
173
+ --nomos-radius-field: 0.5rem;
174
+ --nomos-radius-chip: 0.375rem;
175
+ --nomos-space-hairline: 2px;
176
+ --nomos-space-tight: 4px;
177
+ --nomos-space-snug: 8px;
178
+ --nomos-space-base: 12px;
179
+ --nomos-space-comfy: 16px;
180
+ --nomos-space-loose: 24px;
181
+ --nomos-space-section: 32px;
182
+ --nomos-type-size-micro: 0.6875rem;
183
+ --nomos-type-size-caption: 0.75rem;
184
+ --nomos-type-size-body: 0.875rem;
185
+ --nomos-type-size-lead: 1rem;
186
+ --nomos-type-size-title: 1.125rem;
187
+ --nomos-type-size-display: 1.5rem;
188
+ --nomos-type-leading-micro: 0.875rem;
189
+ --nomos-type-leading-caption: 1rem;
190
+ --nomos-type-leading-body: 1.25rem;
191
+ --nomos-type-leading-lead: 1.5rem;
192
+ --nomos-type-leading-title: 1.75rem;
193
+ --nomos-type-leading-display: 2rem;
194
+ --nomos-type-weight-regular: 400;
195
+ --nomos-type-weight-medium: 500;
196
+ --nomos-type-weight-strong: 600;
197
+ --nomos-type-family-sans: ui-sans-serif, system-ui, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
198
+ }
199
+
200
+ .light, [data-theme='light'] {
201
+ color-scheme: light;
202
+ --nomos-color-background: 0 0% 100%;
203
+ --nomos-color-foreground: 240 10% 10%;
204
+ --nomos-color-card: 0 0% 98%;
205
+ --nomos-color-card-foreground: 240 10% 10%;
206
+ --nomos-color-popover: 0 0% 100%;
207
+ --nomos-color-popover-foreground: 240 10% 10%;
208
+ --nomos-color-primary: 174 100% 35%;
209
+ --nomos-color-primary-foreground: 0 0% 100%;
210
+ --nomos-color-secondary: 240 5% 92%;
211
+ --nomos-color-secondary-foreground: 240 10% 10%;
212
+ --nomos-color-muted: 240 5% 92%;
213
+ --nomos-color-muted-foreground: 240 4% 46%;
214
+ --nomos-color-accent: 240 5% 92%;
215
+ --nomos-color-accent-foreground: 240 10% 10%;
216
+ --nomos-color-destructive: 0 72% 51%;
217
+ --nomos-color-destructive-foreground: 0 0% 100%;
218
+ --nomos-color-border: 240 6% 85%;
219
+ --nomos-color-input: 240 6% 85%;
220
+ --nomos-color-ring: 174 100% 35%;
221
+ --nomos-color-brand: #00c9b1;
222
+ --nomos-color-status-info: 199 89% 48%;
223
+ --nomos-color-status-info-ink: 201 96% 32%;
224
+ --nomos-color-status-progress: 258 90% 66%;
225
+ --nomos-color-status-progress-ink: 263 70% 50%;
226
+ --nomos-color-status-attention: 38 92% 50%;
227
+ --nomos-color-status-attention-ink: 26 90% 37%;
228
+ --nomos-color-status-warning: 25 95% 53%;
229
+ --nomos-color-status-warning-ink: 17 88% 40%;
230
+ --nomos-color-status-danger: 0 84% 60%;
231
+ --nomos-color-status-danger-ink: 0 74% 42%;
232
+ --nomos-color-status-success: 160 84% 39%;
233
+ --nomos-color-status-success-ink: 161 94% 25%;
234
+ --nomos-radius-pill: 9999px;
235
+ --nomos-radius-control: 0.625rem;
236
+ --nomos-radius-field: 0.5rem;
237
+ --nomos-radius-chip: 0.375rem;
238
+ --nomos-space-hairline: 2px;
239
+ --nomos-space-tight: 4px;
240
+ --nomos-space-snug: 8px;
241
+ --nomos-space-base: 12px;
242
+ --nomos-space-comfy: 16px;
243
+ --nomos-space-loose: 24px;
244
+ --nomos-space-section: 32px;
245
+ --nomos-type-size-micro: 0.6875rem;
246
+ --nomos-type-size-caption: 0.75rem;
247
+ --nomos-type-size-body: 0.875rem;
248
+ --nomos-type-size-lead: 1rem;
249
+ --nomos-type-size-title: 1.125rem;
250
+ --nomos-type-size-display: 1.5rem;
251
+ --nomos-type-leading-micro: 0.875rem;
252
+ --nomos-type-leading-caption: 1rem;
253
+ --nomos-type-leading-body: 1.25rem;
254
+ --nomos-type-leading-lead: 1.5rem;
255
+ --nomos-type-leading-title: 1.75rem;
256
+ --nomos-type-leading-display: 2rem;
257
+ --nomos-type-weight-regular: 400;
258
+ --nomos-type-weight-medium: 500;
259
+ --nomos-type-weight-strong: 600;
260
+ --nomos-type-family-sans: ui-sans-serif, system-ui, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
261
+ }
262
+
263
+ :root { --nomos-density: 1; }
264
+
265
+ [data-density='comfortable'], .comfortable { --nomos-density: 1; }
266
+
267
+ [data-density='compact'], .compact { --nomos-density: 0.8; }
268
+
269
+ }
270
+
271
+ /* namespace : --nomos — un thème d'app remplace ces emplacements (ADR 0003). */