@zevra/ui 0.3.2 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/DECISIONS.md +25 -0
  2. package/README.md +83 -11
  3. package/dist/actions.d.ts +41 -0
  4. package/dist/actions.d.ts.map +1 -0
  5. package/dist/actions.js +24 -0
  6. package/dist/actions.js.map +1 -0
  7. package/dist/catalogue.d.ts +30 -0
  8. package/dist/catalogue.d.ts.map +1 -0
  9. package/dist/catalogue.js +830 -0
  10. package/dist/catalogue.js.map +1 -0
  11. package/dist/content.d.ts +135 -0
  12. package/dist/content.d.ts.map +1 -0
  13. package/dist/content.js +85 -0
  14. package/dist/content.js.map +1 -0
  15. package/dist/css-inline.d.ts +11 -0
  16. package/dist/css-inline.d.ts.map +1 -0
  17. package/dist/css-inline.js +13 -0
  18. package/dist/css-inline.js.map +1 -0
  19. package/dist/cx.d.ts +16 -0
  20. package/dist/cx.d.ts.map +1 -0
  21. package/dist/cx.js +20 -0
  22. package/dist/cx.js.map +1 -0
  23. package/dist/data.d.ts +136 -0
  24. package/dist/data.d.ts.map +1 -0
  25. package/dist/data.js +98 -0
  26. package/dist/data.js.map +1 -0
  27. package/dist/feedback.d.ts +88 -0
  28. package/dist/feedback.d.ts.map +1 -0
  29. package/dist/feedback.js +38 -0
  30. package/dist/feedback.js.map +1 -0
  31. package/dist/forms.d.ts +120 -0
  32. package/dist/forms.d.ts.map +1 -0
  33. package/dist/forms.js +60 -0
  34. package/dist/forms.js.map +1 -0
  35. package/dist/icon-data.d.ts +6 -0
  36. package/dist/icon-data.d.ts.map +1 -0
  37. package/dist/icon-data.js +77 -0
  38. package/dist/icon-data.js.map +1 -0
  39. package/dist/icon.d.ts +33 -0
  40. package/dist/icon.d.ts.map +1 -0
  41. package/dist/icon.js +13 -0
  42. package/dist/icon.js.map +1 -0
  43. package/dist/index.d.ts +13 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +41 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/layout.d.ts +166 -0
  48. package/dist/layout.d.ts.map +1 -0
  49. package/dist/layout.js +120 -0
  50. package/dist/layout.js.map +1 -0
  51. package/dist/navigation.d.ts +150 -0
  52. package/dist/navigation.d.ts.map +1 -0
  53. package/dist/navigation.js +104 -0
  54. package/dist/navigation.js.map +1 -0
  55. package/dist/overlays.d.ts +68 -0
  56. package/dist/overlays.d.ts.map +1 -0
  57. package/dist/overlays.js +114 -0
  58. package/dist/overlays.js.map +1 -0
  59. package/dist/surfaces.d.ts +61 -0
  60. package/dist/surfaces.d.ts.map +1 -0
  61. package/dist/surfaces.js +54 -0
  62. package/dist/surfaces.js.map +1 -0
  63. package/dist/typography.d.ts +89 -0
  64. package/dist/typography.d.ts.map +1 -0
  65. package/dist/typography.js +76 -0
  66. package/dist/typography.js.map +1 -0
  67. package/logos/index.json +10 -500
  68. package/package.json +36 -4
  69. package/react/actions.tsx +138 -0
  70. package/react/catalogue.tsx +1644 -0
  71. package/react/content.tsx +313 -0
  72. package/react/css-inline.ts +14 -0
  73. package/react/cx.ts +20 -0
  74. package/react/data.tsx +300 -0
  75. package/react/feedback.tsx +229 -0
  76. package/react/forms.tsx +383 -0
  77. package/react/icon-data.ts +114 -0
  78. package/react/icon.tsx +84 -0
  79. package/react/index.ts +42 -0
  80. package/react/layout.tsx +347 -0
  81. package/react/navigation.tsx +329 -0
  82. package/react/overlays.tsx +237 -0
  83. package/react/surfaces.tsx +161 -0
  84. package/react/typography.tsx +220 -0
  85. package/logos/png/campus-glyph-ink.png +0 -0
  86. package/logos/png/campus-glyph-white.png +0 -0
  87. package/logos/png/campus-lockup.png +0 -0
  88. package/logos/png/lexform-glyph-ink.png +0 -0
  89. package/logos/png/lexform-glyph-white.png +0 -0
  90. package/logos/png/lexform-lockup.png +0 -0
  91. package/logos/png/mcp-glyph-ink.png +0 -0
  92. package/logos/png/mcp-glyph-white.png +0 -0
  93. package/logos/png/mcp-lockup.png +0 -0
  94. package/logos/png/memoire-dark.png +0 -0
  95. package/logos/png/memoire-glyph-ink.png +0 -0
  96. package/logos/png/memoire-glyph-white.png +0 -0
  97. package/logos/png/memoire-lockup.png +0 -0
  98. package/logos/png/zevra-lockup-ink.png +0 -0
  99. package/logos/png/zevra-lockup-white.png +0 -0
  100. package/logos/png/zevra-lockup.png +0 -0
  101. package/logos/png/zevra-mark-ink.png +0 -0
  102. package/logos/png/zevra-mark-white.png +0 -0
  103. package/logos/png/zevra-mark.png +0 -0
  104. package/logos/svg/campus-glyph-ink.svg +0 -1
  105. package/logos/svg/campus-glyph-navy.svg +0 -1
  106. package/logos/svg/campus-glyph-orig.svg +0 -1
  107. package/logos/svg/campus-glyph-white.svg +0 -1
  108. package/logos/svg/campus-lockup-ink.svg +0 -1
  109. package/logos/svg/campus-lockup-navy.svg +0 -1
  110. package/logos/svg/campus-lockup-orig.svg +0 -1
  111. package/logos/svg/campus-lockup-white.svg +0 -1
  112. package/logos/svg/lexform-glyph-ink.svg +0 -1
  113. package/logos/svg/lexform-glyph-navy.svg +0 -1
  114. package/logos/svg/lexform-glyph-orig.svg +0 -1
  115. package/logos/svg/lexform-glyph-white.svg +0 -1
  116. package/logos/svg/lexform-lockup-ink.svg +0 -1
  117. package/logos/svg/lexform-lockup-navy.svg +0 -1
  118. package/logos/svg/lexform-lockup-orig.svg +0 -1
  119. package/logos/svg/lexform-lockup-white.svg +0 -1
  120. package/logos/svg/mcp-glyph-ink.svg +0 -1
  121. package/logos/svg/mcp-glyph-navy.svg +0 -1
  122. package/logos/svg/mcp-glyph-orig.svg +0 -1
  123. package/logos/svg/mcp-glyph-white.svg +0 -1
  124. package/logos/svg/mcp-lockup-ink.svg +0 -1
  125. package/logos/svg/mcp-lockup-navy.svg +0 -1
  126. package/logos/svg/mcp-lockup-orig.svg +0 -1
  127. package/logos/svg/mcp-lockup-white.svg +0 -1
  128. package/logos/svg/memoire-glyph-ink.svg +0 -1
  129. package/logos/svg/memoire-glyph-navy.svg +0 -1
  130. package/logos/svg/memoire-glyph-orig.svg +0 -1
  131. package/logos/svg/memoire-glyph-white.svg +0 -1
  132. package/logos/svg/memoire-lockup-ink.svg +0 -1
  133. package/logos/svg/memoire-lockup-navy.svg +0 -1
  134. package/logos/svg/memoire-lockup-orig.svg +0 -1
  135. package/logos/svg/memoire-lockup-white.svg +0 -1
  136. package/logos/svg/zevra-lockup-ink.svg +0 -1
  137. package/logos/svg/zevra-lockup-navy.svg +0 -1
  138. package/logos/svg/zevra-lockup-orig.svg +0 -1
  139. package/logos/svg/zevra-lockup-white.svg +0 -1
  140. package/logos/svg/zevra-mark-ink.svg +0 -1
  141. package/logos/svg/zevra-mark-navy.svg +0 -1
  142. package/logos/svg/zevra-mark-orig.svg +0 -1
  143. package/logos/svg/zevra-mark-white.svg +0 -1
