@tollerud/ui 3.0.0 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/AGENTS.md +5 -3
  2. package/CHANGELOG.md +67 -0
  3. package/COMPONENTS.md +13 -1
  4. package/README.md +1 -0
  5. package/SKILL.md +8 -5
  6. package/components.json +1 -1
  7. package/dist/avatar.d.ts +3 -2
  8. package/dist/avatar.js +1 -1
  9. package/dist/bento-dashboard.js +6 -1
  10. package/dist/button.d.ts +3 -3
  11. package/dist/button.js +1 -1
  12. package/dist/checkbox.js +1 -1
  13. package/dist/{chunk-7TOT5ME3.js → chunk-3LTW224O.js} +6 -6
  14. package/dist/chunk-3LTW224O.js.map +1 -0
  15. package/dist/chunk-AQT3FZRQ.js +23 -0
  16. package/dist/chunk-AQT3FZRQ.js.map +1 -0
  17. package/dist/{chunk-RWJELAS6.js → chunk-BQWF5MP7.js} +14 -6
  18. package/dist/chunk-BQWF5MP7.js.map +1 -0
  19. package/dist/{chunk-VTRUUT5K.js → chunk-FPFLOYIJ.js} +6 -6
  20. package/dist/chunk-FPFLOYIJ.js.map +1 -0
  21. package/dist/{chunk-6SKTH45H.js → chunk-J2Z4ZFVX.js} +29 -18
  22. package/dist/chunk-J2Z4ZFVX.js.map +1 -0
  23. package/dist/{chunk-ISHZ6ZPJ.js → chunk-JFOW2DI5.js} +17 -5
  24. package/dist/chunk-JFOW2DI5.js.map +1 -0
  25. package/dist/{chunk-3TGMGBKM.js → chunk-K4ALNUZI.js} +6 -6
  26. package/dist/{chunk-3TGMGBKM.js.map → chunk-K4ALNUZI.js.map} +1 -1
  27. package/dist/chunk-LGVXEWNB.js +54 -0
  28. package/dist/chunk-LGVXEWNB.js.map +1 -0
  29. package/dist/{chunk-OONIUDST.js → chunk-OLHMMFQ7.js} +3 -8
  30. package/dist/chunk-OLHMMFQ7.js.map +1 -0
  31. package/dist/{chunk-V3P5QLLX.js → chunk-Q54CVE3W.js} +3 -3
  32. package/dist/{chunk-V3P5QLLX.js.map → chunk-Q54CVE3W.js.map} +1 -1
  33. package/dist/chunk-QEIEWGHA.js +62 -0
  34. package/dist/chunk-QEIEWGHA.js.map +1 -0
  35. package/dist/{chunk-CBQ63EBL.js → chunk-QQHBEACI.js} +9 -6
  36. package/dist/chunk-QQHBEACI.js.map +1 -0
  37. package/dist/{chunk-XR5QBVEV.js → chunk-SNNMZ444.js} +3 -3
  38. package/dist/{chunk-XR5QBVEV.js.map → chunk-SNNMZ444.js.map} +1 -1
  39. package/dist/chunk-T3UQ7G4T.js +58 -0
  40. package/dist/chunk-T3UQ7G4T.js.map +1 -0
  41. package/dist/{chunk-T3TQPOVM.js → chunk-TLEKK53J.js} +5 -8
  42. package/dist/chunk-TLEKK53J.js.map +1 -0
  43. package/dist/{chunk-DGCRHVWW.js → chunk-VFS3V3VY.js} +12 -5
  44. package/dist/chunk-VFS3V3VY.js.map +1 -0
  45. package/dist/chunk-VOARBYVQ.js +44 -0
  46. package/dist/chunk-VOARBYVQ.js.map +1 -0
  47. package/dist/{chunk-O57QMLNI.js → chunk-YTU7BRDW.js} +16 -12
  48. package/dist/chunk-YTU7BRDW.js.map +1 -0
  49. package/dist/{chunk-DFM7UUKB.js → chunk-ZTFOR3AN.js} +4 -4
  50. package/dist/{chunk-DFM7UUKB.js.map → chunk-ZTFOR3AN.js.map} +1 -1
  51. package/dist/cta-band.js +1 -1
  52. package/dist/data-table.js +4 -4
  53. package/dist/date-picker.js +1 -1
  54. package/dist/footer.js +2 -1
  55. package/dist/form-row.d.ts +4 -0
  56. package/dist/form-row.js +1 -1
  57. package/dist/hero-block.js +3 -3
  58. package/dist/index.d.ts +1 -0
  59. package/dist/index.js +24 -23
  60. package/dist/monogram.d.ts +20 -0
  61. package/dist/monogram.js +5 -0
  62. package/dist/monogram.js.map +1 -0
  63. package/dist/noir-glow-background.d.ts +7 -1
  64. package/dist/noir-glow-background.js +1 -1
  65. package/dist/pill.d.ts +5 -2
  66. package/dist/pill.js +1 -1
  67. package/dist/pricing-card.js +2 -2
  68. package/dist/radio-group.d.ts +6 -0
  69. package/dist/radio-group.js +1 -1
  70. package/dist/skeleton.d.ts +10 -2
  71. package/dist/skeleton.js +1 -1
  72. package/dist/slider.js +1 -1
  73. package/dist/switch.js +1 -1
  74. package/dist/timeline.js +1 -1
  75. package/globals-layers.css +111 -1
  76. package/package.json +5 -3
  77. package/registry.json +30 -9
  78. package/tokens.css +49 -5
  79. package/tollerud-avatar-full.png +0 -0
  80. package/dist/chunk-6SKTH45H.js.map +0 -1
  81. package/dist/chunk-7TOT5ME3.js.map +0 -1
  82. package/dist/chunk-CBQ63EBL.js.map +0 -1
  83. package/dist/chunk-DGCRHVWW.js.map +0 -1
  84. package/dist/chunk-FGXOV2QH.js +0 -23
  85. package/dist/chunk-FGXOV2QH.js.map +0 -1
  86. package/dist/chunk-HYQGOC2E.js +0 -79
  87. package/dist/chunk-HYQGOC2E.js.map +0 -1
  88. package/dist/chunk-ISHZ6ZPJ.js.map +0 -1
  89. package/dist/chunk-O57QMLNI.js.map +0 -1
  90. package/dist/chunk-OONIUDST.js.map +0 -1
  91. package/dist/chunk-PLF3BBQI.js +0 -139
  92. package/dist/chunk-PLF3BBQI.js.map +0 -1
  93. package/dist/chunk-Q74VRQEX.js +0 -26
  94. package/dist/chunk-Q74VRQEX.js.map +0 -1
  95. package/dist/chunk-RWJELAS6.js.map +0 -1
  96. package/dist/chunk-T3TQPOVM.js.map +0 -1
  97. package/dist/chunk-VTRUUT5K.js.map +0 -1
  98. /package/{tia-full-figure.svg → tollerud-avatar-full.svg} +0 -0
