@ramses1er/cbk-toolkit 1.0.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 ADDED
@@ -0,0 +1,280 @@
1
+ # CBK Toolkit
2
+
3
+ Package de composants React réutilisables, framework-agnostic.
4
+ **Livré avec son propre CSS Tailwind pré-compilé + la police Merriweather** — le consommateur n'a pas besoin d'installer Tailwind.
5
+
6
+ ```bash
7
+ npm install @ramses1er/cbk-toolkit
8
+ ```
9
+
10
+ ---
11
+
12
+ ## CSS et police
13
+
14
+ Le package fournit **tout le CSS nécessaire** (Tailwind + Merriweather).
15
+
16
+ ```tsx
17
+ import "@ramses1er/cbk-toolkit/styles.css";
18
+ ```
19
+
20
+ Ne **surtout pas** avoir d'import Tailwind parallèle dans votre CSS, sinon les valeurs du package (police Merriweather, thème) seront écrasées.
21
+
22
+ ### Dans un projet Next.js
23
+
24
+ Commenter ou supprimer ces lignes dans `src/app/globals.css` :
25
+
26
+ ```css
27
+ /* @import "tailwindcss"; */
28
+
29
+ /* @theme inline {
30
+ --color-background: var(--background);
31
+ --color-foreground: var(--foreground);
32
+ --font-sans: var(--font-geist-sans);
33
+ --font-mono: var(--font-geist-mono);
34
+ } */
35
+
36
+ /* body {
37
+ background: var(--background);
38
+ color: var(--foreground);
39
+ font-family: Arial, Helvetica, sans-serif;
40
+ } */
41
+ ```
42
+
43
+ Supprimer aussi `transpilePackages: ["@ramses1er/cbk-toolkit"]` de `next.config.ts` (inutile, le package est pré-compilé).
44
+
45
+ ---
46
+
47
+ ## SideNav
48
+
49
+ Sidebar de navigation latérale avec header, sous-menus imbriqués, footer et branding configurable. Compatible Next.js, Vite, React Router.
50
+
51
+ ### Installation
52
+
53
+ ```bash
54
+ npm install @ramses1er/cbk-toolkit
55
+ ```
56
+
57
+ ```tsx
58
+ import { SideNav, createSideNav } from "@ramses1er/cbk-toolkit";
59
+ import "@ramses1er/cbk-toolkit/styles.css";
60
+ import type { NavItem } from "@ramses1er/cbk-toolkit";
61
+ ```
62
+
63
+ ### API factory (recommandée)
64
+
65
+ Créer un fichier de configuration de la sidebar :
66
+
67
+ ```ts
68
+ // config/side-nav.ts
69
+ import { createSideNav } from "@ramses1er/cbk-toolkit";
70
+
71
+ export const MySideNav = createSideNav({
72
+ brand: {
73
+ name: "Genesis",
74
+ tagline: "Gestion scolaire",
75
+ logo: "/logo.png",
76
+ },
77
+ mainItems: [
78
+ { id: "dashboard", label: "Accueil", icon: "🏠", href: "/dashboard" },
79
+ {
80
+ id: "students",
81
+ label: "Élèves",
82
+ icon: "🎓",
83
+ href: "/students",
84
+ subItems: [
85
+ { id: "list", label: "Liste", href: "/students" },
86
+ { id: "classes", label: "Classes", href: "/students/classes" },
87
+ ],
88
+ },
89
+ { id: "payments", label: "Paiements", icon: "💳", href: "/payments" },
90
+ ],
91
+ footer: [
92
+ { icon: "⚙️", label: "Paramètres", href: "/settings" },
93
+ ],
94
+ });
95
+ ```
96
+
97
+ Le `title` du header est automatiquement déduit du menu actif (son `label` ou son champ `title` optionnel). Voir la section [Titre dynamique](#titre-dynamique).
98
+
99
+ ### Intégration dans le layout
100
+
101
+ #### Next.js (App Router)
102
+
103
+ ```tsx
104
+ // app/layout.tsx
105
+ "use client";
106
+
107
+ import { usePathname } from "next/navigation";
108
+ import { MySideNav } from "@/config/side-nav";
109
+ import "@ramses1er/cbk-toolkit/styles.css";
110
+
111
+ export default function Layout({ children }: { children: React.ReactNode }) {
112
+ const pathname = usePathname();
113
+
114
+ return (
115
+ <html lang="fr">
116
+ <body>
117
+ <MySideNav currentPath={pathname}>{children}</MySideNav>
118
+ </body>
119
+ </html>
120
+ );
121
+ }
122
+ ```
123
+
124
+ **Notes pour Next.js :**
125
+ - Le layout doit être `"use client"` à cause de `usePathname`
126
+ - Voir la section [CSS et police](#css-et-politique) pour les lignes à commenter dans `globals.css`
127
+ - Pas besoin de `transpilePackages` dans `next.config.ts`
128
+ - Pas besoin d'importer des polices via `next/font/google` — le package fournit Merriweather
129
+
130
+ #### Vite + React Router
131
+
132
+ ```tsx
133
+ // src/App.tsx ou src/layouts/MainLayout.tsx
134
+ import "@ramses1er/cbk-toolkit/styles.css";
135
+ import { MySideNav } from "./config/side-nav";
136
+ import { useLocation } from "react-router-dom";
137
+
138
+ function MainLayout({ children }: { children: React.ReactNode }) {
139
+ const { pathname } = useLocation();
140
+
141
+ return <MySideNav currentPath={pathname}>{children}</MySideNav>;
142
+ }
143
+
144
+ export default MainLayout;
145
+ ```
146
+
147
+ **Notes pour Vite :**
148
+ - Voir la section [CSS et police](#css-et-politique) pour les lignes à commenter dans `globals.css`
149
+ - Si vous utilisez PostCSS + Tailwind (`@tailwindcss/postcss`), supprimer la config ou ne pas importer Tailwind dans le CSS
150
+ - Pas besoin d'importer des polices via Google Fonts manuellement — le package fournit Merriweather
151
+
152
+ #### Vite vanilla (sans React Router)
153
+
154
+ ```tsx
155
+ import "@ramses1er/cbk-toolkit/styles.css";
156
+ import { MySideNav } from "./config/side-nav";
157
+ import { useState, useEffect } from "react";
158
+
159
+ function App() {
160
+ const [pathname, setPathname] = useState(window.location.pathname);
161
+
162
+ useEffect(() => {
163
+ const onPopState = () => setPathname(window.location.pathname);
164
+ window.addEventListener("popstate", onPopState);
165
+ return () => window.removeEventListener("popstate", onPopState);
166
+ }, []);
167
+
168
+ return <MySideNav currentPath={pathname}>{children}</MySideNav>;
169
+ }
170
+ ```
171
+
172
+ ### API directe
173
+
174
+ ```tsx
175
+ <SideNav
176
+ currentPath={pathname}
177
+ brand={{ name: "Mon App", logo: "/logo.svg", tagline: "Slogan" }}
178
+ mainItems={[
179
+ { id: "dashboard", label: "Dashboard", icon: "🏠", href: "/dashboard" },
180
+ { id: "students", label: "Élèves", icon: "🎓", href: "/students" },
181
+ ]}
182
+ title="Dashboard"
183
+ >
184
+ <YourContent />
185
+ </SideNav>
186
+ ```
187
+
188
+ ---
189
+
190
+ ## Titre dynamique
191
+
192
+ Le header affiché en haut de la page (à droite de la sidebar) est déterminé automatiquement selon cet ordre de priorité :
193
+
194
+ 1. **`title` explicite** (prop passée à `SideNav` ou `createSideNav`)
195
+ 2. **`title` optionnel** dans `NavItem` de l'entrée active
196
+ 3. **`label`** de l'entrée active (par défaut)
197
+
198
+ ```ts
199
+ mainItems: [
200
+ {
201
+ id: "dashboard",
202
+ label: "Accueil", // header = "Accueil"
203
+ title: "Tableau de bord", // header = "Tableau de bord" si défini
204
+ href: "/dashboard",
205
+ },
206
+ ];
207
+ ```
208
+
209
+ ---
210
+
211
+ ## Props
212
+
213
+ ### SideNavStaticConfig (configuration statique)
214
+
215
+ | Prop | Type | Défaut | Description |
216
+ |------|------|--------|-------------|
217
+ | `mainItems` | `NavItem[]` | requis | Entrées de navigation |
218
+ | `brand` | `{ logo?, name?, tagline? }` | — | Branding en haut de la sidebar |
219
+ | `footer` | `{ icon?, label, href }[]` | — | Liens en pied de sidebar |
220
+ | `title` | `string` | — | Titre du header (override le titre auto) |
221
+ | `toggleIcon` | `ReactNode` | `"▼"/"▶"` | Icône de toggle des sous-menus |
222
+
223
+ ### Props dynamiques (passées au render)
224
+
225
+ | Prop | Type | Défaut | Description |
226
+ |------|------|--------|-------------|
227
+ | `children` | `ReactNode` | requis | Contenu principal |
228
+ | `currentPath` | `string` | requis | Chemin actif pour le surlignage |
229
+
230
+ ### NavItem
231
+
232
+ ```ts
233
+ type NavItem = {
234
+ id: string;
235
+ label: string;
236
+ title?: string; // Optionnel : surcharge le titre dans le header
237
+ icon?: ReactNode;
238
+ href: string;
239
+ subItems?: NavItem[];
240
+ };
241
+ ```
242
+
243
+ ---
244
+
245
+ ## Police Merriweather
246
+
247
+ Le package charge et applique automatiquement Merriweather (poids 300, 400, 700, 900) via Google Fonts avec `display=swap`. Aucune configuration requise.
248
+
249
+ **Pour que la police fonctionne :**
250
+ - Le CSS du package (`@ramses1er/cbk-toolkit/styles.css`) doit être importé **avant** le CSS local
251
+ - Ne pas avoir d'import Tailwind parallèle qui écrase `--font-sans`
252
+ - Ne pas avoir `body { font-family: ... }` dans son propre CSS qui écrase la valeur
253
+
254
+ ---
255
+
256
+ ## Composants commentés
257
+
258
+ Les composants suivants sont temporairement mis en commentaire en attendant leur refactoring :
259
+
260
+ Confirmation, Date, ErrorDisplay, FieldContainer, Form, HeaderContent, Input, InputSearch, InstallPrompt, Label, LoaderSubmit, Loading, Modal, Option, Select, SelectSearch, SwRegistration, Table, TextArea, TopicIllustration
261
+
262
+ ---
263
+
264
+ ## Développement
265
+
266
+ ```bash
267
+ pnpm install
268
+ pnpm dev # Build watch avec tsup (JS uniquement)
269
+ pnpm build # Build JS + CSS de production (dist/)
270
+ ```
271
+
272
+ Le CSS est généré via Tailwind v4 en scannant les sources `packages/*/src/`.
273
+ Les fichiers de sortie :
274
+
275
+ ```
276
+ dist/
277
+ index.js # Bundle JS (composants)
278
+ index.d.ts # Types TypeScript
279
+ styles.css # CSS Tailwind compilé + Merriweather (minifié)
280
+ ```
@@ -0,0 +1,41 @@
1
+ import * as react from 'react';
2
+ import { ReactNode, ComponentType } from 'react';
3
+
4
+ type IconType = ReactNode | ComponentType<{
5
+ size?: number;
6
+ }>;
7
+ interface NavItem {
8
+ id: string;
9
+ label: string;
10
+ title?: string;
11
+ icon?: IconType;
12
+ href: string;
13
+ subItems?: NavItem[];
14
+ }
15
+ interface SideNavStaticConfig {
16
+ brand?: {
17
+ logo?: ReactNode;
18
+ name?: string;
19
+ tagline?: string;
20
+ };
21
+ mainItems: NavItem[];
22
+ title?: string;
23
+ footer?: {
24
+ icon?: IconType;
25
+ label: string;
26
+ href: string;
27
+ }[];
28
+ toggleIcon?: ReactNode;
29
+ }
30
+ interface SideNavProps extends SideNavStaticConfig {
31
+ children: ReactNode;
32
+ currentPath: string;
33
+ }
34
+ declare function SideNav({ children, title, mainItems, currentPath, brand, footer, toggleIcon, }: SideNavProps): react.JSX.Element;
35
+
36
+ declare function createSideNav(config: SideNavStaticConfig): ({ children, currentPath, }: {
37
+ children: React.ReactNode;
38
+ currentPath: string;
39
+ }) => react.JSX.Element;
40
+
41
+ export { type NavItem, SideNav, type SideNavProps, type SideNavStaticConfig, createSideNav };
package/dist/index.js ADDED
@@ -0,0 +1,135 @@
1
+ // packages/ui/src/layouts/side-nav.tsx
2
+ import {
3
+ useState,
4
+ createElement,
5
+ isValidElement
6
+ } from "react";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ function isActive(href, currentPath) {
9
+ return currentPath === href || currentPath.startsWith(href + "/");
10
+ }
11
+ function isExactActive(href, currentPath) {
12
+ return currentPath === href;
13
+ }
14
+ function SideNav({
15
+ children,
16
+ title,
17
+ mainItems,
18
+ currentPath,
19
+ brand,
20
+ footer,
21
+ toggleIcon
22
+ }) {
23
+ const activeMain = mainItems.find((item) => isActive(item.href, currentPath));
24
+ const headerTitle = title ?? activeMain?.title ?? activeMain?.label;
25
+ const [expandedSection, setExpandedSection] = useState(
26
+ activeMain?.id ?? null
27
+ );
28
+ const toggleSection = (id) => {
29
+ setExpandedSection((prev) => prev === id ? null : id);
30
+ };
31
+ return /* @__PURE__ */ jsxs("div", { className: "flex min-h-screen", children: [
32
+ /* @__PURE__ */ jsxs("aside", { className: "w-64 bg-white border-r border-gray-200 flex flex-col fixed h-full", children: [
33
+ brand && /* @__PURE__ */ jsx("div", { className: "p-[6.5px] border-b border-gray-100", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-row gap-2 items-center", children: [
34
+ brand.logo && (typeof brand.logo === "string" ? /* @__PURE__ */ jsx(
35
+ "img",
36
+ {
37
+ src: brand.logo,
38
+ alt: brand.name ?? "",
39
+ className: "w-12.5 h-12.5"
40
+ }
41
+ ) : brand.logo),
42
+ brand.name && /* @__PURE__ */ jsx("p", { className: "text-gray-500 text-base font-semibold", children: brand.name })
43
+ ] }) }),
44
+ /* @__PURE__ */ jsx("nav", { className: "flex-1 p-4 overflow-y-auto", children: /* @__PURE__ */ jsx("ul", { className: "space-y-1", children: mainItems.map((item) => {
45
+ const active = isActive(item.href, currentPath);
46
+ const isExpanded = expandedSection === item.id;
47
+ const hasSubItems = item.subItems && item.subItems.length > 0;
48
+ return /* @__PURE__ */ jsxs("li", { children: [
49
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
50
+ /* @__PURE__ */ jsxs(
51
+ "a",
52
+ {
53
+ href: item.href,
54
+ className: `flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium transition-colors flex-1 ${active ? "bg-gray-200 text-black" : "text-gray-500 hover:bg-gray-100"}`,
55
+ children: [
56
+ item.icon && (typeof item.icon === "string" ? /* @__PURE__ */ jsx("span", { className: "text-lg", children: item.icon }) : isValidElement(item.icon) ? item.icon : createElement(
57
+ item.icon,
58
+ { size: 20 }
59
+ )),
60
+ item.label
61
+ ]
62
+ }
63
+ ),
64
+ active && hasSubItems && /* @__PURE__ */ jsx(
65
+ "button",
66
+ {
67
+ onClick: () => toggleSection(item.id),
68
+ className: `p-1.5 rounded-lg transition-colors ${active ? "text-black hover:bg-gray-100" : "text-gray-500 hover:bg-gray-100"}`,
69
+ title: isExpanded ? "R\xE9duire" : "D\xE9velopper",
70
+ children: toggleIcon ? /* @__PURE__ */ jsx(
71
+ "span",
72
+ {
73
+ className: `inline-block transition-transform duration-200 ${isExpanded ? "rotate-0" : "-rotate-90"}`,
74
+ children: toggleIcon
75
+ }
76
+ ) : /* @__PURE__ */ jsx("span", { className: "text-xs", children: isExpanded ? "\u25BC" : "\u25B6" })
77
+ }
78
+ )
79
+ ] }),
80
+ active && hasSubItems && /* @__PURE__ */ jsx(
81
+ "div",
82
+ {
83
+ className: `grid transition-all duration-300 ease-in-out ${isExpanded ? "grid-rows-[1fr]" : "grid-rows-[0fr]"}`,
84
+ children: /* @__PURE__ */ jsx("div", { className: "overflow-hidden", children: /* @__PURE__ */ jsx("ul", { className: "ml-4 mt-1 space-y-1 pl-2", children: item.subItems.map((sub) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
85
+ "a",
86
+ {
87
+ href: sub.href,
88
+ className: `flex items-center gap-2 px-3 py-2 rounded-lg text-sm font-medium transition-colors ${isExactActive(sub.href, currentPath) ? "bg-gray-200 text-black" : "text-gray-500 hover:bg-gray-100"}`,
89
+ children: sub.label
90
+ }
91
+ ) }, sub.id)) }) })
92
+ }
93
+ )
94
+ ] }, item.id);
95
+ }) }) }),
96
+ footer && footer.length > 0 && /* @__PURE__ */ jsx("div", { className: "p-4 border-t border-gray-100 space-y-1", children: footer.map((item) => /* @__PURE__ */ jsxs(
97
+ "a",
98
+ {
99
+ href: item.href,
100
+ className: "flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium text-gray-700 hover:bg-gray-100 transition-colors",
101
+ children: [
102
+ typeof item.icon === "string" ? /* @__PURE__ */ jsx("span", { className: "text-lg", children: item.icon }) : isValidElement(item.icon) ? item.icon : createElement(item.icon, {
103
+ size: 20
104
+ }),
105
+ item.label
106
+ ]
107
+ },
108
+ item.label
109
+ )) })
110
+ ] }),
111
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 ml-64", children: [
112
+ headerTitle && /* @__PURE__ */ jsxs("header", { className: "h-16 bg-white border-b border-gray-200 flex items-center justify-between px-6 fixed top-0 right-0 left-64 z-10", children: [
113
+ /* @__PURE__ */ jsx("h1", { className: "text-base font-semibold text-gray-500", children: headerTitle }),
114
+ brand?.tagline && /* @__PURE__ */ jsx("span", { className: "text-sm text-gray-500", children: brand.tagline })
115
+ ] }),
116
+ /* @__PURE__ */ jsx("main", { className: headerTitle ? "p-6 pt-20" : "p-6", children })
117
+ ] })
118
+ ] });
119
+ }
120
+
121
+ // packages/ui/src/config/create-side-nav.tsx
122
+ import { jsx as jsx2 } from "react/jsx-runtime";
123
+ function createSideNav(config) {
124
+ return function ConfiguredSideNav({
125
+ children,
126
+ currentPath
127
+ }) {
128
+ return /* @__PURE__ */ jsx2(SideNav, { ...config, currentPath, children });
129
+ };
130
+ }
131
+ export {
132
+ SideNav,
133
+ createSideNav
134
+ };
135
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../packages/ui/src/layouts/side-nav.tsx","../packages/ui/src/config/create-side-nav.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n ReactNode,\n useState,\n createElement,\n isValidElement,\n type ComponentType,\n} from \"react\";\n\ntype IconType = ReactNode | ComponentType<{ size?: number }>;\n\nexport interface NavItem {\n id: string;\n label: string;\n title?: string;\n icon?: IconType;\n href: string;\n subItems?: NavItem[];\n}\n\nexport interface SideNavStaticConfig {\n brand?: {\n logo?: ReactNode;\n name?: string;\n tagline?: string;\n };\n mainItems: NavItem[];\n title?: string;\n footer?: { icon?: IconType; label: string; href: string }[];\n toggleIcon?: ReactNode;\n}\n\nexport interface SideNavProps extends SideNavStaticConfig {\n children: ReactNode;\n currentPath: string;\n}\n\nfunction isActive(href: string, currentPath: string) {\n return currentPath === href || currentPath.startsWith(href + \"/\");\n}\n\nfunction isExactActive(href: string, currentPath: string) {\n return currentPath === href;\n}\n\nexport function SideNav({\n children,\n title,\n mainItems,\n currentPath,\n brand,\n footer,\n toggleIcon,\n}: SideNavProps) {\n const activeMain = mainItems.find((item) => isActive(item.href, currentPath));\n const headerTitle = title ?? activeMain?.title ?? activeMain?.label;\n const [expandedSection, setExpandedSection] = useState<string | null>(\n activeMain?.id ?? null,\n );\n\n const toggleSection = (id: string) => {\n setExpandedSection((prev) => (prev === id ? null : id));\n };\n\n return (\n <div className=\"flex min-h-screen\">\n <aside className=\"w-64 bg-white border-r border-gray-200 flex flex-col fixed h-full\">\n {brand && (\n <div className=\"p-[6.5px] border-b border-gray-100\">\n <div className=\"flex flex-row gap-2 items-center\">\n {brand.logo &&\n (typeof brand.logo === \"string\" ? (\n <img\n src={brand.logo}\n alt={brand.name ?? \"\"}\n className=\"w-12.5 h-12.5\"\n />\n ) : (\n brand.logo\n ))}\n {brand.name && (\n <p className=\"text-gray-500 text-base font-semibold\">\n {brand.name}\n </p>\n )}\n </div>\n </div>\n )}\n\n <nav className=\"flex-1 p-4 overflow-y-auto\">\n <ul className=\"space-y-1\">\n {mainItems.map((item) => {\n const active = isActive(item.href, currentPath);\n const isExpanded = expandedSection === item.id;\n const hasSubItems = item.subItems && item.subItems.length > 0;\n\n return (\n <li key={item.id}>\n <div className=\"flex items-center gap-1\">\n <a\n href={item.href}\n className={`flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium transition-colors flex-1 ${\n active\n ? \"bg-gray-200 text-black\"\n : \"text-gray-500 hover:bg-gray-100\"\n }`}\n >\n {item.icon &&\n (typeof item.icon === \"string\" ? (\n <span className=\"text-lg\">{item.icon}</span>\n ) : isValidElement(item.icon) ? (\n item.icon\n ) : (\n createElement(\n item.icon as ComponentType<{ size?: number }>,\n { size: 20 },\n )\n ))}\n {item.label}\n </a>\n {active && hasSubItems && (\n <button\n onClick={() => toggleSection(item.id)}\n className={`p-1.5 rounded-lg transition-colors ${\n active\n ? \"text-black hover:bg-gray-100\"\n : \"text-gray-500 hover:bg-gray-100\"\n }`}\n title={isExpanded ? \"Réduire\" : \"Développer\"}\n >\n {toggleIcon ? (\n <span\n className={`inline-block transition-transform duration-200 ${\n isExpanded ? \"rotate-0\" : \"-rotate-90\"\n }`}\n >\n {toggleIcon}\n </span>\n ) : (\n <span className=\"text-xs\">\n {isExpanded ? \"▼\" : \"▶\"}\n </span>\n )}\n </button>\n )}\n </div>\n\n {active && hasSubItems && (\n <div\n className={`grid transition-all duration-300 ease-in-out ${\n isExpanded ? \"grid-rows-[1fr]\" : \"grid-rows-[0fr]\"\n }`}\n >\n <div className=\"overflow-hidden\">\n <ul className=\"ml-4 mt-1 space-y-1 pl-2\">\n {item.subItems!.map((sub) => (\n <li key={sub.id}>\n <a\n href={sub.href}\n className={`flex items-center gap-2 px-3 py-2 rounded-lg text-sm font-medium transition-colors ${\n isExactActive(sub.href, currentPath)\n ? \"bg-gray-200 text-black\"\n : \"text-gray-500 hover:bg-gray-100\"\n }`}\n >\n {sub.label}\n </a>\n </li>\n ))}\n </ul>\n </div>\n </div>\n )}\n </li>\n );\n })}\n </ul>\n </nav>\n\n {footer && footer.length > 0 && (\n <div className=\"p-4 border-t border-gray-100 space-y-1\">\n {footer.map((item) => (\n <a\n key={item.label}\n href={item.href}\n className=\"flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium text-gray-700 hover:bg-gray-100 transition-colors\"\n >\n {typeof item.icon === \"string\" ? (\n <span className=\"text-lg\">{item.icon}</span>\n ) : isValidElement(item.icon) ? (\n item.icon\n ) : (\n createElement(item.icon as ComponentType<{ size?: number }>, {\n size: 20,\n })\n )}\n {item.label}\n </a>\n ))}\n </div>\n )}\n </aside>\n\n <div className=\"flex-1 ml-64\">\n {headerTitle && (\n <header className=\"h-16 bg-white border-b border-gray-200 flex items-center justify-between px-6 fixed top-0 right-0 left-64 z-10\">\n <h1 className=\"text-base font-semibold text-gray-500\">\n {headerTitle}\n </h1>\n {brand?.tagline && (\n <span className=\"text-sm text-gray-500\">{brand.tagline}</span>\n )}\n </header>\n )}\n <main className={headerTitle ? \"p-6 pt-20\" : \"p-6\"}>{children}</main>\n </div>\n </div>\n );\n}\n","import { SideNav, type SideNavStaticConfig } from \"../layouts/side-nav\";\n\nexport function createSideNav(config: SideNavStaticConfig) {\n return function ConfiguredSideNav({\n children,\n currentPath,\n }: {\n children: React.ReactNode;\n currentPath: string;\n }) {\n return (\n <SideNav {...config} currentPath={currentPath}>\n {children}\n </SideNav>\n );\n };\n}\n"],"mappings":"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","names":["jsx"]}
@@ -0,0 +1,2 @@
1
+ /*! tailwindcss v4.3.1 | MIT License | https://tailwindcss.com */
2
+ @import "https://fonts.googleapis.com/css2?family=Merriweather:wght@300;400;700;900&display=swap";@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}@layer theme{:root,:host{--font-sans:"Merriweather", Georgia, serif;--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-100:oklch(93.6% .032 17.717);--color-red-200:oklch(88.5% .062 18.334);--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-red-700:oklch(50.5% .213 27.518);--color-yellow-50:oklch(98.7% .026 102.212);--color-yellow-100:oklch(97.3% .071 103.193);--color-yellow-200:oklch(94.5% .129 101.54);--color-yellow-700:oklch(55.4% .135 66.442);--color-blue-50:oklch(97% .014 254.604);--color-blue-100:oklch(93.2% .032 255.585);--color-blue-200:oklch(88.2% .059 254.128);--color-blue-300:oklch(80.9% .105 251.813);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-blue-700:oklch(48.8% .243 264.376);--color-blue-800:oklch(42.4% .199 265.638);--color-blue-900:oklch(37.9% .146 265.522);--color-blue-950:oklch(28.2% .091 267.935);--color-gray-50:oklch(98.5% .002 247.839);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-500:oklch(55.1% .027 264.364);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-800:oklch(27.8% .033 256.848);--color-gray-900:oklch(21% .034 264.665);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-md:28rem;--container-2xl:42rem;--container-5xl:64rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25 / 1.875);--text-5xl:3rem;--text-5xl--line-height:1;--text-6xl:3.75rem;--text-6xl--line-height:1;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-wider:.05em;--leading-relaxed:1.625;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--radius-2xl:1rem;--ease-in-out:cubic-bezier(.4, 0, .2, 1);--animate-spin:spin 1s linear infinite;--blur-sm:8px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:0}.inset-y-0{inset-block:0}.top-0{top:0}.top-1\/2{top:50%}.top-2{top:calc(var(--spacing) * 2)}.right-0{right:0}.right-2{right:calc(var(--spacing) * 2)}.right-4{right:calc(var(--spacing) * 4)}.right-8{right:calc(var(--spacing) * 8)}.bottom-4{bottom:calc(var(--spacing) * 4)}.left-0{left:0}.left-4{left:calc(var(--spacing) * 4)}.left-64{left:calc(var(--spacing) * 64)}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-40{z-index:40}.z-50{z-index:50}.mx-4{margin-inline:calc(var(--spacing) * 4)}.mx-auto{margin-inline:auto}.mt-1{margin-top:var(--spacing)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-6{margin-top:calc(var(--spacing) * 6)}.mt-auto{margin-top:auto}.mr-2{margin-right:calc(var(--spacing) * 2)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.ml-1{margin-left:var(--spacing)}.ml-4{margin-left:calc(var(--spacing) * 4)}.ml-64{margin-left:calc(var(--spacing) * 64)}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.table{display:table}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-10{height:calc(var(--spacing) * 10)}.h-12\.5{height:calc(var(--spacing) * 12.5)}.h-14{height:calc(var(--spacing) * 14)}.h-16{height:calc(var(--spacing) * 16)}.h-full{height:100%}.max-h-60{max-height:calc(var(--spacing) * 60)}.max-h-\[85vh\]{max-height:85vh}.min-h-0{min-height:0}.min-h-\[200px\]{min-height:200px}.min-h-screen{min-height:100vh}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-7{width:calc(var(--spacing) * 7)}.w-8{width:calc(var(--spacing) * 8)}.w-10{width:calc(var(--spacing) * 10)}.w-12\.5{width:calc(var(--spacing) * 12.5)}.w-14{width:calc(var(--spacing) * 14)}.w-64{width:calc(var(--spacing) * 64)}.w-full{width:100%}.max-w-2xl{max-width:var(--container-2xl)}.max-w-5xl{max-width:var(--container-5xl)}.max-w-md{max-width:var(--container-md)}.min-w-\[32px\]{min-width:32px}.flex-1{flex:1}.shrink-0{flex-shrink:0}.table-fixed{table-layout:fixed}.-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-full{--tw-translate-y:-100%;translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-y-0{--tw-translate-y:0;translate:var(--tw-translate-x) var(--tw-translate-y)}.-rotate-90{rotate:-90deg}.rotate-0{rotate:0deg}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-spin{animation:var(--animate-spin)}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.resize-none{resize:none}.list-inside{list-style-position:inside}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.appearance-none{appearance:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-rows-\[0fr\]{grid-template-rows:0fr}.grid-rows-\[1fr\]{grid-template-rows:1fr}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1{gap:var(--spacing)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}:where(.space-y-0\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * .5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * .5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(var(--spacing) * var(--tw-space-y-reverse));margin-block-end:calc(var(--spacing) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-8>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 8) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 8) * calc(1 - var(--tw-space-y-reverse)))}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-gray-200>:not(:last-child)){border-color:var(--color-gray-200)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-t-lg{border-top-left-radius:var(--radius-lg);border-top-right-radius:var(--radius-lg)}.rounded-b-md{border-bottom-right-radius:var(--radius-md);border-bottom-left-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-blue-100{border-color:var(--color-blue-100)}.border-blue-200{border-color:var(--color-blue-200)}.border-gray-100{border-color:var(--color-gray-100)}.border-gray-200{border-color:var(--color-gray-200)}.border-gray-300{border-color:var(--color-gray-300)}.border-gray-400{border-color:var(--color-gray-400)}.border-red-200{border-color:var(--color-red-200)}.border-yellow-200{border-color:var(--color-yellow-200)}.bg-\[\#0C44AA\]{background-color:#0c44aa}.bg-black\/20{background-color:#0003}@supports (color:color-mix(in lab, red, red)){.bg-black\/20{background-color:color-mix(in oklab, var(--color-black) 20%, transparent)}}.bg-blue-50{background-color:var(--color-blue-50)}.bg-blue-100{background-color:var(--color-blue-100)}.bg-blue-500{background-color:var(--color-blue-500)}.bg-gray-50{background-color:var(--color-gray-50)}.bg-gray-100{background-color:var(--color-gray-100)}.bg-gray-200{background-color:var(--color-gray-200)}.bg-gray-700{background-color:var(--color-gray-700)}.bg-gray-800{background-color:var(--color-gray-800)}.bg-gray-900{background-color:var(--color-gray-900)}.bg-red-50{background-color:var(--color-red-50)}.bg-red-100{background-color:var(--color-red-100)}.bg-red-400{background-color:var(--color-red-400)}.bg-red-500{background-color:var(--color-red-500)}.bg-white{background-color:var(--color-white)}.bg-yellow-50{background-color:var(--color-yellow-50)}.bg-yellow-100{background-color:var(--color-yellow-100)}.bg-gradient-to-br{--tw-gradient-position:to bottom right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-blue-50{--tw-gradient-from:var(--color-blue-50);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.to-blue-100{--tw-gradient-to:var(--color-blue-100);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.bg-contain{background-size:contain}.bg-right{background-position:100%}.bg-no-repeat{background-repeat:no-repeat}.p-1{padding:var(--spacing)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.p-\[6\.5px\]{padding:6.5px}.px-1{padding-inline:var(--spacing)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-20{padding-block:calc(var(--spacing) * 20)}.pt-20{padding-top:calc(var(--spacing) * 20)}.pr-3{padding-right:calc(var(--spacing) * 3)}.pr-10{padding-right:calc(var(--spacing) * 10)}.pr-16{padding-right:calc(var(--spacing) * 16)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pl-2{padding-left:calc(var(--spacing) * 2)}.text-center{text-align:center}.text-left{text-align:left}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-5xl{font-size:var(--text-5xl);line-height:var(--tw-leading,var(--text-5xl--line-height))}.text-6xl{font-size:var(--text-6xl);line-height:var(--tw-leading,var(--text-6xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.whitespace-nowrap{white-space:nowrap}.text-black{color:var(--color-black)}.text-blue-600{color:var(--color-blue-600)}.text-blue-700{color:var(--color-blue-700)}.text-blue-800{color:var(--color-blue-800)}.text-gray-100{color:var(--color-gray-100)}.text-gray-200{color:var(--color-gray-200)}.text-gray-300{color:var(--color-gray-300)}.text-gray-400{color:var(--color-gray-400)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-gray-700{color:var(--color-gray-700)}.text-gray-800{color:var(--color-gray-800)}.text-gray-900{color:var(--color-gray-900)}.text-red-400{color:var(--color-red-400)}.text-red-500{color:var(--color-red-500)}.text-red-600{color:var(--color-red-600)}.text-red-700{color:var(--color-red-700)}.text-white{color:var(--color-white)}.text-yellow-700{color:var(--color-yellow-700)}.uppercase{text-transform:uppercase}.underline{text-decoration-line:underline}.placeholder-gray-400::placeholder{color:var(--color-gray-400)}.opacity-0{opacity:0}.opacity-60{opacity:.6}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-1{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-gray-900\/5{--tw-ring-color:#1018280d}@supports (color:color-mix(in lab, red, red)){.ring-gray-900\/5{--tw-ring-color:color-mix(in oklab, var(--color-gray-900) 5%, transparent)}}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ring-inset{--tw-ring-inset:inset}@media (hover:hover){.group-hover\:from-blue-100:is(:where(.group):hover *){--tw-gradient-from:var(--color-blue-100);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.group-hover\:to-blue-200:is(:where(.group):hover *){--tw-gradient-to:var(--color-blue-200);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.group-hover\:text-blue-700:is(:where(.group):hover *){color:var(--color-blue-700)}.group-hover\:text-gray-600:is(:where(.group):hover *){color:var(--color-gray-600)}.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}.group-hover\:ring-blue-300\/50:is(:where(.group):hover *){--tw-ring-color:#90c5ff80}@supports (color:color-mix(in lab, red, red)){.group-hover\:ring-blue-300\/50:is(:where(.group):hover *){--tw-ring-color:color-mix(in oklab, var(--color-blue-300) 50%, transparent)}}.hover\:cursor-pointer:hover{cursor:pointer}.hover\:border-blue-300:hover{border-color:var(--color-blue-300)}.hover\:bg-\[\#0a3a94\]:hover{background-color:#0a3a94}.hover\:bg-blue-600:hover{background-color:var(--color-blue-600)}.hover\:bg-blue-700:hover{background-color:var(--color-blue-700)}.hover\:bg-gray-50:hover{background-color:var(--color-gray-50)}.hover\:bg-gray-100:hover{background-color:var(--color-gray-100)}.hover\:bg-gray-600:hover{background-color:var(--color-gray-600)}.hover\:bg-red-200:hover{background-color:var(--color-red-200)}.hover\:bg-red-500:hover{background-color:var(--color-red-500)}.hover\:text-gray-600:hover{color:var(--color-gray-600)}.hover\:text-gray-700:hover{color:var(--color-gray-700)}.hover\:text-red-600:hover{color:var(--color-red-600)}.hover\:shadow:hover{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.hover\:shadow-xl:hover{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}}.focus\:border-transparent:focus{border-color:#0000}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus\:ring-blue-400:focus{--tw-ring-color:var(--color-blue-400)}.focus\:ring-blue-500:focus{--tw-ring-color:var(--color-blue-500)}.focus\:ring-gray-500:focus{--tw-ring-color:var(--color-gray-500)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.active\:scale-95:active{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x) var(--tw-scale-y)}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}@media (hover:hover){.disabled\:hover\:bg-red-500:disabled:hover{background-color:var(--color-red-500)}.disabled\:hover\:bg-white:disabled:hover{background-color:var(--color-white)}}@media (min-width:48rem){.md\:inline-flex{display:inline-flex}.md\:flex-row{flex-direction:row}.md\:items-center{align-items:center}.md\:justify-between{justify-content:space-between}}@media (prefers-color-scheme:dark){.dark\:border-blue-900{border-color:var(--color-blue-900)}.dark\:bg-blue-600{background-color:var(--color-blue-600)}.dark\:bg-blue-900{background-color:var(--color-blue-900)}.dark\:bg-blue-950{background-color:var(--color-blue-950)}.dark\:bg-gray-800{background-color:var(--color-gray-800)}.dark\:text-blue-300{color:var(--color-blue-300)}.dark\:text-gray-100{color:var(--color-gray-100)}.dark\:text-gray-300{color:var(--color-gray-300)}.dark\:text-gray-400{color:var(--color-gray-400)}@media (hover:hover){.dark\:hover\:bg-blue-500:hover{background-color:var(--color-blue-500)}.dark\:hover\:bg-gray-700:hover{background-color:var(--color-gray-700)}.dark\:hover\:text-gray-300:hover{color:var(--color-gray-300)}}}@media print{.print\:hidden{display:none}.print\:table-row-group{display:table-row-group}.print\:table-fixed{table-layout:fixed}}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"<length-percentage>";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"<length-percentage>";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"<length-percentage>";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@keyframes spin{to{transform:rotate(360deg)}}
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@ramses1er/cbk-toolkit",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.js",
7
+ "exports": {
8
+ ".": {
9
+ "import": "./dist/index.js",
10
+ "types": "./dist/index.d.ts"
11
+ },
12
+ "./styles.css": "./dist/styles.css"
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "peerDependencies": {
18
+ "react": ">=18",
19
+ "react-dom": ">=18"
20
+ },
21
+ "devDependencies": {
22
+ "@tailwindcss/cli": "^4.3.1",
23
+ "@types/react": "^19",
24
+ "@types/react-dom": "^19",
25
+ "tailwindcss": "^4.3.1",
26
+ "tsup": "^8.5.0"
27
+ },
28
+ "scripts": {
29
+ "build": "tsup && pnpm build:css",
30
+ "build:css": "pnpm exec tailwindcss -i src/styles.css -o dist/styles.css --minify",
31
+ "dev": "tsup --watch",
32
+ "clean": "rm -rf dist"
33
+ }
34
+ }