@@ -0,0 +1,150 @@
1
+ import type { AnchorHTMLAttributes, ButtonHTMLAttributes, HTMLAttributes, ReactNode } from 'react';
2
+ type Div = Omit<HTMLAttributes<HTMLDivElement>, 'className'>;
3
+ type Span = Omit<HTMLAttributes<HTMLSpanElement>, 'className'>;
4
+ type A = Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'className'>;
5
+ type Btn = Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'className'>;
6
+ /** Une colonne, un filet, rien d'autre : ni ombre, ni rayon. Une ombre ferait
7
+ * flotter une pièce qui ne bouge jamais. Elle défile pour son propre compte —
8
+ * une nav longue n'entraîne jamais le contenu. */
9
+ export declare function Sidebar({ className, ...reste }: Div & {
10
+ className?: string;
11
+ }): import("react").JSX.Element;
12
+ export declare function SidebarHead({ className, ...reste }: Div & {
13
+ className?: string;
14
+ }): import("react").JSX.Element;
15
+ /** Collé en bas quand la nav est courte, il suit le contenu quand elle est
16
+ * longue. */
17
+ export declare function SidebarFoot({ className, ...reste }: Div & {
18
+ className?: string;
19
+ }): import("react").JSX.Element;
20
+ export interface SideGroupProps extends Div {
21
+ titre?: ReactNode;
22
+ className?: string;
23
+ children?: ReactNode;
24
+ }
25
+ export declare function SideGroup({ titre, className, children, ...reste }: SideGroupProps): import("react").JSX.Element;
26
+ export interface SideLinkProps extends A {
27
+ /** Pose `aria-current="page"` en plus de la classe : sans lui, l'entrée
28
+ * courante est marquée pour l'œil et muette au lecteur d'écran. */
29
+ courant?: boolean;
30
+ /** Rang mono ou glyphe, sur une colonne de largeur fixe — sinon les
31
+ * libellés se décalent d'un groupe à l'autre. */
32
+ num?: ReactNode;
33
+ className?: string;
34
+ children?: ReactNode;
35
+ }
36
+ export declare function SideLink({ courant, num, className, children, ...reste }: SideLinkProps): import("react").JSX.Element;
37
+ /** Elle REMPLACE la colonne sous le point de rupture : masquée au-dessus,
38
+ * elle n'apparaît que dans le bloc mobile du CSS. Ne pas la conditionner en
39
+ * JavaScript — le rendu serveur ne connaît pas la largeur de l'écran. */
40
+ export declare function Topbar({ className, ...reste }: Div & {
41
+ className?: string;
42
+ }): import("react").JSX.Element;
43
+ /** Le logo cède AVANT le nom : un logo client très large ne doit jamais
44
+ * pousser la barre hors de l'écran. */
45
+ export declare function TopbarLogo({ className, ...reste }: Div & {
46
+ className?: string;
47
+ }): import("react").JSX.Element;
48
+ export declare function TopbarTitle({ className, ...reste }: Span & {
49
+ className?: string;
50
+ }): import("react").JSX.Element;
51
+ export declare function TopbarBurger({ className, type, ...reste }: Btn & {
52
+ className?: string;
53
+ }): import("react").JSX.Element;
54
+ /** Croix bordée du chrome — fermeture d'un tiroir, d'une feuille de source.
55
+ * Angles vifs : le rayon signale l'action, le chrome n'en est pas une. */
56
+ export declare function ChromeButton({ className, type, ...reste }: Btn & {
57
+ className?: string;
58
+ 'aria-label': string;
59
+ }): import("react").JSX.Element;
60
+ export interface CrumbsProps extends Omit<A, 'children'> {
61
+ /** Les segments, du plus général au plus précis. Le DERNIER est plus sombre :
62
+ * c'est celui qu'on lit, le reste n'est qu'un chemin. */
63
+ segments: ReactNode[];
64
+ /** Séparateur. Le `/` par défaut est celui du relevé. */
65
+ separateur?: ReactNode;
66
+ className?: string;
67
+ }
68
+ /** ⚠️ Le fil ENTIER est cliquable — c'est un seul nœud, pas une liste de
69
+ * liens. Sans `href`, il se rend en `<span>` : un `<a>` sans cible reste
70
+ * annoncé comme un lien et déçoit. */
71
+ export declare function Crumbs({ segments, separateur, href, className, ...reste }: CrumbsProps): import("react").JSX.Element;
72
+ /** À poser dans un `SelectAnchor` (forms) : c'est l'enveloppe qui ancre le
73
+ * menu, pas le déclencheur — l'ancrer sur le déclencheur casse sa largeur
74
+ * maximale calculée sur la fenêtre. */
75
+ export declare function Menu({ className, ...reste }: Div & {
76
+ className?: string;
77
+ role?: string;
78
+ }): import("react").JSX.Element;
79
+ export interface MenuItemProps extends Btn {
80
+ /** Pose `aria-selected` en plus de la classe. */
81
+ actif?: boolean;
82
+ className?: string;
83
+ }
84
+ export declare function MenuItem({ actif, className, type, ...reste }: MenuItemProps): import("react").JSX.Element;
85
+ export interface TabsProps<T extends string> {
86
+ onglets: readonly {
87
+ id: T;
88
+ label: ReactNode;
89
+ compte?: ReactNode;
90
+ }[];
91
+ actif: T;
92
+ onChange: (id: T) => void;
93
+ /** Rangée qui défile au lieu de passer à la ligne. */
94
+ rail?: boolean;
95
+ /** Identifiant du panneau piloté, pour `aria-controls`. */
96
+ panneau?: string;
97
+ className?: string;
98
+ }
99
+ /** ⚠️ Il n'existe AUCUNE classe d'onglet dans le CSS, et c'est délibéré : une
100
+ * rangée d'onglets est une rangée de puces, avec la grammaire d'état de
101
+ * `Seg`. Un onglet SOULIGNÉ reste à faire — il suppose d'arbitrer couleur et
102
+ * épaisseur du trait actif, ce qu'aucune source ne donne. Ce composant
103
+ * n'ajoute donc que l'ARIA, pas un style de plus. */
104
+ export declare function Tabs<T extends string>({ onglets, actif, onChange, rail, panneau, className, }: TabsProps<T>): import("react").JSX.Element;
105
+ export interface PagerProps extends Div {
106
+ /** Pied de tableau : compte à gauche, sens à droite. C'est un MODIFICATEUR,
107
+ * il se pose avec `Pager`, jamais seul. */
108
+ pied?: boolean;
109
+ className?: string;
110
+ }
111
+ export declare function Pager({ pied, className, ...reste }: PagerProps): import("react").JSX.Element;
112
+ /** ⚠️ Une flèche désactivée reste ATTEIGNABLE au clavier (`aria-disabled` et
113
+ * non `disabled`) : sinon elle disparaît du parcours sans être annoncée. */
114
+ export declare function PagerArrow({ desactive, className, type, ...reste }: Btn & {
115
+ desactive?: boolean;
116
+ className?: string;
117
+ 'aria-label': string;
118
+ }): import("react").JSX.Element;
119
+ /** Le rang courant (« p. 12 / 31 »). Cliquable dans le relevé : il ouvre la
120
+ * saisie directe d'un numéro. */
121
+ export declare function PagerRank({ className, type, ...reste }: Btn & {
122
+ className?: string;
123
+ }): import("react").JSX.Element;
124
+ /** « ‹ Précédent · Suivant › » du pied de tableau. */
125
+ export declare function PagerStep({ className, type, ...reste }: Btn & {
126
+ className?: string;
127
+ }): import("react").JSX.Element;
128
+ export interface CitePanelProps extends Div {
129
+ titre?: ReactNode;
130
+ /** Croix de fermeture et actions de tête. */
131
+ actions?: ReactNode;
132
+ pied?: ReactNode;
133
+ className?: string;
134
+ children?: ReactNode;
135
+ }
136
+ export declare function CitePanel({ titre, actions, pied, className, children, ...reste }: CitePanelProps): import("react").JSX.Element;
137
+ export interface ScrollProps extends Div {
138
+ /** Barre fine, aux couleurs du système. OPT-IN : par défaut la barre native
139
+ * est conservée — sur macOS et iOS, l'habiller la rend permanente et elle
140
+ * mange une colonne. */
141
+ habillee?: boolean;
142
+ className?: string;
143
+ }
144
+ /** ⚠️ Porte `min-height: 0` ET `min-width: 0`. Sans les deux, un enfant flex
145
+ * refuse de rétrécir sous son contenu : la zone déborde et c'est la PAGE qui
146
+ * part en défilement horizontal. C'est la faute la plus fréquente de ce
147
+ * gabarit. */
148
+ export declare function Scroll({ habillee, className, ...reste }: ScrollProps): import("react").JSX.Element;
149
+ export {};
150
+ //# sourceMappingURL=navigation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../react/navigation.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,104 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cx } from './cx.js';
3
+ import { Seg, SegGroup } from './forms.js';
4
+ /* ─── Colonne latérale ─────────────────────────────────────────────── */
5
+ /** Une colonne, un filet, rien d'autre : ni ombre, ni rayon. Une ombre ferait
6
+ * flotter une pièce qui ne bouge jamais. Elle défile pour son propre compte —
7
+ * une nav longue n'entraîne jamais le contenu. */
8
+ export function Sidebar({ className, ...reste }) {
9
+ return _jsx("aside", { className: cx('zv-sidebar', className), ...reste });
10
+ }
11
+ export function SidebarHead({ className, ...reste }) {
12
+ return _jsx("div", { className: cx('zv-sidebar__head', className), ...reste });
13
+ }
14
+ /** Collé en bas quand la nav est courte, il suit le contenu quand elle est
15
+ * longue. */
16
+ export function SidebarFoot({ className, ...reste }) {
17
+ return _jsx("div", { className: cx('zv-sidebar__foot', className), ...reste });
18
+ }
19
+ export function SideGroup({ titre, className, children, ...reste }) {
20
+ return (_jsxs("div", { className: cx('zv-sidegroup', className), ...reste, children: [titre && _jsx("div", { className: "zv-sidegroup__title", children: titre }), children] }));
21
+ }
22
+ export function SideLink({ courant, num, className, children, ...reste }) {
23
+ return (_jsxs("a", { "aria-current": courant ? 'page' : undefined, className: cx('zv-sidelink', courant && 'zv-sidelink--on', className), ...reste, children: [num != null && _jsx("span", { className: "zv-sidelink__num", children: num }), children] }));
24
+ }
25
+ /* ─── Barre supérieure ─────────────────────────────────────────────── */
26
+ /** Elle REMPLACE la colonne sous le point de rupture : masquée au-dessus,
27
+ * elle n'apparaît que dans le bloc mobile du CSS. Ne pas la conditionner en
28
+ * JavaScript — le rendu serveur ne connaît pas la largeur de l'écran. */
29
+ export function Topbar({ className, ...reste }) {
30
+ return _jsx("header", { className: cx('zv-topbar', className), ...reste });
31
+ }
32
+ /** Le logo cède AVANT le nom : un logo client très large ne doit jamais
33
+ * pousser la barre hors de l'écran. */
34
+ export function TopbarLogo({ className, ...reste }) {
35
+ return _jsx("div", { className: cx('zv-topbar__logo', className), ...reste });
36
+ }
37
+ export function TopbarTitle({ className, ...reste }) {
38
+ return _jsx("span", { className: cx('zv-topbar__title', className), ...reste });
39
+ }
40
+ export function TopbarBurger({ className, type = 'button', ...reste }) {
41
+ return _jsx("button", { type: type, className: cx('zv-topbar__burger', className), ...reste });
42
+ }
43
+ /** Croix bordée du chrome — fermeture d'un tiroir, d'une feuille de source.
44
+ * Angles vifs : le rayon signale l'action, le chrome n'en est pas une. */
45
+ export function ChromeButton({ className, type = 'button', ...reste }) {
46
+ return _jsx("button", { type: type, className: cx('zv-chrome-btn', className), ...reste });
47
+ }
48
+ /** ⚠️ Le fil ENTIER est cliquable — c'est un seul nœud, pas une liste de
49
+ * liens. Sans `href`, il se rend en `<span>` : un `<a>` sans cible reste
50
+ * annoncé comme un lien et déçoit. */
51
+ export function Crumbs({ segments, separateur = '/', href, className, ...reste }) {
52
+ const contenu = segments.map((seg, i) => (_jsxs("span", { children: [i > 0 && (_jsx("span", { className: "zv-crumbs__sep", "aria-hidden": "true", children: separateur })), _jsx("span", { className: i === segments.length - 1 ? 'zv-crumbs__seg' : undefined, children: seg })] }, i)));
53
+ const classe = cx('zv-crumbs', className);
54
+ if (!href) {
55
+ return _jsx("span", { className: classe, children: contenu });
56
+ }
57
+ return (_jsx("a", { href: href, className: classe, ...reste, children: contenu }));
58
+ }
59
+ /* ─── Menu déroulant ───────────────────────────────────────────────── */
60
+ /** À poser dans un `SelectAnchor` (forms) : c'est l'enveloppe qui ancre le
61
+ * menu, pas le déclencheur — l'ancrer sur le déclencheur casse sa largeur
62
+ * maximale calculée sur la fenêtre. */
63
+ export function Menu({ className, ...reste }) {
64
+ return _jsx("div", { role: "listbox", className: cx('zv-menu', className), ...reste });
65
+ }
66
+ export function MenuItem({ actif, className, type = 'button', ...reste }) {
67
+ return (_jsx("button", { type: type, role: "option", "aria-selected": actif ?? false, className: cx('zv-menu__item', actif && 'zv-menu__item--on', className), ...reste }));
68
+ }
69
+ /** ⚠️ Il n'existe AUCUNE classe d'onglet dans le CSS, et c'est délibéré : une
70
+ * rangée d'onglets est une rangée de puces, avec la grammaire d'état de
71
+ * `Seg`. Un onglet SOULIGNÉ reste à faire — il suppose d'arbitrer couleur et
72
+ * épaisseur du trait actif, ce qu'aucune source ne donne. Ce composant
73
+ * n'ajoute donc que l'ARIA, pas un style de plus. */
74
+ export function Tabs({ onglets, actif, onChange, rail, panneau, className, }) {
75
+ return (_jsx(SegGroup, { role: "tablist", rail: rail, className: className, children: onglets.map((o) => (_jsx(Seg, { role: "tab", "aria-selected": o.id === actif, "aria-controls": panneau, on: o.id === actif, compte: o.compte, onClick: () => onChange(o.id), children: o.label }, o.id))) }));
76
+ }
77
+ export function Pager({ pied, className, ...reste }) {
78
+ return (_jsx("nav", { className: cx('zv-pager', pied && 'zv-pager--foot', className), ...reste }));
79
+ }
80
+ /** ⚠️ Une flèche désactivée reste ATTEIGNABLE au clavier (`aria-disabled` et
81
+ * non `disabled`) : sinon elle disparaît du parcours sans être annoncée. */
82
+ export function PagerArrow({ desactive, className, type = 'button', ...reste }) {
83
+ return (_jsx("button", { type: type, "aria-disabled": desactive || undefined, className: cx('zv-pager__arrow', className), ...reste }));
84
+ }
85
+ /** Le rang courant (« p. 12 / 31 »). Cliquable dans le relevé : il ouvre la
86
+ * saisie directe d'un numéro. */
87
+ export function PagerRank({ className, type = 'button', ...reste }) {
88
+ return _jsx("button", { type: type, className: cx('zv-pager__rank', className), ...reste });
89
+ }
90
+ /** « ‹ Précédent · Suivant › » du pied de tableau. */
91
+ export function PagerStep({ className, type = 'button', ...reste }) {
92
+ return _jsx("button", { type: type, className: cx('zv-pager__step', className), ...reste });
93
+ }
94
+ export function CitePanel({ titre, actions, pied, className, children, ...reste }) {
95
+ return (_jsxs("div", { className: cx('zv-cite-panel', className), ...reste, children: [_jsxs("div", { className: "zv-cite-panel__head", children: [titre && _jsx("span", { className: "zv-cite-panel__title", children: titre }), actions] }), _jsx("div", { className: "zv-cite-panel__body", children: children }), pied && _jsx("div", { className: "zv-cite-panel__foot", children: pied })] }));
96
+ }
97
+ /** ⚠️ Porte `min-height: 0` ET `min-width: 0`. Sans les deux, un enfant flex
98
+ * refuse de rétrécir sous son contenu : la zone déborde et c'est la PAGE qui
99
+ * part en défilement horizontal. C'est la faute la plus fréquente de ce
100
+ * gabarit. */
101
+ export function Scroll({ habillee, className, ...reste }) {
102
+ return (_jsx("div", { className: cx('zv-scroll-y', habillee && 'zv-scrollbar', className), ...reste }));
103
+ }
104
+ //# sourceMappingURL=navigation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigation.js","sourceRoot":"","sources":["../react/navigation.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ import type { HTMLAttributes, ReactNode, RefObject } from 'react';
2
+ type Div = Omit<HTMLAttributes<HTMLDivElement>, 'className'>;
3
+ export interface UseOverlayOptions {
4
+ ouvert: boolean;
5
+ onClose: () => void;
6
+ /** Le nœud à piéger. Sans lui, pas de piège — mais Échap fonctionne quand
7
+ * même. */
8
+ panneau?: RefObject<HTMLElement | null>;
9
+ /** Verrouille le défilement du document. Vrai pour une modale, vrai pour un
10
+ * tiroir mobile ; faux pour ce qui ne recouvre pas la page. */
11
+ verrouille?: boolean;
12
+ }
13
+ /** Échap, piège de focus, restitution du focus, verrou de défilement.
14
+ * Exporté : une app qui dessine son propre enrobage doit pouvoir reprendre
15
+ * ce comportement sans recopier trente lignes qui se trompent une fois sur
16
+ * deux. */
17
+ export declare function useOverlay({ ouvert, onClose, panneau, verrouille }: UseOverlayOptions): void;
18
+ /** Toujours l'encre de charte diluée, jamais un noir pur : la page est
19
+ * bleutée, un gris neutre y ferait un trou sale. */
20
+ export declare function Scrim({ className, ...reste }: Div & {
21
+ className?: string;
22
+ }): import("react").JSX.Element;
23
+ export interface DrawerProps extends Omit<Div, 'title'> {
24
+ ouvert: boolean;
25
+ onClose: () => void;
26
+ /** Nom du dialogue — ce que le lecteur d'écran annonce à l'ouverture. */
27
+ label?: string;
28
+ /** Croix de fermeture posée en absolu par-dessus la tête du panneau. */
29
+ fermeture?: ReactNode;
30
+ className?: string;
31
+ children?: ReactNode;
32
+ }
33
+ /** ⚠️ Le tiroir n'existe QUE sous le point de rupture : au-dessus, la
34
+ * navigation est une colonne et il n'y a rien à ouvrir. Le CSS s'en charge —
35
+ * ne pas conditionner le rendu sur la largeur en JavaScript, le serveur ne
36
+ * la connaît pas. */
37
+ export declare function Drawer({ ouvert, onClose, label, fermeture, className, children, ...reste }: DrawerProps): import("react").JSX.Element;
38
+ export interface ModalProps extends Omit<Div, 'title'> {
39
+ ouvert: boolean;
40
+ onClose: () => void;
41
+ titre?: ReactNode;
42
+ /** Actions de tête, à droite du titre (la croix, en général). */
43
+ actions?: ReactNode;
44
+ /** Pied d'actions. Il reste visible quand le corps défile — c'est tout
45
+ * l'intérêt du plafond de hauteur. */
46
+ pied?: ReactNode;
47
+ /** Modale destructive : le filet HAUT porte l'avertissement, pas un fond
48
+ * rouge — une surface d'alerte pleine rendrait le texte pénible à lire. */
49
+ danger?: boolean;
50
+ className?: string;
51
+ children?: ReactNode;
52
+ }
53
+ export declare function Modal({ ouvert, onClose, titre, actions, pied, danger, className, children, ...reste }: ModalProps): import("react").JSX.Element | null;
54
+ /** Le conteneur ne capte RIEN : seules les notifications le font, sans quoi
55
+ * une colonne invisible bloquerait les clics dans tout le coin de l'écran. */
56
+ export declare function Toasts({ className, ...reste }: Div & {
57
+ className?: string;
58
+ }): import("react").JSX.Element;
59
+ export interface ToastProps extends Div {
60
+ ton?: 'ok' | 'err';
61
+ className?: string;
62
+ }
63
+ /** ⚠️ Ne remplace PAS `Alert` : une erreur de formulaire se dit à côté du
64
+ * champ, jamais dans un coin qui disparaît. Réserver ce composant à ce qui
65
+ * est vrai APRÈS COUP — « copié », « enregistré », « envoyé ». */
66
+ export declare function Toast({ ton, className, ...reste }: ToastProps): import("react").JSX.Element;
67
+ export {};
68
+ //# sourceMappingURL=overlays.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlays.d.ts","sourceRoot":"","sources":["../react/overlays.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGjE,KAAK,GAAG,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,WAAW,CAAC,CAAA;AAK5D,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,OAAO,CAAA;IACf,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB;gBACY;IACZ,OAAO,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAA;IACvC;oEACgE;IAChE,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAED;;;YAGY;AACZ,wBAAgB,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,UAAiB,EAAE,EAAE,iBAAiB,QAwD5F;AAID;qDACqD;AACrD,wBAAgB,KAAK,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAE1E;AAID,MAAM,WAAW,WAAY,SAAQ,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC;IACrD,MAAM,EAAE,OAAO,CAAA;IACf,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,wEAAwE;IACxE,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB;AAED;;;sBAGsB;AACtB,wBAAgB,MAAM,CAAC,EACrB,MAAM,EACN,OAAO,EACP,KAAoB,EACpB,SAAS,EACT,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,WAAW,+BAqBb;AAID,MAAM,WAAW,UAAW,SAAQ,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC;IACpD,MAAM,EAAE,OAAO,CAAA;IACf,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,iEAAiE;IACjE,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB;2CACuC;IACvC,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB;gFAC4E;IAC5E,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB;AAED,wBAAgB,KAAK,CAAC,EACpB,MAAM,EACN,OAAO,EACP,KAAK,EACL,OAAO,EACP,IAAI,EACJ,MAAM,EACN,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,UAAU,sCA+BZ;AAID;+EAC+E;AAC/E,wBAAgB,MAAM,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAS3E;AAED,MAAM,WAAW,UAAW,SAAQ,GAAG;IACrC,GAAG,CAAC,EAAE,IAAI,GAAG,KAAK,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;mEAEmE;AACnE,wBAAgB,KAAK,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,UAAU,+BAE7D"}
@@ -0,0 +1,114 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ // Enrobages — voile, tiroir, modale, notification flottante.
4
+ //
5
+ // SEUL fichier du paquet marqué « use client », avec un hook. Tout ce qui vit
6
+ // ici vole le regard à la page : il faut une touche Échap, un piège de focus
7
+ // et un verrou de défilement, et rien de cela ne s'écrit en CSS.
8
+ //
9
+ // ⚠️ Ne PAS écrire `data-open={ouvert}` en React : cela rend `data-open="false"`,
10
+ // que le sélecteur d'attribut du CSS considère comme PRÉSENT — le panneau
11
+ // resterait ouvert. Ces composants emploient la classe `--open`, prévue pour ça.
12
+ import { useCallback, useEffect, useRef } from 'react';
13
+ import { cx } from './cx.js';
14
+ const FOCUSABLES = 'a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])';
15
+ /** Échap, piège de focus, restitution du focus, verrou de défilement.
16
+ * Exporté : une app qui dessine son propre enrobage doit pouvoir reprendre
17
+ * ce comportement sans recopier trente lignes qui se trompent une fois sur
18
+ * deux. */
19
+ export function useOverlay({ ouvert, onClose, panneau, verrouille = true }) {
20
+ // Le nœud qui avait le focus AVANT l'ouverture : c'est à lui qu'il revient
21
+ // à la fermeture. Sans cela, le focus repart au début du document et un
22
+ // utilisateur au clavier perd sa place dans la page.
23
+ const origine = useRef(null);
24
+ useEffect(() => {
25
+ if (!ouvert)
26
+ return;
27
+ const cible = panneau?.current;
28
+ // ⚠️ Le document du PANNEAU, pas `document` : un enrobage peut vivre dans
29
+ // un autre document que celui du script (planche de composants rendue dans
30
+ // un iframe, fenêtre détachée). Écouter `document` y poserait la touche
31
+ // Échap sur la page hôte — elle fermerait la modale d'à côté et pas
32
+ // celle-ci. Sans panneau, on retombe sur le document courant.
33
+ const docu = cible?.ownerDocument ?? document;
34
+ origine.current = docu.activeElement;
35
+ // ⚠️ La valeur PRÉCÉDENTE est restaurée, pas remise à '' : une page qui
36
+ // gérait déjà son propre défilement serait cassée par un reset aveugle.
37
+ const overflowPrecedent = verrouille ? docu.body.style.overflow : null;
38
+ if (verrouille)
39
+ docu.body.style.overflow = 'hidden';
40
+ const premier = cible?.querySelector(FOCUSABLES);
41
+ premier?.focus();
42
+ function onKey(e) {
43
+ if (e.key === 'Escape') {
44
+ e.stopPropagation();
45
+ onClose();
46
+ return;
47
+ }
48
+ if (e.key !== 'Tab' || !cible)
49
+ return;
50
+ const noeuds = Array.from(cible.querySelectorAll(FOCUSABLES)).filter((n) => n.offsetParent !== null || n === docu.activeElement);
51
+ if (noeuds.length === 0)
52
+ return;
53
+ const debut = noeuds[0];
54
+ const fin = noeuds[noeuds.length - 1];
55
+ // Le cycle est refermé à la main : sans cela, Tab sort du panneau et
56
+ // l'utilisateur se retrouve à parcourir la page cachée derrière le voile.
57
+ if (e.shiftKey && docu.activeElement === debut) {
58
+ e.preventDefault();
59
+ fin.focus();
60
+ }
61
+ else if (!e.shiftKey && docu.activeElement === fin) {
62
+ e.preventDefault();
63
+ debut.focus();
64
+ }
65
+ }
66
+ docu.addEventListener('keydown', onKey);
67
+ return () => {
68
+ docu.removeEventListener('keydown', onKey);
69
+ if (overflowPrecedent !== null)
70
+ docu.body.style.overflow = overflowPrecedent;
71
+ origine.current?.focus?.();
72
+ };
73
+ }, [ouvert, onClose, panneau, verrouille]);
74
+ }
75
+ /* ─── Voile ────────────────────────────────────────────────────────── */
76
+ /** Toujours l'encre de charte diluée, jamais un noir pur : la page est
77
+ * bleutée, un gris neutre y ferait un trou sale. */
78
+ export function Scrim({ className, ...reste }) {
79
+ return _jsx("div", { className: cx('zv-scrim', className), "aria-hidden": "true", ...reste });
80
+ }
81
+ /** ⚠️ Le tiroir n'existe QUE sous le point de rupture : au-dessus, la
82
+ * navigation est une colonne et il n'y a rien à ouvrir. Le CSS s'en charge —
83
+ * ne pas conditionner le rendu sur la largeur en JavaScript, le serveur ne
84
+ * la connaît pas. */
85
+ export function Drawer({ ouvert, onClose, label = 'Navigation', fermeture, className, children, ...reste }) {
86
+ const panneau = useRef(null);
87
+ useOverlay({ ouvert, onClose, panneau });
88
+ const fermer = useCallback(() => onClose(), [onClose]);
89
+ return (_jsxs("div", { role: "dialog", "aria-modal": "true", "aria-label": label, "aria-hidden": !ouvert, className: cx('zv-drawer', ouvert && 'zv-drawer--open', className), ...reste, children: [_jsx("div", { className: "zv-scrim", onClick: fermer, "aria-hidden": "true" }), _jsxs("div", { className: "zv-drawer__panel", ref: panneau, children: [fermeture && _jsx("div", { className: "zv-drawer__close", children: fermeture }), children] })] }));
90
+ }
91
+ export function Modal({ ouvert, onClose, titre, actions, pied, danger, className, children, ...reste }) {
92
+ const panneau = useRef(null);
93
+ useOverlay({ ouvert, onClose, panneau });
94
+ const fermer = useCallback(() => onClose(), [onClose]);
95
+ // Une modale fermée n'est pas rendue du tout : contrairement au tiroir, elle
96
+ // n'a pas d'animation d'entrée à préserver, et son contenu (un formulaire,
97
+ // le plus souvent) ne doit pas rester dans le DOM à l'état fantôme.
98
+ if (!ouvert)
99
+ return null;
100
+ return (_jsxs("div", { role: "dialog", "aria-modal": "true", "aria-label": typeof titre === 'string' ? titre : undefined, className: cx('zv-modal', 'zv-modal--open', danger && 'zv-modal--danger', className), ...reste, children: [_jsx("div", { className: "zv-scrim", onClick: fermer, "aria-hidden": "true" }), _jsxs("div", { className: "zv-modal__panel", ref: panneau, children: [(titre || actions) && (_jsxs("div", { className: "zv-modal__head", children: [titre && _jsx("h2", { className: "zv-modal__title", children: titre }), actions] })), _jsx("div", { className: "zv-modal__body", children: children }), pied && _jsx("div", { className: "zv-modal__foot", children: pied })] })] }));
101
+ }
102
+ /* ─── Notification flottante ───────────────────────────────────────── */
103
+ /** Le conteneur ne capte RIEN : seules les notifications le font, sans quoi
104
+ * une colonne invisible bloquerait les clics dans tout le coin de l'écran. */
105
+ export function Toasts({ className, ...reste }) {
106
+ return (_jsx("div", { className: cx('zv-toasts', className), role: "region", "aria-live": "polite", ...reste }));
107
+ }
108
+ /** ⚠️ Ne remplace PAS `Alert` : une erreur de formulaire se dit à côté du
109
+ * champ, jamais dans un coin qui disparaît. Réserver ce composant à ce qui
110
+ * est vrai APRÈS COUP — « copié », « enregistré », « envoyé ». */
111
+ export function Toast({ ton, className, ...reste }) {
112
+ return _jsx("div", { className: cx('zv-toast', ton && `zv-toast--${ton}`, className), ...reste });
113
+ }
114
+ //# sourceMappingURL=overlays.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlays.js","sourceRoot":"","sources":["../react/overlays.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ import type { HTMLAttributes, ReactNode } from 'react';
2
+ type Div = Omit<HTMLAttributes<HTMLDivElement>, 'className'>;
3
+ /** Le violet et le cyan du spectre, très dilués. Ce n'est PAS un emploi du
4
+ * spectre en aplat : c'est une lumière — elle ne compte pas dans les trois
5
+ * emplois autorisés. */
6
+ export declare function Halo({ place, className, ...reste }: Div & {
7
+ place: 'hero' | 'cta' | 'core';
8
+ className?: string;
9
+ }): import("react").JSX.Element;
10
+ export declare function GridFloor({ carte, className, ...reste }: Div & {
11
+ carte?: boolean;
12
+ className?: string;
13
+ }): import("react").JSX.Element;
14
+ /** Éteint le bas d'une scène pour que le texte qui la suit reste lisible.
15
+ * `blanc` quand la page est blanche sous la scène. */
16
+ export declare function Fade({ blanc, className, ...reste }: Div & {
17
+ blanc?: boolean;
18
+ className?: string;
19
+ }): import("react").JSX.Element;
20
+ export interface BandProps extends Div {
21
+ /** Glyphe en filigrane, très dilué, dans un coin. */
22
+ filigrane?: ReactNode;
23
+ /** Lueur d'accent derrière le contenu. */
24
+ lueur?: boolean;
25
+ className?: string;
26
+ children?: ReactNode;
27
+ }
28
+ /** LA surface sombre du système. ⚠️ Les surfaces sombres se font avec elle et
29
+ * `--accent-on-dark`, JAMAIS en inversant les neutres : les contrastes ont
30
+ * été réglés dans ce sens-là et pas dans l'autre. */
31
+ export declare function Band({ filigrane, lueur, className, children, ...reste }: BandProps): import("react").JSX.Element;
32
+ /** Panneau sombre plus petit qu'une bande : une carte, un encart. */
33
+ export declare function PanelNavy({ className, ...reste }: Div & {
34
+ className?: string;
35
+ }): import("react").JSX.Element;
36
+ /** Repeint un texte pour une surface sombre. `Band` le fait déjà pour son
37
+ * contenu courant — cette classe sert aux cas isolés. */
38
+ export declare function TextOnDark({ className, ...reste }: Div & {
39
+ className?: string;
40
+ }): import("react").JSX.Element;
41
+ export interface GlyphProps extends Div {
42
+ /** `deep` accentue l'ombre portée, `watermark` dilue le glyphe jusqu'au
43
+ * filigrane. */
44
+ variante?: 'deep' | 'watermark';
45
+ className?: string;
46
+ children?: ReactNode;
47
+ }
48
+ /** Enveloppe d'un logo de produit posé comme motif. Le glyphe lui-même est
49
+ * une image du paquet (`@zevra/ui/logos/…`), pas un tracé du CSS. */
50
+ export declare function Glyph({ variante, className, children, ...reste }: GlyphProps): import("react").JSX.Element;
51
+ export type Animation = 'rise' | 'pop' | 'filet' | 'glyph-in' | 'converge' | 'breathe' | 'drift' | 'dot-active' | 'progress';
52
+ /** Les neuf animations du paquet, nommées. ⚠️ Elles sont pilotées AU
53
+ * DÉFILEMENT et réservées à la vitrine : le chrome applicatif n'anime rien.
54
+ * `prefers-reduced-motion` les coupe toutes, globalement, depuis base.css.
55
+ *
56
+ * `option` échelonne les entrées d'une même rangée (`pop`, rangs 2 à 6) ou
57
+ * donne le coin d'arrivée (`converge` : tr, bl, br — le défaut vient du
58
+ * haut-gauche). Passée à une autre animation, elle est ignorée. */
59
+ export declare function anim(nom: Animation, option?: 2 | 3 | 4 | 5 | 6 | 'tr' | 'bl' | 'br'): string;
60
+ export {};
61
+ //# sourceMappingURL=surfaces.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"surfaces.d.ts","sourceRoot":"","sources":["../react/surfaces.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtD,KAAK,GAAG,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,WAAW,CAAC,CAAA;AAI5D;;yBAEyB;AACzB,wBAAgB,IAAI,CAAC,EACnB,KAAK,EACL,SAAS,EACT,GAAG,KAAK,EACT,EAAE,GAAG,GAAG;IAAE,KAAK,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAQ9D;AAID,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,SAAS,EACT,GAAG,KAAK,EACT,EAAE,GAAG,GAAG;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAQ/C;AAID;uDACuD;AACvD,wBAAgB,IAAI,CAAC,EACnB,KAAK,EACL,SAAS,EACT,GAAG,KAAK,EACT,EAAE,GAAG,GAAG;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAQ/C;AAID,MAAM,WAAW,SAAU,SAAQ,GAAG;IACpC,qDAAqD;IACrD,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB,0CAA0C;IAC1C,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB;AAED;;sDAEsD;AACtD,wBAAgB,IAAI,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,SAAS,+BAYlF;AAED,qEAAqE;AACrE,wBAAgB,SAAS,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAE9E;AAED;0DAC0D;AAC1D,wBAAgB,UAAU,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAE/E;AAID,MAAM,WAAW,UAAW,SAAQ,GAAG;IACrC;qBACiB;IACjB,QAAQ,CAAC,EAAE,MAAM,GAAG,WAAW,CAAA;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB;AAED;sEACsE;AACtE,wBAAgB,KAAK,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,UAAU,+BAU5E;AAID,MAAM,MAAM,SAAS,GACjB,MAAM,GACN,KAAK,GACL,OAAO,GACP,UAAU,GACV,UAAU,GACV,SAAS,GACT,OAAO,GACP,YAAY,GACZ,UAAU,CAAA;AAEd;;;;;;oEAMoE;AACpE,wBAAgB,IAAI,CAClB,GAAG,EAAE,SAAS,EACd,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAC9C,MAAM,CAKR"}
@@ -0,0 +1,54 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cx } from './cx.js';
3
+ /* ─── Halo ambiant ─────────────────────────────────────────────────── */
4
+ /** Le violet et le cyan du spectre, très dilués. Ce n'est PAS un emploi du
5
+ * spectre en aplat : c'est une lumière — elle ne compte pas dans les trois
6
+ * emplois autorisés. */
7
+ export function Halo({ place, className, ...reste }) {
8
+ return (_jsx("div", { "aria-hidden": "true", className: cx('zv-halo', `zv-halo--${place}`, className), ...reste }));
9
+ }
10
+ /* ─── Sol quadrillé ────────────────────────────────────────────────── */
11
+ export function GridFloor({ carte, className, ...reste }) {
12
+ return (_jsx("div", { "aria-hidden": "true", className: cx('zv-grid-floor', carte && 'zv-grid-floor--card', className), ...reste }));
13
+ }
14
+ /* ─── Voile de fondu ───────────────────────────────────────────────── */
15
+ /** Éteint le bas d'une scène pour que le texte qui la suit reste lisible.
16
+ * `blanc` quand la page est blanche sous la scène. */
17
+ export function Fade({ blanc, className, ...reste }) {
18
+ return (_jsx("div", { "aria-hidden": "true", className: cx('zv-fade', blanc && 'zv-fade--white', className), ...reste }));
19
+ }
20
+ /** LA surface sombre du système. ⚠️ Les surfaces sombres se font avec elle et
21
+ * `--accent-on-dark`, JAMAIS en inversant les neutres : les contrastes ont
22
+ * été réglés dans ce sens-là et pas dans l'autre. */
23
+ export function Band({ filigrane, lueur, className, children, ...reste }) {
24
+ return (_jsxs("section", { className: cx('zv-band', className), ...reste, children: [lueur && _jsx("div", { className: "zv-band__glow", "aria-hidden": "true" }), filigrane && (_jsx("div", { className: "zv-band__watermark", "aria-hidden": "true", children: filigrane })), _jsx("div", { className: "zv-band__content", children: children })] }));
25
+ }
26
+ /** Panneau sombre plus petit qu'une bande : une carte, un encart. */
27
+ export function PanelNavy({ className, ...reste }) {
28
+ return _jsx("div", { className: cx('zv-panel-navy', className), ...reste });
29
+ }
30
+ /** Repeint un texte pour une surface sombre. `Band` le fait déjà pour son
31
+ * contenu courant — cette classe sert aux cas isolés. */
32
+ export function TextOnDark({ className, ...reste }) {
33
+ return _jsx("div", { className: cx('zv-text-on-dark', className), ...reste });
34
+ }
35
+ /** Enveloppe d'un logo de produit posé comme motif. Le glyphe lui-même est
36
+ * une image du paquet (`@zevra/ui/logos/…`), pas un tracé du CSS. */
37
+ export function Glyph({ variante, className, children, ...reste }) {
38
+ return (_jsx("div", { "aria-hidden": "true", className: cx('zv-glyph', variante && `zv-glyph--${variante}`, className), ...reste, children: children }));
39
+ }
40
+ /** Les neuf animations du paquet, nommées. ⚠️ Elles sont pilotées AU
41
+ * DÉFILEMENT et réservées à la vitrine : le chrome applicatif n'anime rien.
42
+ * `prefers-reduced-motion` les coupe toutes, globalement, depuis base.css.
43
+ *
44
+ * `option` échelonne les entrées d'une même rangée (`pop`, rangs 2 à 6) ou
45
+ * donne le coin d'arrivée (`converge` : tr, bl, br — le défaut vient du
46
+ * haut-gauche). Passée à une autre animation, elle est ignorée. */
47
+ export function anim(nom, option) {
48
+ if (nom === 'pop' && typeof option === 'number')
49
+ return `zv-anim-pop zv-anim-pop--${option}`;
50
+ if (nom === 'converge' && typeof option === 'string')
51
+ return `zv-anim-converge zv-anim-converge--${option}`;
52
+ return `zv-anim-${nom}`;
53
+ }
54
+ //# sourceMappingURL=surfaces.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"surfaces.js","sourceRoot":"","sources":["../react/surfaces.tsx"],"names":[],"mappings":";AAYA,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAA;AAI5B,0EAA0E;AAE1E;;yBAEyB;AACzB,MAAM,UAAU,IAAI,CAAC,EACnB,KAAK,EACL,SAAS,EACT,GAAG,KAAK,EACqD;IAC7D,OAAO,CACL,6BACc,MAAM,EAClB,SAAS,EAAE,EAAE,CAAC,SAAS,EAAE,YAAY,KAAK,EAAE,EAAE,SAAS,CAAC,KACpD,KAAK,GACT,CACH,CAAA;AACH,CAAC;AAED,0EAA0E;AAE1E,MAAM,UAAU,SAAS,CAAC,EACxB,KAAK,EACL,SAAS,EACT,GAAG,KAAK,EACsC;IAC9C,OAAO,CACL,6BACc,MAAM,EAClB,SAAS,EAAE,EAAE,CAAC,eAAe,EAAE,KAAK,IAAI,qBAAqB,EAAE,SAAS,CAAC,KACrE,KAAK,GACT,CACH,CAAA;AACH,CAAC;AAED,0EAA0E;AAE1E;uDACuD;AACvD,MAAM,UAAU,IAAI,CAAC,EACnB,KAAK,EACL,SAAS,EACT,GAAG,KAAK,EACsC;IAC9C,OAAO,CACL,6BACc,MAAM,EAClB,SAAS,EAAE,EAAE,CAAC,SAAS,EAAE,KAAK,IAAI,gBAAgB,EAAE,SAAS,CAAC,KAC1D,KAAK,GACT,CACH,CAAA;AACH,CAAC;AAaD;;sDAEsD;AACtD,MAAM,UAAU,IAAI,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAa;IACjF,OAAO,CACL,mBAAS,SAAS,EAAE,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,KAAM,KAAK,aACpD,KAAK,IAAI,cAAK,SAAS,EAAC,eAAe,iBAAa,MAAM,GAAG,EAC7D,SAAS,IAAI,CACZ,cAAK,SAAS,EAAC,oBAAoB,iBAAa,MAAM,YACnD,SAAS,GACN,CACP,EACD,cAAK,SAAS,EAAC,kBAAkB,YAAE,QAAQ,GAAO,IAC1C,CACX,CAAA;AACH,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,SAAS,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAgC;IAC7E,OAAO,cAAK,SAAS,EAAE,EAAE,CAAC,eAAe,EAAE,SAAS,CAAC,KAAM,KAAK,GAAI,CAAA;AACtE,CAAC;AAED;0DAC0D;AAC1D,MAAM,UAAU,UAAU,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAgC;IAC9E,OAAO,cAAK,SAAS,EAAE,EAAE,CAAC,iBAAiB,EAAE,SAAS,CAAC,KAAM,KAAK,GAAI,CAAA;AACxE,CAAC;AAYD;sEACsE;AACtE,MAAM,UAAU,KAAK,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAc;IAC3E,OAAO,CACL,6BACc,MAAM,EAClB,SAAS,EAAE,EAAE,CAAC,UAAU,EAAE,QAAQ,IAAI,aAAa,QAAQ,EAAE,EAAE,SAAS,CAAC,KACrE,KAAK,YAER,QAAQ,GACL,CACP,CAAA;AACH,CAAC;AAeD;;;;;;oEAMoE;AACpE,MAAM,UAAU,IAAI,CAClB,GAAc,EACd,MAA+C;IAE/C,IAAI,GAAG,KAAK,KAAK,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,4BAA4B,MAAM,EAAE,CAAA;IAC5F,IAAI,GAAG,KAAK,UAAU,IAAI,OAAO,MAAM,KAAK,QAAQ;QAClD,OAAO,sCAAsC,MAAM,EAAE,CAAA;IACvD,OAAO,WAAW,GAAG,EAAE,CAAA;AACzB,CAAC"}