package/AGENTS.md CHANGED
@@ -134,8 +134,8 @@ import { BarChart, AreaChart, Donut, Sparkline, HeroBlock, FeatureCard, CTABand
134
134
  // Infra / homelab set
135
135
  import { HostCard, ServiceHealthCard, DockerStackCard, IncidentCard } from '@tollerud/ui'
136
136
  import { ApprovalCard, ActionDiff, AlertInbox, RollbackPlan, BackupStatusPanel } from '@tollerud/ui'
137
- // Footer
138
- import { Footer } from '@tollerud/ui' // or: import { Footer } from '@tollerud/footer'
137
+ // Footer & branding
138
+ import { Footer, Monogram } from '@tollerud/ui' // or: import { Footer } from '@tollerud/footer'
139
139
  ```
140
140
 
141
141
  ### Button
@@ -330,7 +330,9 @@ Monogram sizing: top bar/sidebar expanded → `h-5`, sidebar collapsed → `h-6`
330
330
 
331
331
  ```html
332
332
  <h1 class="tollerud-display text-[70px]">Dark. Monochrome.</h1>
333
- <h2 class="tollerud-display--secondary text-[40px]">Yellow where it counts</h2>
333
+ <h2 class="tollerud-display--secondary text-[40px]">
334
+ <span class="tollerud-display-shimmer">Yellow where it counts</span>
335
+ </h2>
334
336
  ```
335
337
 
336
338
  ### Container
package/CHANGELOG.md CHANGED
@@ -7,6 +7,73 @@
7
7
  • Never write bold mid-paragraph as a heading substitute — it merges into surrounding text
8
8
  -->
9
9
 
10
+ ## 3.1.1 — 2026-06-09 — Display shimmer, form indicators, and button fixes
11
+
12
+ Patch release: ships hero text shimmer for consumer apps, fixes secondary/checkbox/radio styling, and polishes docs layout components.
13
+
14
+ ### New utilities
15
+
16
+ - `.tollerud-display-shimmer` — animated yellow gradient clipped to text; respects `prefers-reduced-motion` (static `var(--primary)` fallback)
17
+
18
+ ### Fixes
19
+
20
+ - `Button` — secondary variant restores raised surface and border (theme-aware CSS vars); all variants apply layer classes again
21
+ - `Checkbox` — checkmark visible on `defaultChecked` and click via `peer-checked` on the custom indicator
22
+ - `RadioGroup` — wires `value`, `onChange`, and `name` to children; inner dot shows when selected
23
+ - `CTABand` — title and description centered in the band
24
+ - `BentoDashboard` — section spacing and label alignment
25
+ - Docs `PageTOC` — restores `jumpToSection` import for in-page scroll
26
+
27
+ ### Registry
28
+
29
+ - Top-level `name` → `Tollerud User Interface`; updated description and component metadata for blocks
30
+
31
+ ### Docs
32
+
33
+ - Overview, Backgrounds, and Foundations Typography use `.tollerud-display-shimmer` (replaces docs-only `.ds-shimmer`)
34
+ - Light theme shimmer and secondary-button token overrides
35
+
36
+ ### Migration
37
+
38
+ Drop-in. Replace any copied `.ds-shimmer` with `.tollerud-display-shimmer` from `@tollerud/ui/globals.css`.
39
+
40
+ ---
41
+
42
+ ## 3.1.0 — 2026-06-09 — Monogram component and docs fixes
43
+
44
+ Restores component styling in the docs site, ships the monogram as an npm component, and renames brand avatar assets.
45
+
46
+ ### New components
47
+
48
+ - `Monogram` — inline SVG with `color`: `yellow` | `black` | `white`, optional `size` and `title`
49
+
50
+ ### Fixes
51
+
52
+ - `Button` — `terminal` variant uses layer classes again
53
+ - `Pill`, `Avatar`, `Skeleton`, `Timeline`, `Switch`, `Slider`, `FormRow` — layer-class / prop adapter fixes
54
+ - `DatePicker` — calendar popover `z-50`
55
+ - `DataTable` — explicit `text-left` on column headers
56
+ - `CTABand` — inline accent bar margin
57
+ - `BentoDashboard` — real infra cards instead of placeholders
58
+ - `Footer` — uses `<Monogram color="yellow" />`
59
+ - `NoirGlowBackground` — `scale` and `offsetX` for edge-biased shader placement
60
+
61
+ ### Brand assets
62
+
63
+ - `tia-full-figure.svg` renamed to `tollerud-avatar-full.svg` (plus PNG export)
64
+ - npm exports: `@tollerud/ui/tollerud-avatar-full.svg` and `@tollerud/ui/tollerud-avatar-full.png`
65
+
66
+ ### Docs
67
+
68
+ - Docs-only brand layer: `Monogram`, `TiaPortrait`, `TollerudAvatarFull`, `NavLockup` under `@/components/brand`
69
+ - Tailwind `@source` fix, light-mode monogram via `currentColor`, onboarding/auth/foundations page updates
70
+
71
+ ### Migration
72
+
73
+ Drop-in. Replace any copied `tia-full-figure` paths with `tollerud-avatar-full`. Use `<Monogram />` instead of inline SVG or `<img src={logo}>` where you need theme-aware fill.
74
+
75
+ ---
76
+
10
77
  ## 3.0.0 — 2026-06-09 — ESM-only and rich DataTable
11
78
 
12
79
  Ships the full table pattern in npm, drops CommonJS builds, and adds release/props tooling.
package/COMPONENTS.md CHANGED
@@ -786,10 +786,22 @@ The config-driven table. Pass `rows` + a `columns` spec and opt into search, a f
786
786
 
787
787
  ```html
788
788
  <h1 class="tollerud-display text-[70px]">Dark. Monochrome.</h1>
789
- <h2 class="tollerud-display--secondary text-[40px]">Yellow where it counts</h2>
789
+ <h2 class="tollerud-display--secondary text-[40px]">
790
+ <span class="tollerud-display-shimmer">Yellow where it counts</span>
791
+ </h2>
790
792
  <h3 class="tollerud-display--tertiary text-[28px]">Subtle hierarchy</h3>
791
793
  ```
792
794
 
795
+ ## Display shimmer
796
+
797
+ Animated yellow gradient clipped to text — for hero accent lines and key metrics on **dark surfaces**. Respects `prefers-reduced-motion` (falls back to static `var(--primary)` / `var(--tollerud-yellow)`).
798
+
799
+ ```html
800
+ <span class="tollerud-display-shimmer">Yellow where it counts.</span>
801
+ ```
802
+
803
+ Pair with `.tollerud-display` on the parent heading. Not for body copy or light backgrounds (yellow fails contrast on white).
804
+
793
805
  ## Container
794
806
 
795
807
  ```jsx
package/README.md CHANGED
@@ -288,4 +288,5 @@ New additions inspired by [Graphify Labs](https://graphifylabs.ai/):
288
288
  | Accent Bar | `.tollerud-accent-bar` | `bg-tollerud-gradient-bar h-[1px]` | Gradient divider bar |
289
289
  | Gradient Text | `.tollerud-gradient-text` | `bg-tollerud-gradient-soft bg-clip-text text-transparent` | Yellow → amber gradient text |
290
290
  | Display Heading | `.tollerud-display` | `tracking-tightest leading-[0.95] font-semibold text-white` | Tight, impactful display heads |
291
+ | Display Shimmer | `.tollerud-display-shimmer` | — | Animated yellow gradient sweep clipped to hero accent text (dark surfaces) |
291
292
  | Section Container | `.tollerud-section` | `max-w-[1100px] mx-auto px-6` | Content width constraint |
package/SKILL.md CHANGED
@@ -20,7 +20,7 @@ npm install @tollerud/ui clsx tailwind-merge tailwindcss@4 \
20
20
  npm install @paper-design/shaders-react
21
21
  ```
22
22
 
23
- As of **v3.0.0**, the package is **ESM-only** (no CJS `require` entry). As of **v2.0.0**, Radix, Lucide, Framer Motion, and Sonner are **required peers** (not bundled).
23
+ As of **v3.1.1**, `.tollerud-display-shimmer` ships in `globals.css` for animated hero accent text. As of **v3.1.0**, `Monogram` ships as an inline SVG component (`color`: `yellow` | `black` | `white`). As of **v3.0.0**, the package is **ESM-only** (no CJS `require` entry). As of **v2.0.0**, Radix, Lucide, Framer Motion, and Sonner are **required peers** (not bundled).
24
24
 
25
25
  Apply the Tailwind preset when you need extra utilities from `tollerud-preset.js` — `globals.css` already includes tokens and component layers for v4:
26
26
 
@@ -445,8 +445,7 @@ import type { IncidentSeverity } from '@tollerud/ui'
445
445
  ### Footer & branding
446
446
 
447
447
  ```tsx
448
- import { Footer } from '@tollerud/ui'
449
- import logo from '@tollerud/ui/tollerud-logo.svg'
448
+ import { Footer, Monogram } from '@tollerud/ui'
450
449
 
451
450
  <Footer layout="responsive" accent labels={{ tollerudProject: 'A Tollerud Project' }} />
452
451
  ```
@@ -454,10 +453,12 @@ The monogram must always sit left of the project name with `gap-2`. Never show t
454
453
 
455
454
  ```tsx
456
455
  <div className="flex items-center gap-2 shrink-0">
457
- <img src={logo} alt="Tollerud" className="h-5 w-auto" />
456
+ <Monogram color="yellow" className="h-5 w-auto" />
458
457
  <span className="font-semibold text-sm text-white">Project Name</span>
459
458
  </div>
460
459
  ```
460
+
461
+ **Monogram** — `color?: 'yellow' | 'black' | 'white'` (default `yellow`), `size?: number`, `title?: string` (default `'Tollerud'`). Brand avatars: `@tollerud/ui/tollerud-avatar.svg`, `tollerud-avatar-full.svg` (+ `.png` variants).
461
462
  Monogram sizing: top bar/sidebar expanded → `h-5`, collapsed → `h-6`, footer → `h-4` (handled automatically by `<Footer />`).
462
463
 
463
464
  ---
@@ -468,7 +469,9 @@ Monogram sizing: top bar/sidebar expanded → `h-5`, collapsed → `h-6`, footer
468
469
  <nav class="tollerud-glass fixed top-0 inset-x-0 z-50 h-14 flex items-center px-6">…</nav>
469
470
  <section class="tollerud-grid-bg">…</section>
470
471
  <h1 class="tollerud-display text-[70px]">Dark. Monochrome.</h1>
471
- <h2 class="tollerud-display--secondary text-[40px]">Yellow where it counts</h2>
472
+ <h2 class="tollerud-display--secondary text-[40px]">
473
+ <span class="tollerud-display-shimmer">Yellow where it counts</span>
474
+ </h2>
472
475
  <div data-density="compact">…dense tables / forms…</div>
473
476
  ```
474
477
 
package/components.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://ui.shadcn.com/schema.json",
3
- "name": "tollerud-noir",
3
+ "name": "Tollerud User Interface",
4
4
  "style": "default",
5
5
  "rsc": true,
6
6
  "tsx": true,
package/dist/avatar.d.ts CHANGED
@@ -13,13 +13,14 @@ interface AvatarProps extends HTMLAttributes<HTMLSpanElement> {
13
13
  name?: string;
14
14
  /** Explicit fallback content (overrides derived initials) */
15
15
  fallback?: React.ReactNode;
16
- size?: keyof typeof avatarSizes;
16
+ /** Named size token or explicit pixel diameter */
17
+ size?: keyof typeof avatarSizes | number;
17
18
  }
18
19
  declare const Avatar: react.ForwardRefExoticComponent<AvatarProps & react.RefAttributes<HTMLSpanElement>>;
19
20
  interface AvatarGroupProps extends HTMLAttributes<HTMLDivElement> {
20
21
  /** Maximum avatars to render before collapsing into a "+N" overflow indicator */
21
22
  max?: number;
22
- size?: keyof typeof avatarSizes;
23
+ size?: keyof typeof avatarSizes | number;
23
24
  children: React.ReactNode;
24
25
  }
25
26
  declare const AvatarGroup: react.ForwardRefExoticComponent<AvatarGroupProps & react.RefAttributes<HTMLDivElement>>;
package/dist/avatar.js CHANGED
@@ -1,5 +1,5 @@
1
1
  'use client';
2
- export { Avatar, AvatarGroup } from './chunk-DGCRHVWW.js';
2
+ export { Avatar, AvatarGroup } from './chunk-VFS3V3VY.js';
3
3
  import './chunk-WSQNPRGN.js';
4
4
  //# sourceMappingURL=avatar.js.map
5
5
  //# sourceMappingURL=avatar.js.map
@@ -1,5 +1,10 @@
1
1
  'use client';
2
- export { BentoDashboard } from './chunk-PLF3BBQI.js';
2
+ export { BentoDashboard } from './chunk-LGVXEWNB.js';
3
+ import './chunk-LUM2YJBH.js';
4
+ import './chunk-7EP2T3OW.js';
5
+ import './chunk-DOUDJU4P.js';
6
+ import './chunk-NHPISZWS.js';
7
+ import './chunk-EN4OJCEF.js';
3
8
  import './chunk-WSQNPRGN.js';
4
9
  //# sourceMappingURL=bento-dashboard.js.map
5
10
  //# sourceMappingURL=bento-dashboard.js.map
package/dist/button.d.ts CHANGED
@@ -3,10 +3,10 @@ import { ButtonHTMLAttributes } from 'react';
3
3
 
4
4
  declare const variants: {
5
5
  readonly primary: "bg-tollerud-yellow text-tollerud-black border-tollerud-yellow hover:bg-tollerud-yellow hover:shadow-tollerud-glow";
6
- readonly secondary: "bg-transparent text-tollerud-text-primary border-tollerud-border hover:border-tollerud-text-secondary hover:bg-tollerud-surface-hover";
7
- readonly ghost: "bg-transparent text-tollerud-text-secondary border-transparent hover:text-tollerud-text-primary hover:bg-tollerud-surface-hover";
6
+ readonly secondary: "text-tollerud-text-primary [background:var(--surface-raised,var(--tollerud-surface-raised))] [border-color:var(--border,var(--tollerud-border))] hover:[border-color:var(--text-secondary,var(--tollerud-text-secondary))] hover:[background:var(--surface-hover,var(--tollerud-surface-hover))]";
7
+ readonly ghost: "text-tollerud-text-secondary border-transparent hover:text-tollerud-text-primary hover:bg-tollerud-surface-hover";
8
8
  readonly destructive: "bg-tollerud-error text-white border-tollerud-error hover:shadow-[0_0_12px_rgba(239,68,68,0.3)]";
9
- readonly terminal: "font-mono text-tollerud-yellow border-[rgba(255,255,0,0.25)] bg-transparent before:content-[\"❯_\"] before:opacity-70 hover:border-tollerud-yellow hover:shadow-tollerud-glow hover:bg-[rgba(255,255,0,0.05)]";
9
+ readonly terminal: "font-mono text-tollerud-yellow border-[rgba(255,255,0,0.25)] bg-transparent hover:border-tollerud-yellow hover:shadow-tollerud-glow hover:bg-[rgba(255,255,0,0.05)]";
10
10
  };
11
11
  declare const sizes: {
12
12
  readonly sm: "px-3 py-1 text-sm";
package/dist/button.js CHANGED
@@ -1,5 +1,5 @@
1
1
  'use client';
2
- export { Button, buttonVariants } from './chunk-RWJELAS6.js';
2
+ export { Button, buttonVariants } from './chunk-BQWF5MP7.js';
3
3
  import './chunk-WSQNPRGN.js';
4
4
  //# sourceMappingURL=button.js.map
5
5
  //# sourceMappingURL=button.js.map
package/dist/checkbox.js CHANGED
@@ -1,5 +1,5 @@
1
1
  'use client';
2
- export { Checkbox } from './chunk-T3TQPOVM.js';
2
+ export { Checkbox } from './chunk-TLEKK53J.js';
3
3
  import './chunk-WSQNPRGN.js';
4
4
  //# sourceMappingURL=checkbox.js.map
5
5
  //# sourceMappingURL=checkbox.js.map
@@ -23,10 +23,10 @@ var Timeline = forwardRef(
23
23
  className: cn(
24
24
  "tollerud-timeline__dot",
25
25
  active && "tollerud-timeline__dot--active",
26
- item.status === "online" && "bg-tollerud-success shadow-[0_0_6px_rgba(34,197,94,0.5)]",
27
- item.status === "offline" && "bg-tollerud-error",
28
- item.status === "warning" && "bg-tollerud-yellow shadow-[0_0_6px_rgba(232,213,0,0.5)]",
29
- !item.status && "bg-tollerud-noir-500"
26
+ item.status === "online" && "tollerud-timeline__dot--online",
27
+ item.status === "offline" && "tollerud-timeline__dot--offline",
28
+ item.status === "warning" && "tollerud-timeline__dot--warning",
29
+ item.status === "idle" && "tollerud-timeline__dot--idle"
30
30
  )
31
31
  }
32
32
  ),
@@ -49,5 +49,5 @@ var Timeline = forwardRef(
49
49
  Timeline.displayName = "Timeline";
50
50
 
51
51
  export { Timeline };
52
- //# sourceMappingURL=chunk-7TOT5ME3.js.map
53
- //# sourceMappingURL=chunk-7TOT5ME3.js.map
52
+ //# sourceMappingURL=chunk-3LTW224O.js.map
53
+ //# sourceMappingURL=chunk-3LTW224O.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../components/Timeline.tsx"],"names":[],"mappings":";;;;AA6BA,IAAM,QAAA,GAAW,UAAA;AAAA,EACf,CAAC,EAAE,SAAA,EAAW,KAAA,EAAO,QAAQ,OAAA,EAAS,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AACxD,IAAA,uBACE,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,SAAA,EAAW,EAAA,CAAG,mBAAA,EAAqB,OAAA,IAAW,iBAAiB,SAAS,CAAA;AAAA,QACxE,IAAA,EAAK,MAAA;AAAA,QACL,YAAA,EAAW,mBAAA;AAAA,QACV,GAAG,KAAA;AAAA,QAEH,QAAA,EAAA,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,EAAM,CAAA,KAAM;AACtB,UAAA,MAAM,MAAA,GAAS,CAAA,KAAM,KAAA,CAAM,MAAA,GAAS,CAAA;AAEpC,UAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAkB,SAAA,EAAU,yBAAA,EAA0B,MAAK,UAAA,EAE1D,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,SAAI,SAAA,EAAU,2BAAA,EACb,QAAA,kBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,8BAAA,EACZ,QAAA,EAAA;AAAA,cAAA,IAAA,CAAK,uBACJ,GAAA,CAAC,MAAA,EAAA,EAAK,WAAU,yBAAA,EAA2B,QAAA,EAAA,IAAA,CAAK,MAAK,CAAA,mBAErD,GAAA;AAAA,gBAAC,MAAA;AAAA,gBAAA;AAAA,kBACC,SAAA,EAAW,EAAA;AAAA,oBACT,wBAAA;AAAA,oBACA,MAAA,IAAU,gCAAA;AAAA,oBACV,IAAA,CAAK,WAAW,QAAA,IAAY,gCAAA;AAAA,oBAC5B,IAAA,CAAK,WAAW,SAAA,IAAa,iCAAA;AAAA,oBAC7B,IAAA,CAAK,WAAW,SAAA,IAAa,iCAAA;AAAA,oBAC7B,IAAA,CAAK,WAAW,MAAA,IAAU;AAAA;AAC5B;AAAA,eACF;AAAA,cAED,CAAC,MAAA,oBAAU,GAAA,CAAC,KAAA,EAAA,EAAI,WAAU,yBAAA,EAA0B;AAAA,aAAA,EACvD,CAAA,EACF,CAAA;AAAA,4BAGA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,4BAAA,EACb,QAAA,EAAA;AAAA,8BAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,wCAAA,EACb,QAAA,EAAA;AAAA,gCAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,0BAAA,EAA4B,QAAA,EAAA,IAAA,CAAK,KAAA,EAAM,CAAA;AAAA,gCACvD,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,yBAAA,EAA2B,eAAK,IAAA,EAAK;AAAA,eAAA,EACvD,CAAA;AAAA,cACC,KAAK,WAAA,oBACJ,GAAA,CAAC,OAAE,SAAA,EAAU,gCAAA,EAAkC,eAAK,WAAA,EAAY,CAAA;AAAA,cAEjE,IAAA,CAAK,QAAQ,IAAA,CAAK,IAAA,CAAK,SAAS,CAAA,oBAC/B,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,6BAAA,EACZ,QAAA,EAAA,IAAA,CAAK,KAAK,GAAA,CAAI,CAAC,sBACd,GAAA,CAAC,MAAA,EAAA,EAAa,WAAU,yBAAA,EAA2B,QAAA,EAAA,CAAA,EAAA,EAAxC,CAA0C,CACtD,CAAA,EACH;AAAA,aAAA,EAEJ;AAAA,WAAA,EAAA,EAtCQ,KAAK,EAuCf,CAAA;AAAA,QAEJ,CAAC;AAAA;AAAA,KACH;AAAA,EAEJ;AACF;AACA,QAAA,CAAS,WAAA,GAAc,UAAA","file":"chunk-3LTW224O.js","sourcesContent":["import { type HTMLAttributes, type ReactNode, forwardRef } from 'react'\nimport { cn } from '@/lib/utils'\nimport type { Status } from './StatusDot'\n\nexport interface TimelineItemData {\n id: string\n /** Timestamp label */\n time: string\n /** Title/headline of the event */\n title: string\n /** Description */\n description?: string\n /** Status indicator dot */\n status?: Status\n /** Optional icon to replace dot */\n icon?: ReactNode\n /** Optional metadata badges */\n meta?: string[]\n}\n\nexport interface TimelineProps extends HTMLAttributes<HTMLDivElement> {\n /** Timeline events */\n items: TimelineItemData[]\n /** Whether items are active (show animated dot pulse) */\n active?: boolean\n /** Whether the timeline is loading */\n loading?: boolean\n}\n\nconst Timeline = forwardRef<HTMLDivElement, TimelineProps>(\n ({ className, items, active, loading, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn('tollerud-timeline', loading && 'animate-pulse', className)}\n role=\"list\"\n aria-label=\"Activity timeline\"\n {...props}\n >\n {items.map((item, i) => {\n const isLast = i === items.length - 1\n\n return (\n <div key={item.id} className=\"tollerud-timeline__item\" role=\"listitem\">\n {/* Dot column */}\n <div className=\"tollerud-timeline__marker\">\n <div className=\"tollerud-timeline__dot-group\">\n {item.icon ? (\n <span className=\"tollerud-timeline__icon\">{item.icon}</span>\n ) : (\n <span\n className={cn(\n 'tollerud-timeline__dot',\n active && 'tollerud-timeline__dot--active',\n item.status === 'online' && 'tollerud-timeline__dot--online',\n item.status === 'offline' && 'tollerud-timeline__dot--offline',\n item.status === 'warning' && 'tollerud-timeline__dot--warning',\n item.status === 'idle' && 'tollerud-timeline__dot--idle'\n )}\n />\n )}\n {!isLast && <div className=\"tollerud-timeline__line\" />}\n </div>\n </div>\n\n {/* Content */}\n <div className=\"tollerud-timeline__content\">\n <div className=\"flex items-start justify-between gap-2\">\n <span className=\"tollerud-timeline__title\">{item.title}</span>\n <span className=\"tollerud-timeline__time\">{item.time}</span>\n </div>\n {item.description && (\n <p className=\"tollerud-timeline__description\">{item.description}</p>\n )}\n {item.meta && item.meta.length > 0 && (\n <div className=\"flex flex-wrap gap-1.5 mt-1\">\n {item.meta.map((m) => (\n <span key={m} className=\"tollerud-timeline__meta\">{m}</span>\n ))}\n </div>\n )}\n </div>\n </div>\n )\n })}\n </div>\n )\n }\n)\nTimeline.displayName = 'Timeline'\n\nexport { Timeline }"]}
@@ -0,0 +1,23 @@
1
+ 'use client';
2
+ import { cn } from './chunk-WSQNPRGN.js';
3
+ import { jsx } from 'react/jsx-runtime';
4
+
5
+ function Skeleton({ className, h, w, r, style, ...props }) {
6
+ return /* @__PURE__ */ jsx(
7
+ "div",
8
+ {
9
+ className: cn("tollerud-skeleton", className),
10
+ style: {
11
+ ...h != null ? { height: h } : null,
12
+ ...w != null ? { width: w } : null,
13
+ ...r != null ? { borderRadius: r } : null,
14
+ ...style
15
+ },
16
+ ...props
17
+ }
18
+ );
19
+ }
20
+
21
+ export { Skeleton };
22
+ //# sourceMappingURL=chunk-AQT3FZRQ.js.map
23
+ //# sourceMappingURL=chunk-AQT3FZRQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../components/Skeleton.tsx"],"names":[],"mappings":";;;AAWA,SAAS,QAAA,CAAS,EAAE,SAAA,EAAW,CAAA,EAAG,GAAG,CAAA,EAAG,KAAA,EAAO,GAAG,KAAA,EAAM,EAAkB;AACxE,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA,CAAG,mBAAA,EAAqB,SAAS,CAAA;AAAA,MAC5C,KAAA,EAAO;AAAA,QACL,GAAI,CAAA,IAAK,IAAA,GAAO,EAAE,MAAA,EAAQ,GAAE,GAAI,IAAA;AAAA,QAChC,GAAI,CAAA,IAAK,IAAA,GAAO,EAAE,KAAA,EAAO,GAAE,GAAI,IAAA;AAAA,QAC/B,GAAI,CAAA,IAAK,IAAA,GAAO,EAAE,YAAA,EAAc,GAAE,GAAI,IAAA;AAAA,QACtC,GAAG;AAAA,OACL;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ","file":"chunk-AQT3FZRQ.js","sourcesContent":["import { cn } from '@/lib/utils'\n\nexport interface SkeletonProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Shorthand height in px (or any CSS length via className) */\n h?: number | string\n /** Shorthand width in px or percentage string e.g. \"60%\" */\n w?: number | string\n /** Shorthand border-radius in px */\n r?: number | string\n}\n\nfunction Skeleton({ className, h, w, r, style, ...props }: SkeletonProps) {\n return (\n <div\n className={cn('tollerud-skeleton', className)}\n style={{\n ...(h != null ? { height: h } : null),\n ...(w != null ? { width: w } : null),\n ...(r != null ? { borderRadius: r } : null),\n ...style,\n }}\n {...props}\n />\n )\n}\n\nexport { Skeleton }\n"]}
@@ -6,10 +6,17 @@ import { jsx } from 'react/jsx-runtime';
6
6
 
7
7
  var variants = {
8
8
  primary: "bg-tollerud-yellow text-tollerud-black border-tollerud-yellow hover:bg-tollerud-yellow hover:shadow-tollerud-glow",
9
- secondary: "bg-transparent text-tollerud-text-primary border-tollerud-border hover:border-tollerud-text-secondary hover:bg-tollerud-surface-hover",
10
- ghost: "bg-transparent text-tollerud-text-secondary border-transparent hover:text-tollerud-text-primary hover:bg-tollerud-surface-hover",
9
+ secondary: "text-tollerud-text-primary [background:var(--surface-raised,var(--tollerud-surface-raised))] [border-color:var(--border,var(--tollerud-border))] hover:[border-color:var(--text-secondary,var(--tollerud-text-secondary))] hover:[background:var(--surface-hover,var(--tollerud-surface-hover))]",
10
+ ghost: "text-tollerud-text-secondary border-transparent hover:text-tollerud-text-primary hover:bg-tollerud-surface-hover",
11
11
  destructive: "bg-tollerud-error text-white border-tollerud-error hover:shadow-[0_0_12px_rgba(239,68,68,0.3)]",
12
- terminal: 'font-mono text-tollerud-yellow border-[rgba(255,255,0,0.25)] bg-transparent before:content-["\u276F_"] before:opacity-70 hover:border-tollerud-yellow hover:shadow-tollerud-glow hover:bg-[rgba(255,255,0,0.05)]'
12
+ terminal: "font-mono text-tollerud-yellow border-[rgba(255,255,0,0.25)] bg-transparent hover:border-tollerud-yellow hover:shadow-tollerud-glow hover:bg-[rgba(255,255,0,0.05)]"
13
+ };
14
+ var variantLayers = {
15
+ primary: "tollerud-btn--primary",
16
+ secondary: "tollerud-btn--secondary",
17
+ ghost: "tollerud-btn--ghost",
18
+ destructive: "tollerud-btn--destructive",
19
+ terminal: "tollerud-btn--terminal"
13
20
  };
14
21
  var sizes = {
15
22
  sm: "px-3 py-1 text-sm",
@@ -18,10 +25,11 @@ var sizes = {
18
25
  };
19
26
  function buttonVariants({ variant = "secondary", size = "md", className } = {}) {
20
27
  return cn(
21
- "inline-flex items-center justify-center gap-2 font-semibold rounded transition-all duration-[150ms] focus-visible:outline-2 focus-visible:outline-tollerud-yellow focus-visible:outline-offset-2",
28
+ "tollerud-btn inline-flex items-center justify-center gap-2 font-semibold rounded transition-all duration-[150ms] focus-visible:outline-2 focus-visible:outline-tollerud-yellow focus-visible:outline-offset-2",
22
29
  "border cursor-pointer",
23
30
  "disabled:opacity-50 disabled:pointer-events-none",
24
31
  variants[variant],
32
+ variantLayers[variant],
25
33
  sizes[size],
26
34
  className
27
35
  );
@@ -42,5 +50,5 @@ var Button = forwardRef(
42
50
  Button.displayName = "Button";
43
51
 
44
52
  export { Button, buttonVariants };
45
- //# sourceMappingURL=chunk-RWJELAS6.js.map
46
- //# sourceMappingURL=chunk-RWJELAS6.js.map
53
+ //# sourceMappingURL=chunk-BQWF5MP7.js.map
54
+ //# sourceMappingURL=chunk-BQWF5MP7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../components/Button.tsx"],"names":[],"mappings":";;;;;AAIA,IAAM,QAAA,GAAW;AAAA,EACf,OAAA,EAAS,mHAAA;AAAA,EACT,SAAA,EACE,kSAAA;AAAA,EACF,KAAA,EAAO,kHAAA;AAAA,EACP,WAAA,EAAa,gGAAA;AAAA,EACb,QAAA,EAAU;AACZ,CAAA;AAGA,IAAM,aAAA,GAAgB;AAAA,EACpB,OAAA,EAAS,uBAAA;AAAA,EACT,SAAA,EAAW,yBAAA;AAAA,EACX,KAAA,EAAO,qBAAA;AAAA,EACP,WAAA,EAAa,2BAAA;AAAA,EACb,QAAA,EAAU;AACZ,CAAA;AAEA,IAAM,KAAA,GAAQ;AAAA,EACZ,EAAA,EAAI,mBAAA;AAAA,EACJ,EAAA,EAAI,qBAAA;AAAA,EACJ,EAAA,EAAI;AACN,CAAA;AAOO,SAAS,cAAA,CAAe,EAAE,OAAA,GAAU,WAAA,EAAa,OAAO,IAAA,EAAM,SAAA,EAAU,GAAiD,EAAC,EAAG;AAClI,EAAA,OAAO,EAAA;AAAA,IACL,+MAAA;AAAA,IACA,uBAAA;AAAA,IACA,kDAAA;AAAA,IACA,SAAS,OAAO,CAAA;AAAA,IAChB,cAAc,OAAO,CAAA;AAAA,IACrB,MAAM,IAAI,CAAA;AAAA,IACV;AAAA,GACF;AACF;AAOA,IAAM,MAAA,GAAS,UAAA;AAAA,EACb,CAAC,EAAE,SAAA,EAAW,OAAA,GAAU,WAAA,EAAa,IAAA,GAAO,IAAA,EAAM,OAAA,GAAU,KAAA,EAAO,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AACrF,IAAA,MAAM,IAAA,GAAO,UAAU,IAAA,GAAO,QAAA;AAC9B,IAAA,uBACE,GAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,WAAW,cAAA,CAAe,EAAE,OAAA,EAAS,IAAA,EAAM,WAAW,CAAA;AAAA,QACrD,GAAG;AAAA;AAAA,KACN;AAAA,EAEJ;AACF;AACA,MAAA,CAAO,WAAA,GAAc,QAAA","file":"chunk-BQWF5MP7.js","sourcesContent":["import { type ButtonHTMLAttributes, forwardRef } from 'react'\nimport { Slot } from '@radix-ui/react-slot'\nimport { cn } from '@/lib/utils'\n\nconst variants = {\n primary: 'bg-tollerud-yellow text-tollerud-black border-tollerud-yellow hover:bg-tollerud-yellow hover:shadow-tollerud-glow',\n secondary:\n 'text-tollerud-text-primary [background:var(--surface-raised,var(--tollerud-surface-raised))] [border-color:var(--border,var(--tollerud-border))] hover:[border-color:var(--text-secondary,var(--tollerud-text-secondary))] hover:[background:var(--surface-hover,var(--tollerud-surface-hover))]',\n ghost: 'text-tollerud-text-secondary border-transparent hover:text-tollerud-text-primary hover:bg-tollerud-surface-hover',\n destructive: 'bg-tollerud-error text-white border-tollerud-error hover:shadow-[0_0_12px_rgba(239,68,68,0.3)]',\n terminal: 'font-mono text-tollerud-yellow border-[rgba(255,255,0,0.25)] bg-transparent hover:border-tollerud-yellow hover:shadow-tollerud-glow hover:bg-[rgba(255,255,0,0.05)]',\n} as const\n\n/** Layer classes from globals-layers.css — ❯ prefix, hover glow, magnetic glow in docs */\nconst variantLayers = {\n primary: 'tollerud-btn--primary',\n secondary: 'tollerud-btn--secondary',\n ghost: 'tollerud-btn--ghost',\n destructive: 'tollerud-btn--destructive',\n terminal: 'tollerud-btn--terminal',\n} as const\n\nconst sizes = {\n sm: 'px-3 py-1 text-sm',\n md: 'px-4 py-2 text-base',\n lg: 'px-6 py-3 text-lg',\n} as const\n\nexport interface ButtonVariantProps {\n variant?: keyof typeof variants\n size?: keyof typeof sizes\n}\n\nexport function buttonVariants({ variant = 'secondary', size = 'md', className }: ButtonVariantProps & { className?: string } = {}) {\n return cn(\n 'tollerud-btn inline-flex items-center justify-center gap-2 font-semibold rounded transition-all duration-[150ms] focus-visible:outline-2 focus-visible:outline-tollerud-yellow focus-visible:outline-offset-2',\n 'border cursor-pointer',\n 'disabled:opacity-50 disabled:pointer-events-none',\n variants[variant],\n variantLayers[variant],\n sizes[size],\n className\n )\n}\n\nexport interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement>, ButtonVariantProps {\n /** Render as the single child element (e.g. a `<Link>`) instead of a `<button>`, merging props and styles onto it. */\n asChild?: boolean\n}\n\nconst Button = forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant = 'secondary', size = 'md', asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot : 'button'\n return (\n <Comp\n ref={ref}\n className={buttonVariants({ variant, size, className })}\n {...props}\n />\n )\n }\n)\nButton.displayName = 'Button'\n\nexport { Button }\n"]}
@@ -10,15 +10,15 @@ var CTABand = forwardRef(
10
10
  {
11
11
  ref,
12
12
  className: cn(
13
- "rounded-xl border border-tollerud-border bg-tollerud-surface px-8 py-11 text-center",
13
+ "tollerud-card w-full rounded-xl border border-tollerud-border bg-tollerud-surface px-8 py-11 text-center",
14
14
  className
15
15
  ),
16
16
  ...props,
17
17
  children: [
18
- /* @__PURE__ */ jsx("h2", { className: "tollerud-display text-[30px] text-tollerud-text-primary", children: title }),
19
- description && /* @__PURE__ */ jsx("p", { className: "mx-auto mt-3 max-w-[440px] text-[15px] text-tollerud-text-secondary", children: description }),
18
+ /* @__PURE__ */ jsx("h2", { className: "tollerud-display mx-auto max-w-[640px] text-center text-[30px] text-tollerud-text-primary", children: title }),
19
+ description && /* @__PURE__ */ jsx("p", { className: "mx-auto mt-3 max-w-[440px] text-center text-[15px] text-tollerud-text-secondary", children: description }),
20
20
  actions && /* @__PURE__ */ jsx("div", { className: "mt-[22px] flex flex-wrap items-center justify-center gap-3", children: actions }),
21
- accentBar && /* @__PURE__ */ jsx("hr", { className: "tollerud-accent-bar mx-auto mt-8 max-w-[320px] border-0" })
21
+ accentBar && /* @__PURE__ */ jsx("hr", { className: "tollerud-accent-bar tollerud-accent-bar--inline mx-auto mt-8 max-w-[320px] border-0" })
22
22
  ]
23
23
  }
24
24
  );
@@ -27,5 +27,5 @@ var CTABand = forwardRef(
27
27
  CTABand.displayName = "CTABand";
28
28
 
29
29
  export { CTABand };
30
- //# sourceMappingURL=chunk-VTRUUT5K.js.map
31
- //# sourceMappingURL=chunk-VTRUUT5K.js.map
30
+ //# sourceMappingURL=chunk-FPFLOYIJ.js.map
31
+ //# sourceMappingURL=chunk-FPFLOYIJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../components/CTABand.tsx"],"names":[],"mappings":";;;;AAUA,IAAM,OAAA,GAAU,UAAA;AAAA,EACd,CAAC,EAAE,SAAA,EAAW,KAAA,EAAO,WAAA,EAAa,OAAA,EAAS,SAAA,GAAY,IAAA,EAAM,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AAC/E,IAAA,uBACE,IAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,SAAA,EAAW,EAAA;AAAA,UACT,0GAAA;AAAA,UACA;AAAA,SACF;AAAA,QACC,GAAG,KAAA;AAAA,QAEJ,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,2FAAA,EACX,QAAA,EAAA,KAAA,EACH,CAAA;AAAA,UACC,WAAA,oBACC,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,mFACV,QAAA,EAAA,WAAA,EACH,CAAA;AAAA,UAED,OAAA,oBACC,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,8DAA8D,QAAA,EAAA,OAAA,EAAQ,CAAA;AAAA,UAEtF,SAAA,oBACC,GAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,qFAAA,EAAsF;AAAA;AAAA;AAAA,KAExG;AAAA,EAEJ;AACF;AACA,OAAA,CAAQ,WAAA,GAAc,SAAA","file":"chunk-FPFLOYIJ.js","sourcesContent":["import { type HTMLAttributes, forwardRef } from 'react'\nimport { cn } from '@/lib/utils'\n\nexport interface CTABandProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {\n title: React.ReactNode\n description?: React.ReactNode\n actions?: React.ReactNode\n accentBar?: boolean\n}\n\nconst CTABand = forwardRef<HTMLDivElement, CTABandProps>(\n ({ className, title, description, actions, accentBar = true, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\n 'tollerud-card w-full rounded-xl border border-tollerud-border bg-tollerud-surface px-8 py-11 text-center',\n className\n )}\n {...props}\n >\n <h2 className=\"tollerud-display mx-auto max-w-[640px] text-center text-[30px] text-tollerud-text-primary\">\n {title}\n </h2>\n {description && (\n <p className=\"mx-auto mt-3 max-w-[440px] text-center text-[15px] text-tollerud-text-secondary\">\n {description}\n </p>\n )}\n {actions && (\n <div className=\"mt-[22px] flex flex-wrap items-center justify-center gap-3\">{actions}</div>\n )}\n {accentBar && (\n <hr className=\"tollerud-accent-bar tollerud-accent-bar--inline mx-auto mt-8 max-w-[320px] border-0\" />\n )}\n </div>\n )\n }\n)\nCTABand.displayName = 'CTABand'\n\nexport { CTABand }\n"]}
@@ -1,20 +1,38 @@
1
1
  'use client';
2
2
  import { cn } from './chunk-WSQNPRGN.js';
3
- import { forwardRef, useId } from 'react';
3
+ import { forwardRef, useId, Children, isValidElement, cloneElement } from 'react';
4
4
  import { jsxs, jsx } from 'react/jsx-runtime';
5
5
 
6
6
  var RadioGroup = forwardRef(
7
- ({ label, error, children, className }, ref) => {
7
+ ({ label, error, value, onChange, name: nameProp, children, className }, ref) => {
8
+ const autoName = useId();
9
+ const name = nameProp ?? autoName;
10
+ const wired = Children.map(children, (child) => {
11
+ if (!isValidElement(child)) return child;
12
+ const radio = child;
13
+ const optionValue = radio.props.value;
14
+ if (optionValue === void 0) return child;
15
+ const option = String(optionValue);
16
+ const checked = value !== void 0 ? value === option : radio.props.checked;
17
+ return cloneElement(radio, {
18
+ name,
19
+ ...checked !== void 0 ? { checked } : {},
20
+ onChange: (e) => {
21
+ radio.props.onChange?.(e);
22
+ if (e.target.checked) onChange?.(option);
23
+ }
24
+ });
25
+ });
8
26
  return /* @__PURE__ */ jsxs("fieldset", { ref, className: cn("flex flex-col gap-1", className), children: [
9
27
  label && /* @__PURE__ */ jsx("legend", { className: "text-xs font-medium text-tollerud-text-muted mb-1", children: label }),
10
- /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children }),
28
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: wired }),
11
29
  error && /* @__PURE__ */ jsx("p", { className: "text-xs text-tollerud-error mt-0.5", children: error })
12
30
  ] });
13
31
  }
14
32
  );
15
33
  RadioGroup.displayName = "RadioGroup";
16
34
  var Radio = forwardRef(
17
- ({ className, label, id: idProp, ...props }, ref) => {
35
+ ({ className, label, id: idProp, checked, ...props }, ref) => {
18
36
  const autoId = useId();
19
37
  const id = idProp ?? autoId;
20
38
  return /* @__PURE__ */ jsxs(
@@ -35,6 +53,7 @@ var Radio = forwardRef(
35
53
  ref,
36
54
  id,
37
55
  type: "radio",
56
+ ...checked !== void 0 ? { checked } : {},
38
57
  className: "peer sr-only",
39
58
  ...props
40
59
  }
@@ -43,22 +62,14 @@ var Radio = forwardRef(
43
62
  "span",
44
63
  {
45
64
  className: cn(
46
- "h-4 w-4 rounded-full border transition-all duration-[150ms]",
65
+ "flex h-4 w-4 items-center justify-center rounded-full border transition-all duration-[150ms]",
47
66
  "bg-tollerud-surface-raised border-tollerud-border",
48
67
  "peer-focus-visible:outline-2 peer-focus-visible:outline-tollerud-yellow",
49
68
  "peer-checked:border-tollerud-yellow",
50
- "group-hover:border-tollerud-text-secondary",
51
- "flex items-center justify-center"
69
+ "peer-checked:[&>span]:opacity-100",
70
+ "group-hover:border-tollerud-text-secondary"
52
71
  ),
53
- children: /* @__PURE__ */ jsx(
54
- "span",
55
- {
56
- className: cn(
57
- "h-2 w-2 rounded-full bg-tollerud-yellow transition-opacity duration-[150ms]",
58
- props.checked ? "opacity-100" : "opacity-0"
59
- )
60
- }
61
- )
72
+ children: /* @__PURE__ */ jsx("span", { className: "pointer-events-none h-2 w-2 rounded-full bg-tollerud-yellow opacity-0 transition-opacity duration-[150ms]" })
62
73
  }
63
74
  )
64
75
  ] }),
@@ -71,5 +82,5 @@ var Radio = forwardRef(
71
82
  Radio.displayName = "Radio";
72
83
 
73
84
  export { Radio, RadioGroup };
74
- //# sourceMappingURL=chunk-6SKTH45H.js.map
75
- //# sourceMappingURL=chunk-6SKTH45H.js.map
85
+ //# sourceMappingURL=chunk-J2Z4ZFVX.js.map
86
+ //# sourceMappingURL=chunk-J2Z4ZFVX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../components/RadioGroup.tsx"],"names":[],"mappings":";;;;AA4BA,IAAM,UAAA,GAAa,UAAA;AAAA,EACjB,CAAC,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,QAAA,EAAU,IAAA,EAAM,QAAA,EAAU,QAAA,EAAU,SAAA,EAAU,EAAG,GAAA,KAAQ;AAC/E,IAAA,MAAM,WAAW,KAAA,EAAM;AACvB,IAAA,MAAM,OAAO,QAAA,IAAY,QAAA;AAEzB,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,GAAA,CAAI,QAAA,EAAU,CAAC,KAAA,KAAU;AAC9C,MAAA,IAAI,CAAC,cAAA,CAAe,KAAK,CAAA,EAAG,OAAO,KAAA;AACnC,MAAA,MAAM,KAAA,GAAQ,KAAA;AACd,MAAA,MAAM,WAAA,GAAc,MAAM,KAAA,CAAM,KAAA;AAChC,MAAA,IAAI,WAAA,KAAgB,QAAW,OAAO,KAAA;AAEtC,MAAA,MAAM,MAAA,GAAS,OAAO,WAAW,CAAA;AACjC,MAAA,MAAM,UAAU,KAAA,KAAU,MAAA,GAAY,KAAA,KAAU,MAAA,GAAS,MAAM,KAAA,CAAM,OAAA;AAErE,MAAA,OAAO,aAAa,KAAA,EAAO;AAAA,QACzB,IAAA;AAAA,QACA,GAAI,OAAA,KAAY,MAAA,GAAY,EAAE,OAAA,KAAY,EAAC;AAAA,QAC3C,QAAA,EAAU,CAAC,CAAA,KAAM;AACf,UAAA,KAAA,CAAM,KAAA,CAAM,WAAW,CAAC,CAAA;AACxB,UAAA,IAAI,CAAA,CAAE,MAAA,CAAO,OAAA,EAAS,QAAA,GAAW,MAAM,CAAA;AAAA,QACzC;AAAA,OACD,CAAA;AAAA,IACH,CAAC,CAAA;AAED,IAAA,4BACG,UAAA,EAAA,EAAS,GAAA,EAAU,WAAW,EAAA,CAAG,qBAAA,EAAuB,SAAS,CAAA,EAC/D,QAAA,EAAA;AAAA,MAAA,KAAA,oBACC,GAAA,CAAC,QAAA,EAAA,EAAO,SAAA,EAAU,mDAAA,EACf,QAAA,EAAA,KAAA,EACH,CAAA;AAAA,sBAEF,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qBAAA,EAAuB,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,MAC3C,KAAA,oBACC,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,sCAAsC,QAAA,EAAA,KAAA,EAAM;AAAA,KAAA,EAE7D,CAAA;AAAA,EAEJ;AACF;AACA,UAAA,CAAW,WAAA,GAAc,YAAA;AAMzB,IAAM,KAAA,GAAQ,UAAA;AAAA,EACZ,CAAC,EAAE,SAAA,EAAW,KAAA,EAAO,EAAA,EAAI,QAAQ,OAAA,EAAS,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AAC5D,IAAA,MAAM,SAAS,KAAA,EAAM;AACrB,IAAA,MAAM,KAAK,MAAA,IAAU,MAAA;AAErB,IAAA,uBACE,IAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACC,OAAA,EAAS,EAAA;AAAA,QACT,SAAA,EAAW,EAAA;AAAA,UACT,iEAAA;AAAA,UACA,oCAAA;AAAA,UACA,MAAM,QAAA,IAAY,gCAAA;AAAA,UAClB;AAAA,SACF;AAAA,QAEA,QAAA,EAAA;AAAA,0BAAA,IAAA,CAAC,MAAA,EAAA,EAAK,WAAU,2CAAA,EACd,QAAA,EAAA;AAAA,4BAAA,GAAA;AAAA,cAAC,OAAA;AAAA,cAAA;AAAA,gBACC,GAAA;AAAA,gBACA,EAAA;AAAA,gBACA,IAAA,EAAK,OAAA;AAAA,gBACJ,GAAI,OAAA,KAAY,MAAA,GAAY,EAAE,OAAA,KAAY,EAAC;AAAA,gBAC5C,SAAA,EAAU,cAAA;AAAA,gBACT,GAAG;AAAA;AAAA,aACN;AAAA,4BAEA,GAAA;AAAA,cAAC,MAAA;AAAA,cAAA;AAAA,gBACC,SAAA,EAAW,EAAA;AAAA,kBACT,8FAAA;AAAA,kBACA,mDAAA;AAAA,kBACA,yEAAA;AAAA,kBACA,qCAAA;AAAA,kBACA,mCAAA;AAAA,kBACA;AAAA,iBACF;AAAA,gBAGA,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,2GAAA,EAA4G;AAAA;AAAA;AAC9H,WAAA,EACF,CAAA;AAAA,UACC,KAAA,oBAAS,GAAA,CAAC,MAAA,EAAA,EAAM,QAAA,EAAA,KAAA,EAAM;AAAA;AAAA;AAAA,KACzB;AAAA,EAEJ;AACF;AACA,KAAA,CAAM,WAAA,GAAc,OAAA","file":"chunk-J2Z4ZFVX.js","sourcesContent":["'use client'\n\nimport {\n Children,\n cloneElement,\n isValidElement,\n type InputHTMLAttributes,\n type ReactElement,\n forwardRef,\n useId,\n} from 'react'\nimport { cn } from '@/lib/utils'\n\nexport interface RadioGroupProps {\n /** Group label */\n label?: string\n /** Error message */\n error?: string\n /** Controlled selected value */\n value?: string\n /** Called with the selected option value */\n onChange?: (value: string) => void\n /** Shared name for native radio grouping (auto-generated if omitted) */\n name?: string\n children?: React.ReactNode\n className?: string\n}\n\nconst RadioGroup = forwardRef<HTMLFieldSetElement, RadioGroupProps>(\n ({ label, error, value, onChange, name: nameProp, children, className }, ref) => {\n const autoName = useId()\n const name = nameProp ?? autoName\n\n const wired = Children.map(children, (child) => {\n if (!isValidElement(child)) return child\n const radio = child as ReactElement<RadioProps>\n const optionValue = radio.props.value\n if (optionValue === undefined) return child\n\n const option = String(optionValue)\n const checked = value !== undefined ? value === option : radio.props.checked\n\n return cloneElement(radio, {\n name,\n ...(checked !== undefined ? { checked } : {}),\n onChange: (e) => {\n radio.props.onChange?.(e)\n if (e.target.checked) onChange?.(option)\n },\n })\n })\n\n return (\n <fieldset ref={ref} className={cn('flex flex-col gap-1', className)}>\n {label && (\n <legend className=\"text-xs font-medium text-tollerud-text-muted mb-1\">\n {label}\n </legend>\n )}\n <div className=\"flex flex-col gap-2\">{wired}</div>\n {error && (\n <p className=\"text-xs text-tollerud-error mt-0.5\">{error}</p>\n )}\n </fieldset>\n )\n }\n)\nRadioGroup.displayName = 'RadioGroup'\n\nexport interface RadioProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'type'> {\n label?: string\n}\n\nconst Radio = forwardRef<HTMLInputElement, RadioProps>(\n ({ className, label, id: idProp, checked, ...props }, ref) => {\n const autoId = useId()\n const id = idProp ?? autoId\n\n return (\n <label\n htmlFor={id}\n className={cn(\n 'inline-flex items-center gap-2 cursor-pointer select-none group',\n 'text-sm text-tollerud-text-primary',\n props.disabled && 'opacity-50 pointer-events-none',\n className\n )}\n >\n <span className=\"relative flex items-center justify-center\">\n <input\n ref={ref}\n id={id}\n type=\"radio\"\n {...(checked !== undefined ? { checked } : {})}\n className=\"peer sr-only\"\n {...props}\n />\n {/* Custom radio circle */}\n <span\n className={cn(\n 'flex h-4 w-4 items-center justify-center rounded-full border transition-all duration-[150ms]',\n 'bg-tollerud-surface-raised border-tollerud-border',\n 'peer-focus-visible:outline-2 peer-focus-visible:outline-tollerud-yellow',\n 'peer-checked:border-tollerud-yellow',\n 'peer-checked:[&>span]:opacity-100',\n 'group-hover:border-tollerud-text-secondary'\n )}\n >\n {/* Inner dot — visible when checked (via peer on sibling input) */}\n <span className=\"pointer-events-none h-2 w-2 rounded-full bg-tollerud-yellow opacity-0 transition-opacity duration-[150ms]\" />\n </span>\n </span>\n {label && <span>{label}</span>}\n </label>\n )\n }\n)\nRadio.displayName = 'Radio'\n\nexport { RadioGroup, Radio }"]}
@@ -3,9 +3,20 @@ import { cn } from './chunk-WSQNPRGN.js';
3
3
  import { forwardRef } from 'react';
4
4
  import { jsx } from 'react/jsx-runtime';
5
5
 
6
+ var pillLayers = {
7
+ outline: "tollerud-pill--outline",
8
+ muted: "tollerud-pill--muted",
9
+ success: "tollerud-pill--success",
10
+ error: "tollerud-pill--error",
11
+ solid: "",
12
+ accent: ""
13
+ };
6
14
  var pillVariants = {
7
- outline: "bg-transparent border border-tollerud-border text-tollerud-text-secondary",
8
- solid: "bg-tollerud-surface-raised text-tollerud-text-primary",
15
+ outline: "",
16
+ muted: "",
17
+ success: "",
18
+ error: "",
19
+ solid: "bg-tollerud-surface-raised text-tollerud-text-primary border-transparent",
9
20
  accent: "bg-tollerud-yellow/15 border border-tollerud-yellow/30 text-tollerud-yellow"
10
21
  };
11
22
  var Pill = forwardRef(
@@ -15,7 +26,8 @@ var Pill = forwardRef(
15
26
  {
16
27
  ref,
17
28
  className: cn(
18
- "inline-flex items-center gap-1 px-2.5 py-1 text-xs font-medium rounded-full leading-none",
29
+ "tollerud-pill inline-flex items-center gap-1 leading-none",
30
+ pillLayers[variant],
19
31
  pillVariants[variant],
20
32
  className
21
33
  ),
@@ -27,5 +39,5 @@ var Pill = forwardRef(
27
39
  Pill.displayName = "Pill";
28
40
 
29
41
  export { Pill };
30
- //# sourceMappingURL=chunk-ISHZ6ZPJ.js.map
31
- //# sourceMappingURL=chunk-ISHZ6ZPJ.js.map
42
+ //# sourceMappingURL=chunk-JFOW2DI5.js.map
43
+ //# sourceMappingURL=chunk-JFOW2DI5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../components/Pill.tsx"],"names":[],"mappings":";;;;AAIA,IAAM,UAAA,GAAa;AAAA,EACjB,OAAA,EAAS,wBAAA;AAAA,EACT,KAAA,EAAO,sBAAA;AAAA,EACP,OAAA,EAAS,wBAAA;AAAA,EACT,KAAA,EAAO,sBAAA;AAAA,EACP,KAAA,EAAO,EAAA;AAAA,EACP,MAAA,EAAQ;AACV,CAAA;AAEA,IAAM,YAAA,GAAe;AAAA,EACnB,OAAA,EAAS,EAAA;AAAA,EACT,KAAA,EAAO,EAAA;AAAA,EACP,OAAA,EAAS,EAAA;AAAA,EACT,KAAA,EAAO,EAAA;AAAA,EACP,KAAA,EAAO,0EAAA;AAAA,EACP,MAAA,EAAQ;AACV,CAAA;AAMA,IAAM,IAAA,GAAO,UAAA;AAAA,EACX,CAAC,EAAE,SAAA,EAAW,OAAA,GAAU,WAAW,GAAG,KAAA,IAAS,GAAA,KAAQ;AACrD,IAAA,uBACE,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,SAAA,EAAW,EAAA;AAAA,UACT,2DAAA;AAAA,UACA,WAAW,OAAO,CAAA;AAAA,UAClB,aAAa,OAAO,CAAA;AAAA,UACpB;AAAA,SACF;AAAA,QACC,GAAG;AAAA;AAAA,KACN;AAAA,EAEJ;AACF;AACA,IAAA,CAAK,WAAA,GAAc,MAAA","file":"chunk-JFOW2DI5.js","sourcesContent":["import { type HTMLAttributes, forwardRef } from 'react'\nimport { cn } from '@/lib/utils'\n\n/** Layer classes from globals-layers.css — colored mono tags */\nconst pillLayers = {\n outline: 'tollerud-pill--outline',\n muted: 'tollerud-pill--muted',\n success: 'tollerud-pill--success',\n error: 'tollerud-pill--error',\n solid: '',\n accent: '',\n} as const\n\nconst pillVariants = {\n outline: '',\n muted: '',\n success: '',\n error: '',\n solid: 'bg-tollerud-surface-raised text-tollerud-text-primary border-transparent',\n accent: 'bg-tollerud-yellow/15 border border-tollerud-yellow/30 text-tollerud-yellow',\n} as const\n\nexport interface PillProps extends HTMLAttributes<HTMLSpanElement> {\n variant?: keyof typeof pillVariants\n}\n\nconst Pill = forwardRef<HTMLSpanElement, PillProps>(\n ({ className, variant = 'outline', ...props }, ref) => {\n return (\n <span\n ref={ref}\n className={cn(\n 'tollerud-pill inline-flex items-center gap-1 leading-none',\n pillLayers[variant],\n pillVariants[variant],\n className\n )}\n {...props}\n />\n )\n }\n)\nPill.displayName = 'Pill'\n\nexport { Pill }\n"]}
@@ -1,11 +1,11 @@
1
1
  'use client';
2
+ import { Skeleton } from './chunk-AQT3FZRQ.js';
2
3
  import { Segmented } from './chunk-NSMU66ZX.js';
3
- import { Skeleton } from './chunk-FGXOV2QH.js';
4
4
  import { Pagination } from './chunk-RJTDQOT2.js';
5
5
  import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuSeparator, DropdownMenuLabel, DropdownMenuItem } from './chunk-435JHF7G.js';
6
- import { Checkbox } from './chunk-T3TQPOVM.js';
6
+ import { Checkbox } from './chunk-TLEKK53J.js';
7
7
  import { Badge } from './chunk-QEHTPQHL.js';
8
- import { Button } from './chunk-RWJELAS6.js';
8
+ import { Button } from './chunk-BQWF5MP7.js';
9
9
  import { cn } from './chunk-WSQNPRGN.js';
10
10
  import { forwardRef, useMemo, useState } from 'react';
11
11
  import { Search, X, MoreHorizontal, ChevronDown } from 'lucide-react';
@@ -146,7 +146,7 @@ function DataTableInner({
146
146
  "th",
147
147
  {
148
148
  className: cn(
149
- "px-3 py-2.5 text-xs font-semibold text-tollerud-text-muted uppercase tracking-wider",
149
+ "px-3 py-2.5 text-left text-xs font-semibold text-tollerud-text-muted uppercase tracking-wider",
150
150
  col.sortable && "cursor-pointer select-none hover:text-tollerud-text-primary transition-colors",
151
151
  col.align === "right" && "text-right",
152
152
  col.align === "center" && "text-center"
@@ -389,5 +389,5 @@ var DataTable = forwardRef((props, ref) => /* @__PURE__ */ jsx(DataTableInner, {
389
389
  DataTable.displayName = "DataTable";
390
390
 
391
391
  export { DataTable };
392
- //# sourceMappingURL=chunk-3TGMGBKM.js.map
393
- //# sourceMappingURL=chunk-3TGMGBKM.js.map
392
+ //# sourceMappingURL=chunk-K4ALNUZI.js.map
393
+ //# sourceMappingURL=chunk-K4ALNUZI.js.map