@timbal-ai/timbal-react 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/CHANGELOG.md +28 -1
  2. package/LICENSE +201 -0
  3. package/README.md +20 -11
  4. package/dist/app.cjs +1675 -1218
  5. package/dist/app.d.cts +22 -6
  6. package/dist/app.d.ts +22 -6
  7. package/dist/app.esm.js +26 -8
  8. package/dist/{chart-artifact-BZp7nmaf.d.ts → chart-artifact-Q5QgMtbj.d.ts} +107 -28
  9. package/dist/{chart-artifact-CX-rh9nq.d.cts → chart-artifact-WDEW9dHT.d.cts} +107 -28
  10. package/dist/{chat-DCms8pJ_.d.cts → chat-ClmzWzCX.d.cts} +2 -0
  11. package/dist/{chat-DCms8pJ_.d.ts → chat-ClmzWzCX.d.ts} +2 -0
  12. package/dist/chat.cjs +868 -511
  13. package/dist/chat.d.cts +1 -1
  14. package/dist/chat.d.ts +1 -1
  15. package/dist/chat.esm.js +3 -3
  16. package/dist/{chunk-YXZ22OJN.esm.js → chunk-GQBYZRD7.esm.js} +670 -402
  17. package/dist/{chunk-XCM3V6RK.esm.js → chunk-OFWC4MIY.esm.js} +2 -2
  18. package/dist/{chunk-6HWMJNZT.esm.js → chunk-OH23AX2V.esm.js} +757 -56
  19. package/dist/{chunk-4AKJ6FKE.esm.js → chunk-QU7ET55D.esm.js} +120 -23
  20. package/dist/{chunk-FRZOEYBO.esm.js → chunk-THBA27QY.esm.js} +4 -4
  21. package/dist/{chunk-JEAUF54A.esm.js → chunk-UCGVL7ZY.esm.js} +1 -1
  22. package/dist/{chunk-P3KDAYX6.esm.js → chunk-VXMM2HX7.esm.js} +1 -1
  23. package/dist/{chunk-TK2AGIME.esm.js → chunk-YCXN67SD.esm.js} +565 -480
  24. package/dist/{pill-segmented-tabs-Ba5q0feL.d.cts → circular-progress-Ci8L-Hfa.d.cts} +230 -6
  25. package/dist/{pill-segmented-tabs-Ba5q0feL.d.ts → circular-progress-Ci8L-Hfa.d.ts} +230 -6
  26. package/dist/index.cjs +2850 -1689
  27. package/dist/index.d.cts +5 -5
  28. package/dist/index.d.ts +5 -5
  29. package/dist/index.esm.js +41 -11
  30. package/dist/studio.cjs +1089 -732
  31. package/dist/studio.d.cts +2 -2
  32. package/dist/studio.d.ts +2 -2
  33. package/dist/studio.esm.js +5 -5
  34. package/dist/styles.css +14 -16
  35. package/dist/ui.cjs +880 -71
  36. package/dist/ui.d.cts +1 -1
  37. package/dist/ui.d.ts +1 -1
  38. package/dist/ui.esm.js +28 -4
  39. package/dist/{welcome-CRqOPKMp.d.cts → welcome-BFGRoNfK.d.cts} +1 -1
  40. package/dist/{welcome-DlHUa3OL.d.ts → welcome-DXqsGTwH.d.ts} +1 -1
  41. package/package.json +1 -1
  42. package/vite/local-dev.d.ts +5 -1
  43. package/vite/local-dev.mjs +17 -13
@@ -15,14 +15,14 @@ import {
15
15
  studioIntegrationCardClass,
16
16
  studioTopbarPillHeightClass,
17
17
  toNum
18
- } from "./chunk-YXZ22OJN.esm.js";
18
+ } from "./chunk-GQBYZRD7.esm.js";
19
19
  import {
20
20
  Checkbox,
21
21
  Skeleton
22
- } from "./chunk-JEAUF54A.esm.js";
22
+ } from "./chunk-UCGVL7ZY.esm.js";
23
23
  import {
24
24
  PillSegmentedTabs
25
- } from "./chunk-P3KDAYX6.esm.js";
25
+ } from "./chunk-VXMM2HX7.esm.js";
26
26
  import {
27
27
  Button,
28
28
  Dialog,
@@ -35,7 +35,7 @@ import {
35
35
  TimbalV2Button,
36
36
  cn,
37
37
  controlClass
38
- } from "./chunk-4AKJ6FKE.esm.js";
38
+ } from "./chunk-QU7ET55D.esm.js";
39
39
 
40
40
  // src/design/ui-vocabulary.ts
41
41
  var SEMANTIC_COLOR_TOKENS = [
@@ -198,8 +198,8 @@ var HOUSE_RULES = [
198
198
  },
199
199
  {
200
200
  id: "no-data-gradient",
201
- rule: "Gradients are reserved for chrome (composer, elevated surface, playground). Never on a data card, tile, or table.",
202
- why: "Gradient stat cards are the canonical 'AI dashboard' look."
201
+ rule: "Gradients are reserved for chrome (composer, elevated surface, playground) and built-in chart/avatar fills \u2014 never on a data card shell, stat tile, or table row background.",
202
+ why: `Gradient stat cards are the canonical 'AI dashboard' look; SVG bar/pie fills and AvatarFallback variant="secondary" (Action button chrome) are kit-owned exceptions.`
203
203
  },
204
204
  {
205
205
  id: "compose-from-blocks",
@@ -254,7 +254,7 @@ Presentational groups \u2014 import from the package root, not from these paths:
254
254
 
255
255
  Also re-exported: \`Button\`, \`TimbalChat\`, \`ChartArtifactView\`, \`APP_KIT_AGENT_INSTRUCTIONS\`.
256
256
 
257
- Theming helpers (import from the package root or \`/app\`): \`createTimbalTheme\`, \`themeToCss\`, \`applyTimbalTheme\`, \`TIMBAL_THEME_PRESETS\`, \`applyThemePreset\`, \`ThemePresetGallery\`, \`TimbalThemeStyle\`, \`THEME_AGENT_INSTRUCTIONS\`.
257
+ Theming helpers (import from the package root or \`/app\`): \`createTimbalTheme\`, \`themeToCss\`, \`applyTimbalTheme\`, \`TIMBAL_THEME_PRESETS\`, \`applyThemePreset\`, \`TimbalThemeStyle\`, \`THEME_AGENT_INSTRUCTIONS\`. Theming is **configured by the developer**, not surfaced as an end-user theme picker.
258
258
 
259
259
  ### Design guidelines (required)
260
260
 
@@ -263,8 +263,9 @@ Theming helpers (import from the package root or \`/app\`): \`createTimbalTheme\
263
263
  | **Copilot** | Use \`AppCopilotProvider\` for page context (\`useAppCopilotContext\`). Copilot is a **floating overlay** via \`AppShell\` \`chat={<AppChatPanel />}\` \u2014 not a sidebar column that shrinks main content. |
264
264
  | **Chat panel** | \`AppChatPanel\` only; \`Thread\` uses \`variant="panel"\` internally. Dismiss with **X**; trigger is a **text-only** pill (e.g. "Assistant") \u2014 **no** MessageSquare or chat icons on the shell trigger. |
265
265
  | **Context** | Do not show raw JSON context in the panel header; keep context in \`AppCopilotProvider\` only. |
266
- | **Theming** | Use semantic Tailwind tokens (\`bg-background\`, \`text-foreground\`, \`border-border\`, \`bg-elevated-from\`, etc.) from the host app's \`styles.css\`. To rebrand, **never hand-author OKLCH** \u2014 call \`createTimbalTheme({ brand })\` + \`themeToCss\`/\`applyTimbalTheme\`, or apply a catalog preset (\`TIMBAL_THEME_PRESETS\` / \`applyThemePreset\`). To offer styles, render \`ThemePresetGallery\`. See \`THEME_AGENT_INSTRUCTIONS\`. |
267
- | **Layout chrome** | \`Page\` \u2192 \`Section\` for main content hierarchy. \`AppShellTopbar\` for global actions (auth, theme). |
266
+ | **Theming** | Use semantic Tailwind tokens (\`bg-background\`, \`text-foreground\`, \`border-border\`, \`bg-elevated-from\`, etc.) from the host app's \`styles.css\`. To rebrand, **never hand-author OKLCH** \u2014 call \`createTimbalTheme({ brand })\` + \`themeToCss\`/\`applyTimbalTheme\`, or apply a catalog preset (\`TIMBAL_THEME_PRESETS\` / \`applyThemePreset\`). Apply the theme **programmatically** \u2014 do **not** add an end-user theme selector to generated apps. See \`THEME_AGENT_INSTRUCTIONS\`. |
267
+ | **Layout chrome** | \`Page\` \u2192 \`Section\` for main content hierarchy. Default to **no global topbar** \u2014 put account/theme/global actions in the \`Page\` \`actions\` slot (or the sidebar). Add \`AppShellTopbar\` only when a full-width global bar is explicitly requested. |
268
+ | **Density** | Set \`density="compact"\` on \`Page\` for tighter dashboards (full-width column, smaller section gaps, card padding, metric tiles, default chart height 220). Default is \`"default"\` (platform spacing). Wrap custom layouts with \`AppDensityProvider\` when not using \`Page\`. Per-section override: \`Section density="compact"\`. Do **not** hand-tune five layers of \`className\` padding when density covers the need. |
268
269
  | **Data** | Prefer \`DataTable\` with typed \`columns\` / \`rows\` / \`getRowKey\`; use \`ChartPanel\` with a \`ChartArtifact\` for charts (set \`chartType\` + options \u2014 see the chart catalog). Chart colors come from the theme \`--chart-1..6\` tokens; pass \`series[].color\` / \`colors\` only to override, never raw hex on every series. |
269
270
  | **Modals** | Use \`AppConfirmDialog\` for destructive/export confirmations. |
270
271
  | **Metrics** | Overview KPIs \u2192 \`MetricRow\` or \`MetricChartCard\` (not four separate heavy cards). Values use **normal** font weight, not bold. |
@@ -301,8 +302,8 @@ The cause of slop is dropping **below** the curated block layer into raw primiti
301
302
  | \`AppCopilotProvider\` | React context for copilot-aware tools (page, filters, selection, etc.). |
302
303
  | \`AppChatPanel\` | Floating thread: \`workforceId\`, \`welcome\`, \`debug\`. |
303
304
  | \`useAppShellChat\` | Custom open/close trigger when \`hideChatTrigger\` on shell. |
304
- | \`Page\` | Page title, description, \`breadcrumbs\`, \`actions\`, children. |
305
- | \`Section\` | Titled block inside a page. |
305
+ | \`Page\` | Page title, description, \`breadcrumbs\`, \`actions\`, \`density\` (\`"default"\` | \`"compact"\`), children. |
306
+ | \`Section\` | Titled block inside a page. Optional \`density\` overrides inherited page density. |
306
307
  | \`SubNav\` | **Section switcher** (Overview / Reports pill bar): \`items\`, \`activeId\`, \`onChange\`. Never use Radix/shadcn \`Tabs\` \u2014 it is not in this package. Switch panels with state or the router. |
307
308
  | **Menus** | **Select** = short list, no search. **Combobox** = searchable (same trigger as Select). **Command** only inside \`PopoverContent variant="list"\` or Combobox \u2014 never padded default Popover. See \`examples/app-kit/src/recipes/primitives-catalog.ts\`. |
308
309
  | \`Breadcrumbs\` | Trail: \`items: [{ label, href? }]\`. |
@@ -312,8 +313,9 @@ The cause of slop is dropping **below** the curated block layer into raw primiti
312
313
  | \`FilterBar\` | Horizontal filter row \u2014 bottom-aligns controls. Mix \`SearchInput\` with labeled \`FilterField\` + \`Select\` (or \`Field\` + \`Select\`); labels sit above, control baselines match. |
313
314
  | \`FilterField\` | Optional label wrapper for a filter control inside \`FilterBar\` (severity, status, \u2026). Omit \`label\` for search-only fields. |
314
315
  | \`SearchInput\` | Filter field with consistent app styling. |
315
- | \`DataTable\` | Sortable table: \`columns\`, \`rows\`, \`getRowKey\`, optional \`sort\` / \`onSortChange\`, \`emptyTitle\`, \`showRowCount\`, \`caption\`. **Scales:** \`pageSize\` (built-in client pager), \`selectable\` + \`onSelectionChange\` (checkbox column for bulk actions), \`loading\` (skeleton rows). \`onRowClick\` for row \u2192 detail (open a \`Sheet\`). |
316
- | \`ChartPanel\` | Same shell as \`MetricChartCard\`: title row (\`px-4 pt-4\`), flush plot (\`pt-2\` only). Pass \`title\` + \`artifact\` (omit \`artifact.title\` to avoid duplicates) or \`children\`. \`loading\` renders a plot-height skeleton. |
316
+ | \`DataTable\` | Sortable table: \`columns\`, \`rows\`, \`getRowKey\`, optional \`sort\` / \`onSortChange\`, \`emptyTitle\`, \`showRowCount\`, \`caption\`, \`truncate: true\` on columns with long text. **Scales:** \`pageSize\` (built-in client pager), \`selectable\` + \`onSelectionChange\` (checkbox column for bulk actions), \`loading\` (skeleton rows). \`onRowClick\` for row \u2192 detail (open a \`Sheet\`). |
317
+ | \`Avatar\` / \`AvatarFallback\` | User initials: \`variant="secondary"\` (or \`primary\` / \`chart\` alias) on **both** \`Avatar\` and \`AvatarFallback\` \u2014 same chrome as catalog **Action** buttons (\`Button variant="secondary"\`: elevated gradient, \`border-border\`, \`shadow-card\`, \`text-foreground\`). Never dark primary CTA fill or raw \`bg-blue-600\`. |
318
+ | \`ChartPanel\` | Same shell as \`MetricChartCard\`: title row (\`px-4 pt-4\`), flush plot (\`pt-2\` only) with **no axis ticks** \u2014 hover tooltips show category + value. Pass \`title\` + \`artifact\` (omit \`artifact.title\` to avoid duplicates) or \`children\`. \`loading\` renders a plot-height skeleton. Default plot height follows page \`density\` (300 default, 220 compact); pass \`height\` to override. |
317
319
  | \`FieldInput\`, \`FieldTextarea\`, \`FieldSelect\`, \`FieldSwitch\` | Settings-style forms with labels and hints. |
318
320
  | \`FormSection\` | Grouped form block. |
319
321
  | \`AppConfirmDialog\` | Confirm/cancel modal: \`open\`, \`onOpenChange\`, \`title\`, \`description\`, \`onConfirm\`. |
@@ -326,14 +328,14 @@ Charts run on **recharts** with shadcn \`ChartContainer\` / \`ChartTooltipConten
326
328
 
327
329
  | Component | Use for |
328
330
  |-----------|---------|
329
- | \`LineAreaChart\` | Cartesian engine (shadcn-style chrome). Props: \`data\`, \`xKey\`, \`series: [{ dataKey, label?, color? }]\`, \`variant\` (\`area\`\\|\`line\`\\|\`bar\`), \`orientation\` (\`horizontal\` for horizontal bars), \`stacked\`, \`curve\` (\`monotone\`\\|\`linear\`\\|\`step\`), \`dots\`, \`gridLines\`, \`tooltipIndicator\` (\`dot\`\\|\`line\`\\|\`dashed\`), \`layout\` (\`flush\`), \`height\`, \`showLegend\`, \`formatX\`, \`formatValue\`, \`ariaLabel\`. |
331
+ | \`LineAreaChart\` | Cartesian engine (shadcn-style chrome). Bar fills use theme gradients automatically. Props: \`data\`, \`xKey\`, \`series: [{ dataKey, label?, color? }]\`, \`variant\` (\`area\`\\|\`line\`\\|\`bar\`), \`orientation\` (\`horizontal\` for horizontal bars), \`stacked\`, \`curve\`, \`dots\`, \`gridLines\`, \`tooltipIndicator\`, \`layout\` (\`flush\` \u2014 hides axes by default; category + values on hover tooltip), \`showXAxis\` / \`showYAxis\` to opt back in, \`clipTicks\` (truncates long axis labels when axes are on), \`height\`, \`showLegend\`, \`formatX\`, \`formatValue\`, \`ariaLabel\`. |
330
332
  | \`PieChart\` | Pie / donut: \`data\`, \`nameKey\`, \`dataKey\`, \`innerRadius\` (>0 = donut), \`centerValue\`/\`centerLabel\` (donut hole KPI), \`showLabels\`, \`colors\`. |
331
333
  | \`RadialChart\` | Concentric progress rings: \`data\`, \`nameKey\`, \`dataKey\`, \`maxValue\`, \`centerValue\`/\`centerLabel\`. Good for gauges / share-of-target. |
332
334
  | \`RadarChart\` | Spider chart (\u22653 axes): \`data\`, \`nameKey\`, \`series\`, \`maxValue\`. Compare a few metrics across entities. |
333
335
  | \`Sparkline\` | Tiny inline trend (table cells): \`data\`, \`color\`, \`area\`. |
334
336
  | \`MetricTile\` | Low-level KPI cell \u2014 prefer \`MetricRow\` / \`MetricChartCard\` instead of hand-wiring tiles. |
335
337
  | \`MetricRow\` | KPI strip in one elevated card (no chart). Props: \`metrics: [{ id, label, value, unit?, trend?, trendTone? }]\`, optional \`onMetricChange\`, \`metricsAriaLabel\`, \`loading\` (skeleton tiles). |
336
- | \`MetricChartCard\` | KPI strip + flush chart; tile click swaps series. Same metrics shape + \`data\` per metric. Default chart height 300. \`loading\` renders skeleton tiles + chart. |
338
+ | \`MetricChartCard\` | KPI strip + flush chart; tile click swaps series. Same metrics shape + \`data\` per metric. Default chart height follows page \`density\` (300 / 220); pass \`height\` to override. \`loading\` renders skeleton tiles + chart. |
337
339
 
338
340
  #### Settings
339
341
 
@@ -396,7 +398,7 @@ Ready-made **section patterns** assembled from the components above. Each is a c
396
398
  **Shells & theming**
397
399
  - **Minimal shell** \u2014 \`AppShell\` + \`Page\` (no sidebar/chat).
398
400
  - **Copilot overlay** \u2014 \`AppShell\` + floating \`AppChatPanel\`.
399
- - **Theme presets** \u2014 \`ThemePresetGallery\` + \`applyTimbalTheme\` (never hand-author OKLCH).
401
+ - **Theme presets** \u2014 apply a brand preset programmatically (\`applyThemePreset\` / \`applyTimbalTheme\`); never hand-author OKLCH and don't expose a theme picker to end users.
400
402
 
401
403
  ### Typical compositions
402
404
 
@@ -1281,8 +1283,7 @@ Each preset is a **full personality** (color + radius + shadows + font), not jus
1281
1283
  | \`folio\` | Editorial serif (Fraunces), near-sharp corners \u2014 content / docs |
1282
1284
  | \`carbon\` | Terminal monospace (JetBrains Mono), green accent \u2014 dev / infra |
1283
1285
 
1284
- - To present options visually, render \`<ThemePresetGallery value={id} onSelect={setId} />\` \u2014 each swatch previews real components (Button + metric tile) scoped via \`data-timbal-theme\`, so the live app doesn't change until the user picks.
1285
- - On selection, call \`applyThemePreset(id)\` (persists to \`localStorage\` and restores on reload).
1286
+ - Pick a preset at build/config time and apply it with \`applyThemePreset(id)\` (persists to \`localStorage\` and restores on reload). Theme selection is a **developer/config** choice \u2014 do **not** surface an end-user theme picker in generated apps.
1286
1287
 
1287
1288
  ### Rules
1288
1289
 
@@ -1316,17 +1317,142 @@ var TimbalThemeStyle = ({
1316
1317
  ] });
1317
1318
  };
1318
1319
 
1320
+ // src/design/app-classes.ts
1321
+ var appPageColumnClass = "mx-auto w-full max-w-[100rem] px-4 md:px-6 lg:px-8";
1322
+ var appShellTopbarInsetClass = "w-full px-4 md:px-6";
1323
+ var appShellInsetTopClass = "pt-4 md:pt-6";
1324
+ var appShellInsetBottomClass = "pb-8 md:pb-10";
1325
+ var appShellTopbarRowClass = cn(
1326
+ studioTopbarPillHeightClass,
1327
+ "flex w-full items-center justify-between gap-2"
1328
+ );
1329
+ var appShellTopbarStickyClass = cn(
1330
+ "shrink-0 bg-background pb-2",
1331
+ appShellInsetTopClass
1332
+ );
1333
+ var appPageHeaderClass = cn(
1334
+ "flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",
1335
+ "pb-4 pt-2"
1336
+ );
1337
+ var appSectionClass = "flex flex-col gap-4 py-4";
1338
+ var appSectionTitleClass = "text-lg font-semibold text-foreground";
1339
+ var appSectionDescriptionClass = "text-sm text-muted-foreground";
1340
+ var appSurfaceCardClass = cn(
1341
+ studioIntegrationCardClass,
1342
+ "p-4 md:p-5"
1343
+ );
1344
+ var appStatTileClass = cn(
1345
+ appSurfaceCardClass,
1346
+ "flex flex-col gap-1 px-4 py-3 shadow-none"
1347
+ );
1348
+ var appStatValueClass = "text-2xl font-normal tracking-tight text-foreground tabular-nums";
1349
+ var appStatLabelClass = "text-xs font-normal text-muted-foreground";
1350
+ var appFilterBarClass = "flex flex-wrap items-end gap-2";
1351
+ var appSearchInputClass = controlClass({}, "inline-flex items-center gap-2");
1352
+ var appBreadcrumbsClass = "flex flex-wrap items-center gap-1.5 text-sm text-muted-foreground";
1353
+ var appBreadcrumbLinkClass = "transition-colors hover:text-foreground";
1354
+ var appFieldClass = "flex flex-col gap-1.5";
1355
+ var appFieldLabelClass = "text-sm font-medium text-foreground";
1356
+ var appFieldHintClass = "text-xs text-muted-foreground";
1357
+ var appInputClass = controlClass({}, "w-full");
1358
+ var appEmptyStateClass = cn(
1359
+ appSurfaceCardClass,
1360
+ "flex flex-col items-center justify-center gap-2 py-12 text-center"
1361
+ );
1362
+ var appEmptyStateTitleClass = "text-base font-medium text-foreground";
1363
+ var appEmptyStateDescriptionClass = "max-w-sm text-sm text-muted-foreground";
1364
+ var appChartPanelClass = cn(appSurfaceCardClass, "flex flex-col gap-3");
1365
+
1366
+ // src/design/app-density.ts
1367
+ var APP_DENSITY_CHART_HEIGHT = {
1368
+ default: 300,
1369
+ compact: 220
1370
+ };
1371
+ var compactSurfaceCardClass = cn(studioIntegrationCardClass, "p-3");
1372
+ var compactStatTileClass = cn(
1373
+ compactSurfaceCardClass,
1374
+ "flex flex-col gap-1 px-3 py-2 shadow-none"
1375
+ );
1376
+ var compactEmptyStateClass = cn(
1377
+ compactSurfaceCardClass,
1378
+ "flex flex-col items-center justify-center gap-2 py-8 text-center"
1379
+ );
1380
+ var APP_DENSITY_CLASSES = {
1381
+ pageColumn: {
1382
+ default: appPageColumnClass,
1383
+ compact: "mx-auto w-full max-w-none px-3 md:px-4"
1384
+ },
1385
+ pageHeader: {
1386
+ default: appPageHeaderClass,
1387
+ compact: "flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between pb-2 pt-1"
1388
+ },
1389
+ section: {
1390
+ default: appSectionClass,
1391
+ compact: "flex flex-col gap-2 py-2"
1392
+ },
1393
+ surfaceCard: {
1394
+ default: appSurfaceCardClass,
1395
+ compact: compactSurfaceCardClass
1396
+ },
1397
+ statTile: {
1398
+ default: appStatTileClass,
1399
+ compact: compactStatTileClass
1400
+ },
1401
+ emptyState: {
1402
+ default: appEmptyStateClass,
1403
+ compact: compactEmptyStateClass
1404
+ },
1405
+ metricCardHeader: {
1406
+ default: "flex items-start justify-between gap-3 px-4 pb-1 pt-3",
1407
+ compact: "flex items-start justify-between gap-2 px-3 pb-0.5 pt-2"
1408
+ },
1409
+ metricTile: {
1410
+ default: "relative flex min-w-0 flex-1 flex-col gap-1 px-4 py-3 text-left font-normal",
1411
+ compact: "relative flex min-w-0 flex-1 flex-col gap-1 px-3 py-2 text-left font-normal"
1412
+ },
1413
+ metricChartRegion: {
1414
+ default: "relative min-h-0 w-full overflow-x-hidden border-t border-border/40 pt-2",
1415
+ compact: "relative min-h-0 w-full overflow-x-hidden border-t border-border/40 pt-1"
1416
+ },
1417
+ metricChartPlotRegion: {
1418
+ default: "relative min-h-0 w-full overflow-x-hidden border-t border-border/40 px-0 pt-5 pb-3",
1419
+ compact: "relative min-h-0 w-full overflow-x-hidden border-t border-border/40 px-0 pt-3 pb-2"
1420
+ },
1421
+ chartPanelBody: {
1422
+ default: "pt-2 pb-3",
1423
+ compact: "pt-1 pb-2"
1424
+ }
1425
+ };
1426
+ function appDensityClass(key, density = "default") {
1427
+ return APP_DENSITY_CLASSES[key][density];
1428
+ }
1429
+
1430
+ // src/app/layout/app-density-context.tsx
1431
+ import { createContext, useContext } from "react";
1432
+ import { jsx as jsx2 } from "react/jsx-runtime";
1433
+ var AppDensityContext = createContext("default");
1434
+ var AppDensityProvider = ({
1435
+ density = "default",
1436
+ children
1437
+ }) => {
1438
+ return /* @__PURE__ */ jsx2(AppDensityContext.Provider, { value: density, children });
1439
+ };
1440
+ function useAppDensity() {
1441
+ return useContext(AppDensityContext);
1442
+ }
1443
+ function useAppDensityClass(key, override) {
1444
+ const inherited = useAppDensity();
1445
+ return appDensityClass(key, override ?? inherited);
1446
+ }
1447
+
1319
1448
  // src/app/data/metrics-shared.tsx
1320
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
1449
+ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
1321
1450
  var metricCardShellClass = cn(
1322
1451
  studioIntegrationCardClass,
1323
1452
  "aui-app-metric-card shadow-none",
1324
1453
  "flex flex-col overflow-hidden"
1325
1454
  );
1326
- var metricCardHeaderClass = "flex items-start justify-between gap-3 px-4 pb-1 pt-3";
1327
1455
  var metricTilesRowClass = "grid w-full min-w-0";
1328
- var metricChartRegionClass = "relative min-h-0 w-full border-t border-border/40 pt-2";
1329
- var metricChartPlotRegionClass = "relative min-h-0 w-full border-t border-border/40 px-0 pt-5 pb-3";
1330
1456
  var metricCellDividerClass = "border-r border-border/40";
1331
1457
  var MetricCardHeader = ({
1332
1458
  title,
@@ -1334,13 +1460,14 @@ var MetricCardHeader = ({
1334
1460
  description,
1335
1461
  actions
1336
1462
  }) => {
1463
+ const headerClass = useAppDensityClass("metricCardHeader");
1337
1464
  if (!title && !description && !actions) return null;
1338
- return /* @__PURE__ */ jsxs2("header", { className: metricCardHeaderClass, children: [
1465
+ return /* @__PURE__ */ jsxs2("header", { className: headerClass, children: [
1339
1466
  /* @__PURE__ */ jsxs2("div", { className: "min-w-0", children: [
1340
- title ? /* @__PURE__ */ jsx2("h3", { id: titleId, className: "text-base font-normal text-foreground", children: title }) : null,
1341
- description ? /* @__PURE__ */ jsx2("p", { className: "mt-0.5 text-sm text-muted-foreground", children: description }) : null
1467
+ title ? /* @__PURE__ */ jsx3("h3", { id: titleId, className: "text-base font-normal text-foreground", children: title }) : null,
1468
+ description ? /* @__PURE__ */ jsx3("p", { className: "mt-0.5 text-sm text-muted-foreground", children: description }) : null
1342
1469
  ] }),
1343
- actions ? /* @__PURE__ */ jsx2("div", { className: "shrink-0", children: actions }) : null
1470
+ actions ? /* @__PURE__ */ jsx3("div", { className: "shrink-0", children: actions }) : null
1344
1471
  ] });
1345
1472
  };
1346
1473
  function metricTilesGridColsClass(n) {
@@ -1361,15 +1488,13 @@ function metricTilesGridColsClass(n) {
1361
1488
  }
1362
1489
 
1363
1490
  // src/app/data/MetricTile.tsx
1364
- import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
1491
+ import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
1365
1492
  var trendToneClass = {
1366
1493
  up: "border-border/80 bg-muted/40 text-muted-foreground",
1367
1494
  down: "border-border/80 bg-muted/40 text-muted-foreground",
1368
1495
  neutral: "border-border/80 bg-muted/30 text-muted-foreground"
1369
1496
  };
1370
- var metricTileBaseClass = "relative flex min-w-0 flex-1 flex-col gap-1 px-4 py-3 text-left font-normal";
1371
- var metricTileInteractiveClass = cn(
1372
- metricTileBaseClass,
1497
+ var metricTileInteractiveExtraClass = cn(
1373
1498
  "bg-transparent hover:bg-transparent active:bg-transparent",
1374
1499
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-foreground/10"
1375
1500
  );
@@ -1385,21 +1510,22 @@ var MetricTile = ({
1385
1510
  ariaLabel,
1386
1511
  className
1387
1512
  }) => {
1513
+ const metricTileBaseClass = useAppDensityClass("metricTile");
1388
1514
  const content = /* @__PURE__ */ jsxs3(Fragment2, { children: [
1389
- active ? /* @__PURE__ */ jsx3(
1515
+ active ? /* @__PURE__ */ jsx4(
1390
1516
  "span",
1391
1517
  {
1392
1518
  "aria-hidden": true,
1393
1519
  className: "absolute inset-x-0 bottom-0 h-0.5 bg-foreground dark:bg-white"
1394
1520
  }
1395
1521
  ) : null,
1396
- /* @__PURE__ */ jsx3("span", { className: "text-xs font-normal text-muted-foreground", children: label }),
1522
+ /* @__PURE__ */ jsx4("span", { className: "text-xs font-normal text-muted-foreground", children: label }),
1397
1523
  /* @__PURE__ */ jsxs3("span", { className: "flex items-center gap-2", children: [
1398
1524
  /* @__PURE__ */ jsxs3("span", { className: "flex items-baseline gap-1", children: [
1399
- /* @__PURE__ */ jsx3("span", { className: "text-2xl font-normal tracking-tight text-foreground tabular-nums", children: value }),
1400
- unit ? /* @__PURE__ */ jsx3("span", { className: "text-xs font-normal text-muted-foreground", children: unit }) : null
1525
+ /* @__PURE__ */ jsx4("span", { className: "text-2xl font-normal tracking-tight text-foreground tabular-nums", children: value }),
1526
+ unit ? /* @__PURE__ */ jsx4("span", { className: "text-xs font-normal text-muted-foreground", children: unit }) : null
1401
1527
  ] }),
1402
- trend ? /* @__PURE__ */ jsx3(
1528
+ trend ? /* @__PURE__ */ jsx4(
1403
1529
  "span",
1404
1530
  {
1405
1531
  className: cn(
@@ -1413,159 +1539,38 @@ var MetricTile = ({
1413
1539
  ] });
1414
1540
  const divider = showDivider ? metricCellDividerClass : void 0;
1415
1541
  if (onSelect) {
1416
- return /* @__PURE__ */ jsx3(
1542
+ return /* @__PURE__ */ jsx4(
1417
1543
  "button",
1418
1544
  {
1419
1545
  type: "button",
1420
1546
  onClick: onSelect,
1421
1547
  "aria-pressed": active,
1422
1548
  "aria-label": ariaLabel,
1423
- className: cn(metricTileInteractiveClass, divider, className),
1549
+ className: cn(metricTileBaseClass, metricTileInteractiveExtraClass, divider, className),
1424
1550
  children: content
1425
1551
  }
1426
1552
  );
1427
1553
  }
1428
- return /* @__PURE__ */ jsx3("div", { className: cn(metricTileBaseClass, divider, className), children: content });
1554
+ return /* @__PURE__ */ jsx4("div", { className: cn(metricTileBaseClass, divider, className), children: content });
1429
1555
  };
1430
1556
 
1431
1557
  // src/app/theme/ThemePresetGallery.tsx
1432
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1433
- var ThemePresetGallery = ({
1434
- value,
1435
- onSelect,
1436
- presets,
1437
- className
1438
- }) => {
1439
- const items = presets ? TIMBAL_THEME_PRESETS.filter((p) => presets.includes(p.id)) : TIMBAL_THEME_PRESETS;
1440
- return /* @__PURE__ */ jsx4(
1441
- "div",
1442
- {
1443
- role: "radiogroup",
1444
- "aria-label": "Theme presets",
1445
- className: cn(
1446
- "grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3",
1447
- className
1448
- ),
1449
- children: items.map((preset) => {
1450
- const selected = value === preset.id;
1451
- return /* @__PURE__ */ jsxs4("div", { "data-timbal-theme": preset.id, children: [
1452
- /* @__PURE__ */ jsx4(TimbalThemeStyle, { preset: preset.id, scope: preset.id }),
1453
- /* @__PURE__ */ jsxs4(
1454
- "button",
1455
- {
1456
- type: "button",
1457
- role: "radio",
1458
- "aria-checked": selected,
1459
- "aria-label": `${preset.label} theme`,
1460
- onClick: () => onSelect?.(preset.id),
1461
- className: cn(
1462
- "group flex w-full flex-col gap-3 rounded-xl border bg-card p-3 text-left transition-colors",
1463
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
1464
- selected ? "border-primary ring-2 ring-primary/30" : "border-border hover:border-foreground/30"
1465
- ),
1466
- children: [
1467
- /* @__PURE__ */ jsxs4("div", { className: "flex items-center justify-between gap-2", children: [
1468
- /* @__PURE__ */ jsxs4("span", { className: "flex items-center gap-2", children: [
1469
- /* @__PURE__ */ jsx4(
1470
- "span",
1471
- {
1472
- "aria-hidden": true,
1473
- className: "size-4 shrink-0 rounded-full ring-1 ring-black/10",
1474
- style: { background: preset.swatch }
1475
- }
1476
- ),
1477
- /* @__PURE__ */ jsx4("span", { className: "text-sm font-medium text-foreground", children: preset.label })
1478
- ] }),
1479
- selected ? /* @__PURE__ */ jsx4("span", { className: "text-xs font-medium text-primary", children: "Selected" }) : null
1480
- ] }),
1481
- /* @__PURE__ */ jsx4("p", { className: "text-xs leading-snug text-muted-foreground", children: preset.description }),
1482
- preset.font ? /* @__PURE__ */ jsxs4("span", { className: "text-[10px] uppercase tracking-wide text-muted-foreground", children: [
1483
- "Aa \xB7 ",
1484
- preset.font
1485
- ] }) : null,
1486
- /* @__PURE__ */ jsxs4("div", { className: "flex flex-col gap-2 rounded-lg border border-border bg-background p-2", children: [
1487
- /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2", children: [
1488
- /* @__PURE__ */ jsx4(Button, { size: "xs", className: "pointer-events-none", children: "Primary" }),
1489
- /* @__PURE__ */ jsx4("span", { className: "size-5 rounded-md bg-primary", "aria-hidden": true }),
1490
- /* @__PURE__ */ jsx4("span", { className: "size-5 rounded-md bg-muted", "aria-hidden": true }),
1491
- /* @__PURE__ */ jsx4(
1492
- "span",
1493
- {
1494
- className: "size-5 rounded-md border border-border bg-accent",
1495
- "aria-hidden": true
1496
- }
1497
- )
1498
- ] }),
1499
- /* @__PURE__ */ jsx4(MetricTile, { label: "Active users", value: "1,248", trend: "+8%" })
1500
- ] })
1501
- ]
1502
- }
1503
- )
1504
- ] }, preset.id);
1505
- })
1506
- }
1507
- );
1508
- };
1509
-
1510
- // src/design/app-classes.ts
1511
- var appPageColumnClass = "mx-auto w-full max-w-6xl px-4 md:px-6";
1512
- var appShellTopbarInsetClass = "w-full px-4 md:px-6";
1513
- var appShellInsetTopClass = "pt-4 md:pt-6";
1514
- var appShellTopbarRowClass = cn(
1515
- studioTopbarPillHeightClass,
1516
- "flex w-full items-center justify-between gap-2"
1517
- );
1518
- var appShellTopbarStickyClass = cn(
1519
- "sticky top-0 z-20 shrink-0 bg-background pb-2",
1520
- appShellInsetTopClass
1521
- );
1522
- var appPageHeaderClass = cn(
1523
- "flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",
1524
- "pb-4 pt-2"
1525
- );
1526
- var appSectionClass = "flex flex-col gap-4 py-4";
1527
- var appSectionTitleClass = "text-lg font-semibold text-foreground";
1528
- var appSectionDescriptionClass = "text-sm text-muted-foreground";
1529
- var appSurfaceCardClass = cn(
1530
- studioIntegrationCardClass,
1531
- "p-4 md:p-5"
1532
- );
1533
- var appStatTileClass = cn(
1534
- appSurfaceCardClass,
1535
- "flex flex-col gap-1 px-4 py-3 shadow-none"
1536
- );
1537
- var appStatValueClass = "text-2xl font-normal tracking-tight text-foreground tabular-nums";
1538
- var appStatLabelClass = "text-xs font-normal text-muted-foreground";
1539
- var appFilterBarClass = "flex flex-wrap items-end gap-2";
1540
- var appSearchInputClass = controlClass({}, "inline-flex items-center gap-2");
1541
- var appBreadcrumbsClass = "flex flex-wrap items-center gap-1.5 text-sm text-muted-foreground";
1542
- var appBreadcrumbLinkClass = "transition-colors hover:text-foreground";
1543
- var appFieldClass = "flex flex-col gap-1.5";
1544
- var appFieldLabelClass = "text-sm font-medium text-foreground";
1545
- var appFieldHintClass = "text-xs text-muted-foreground";
1546
- var appInputClass = controlClass({}, "w-full");
1547
- var appEmptyStateClass = cn(
1548
- appSurfaceCardClass,
1549
- "flex flex-col items-center justify-center gap-2 py-12 text-center"
1550
- );
1551
- var appEmptyStateTitleClass = "text-base font-medium text-foreground";
1552
- var appEmptyStateDescriptionClass = "max-w-sm text-sm text-muted-foreground";
1553
- var appChartPanelClass = cn(appSurfaceCardClass, "flex flex-col gap-3");
1558
+ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
1554
1559
 
1555
1560
  // src/app/layout/app-shell-chat-context.tsx
1556
- import { createContext, useContext } from "react";
1557
- var AppShellChatContext = createContext(null);
1561
+ import { createContext as createContext2, useContext as useContext2 } from "react";
1562
+ var AppShellChatContext = createContext2(null);
1558
1563
  var AppShellChatProvider = AppShellChatContext.Provider;
1559
1564
  function useAppShellChat() {
1560
- return useContext(AppShellChatContext);
1565
+ return useContext2(AppShellChatContext);
1561
1566
  }
1562
1567
 
1563
1568
  // src/app/layout/app-shell-nav-context.tsx
1564
- import { createContext as createContext2, useContext as useContext2 } from "react";
1565
- var AppShellNavContext = createContext2(null);
1569
+ import { createContext as createContext3, useContext as useContext3 } from "react";
1570
+ var AppShellNavContext = createContext3(null);
1566
1571
  var AppShellNavProvider = AppShellNavContext.Provider;
1567
1572
  function useAppShellNav() {
1568
- return useContext2(AppShellNavContext) ?? {
1573
+ return useContext3(AppShellNavContext) ?? {
1569
1574
  open: false,
1570
1575
  setOpen: () => {
1571
1576
  },
@@ -1577,7 +1582,7 @@ function useAppShellNav() {
1577
1582
  // src/app/layout/AppShell.tsx
1578
1583
  import { motion, useReducedMotion } from "motion/react";
1579
1584
  import { useCallback, useMemo, useState } from "react";
1580
- import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1585
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
1581
1586
  var floatingTriggerClass = cn(
1582
1587
  "aui-app-shell-chat-trigger-fixed fixed z-50 rounded-full px-5 py-2.5 text-sm font-medium shadow-card-elevated",
1583
1588
  "bg-primary text-primary-foreground transition-colors hover:bg-primary/90",
@@ -1606,7 +1611,7 @@ var AppShellBody = ({
1606
1611
  layoutDirection
1607
1612
  );
1608
1613
  const insetPadding = sidebar ? insetPaddingPx : 0;
1609
- return /* @__PURE__ */ jsx5(
1614
+ return /* @__PURE__ */ jsx6(
1610
1615
  motion.div,
1611
1616
  {
1612
1617
  className: "aui-app-shell-body relative z-10 flex min-h-0 min-w-0 flex-1 flex-col",
@@ -1621,8 +1626,18 @@ var AppShellBody = ({
1621
1626
  !topbarContent && appShellInsetTopClass
1622
1627
  ),
1623
1628
  children: [
1624
- topbarContent ? /* @__PURE__ */ jsx5("header", { className: cn("aui-app-shell-topbar-region", appShellTopbarStickyClass), children: /* @__PURE__ */ jsx5("div", { className: appShellTopbarInsetClass, children: topbarContent }) }) : null,
1625
- /* @__PURE__ */ jsx5("main", { className: cn("aui-app-shell-main min-w-0 flex-1", mainClassName), children })
1629
+ topbarContent ? /* @__PURE__ */ jsx6("header", { className: cn("aui-app-shell-topbar-region", appShellTopbarStickyClass), children: /* @__PURE__ */ jsx6("div", { className: appShellTopbarInsetClass, children: topbarContent }) }) : null,
1630
+ /* @__PURE__ */ jsx6(
1631
+ "main",
1632
+ {
1633
+ className: cn(
1634
+ "aui-app-shell-main min-w-0 flex-1",
1635
+ appShellInsetBottomClass,
1636
+ mainClassName
1637
+ ),
1638
+ children
1639
+ }
1640
+ )
1626
1641
  ]
1627
1642
  }
1628
1643
  )
@@ -1688,7 +1703,7 @@ var AppShell = ({
1688
1703
  setInsetPaddingPx(insetPx);
1689
1704
  }, []);
1690
1705
  const insetExpanded = insetPaddingPx >= SIDEBAR_INSET_PX_EXPANDED;
1691
- const shellBody = /* @__PURE__ */ jsx5(
1706
+ const shellBody = /* @__PURE__ */ jsx6(
1692
1707
  AppShellBody,
1693
1708
  {
1694
1709
  sidebar,
@@ -1699,7 +1714,7 @@ var AppShell = ({
1699
1714
  children
1700
1715
  }
1701
1716
  );
1702
- const tree = /* @__PURE__ */ jsx5(ShellInsetProvider, { value: sidebar ? reportShellInset : null, children: /* @__PURE__ */ jsxs5(
1717
+ const tree = /* @__PURE__ */ jsx6(ShellInsetProvider, { value: sidebar ? reportShellInset : null, children: /* @__PURE__ */ jsxs5(
1703
1718
  "div",
1704
1719
  {
1705
1720
  className: cn(
@@ -1709,7 +1724,7 @@ var AppShell = ({
1709
1724
  style: studioChromeShellStyle,
1710
1725
  children: [
1711
1726
  sidebar,
1712
- sidebar && navOpen ? /* @__PURE__ */ jsx5(
1727
+ sidebar && navOpen ? /* @__PURE__ */ jsx6(
1713
1728
  "button",
1714
1729
  {
1715
1730
  type: "button",
@@ -1719,7 +1734,7 @@ var AppShell = ({
1719
1734
  }
1720
1735
  ) : null,
1721
1736
  shellBody,
1722
- hasChat && chatOpen ? /* @__PURE__ */ jsx5(
1737
+ hasChat && chatOpen ? /* @__PURE__ */ jsx6(
1723
1738
  "div",
1724
1739
  {
1725
1740
  className: floatingPanelClass,
@@ -1732,7 +1747,7 @@ var AppShell = ({
1732
1747
  children: chat
1733
1748
  }
1734
1749
  ) : null,
1735
- hasChat && chatCollapsible && !chatOpen && !hideChatTrigger ? /* @__PURE__ */ jsx5(
1750
+ hasChat && chatCollapsible && !chatOpen && !hideChatTrigger ? /* @__PURE__ */ jsx6(
1736
1751
  "button",
1737
1752
  {
1738
1753
  type: "button",
@@ -1745,11 +1760,11 @@ var AppShell = ({
1745
1760
  ]
1746
1761
  }
1747
1762
  ) });
1748
- const withNav = /* @__PURE__ */ jsx5(AppShellNavProvider, { value: navControls, children: tree });
1763
+ const withNav = /* @__PURE__ */ jsx6(AppShellNavProvider, { value: navControls, children: tree });
1749
1764
  if (!hasChat) {
1750
1765
  return withNav;
1751
1766
  }
1752
- return /* @__PURE__ */ jsx5(
1767
+ return /* @__PURE__ */ jsx6(
1753
1768
  AppShellChatProvider,
1754
1769
  {
1755
1770
  value: {
@@ -1764,7 +1779,7 @@ var AppShell = ({
1764
1779
  };
1765
1780
 
1766
1781
  // src/app/layout/AppShellTopbar.tsx
1767
- import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
1782
+ import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
1768
1783
  var AppShellTopbar = ({
1769
1784
  start,
1770
1785
  actions,
@@ -1776,12 +1791,12 @@ var AppShellTopbar = ({
1776
1791
  start,
1777
1792
  children
1778
1793
  ] }),
1779
- actions ? /* @__PURE__ */ jsx6("div", { className: "aui-app-shell-topbar-actions flex shrink-0 items-center gap-2", children: actions }) : null
1794
+ actions ? /* @__PURE__ */ jsx7("div", { className: "aui-app-shell-topbar-actions flex shrink-0 items-center gap-2", children: actions }) : null
1780
1795
  ] });
1781
1796
  };
1782
1797
 
1783
1798
  // src/app/layout/AppShellChatTrigger.tsx
1784
- import { jsx as jsx7 } from "react/jsx-runtime";
1799
+ import { jsx as jsx8 } from "react/jsx-runtime";
1785
1800
  var floatingPositionClass = "fixed bottom-6 right-6 z-50 max-sm:bottom-4 max-sm:right-4";
1786
1801
  var AppShellChatTrigger = ({
1787
1802
  className,
@@ -1790,7 +1805,7 @@ var AppShellChatTrigger = ({
1790
1805
  }) => {
1791
1806
  const shellChat = useAppShellChat();
1792
1807
  if (!shellChat || shellChat.open) return null;
1793
- return /* @__PURE__ */ jsx7(
1808
+ return /* @__PURE__ */ jsx8(
1794
1809
  TimbalV2Button,
1795
1810
  {
1796
1811
  type: "button",
@@ -1811,13 +1826,13 @@ var AppShellChatTrigger = ({
1811
1826
 
1812
1827
  // src/app/layout/AppShellSidebarTrigger.tsx
1813
1828
  import { MenuIcon } from "lucide-react";
1814
- import { jsx as jsx8 } from "react/jsx-runtime";
1829
+ import { jsx as jsx9 } from "react/jsx-runtime";
1815
1830
  var AppShellSidebarTrigger = ({
1816
1831
  label = "Open navigation",
1817
1832
  className
1818
1833
  }) => {
1819
1834
  const nav = useAppShellNav();
1820
- return /* @__PURE__ */ jsx8(
1835
+ return /* @__PURE__ */ jsx9(
1821
1836
  "button",
1822
1837
  {
1823
1838
  type: "button",
@@ -1829,75 +1844,96 @@ var AppShellSidebarTrigger = ({
1829
1844
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/10",
1830
1845
  className
1831
1846
  ),
1832
- children: /* @__PURE__ */ jsx8(MenuIcon, { className: "size-5", "aria-hidden": true })
1847
+ children: /* @__PURE__ */ jsx9(MenuIcon, { className: "size-5", "aria-hidden": true })
1833
1848
  }
1834
1849
  );
1835
1850
  };
1836
1851
 
1837
1852
  // src/app/layout/PageHeader.tsx
1838
- import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
1853
+ import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
1839
1854
  var PageHeader = ({
1840
1855
  title,
1841
1856
  description,
1842
1857
  actions,
1843
1858
  className
1844
1859
  }) => {
1845
- return /* @__PURE__ */ jsxs7("header", { className: cn("aui-app-page-header", appPageHeaderClass, className), children: [
1860
+ const pageHeaderClass = useAppDensityClass("pageHeader");
1861
+ return /* @__PURE__ */ jsxs7("header", { className: cn("aui-app-page-header", pageHeaderClass, className), children: [
1846
1862
  /* @__PURE__ */ jsxs7("div", { className: "min-w-0", children: [
1847
- /* @__PURE__ */ jsx9("h1", { className: "text-2xl font-semibold tracking-tight text-foreground", children: title }),
1848
- description ? /* @__PURE__ */ jsx9("p", { className: "mt-1 text-sm text-muted-foreground", children: description }) : null
1863
+ /* @__PURE__ */ jsx10("h1", { className: "text-2xl font-semibold tracking-tight text-foreground", children: title }),
1864
+ description ? /* @__PURE__ */ jsx10("p", { className: "mt-1 text-sm text-muted-foreground", children: description }) : null
1849
1865
  ] }),
1850
- actions ? /* @__PURE__ */ jsx9("div", { className: "aui-app-page-header-actions flex shrink-0 flex-wrap items-center gap-2", children: actions }) : null
1866
+ actions ? /* @__PURE__ */ jsx10("div", { className: "aui-app-page-header-actions flex shrink-0 flex-wrap items-center gap-2", children: actions }) : null
1851
1867
  ] });
1852
1868
  };
1853
1869
 
1854
1870
  // src/app/layout/Page.tsx
1855
- import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
1871
+ import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
1872
+ var PageFrame = ({
1873
+ children,
1874
+ breadcrumbs,
1875
+ className,
1876
+ ...headerProps
1877
+ }) => {
1878
+ const density = useAppDensity();
1879
+ const pageColumnClass = useAppDensityClass("pageColumn");
1880
+ return /* @__PURE__ */ jsxs8(
1881
+ "div",
1882
+ {
1883
+ className: cn("aui-app-page", pageColumnClass, className),
1884
+ "data-density": density,
1885
+ children: [
1886
+ breadcrumbs,
1887
+ /* @__PURE__ */ jsx11(PageHeader, { ...headerProps }),
1888
+ children
1889
+ ]
1890
+ }
1891
+ );
1892
+ };
1856
1893
  var Page = ({
1894
+ density = "default",
1857
1895
  children,
1858
1896
  breadcrumbs,
1859
1897
  className,
1860
1898
  ...headerProps
1861
1899
  }) => {
1862
- return /* @__PURE__ */ jsxs8("div", { className: cn("aui-app-page", appPageColumnClass, className), children: [
1863
- breadcrumbs,
1864
- /* @__PURE__ */ jsx10(PageHeader, { ...headerProps }),
1865
- children
1866
- ] });
1900
+ return /* @__PURE__ */ jsx11(AppDensityProvider, { density, children: /* @__PURE__ */ jsx11(PageFrame, { breadcrumbs, className, ...headerProps, children }) });
1867
1901
  };
1868
1902
 
1869
1903
  // src/app/layout/Section.tsx
1870
- import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
1904
+ import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
1871
1905
  var Section = ({
1872
1906
  title,
1873
1907
  description,
1874
1908
  children,
1909
+ density,
1875
1910
  className
1876
1911
  }) => {
1877
- return /* @__PURE__ */ jsxs9("section", { className: cn("aui-app-section", appSectionClass, className), children: [
1878
- title ? /* @__PURE__ */ jsx11("h2", { className: appSectionTitleClass, children: title }) : null,
1879
- description ? /* @__PURE__ */ jsx11("p", { className: appSectionDescriptionClass, children: description }) : null,
1912
+ const sectionClass = useAppDensityClass("section", density);
1913
+ return /* @__PURE__ */ jsxs9("section", { className: cn("aui-app-section", sectionClass, className), children: [
1914
+ title ? /* @__PURE__ */ jsx12("h2", { className: appSectionTitleClass, children: title }) : null,
1915
+ description ? /* @__PURE__ */ jsx12("p", { className: appSectionDescriptionClass, children: description }) : null,
1880
1916
  children
1881
1917
  ] });
1882
1918
  };
1883
1919
 
1884
1920
  // src/app/copilot/app-copilot-context.tsx
1885
- import { createContext as createContext3, useContext as useContext3 } from "react";
1886
- import { jsx as jsx12 } from "react/jsx-runtime";
1887
- var AppCopilotContext = createContext3(null);
1921
+ import { createContext as createContext4, useContext as useContext4 } from "react";
1922
+ import { jsx as jsx13 } from "react/jsx-runtime";
1923
+ var AppCopilotContext = createContext4(null);
1888
1924
  var AppCopilotProvider = ({
1889
1925
  value,
1890
1926
  children
1891
1927
  }) => {
1892
- return /* @__PURE__ */ jsx12(AppCopilotContext.Provider, { value, children });
1928
+ return /* @__PURE__ */ jsx13(AppCopilotContext.Provider, { value, children });
1893
1929
  };
1894
1930
  function useAppCopilotContext() {
1895
- return useContext3(AppCopilotContext) ?? {};
1931
+ return useContext4(AppCopilotContext) ?? {};
1896
1932
  }
1897
1933
 
1898
1934
  // src/app/chat/AppChatPanel.tsx
1899
1935
  import { XIcon } from "lucide-react";
1900
- import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
1936
+ import { jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
1901
1937
  var shellClass = "aui-app-chat-panel flex h-full min-h-0 flex-col overflow-hidden";
1902
1938
  var chromeClass = cn(
1903
1939
  "aui-app-chat-panel-chrome relative z-20 flex min-h-10 shrink-0 items-center justify-end px-2 pt-2"
@@ -1943,17 +1979,17 @@ var AppChatPanel = ({
1943
1979
  }) => {
1944
1980
  const shellChat = useAppShellChat();
1945
1981
  return /* @__PURE__ */ jsxs10("div", { className: cn(shellClass, className), children: [
1946
- shellChat?.collapsible ? /* @__PURE__ */ jsx13("div", { className: chromeClass, children: /* @__PURE__ */ jsx13(
1982
+ shellChat?.collapsible ? /* @__PURE__ */ jsx14("div", { className: chromeClass, children: /* @__PURE__ */ jsx14(
1947
1983
  "button",
1948
1984
  {
1949
1985
  type: "button",
1950
1986
  className: closeButtonClass,
1951
1987
  onClick: () => shellChat.setOpen(false),
1952
1988
  "aria-label": "Close assistant",
1953
- children: /* @__PURE__ */ jsx13(XIcon, { className: "size-4", "aria-hidden": true })
1989
+ children: /* @__PURE__ */ jsx14(XIcon, { className: "size-4", "aria-hidden": true })
1954
1990
  }
1955
1991
  ) }) : null,
1956
- /* @__PURE__ */ jsx13("div", { className: bodyClass, children: /* @__PURE__ */ jsx13(
1992
+ /* @__PURE__ */ jsx14("div", { className: bodyClass, children: /* @__PURE__ */ jsx14(
1957
1993
  TimbalRuntimeProvider,
1958
1994
  {
1959
1995
  workforceId,
@@ -1963,7 +1999,7 @@ var AppChatPanel = ({
1963
1999
  attachmentsUploadUrl,
1964
2000
  attachmentsAccept,
1965
2001
  debug,
1966
- children: /* @__PURE__ */ jsx13(
2002
+ children: /* @__PURE__ */ jsx14(
1967
2003
  Thread,
1968
2004
  {
1969
2005
  variant: "panel",
@@ -1984,66 +2020,91 @@ var AppChatPanel = ({
1984
2020
  };
1985
2021
 
1986
2022
  // src/app/surfaces/SurfaceCard.tsx
1987
- import { jsx as jsx14 } from "react/jsx-runtime";
2023
+ import { jsx as jsx15 } from "react/jsx-runtime";
1988
2024
  var SurfaceCard = ({ children, className }) => {
1989
- return /* @__PURE__ */ jsx14("div", { className: cn("aui-app-surface-card", appSurfaceCardClass, className), children });
2025
+ const surfaceCardClass = useAppDensityClass("surfaceCard");
2026
+ return /* @__PURE__ */ jsx15("div", { className: cn("aui-app-surface-card", surfaceCardClass, className), children });
1990
2027
  };
1991
2028
 
1992
2029
  // src/app/surfaces/StatTile.tsx
1993
- import { jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
2030
+ import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
1994
2031
  var StatTile = ({ label, value, hint, className }) => {
1995
- return /* @__PURE__ */ jsxs11("div", { className: cn("aui-app-stat-tile", appStatTileClass, className), children: [
1996
- /* @__PURE__ */ jsx15("span", { className: appStatLabelClass, children: label }),
1997
- /* @__PURE__ */ jsx15("span", { className: appStatValueClass, children: value }),
1998
- hint ? /* @__PURE__ */ jsx15("span", { className: "text-xs text-muted-foreground", children: hint }) : null
2032
+ const statTileClass = useAppDensityClass("statTile");
2033
+ return /* @__PURE__ */ jsxs11("div", { className: cn("aui-app-stat-tile", statTileClass, className), children: [
2034
+ /* @__PURE__ */ jsx16("span", { className: appStatLabelClass, children: label }),
2035
+ /* @__PURE__ */ jsx16("span", { className: appStatValueClass, children: value }),
2036
+ hint ? /* @__PURE__ */ jsx16("span", { className: "text-xs text-muted-foreground", children: hint }) : null
1999
2037
  ] });
2000
2038
  };
2001
2039
 
2002
2040
  // src/app/surfaces/EmptyState.tsx
2003
- import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
2041
+ import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
2004
2042
  var EmptyState = ({
2005
2043
  title,
2006
2044
  description,
2007
2045
  action,
2008
2046
  className
2009
2047
  }) => {
2010
- return /* @__PURE__ */ jsxs12("div", { className: cn("aui-app-empty-state", appEmptyStateClass, className), children: [
2011
- /* @__PURE__ */ jsx16("p", { className: appEmptyStateTitleClass, children: title }),
2012
- description ? /* @__PURE__ */ jsx16("p", { className: appEmptyStateDescriptionClass, children: description }) : null,
2048
+ const emptyStateClass = useAppDensityClass("emptyState");
2049
+ return /* @__PURE__ */ jsxs12("div", { className: cn("aui-app-empty-state", emptyStateClass, className), children: [
2050
+ /* @__PURE__ */ jsx17("p", { className: appEmptyStateTitleClass, children: title }),
2051
+ description ? /* @__PURE__ */ jsx17("p", { className: appEmptyStateDescriptionClass, children: description }) : null,
2013
2052
  action
2014
2053
  ] });
2015
2054
  };
2016
2055
 
2017
2056
  // src/app/surfaces/StatusBadge.tsx
2018
- import { jsx as jsx17 } from "react/jsx-runtime";
2057
+ import { jsx as jsx18, jsxs as jsxs13 } from "react/jsx-runtime";
2019
2058
  var statusBadgeToneClass = {
2020
- default: "bg-muted text-foreground",
2021
- primary: "bg-primary/10 text-primary",
2022
- success: "bg-emerald-500/10 text-emerald-600 dark:text-emerald-400",
2023
- warn: "bg-amber-500/10 text-amber-600 dark:text-amber-400",
2024
- danger: "bg-destructive/10 text-destructive",
2025
- muted: "bg-muted/80 text-muted-foreground"
2059
+ default: "bg-muted text-foreground ring-border",
2060
+ primary: "bg-primary/10 text-primary ring-primary/20",
2061
+ success: "bg-emerald-500/10 text-emerald-700 ring-emerald-500/20 dark:text-emerald-400",
2062
+ warn: "bg-amber-500/10 text-amber-700 ring-amber-500/25 dark:text-amber-400",
2063
+ danger: "bg-destructive/10 text-destructive ring-destructive/20",
2064
+ muted: "bg-muted/70 text-muted-foreground ring-border/60"
2065
+ };
2066
+ var statusBadgeDotClass = {
2067
+ default: "bg-foreground/40",
2068
+ primary: "bg-primary",
2069
+ success: "bg-emerald-500",
2070
+ warn: "bg-amber-500",
2071
+ danger: "bg-destructive",
2072
+ muted: "bg-muted-foreground/60"
2026
2073
  };
2027
2074
  var StatusBadge = ({
2028
2075
  children,
2029
2076
  tone = "default",
2077
+ dot = false,
2030
2078
  className
2031
2079
  }) => {
2032
- return /* @__PURE__ */ jsx17(
2080
+ return /* @__PURE__ */ jsxs13(
2033
2081
  "span",
2034
2082
  {
2035
2083
  className: cn(
2036
- "aui-app-status-badge inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium",
2084
+ "aui-app-status-badge inline-flex items-center gap-1.5 rounded-full px-2 py-0.5",
2085
+ "text-xs font-medium leading-none ring-1 ring-inset",
2037
2086
  statusBadgeToneClass[tone],
2038
2087
  className
2039
2088
  ),
2040
- children
2089
+ children: [
2090
+ dot ? /* @__PURE__ */ jsx18(
2091
+ "span",
2092
+ {
2093
+ "aria-hidden": true,
2094
+ className: cn(
2095
+ "size-1.5 shrink-0 rounded-full",
2096
+ statusBadgeDotClass[tone]
2097
+ )
2098
+ }
2099
+ ) : null,
2100
+ children
2101
+ ]
2041
2102
  }
2042
2103
  );
2043
2104
  };
2044
2105
 
2045
2106
  // src/app/surfaces/AppConfirmDialog.tsx
2046
- import { jsx as jsx18, jsxs as jsxs13 } from "react/jsx-runtime";
2107
+ import { jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
2047
2108
  var bodyClass2 = "flex flex-col gap-4 p-6";
2048
2109
  var titleClass = "pr-8";
2049
2110
  var actionsClass = "flex flex-wrap justify-end gap-2";
@@ -2058,15 +2119,15 @@ var AppConfirmDialog = ({
2058
2119
  destructive = false,
2059
2120
  className
2060
2121
  }) => {
2061
- return /* @__PURE__ */ jsx18(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsx18(
2122
+ return /* @__PURE__ */ jsx19(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsx19(
2062
2123
  DialogContent,
2063
2124
  {
2064
2125
  className: cn("gap-0 p-0 sm:max-w-md", className),
2065
- children: /* @__PURE__ */ jsxs13("div", { className: bodyClass2, children: [
2066
- /* @__PURE__ */ jsx18(DialogTitle, { className: titleClass, children: title }),
2067
- description ? /* @__PURE__ */ jsx18("p", { className: "text-sm text-muted-foreground", children: description }) : null,
2068
- /* @__PURE__ */ jsxs13("div", { className: actionsClass, children: [
2069
- /* @__PURE__ */ jsx18(
2126
+ children: /* @__PURE__ */ jsxs14("div", { className: bodyClass2, children: [
2127
+ /* @__PURE__ */ jsx19(DialogTitle, { className: titleClass, children: title }),
2128
+ description ? /* @__PURE__ */ jsx19("p", { className: "text-sm text-muted-foreground", children: description }) : null,
2129
+ /* @__PURE__ */ jsxs14("div", { className: actionsClass, children: [
2130
+ /* @__PURE__ */ jsx19(
2070
2131
  TimbalV2Button,
2071
2132
  {
2072
2133
  type: "button",
@@ -2076,7 +2137,7 @@ var AppConfirmDialog = ({
2076
2137
  children: cancelLabel
2077
2138
  }
2078
2139
  ),
2079
- /* @__PURE__ */ jsx18(
2140
+ /* @__PURE__ */ jsx19(
2080
2141
  TimbalV2Button,
2081
2142
  {
2082
2143
  type: "button",
@@ -2096,7 +2157,7 @@ var AppConfirmDialog = ({
2096
2157
  };
2097
2158
 
2098
2159
  // src/app/surfaces/InfoCard.tsx
2099
- import { jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
2160
+ import { jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
2100
2161
  var toneClass = {
2101
2162
  neutral: "border-border bg-muted/40",
2102
2163
  info: "border-primary/25 bg-primary/5",
@@ -2111,7 +2172,7 @@ var InfoCard = ({
2111
2172
  action,
2112
2173
  tone = "neutral",
2113
2174
  className
2114
- }) => /* @__PURE__ */ jsxs14(
2175
+ }) => /* @__PURE__ */ jsxs15(
2115
2176
  "div",
2116
2177
  {
2117
2178
  className: cn(
@@ -2120,18 +2181,18 @@ var InfoCard = ({
2120
2181
  className
2121
2182
  ),
2122
2183
  children: [
2123
- icon ? /* @__PURE__ */ jsx19("span", { className: "mt-0.5 shrink-0 text-muted-foreground", children: icon }) : null,
2124
- /* @__PURE__ */ jsxs14("div", { className: "min-w-0 flex-1", children: [
2125
- title ? /* @__PURE__ */ jsx19("p", { className: "text-sm font-medium text-foreground", children: title }) : null,
2126
- children ? /* @__PURE__ */ jsx19("div", { className: cn("text-sm text-muted-foreground", title && "mt-1"), children }) : null
2184
+ icon ? /* @__PURE__ */ jsx20("span", { className: "mt-0.5 shrink-0 text-muted-foreground", children: icon }) : null,
2185
+ /* @__PURE__ */ jsxs15("div", { className: "min-w-0 flex-1", children: [
2186
+ title ? /* @__PURE__ */ jsx20("p", { className: "text-sm font-medium text-foreground", children: title }) : null,
2187
+ children ? /* @__PURE__ */ jsx20("div", { className: cn("text-sm text-muted-foreground", title && "mt-1"), children }) : null
2127
2188
  ] }),
2128
- action ? /* @__PURE__ */ jsx19("div", { className: "shrink-0", children: action }) : null
2189
+ action ? /* @__PURE__ */ jsx20("div", { className: "shrink-0", children: action }) : null
2129
2190
  ]
2130
2191
  }
2131
2192
  );
2132
2193
 
2133
2194
  // src/app/surfaces/StatusDot.tsx
2134
- import { jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
2195
+ import { jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
2135
2196
  var dotClass = {
2136
2197
  online: "bg-emerald-500",
2137
2198
  busy: "bg-amber-500",
@@ -2144,9 +2205,9 @@ var StatusDot = ({
2144
2205
  label,
2145
2206
  pulse = false,
2146
2207
  className
2147
- }) => /* @__PURE__ */ jsxs15("span", { className: cn("inline-flex items-center gap-1.5", className), children: [
2148
- /* @__PURE__ */ jsxs15("span", { className: "relative flex size-2", children: [
2149
- pulse ? /* @__PURE__ */ jsx20(
2208
+ }) => /* @__PURE__ */ jsxs16("span", { className: cn("inline-flex items-center gap-1.5", className), children: [
2209
+ /* @__PURE__ */ jsxs16("span", { className: "relative flex size-2", children: [
2210
+ pulse ? /* @__PURE__ */ jsx21(
2150
2211
  "span",
2151
2212
  {
2152
2213
  className: cn(
@@ -2155,25 +2216,25 @@ var StatusDot = ({
2155
2216
  )
2156
2217
  }
2157
2218
  ) : null,
2158
- /* @__PURE__ */ jsx20("span", { className: cn("relative inline-flex size-2 rounded-full", dotClass[tone]) })
2219
+ /* @__PURE__ */ jsx21("span", { className: cn("relative inline-flex size-2 rounded-full", dotClass[tone]) })
2159
2220
  ] }),
2160
- label ? /* @__PURE__ */ jsx20("span", { className: "text-xs text-muted-foreground", children: label }) : null
2221
+ label ? /* @__PURE__ */ jsx21("span", { className: "text-xs text-muted-foreground", children: label }) : null
2161
2222
  ] });
2162
2223
 
2163
2224
  // src/app/surfaces/DescriptionList.tsx
2164
- import { jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
2225
+ import { jsx as jsx22, jsxs as jsxs17 } from "react/jsx-runtime";
2165
2226
  var DescriptionList = ({
2166
2227
  items,
2167
2228
  stacked = false,
2168
2229
  className
2169
- }) => /* @__PURE__ */ jsx21(
2230
+ }) => /* @__PURE__ */ jsx22(
2170
2231
  "dl",
2171
2232
  {
2172
2233
  className: cn(
2173
2234
  "divide-y divide-border rounded-xl border border-border bg-card",
2174
2235
  className
2175
2236
  ),
2176
- children: items.map((item, i) => /* @__PURE__ */ jsxs16(
2237
+ children: items.map((item, i) => /* @__PURE__ */ jsxs17(
2177
2238
  "div",
2178
2239
  {
2179
2240
  className: cn(
@@ -2181,8 +2242,8 @@ var DescriptionList = ({
2181
2242
  stacked ? "flex flex-col gap-0.5" : "flex items-center justify-between gap-4"
2182
2243
  ),
2183
2244
  children: [
2184
- /* @__PURE__ */ jsx21("dt", { className: "text-sm text-muted-foreground", children: item.label }),
2185
- /* @__PURE__ */ jsx21(
2245
+ /* @__PURE__ */ jsx22("dt", { className: "text-sm text-muted-foreground", children: item.label }),
2246
+ /* @__PURE__ */ jsx22(
2186
2247
  "dd",
2187
2248
  {
2188
2249
  className: cn(
@@ -2202,8 +2263,8 @@ var DescriptionList = ({
2202
2263
  // src/app/surfaces/ExpandableSection.tsx
2203
2264
  import { useId, useState as useState2 } from "react";
2204
2265
  import { AnimatePresence, motion as motion2, useReducedMotion as useReducedMotion2 } from "motion/react";
2205
- import { jsx as jsx22, jsxs as jsxs17 } from "react/jsx-runtime";
2206
- var Chevron = ({ open }) => /* @__PURE__ */ jsx22(
2266
+ import { jsx as jsx23, jsxs as jsxs18 } from "react/jsx-runtime";
2267
+ var Chevron = ({ open }) => /* @__PURE__ */ jsx23(
2207
2268
  "svg",
2208
2269
  {
2209
2270
  viewBox: "0 0 24 24",
@@ -2217,7 +2278,7 @@ var Chevron = ({ open }) => /* @__PURE__ */ jsx22(
2217
2278
  strokeLinecap: "round",
2218
2279
  strokeLinejoin: "round",
2219
2280
  "aria-hidden": true,
2220
- children: /* @__PURE__ */ jsx22("path", { d: "m6 9 6 6 6-6" })
2281
+ children: /* @__PURE__ */ jsx23("path", { d: "m6 9 6 6 6-6" })
2221
2282
  }
2222
2283
  );
2223
2284
  var ExpandableSection = ({
@@ -2238,8 +2299,8 @@ var ExpandableSection = ({
2238
2299
  if (openProp == null) setInternalOpen((o) => !o);
2239
2300
  onOpenChange?.(!open);
2240
2301
  };
2241
- return /* @__PURE__ */ jsxs17("div", { className: cn("border-b border-border last:border-0", className), children: [
2242
- /* @__PURE__ */ jsxs17(
2302
+ return /* @__PURE__ */ jsxs18("div", { className: cn("border-b border-border last:border-0", className), children: [
2303
+ /* @__PURE__ */ jsxs18(
2243
2304
  "button",
2244
2305
  {
2245
2306
  type: "button",
@@ -2248,16 +2309,16 @@ var ExpandableSection = ({
2248
2309
  "aria-controls": panelId,
2249
2310
  className: "flex w-full items-center justify-between gap-3 bg-transparent px-4 py-3 text-left hover:bg-transparent active:bg-transparent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-foreground/10",
2250
2311
  children: [
2251
- /* @__PURE__ */ jsxs17("span", { className: "flex min-w-0 items-center gap-3", children: [
2252
- icon ? /* @__PURE__ */ jsx22("span", { className: "flex size-8 items-center justify-center rounded-lg border border-border bg-muted text-muted-foreground", children: icon }) : null,
2253
- /* @__PURE__ */ jsx22("span", { className: "truncate text-sm font-medium text-foreground", children: title }),
2254
- count != null ? /* @__PURE__ */ jsx22("span", { className: "rounded-full border border-border bg-muted px-2 py-0.5 text-xs text-muted-foreground", children: count }) : null
2312
+ /* @__PURE__ */ jsxs18("span", { className: "flex min-w-0 items-center gap-3", children: [
2313
+ icon ? /* @__PURE__ */ jsx23("span", { className: "flex size-8 items-center justify-center rounded-lg border border-border bg-muted text-muted-foreground", children: icon }) : null,
2314
+ /* @__PURE__ */ jsx23("span", { className: "truncate text-sm font-medium text-foreground", children: title }),
2315
+ count != null ? /* @__PURE__ */ jsx23("span", { className: "rounded-full border border-border bg-muted px-2 py-0.5 text-xs text-muted-foreground", children: count }) : null
2255
2316
  ] }),
2256
- /* @__PURE__ */ jsx22(Chevron, { open })
2317
+ /* @__PURE__ */ jsx23(Chevron, { open })
2257
2318
  ]
2258
2319
  }
2259
2320
  ),
2260
- /* @__PURE__ */ jsx22(AnimatePresence, { initial: false, children: open ? /* @__PURE__ */ jsx22(
2321
+ /* @__PURE__ */ jsx23(AnimatePresence, { initial: false, children: open ? /* @__PURE__ */ jsx23(
2261
2322
  motion2.div,
2262
2323
  {
2263
2324
  id: panelId,
@@ -2266,7 +2327,7 @@ var ExpandableSection = ({
2266
2327
  exit: reduceMotion ? void 0 : { height: 0, opacity: 0 },
2267
2328
  transition: { duration: 0.2, ease: "easeOut" },
2268
2329
  className: "overflow-hidden",
2269
- children: /* @__PURE__ */ jsx22("div", { className: "bg-muted/20", children })
2330
+ children: /* @__PURE__ */ jsx23("div", { className: "bg-muted/20", children })
2270
2331
  },
2271
2332
  "body"
2272
2333
  ) : null })
@@ -2274,7 +2335,7 @@ var ExpandableSection = ({
2274
2335
  };
2275
2336
 
2276
2337
  // src/app/surfaces/ResourceCard.tsx
2277
- import { Fragment as Fragment3, jsx as jsx23, jsxs as jsxs18 } from "react/jsx-runtime";
2338
+ import { Fragment as Fragment3, jsx as jsx24, jsxs as jsxs19 } from "react/jsx-runtime";
2278
2339
  var resourceCardShellClass = cn(
2279
2340
  "flex min-h-[8.5rem] flex-col rounded-2xl p-4 text-left font-normal",
2280
2341
  TIMBAL_V2_ELEVATED_SURFACE
@@ -2299,35 +2360,35 @@ var ResourceCard = ({
2299
2360
  ariaLabel,
2300
2361
  className
2301
2362
  }) => {
2302
- const body = /* @__PURE__ */ jsxs18(Fragment3, { children: [
2303
- /* @__PURE__ */ jsxs18("div", { className: "flex items-start gap-3", children: [
2304
- media ? /* @__PURE__ */ jsx23("span", { className: mediaShellClass, children: media }) : null,
2305
- /* @__PURE__ */ jsxs18("div", { className: "min-w-0 flex-1 pt-0.5", children: [
2306
- /* @__PURE__ */ jsx23("p", { className: "truncate text-sm font-normal leading-snug text-foreground", children: title }),
2307
- subtitle ? /* @__PURE__ */ jsx23("p", { className: "mt-1 line-clamp-2 text-xs font-normal text-muted-foreground", children: subtitle }) : null
2363
+ const body = /* @__PURE__ */ jsxs19(Fragment3, { children: [
2364
+ /* @__PURE__ */ jsxs19("div", { className: "flex items-start gap-3", children: [
2365
+ media ? /* @__PURE__ */ jsx24("span", { className: mediaShellClass, children: media }) : null,
2366
+ /* @__PURE__ */ jsxs19("div", { className: "min-w-0 flex-1 pt-0.5", children: [
2367
+ /* @__PURE__ */ jsx24("p", { className: "truncate text-sm font-normal leading-snug text-foreground", children: title }),
2368
+ subtitle ? /* @__PURE__ */ jsx24("p", { className: "mt-1 line-clamp-2 text-xs font-normal text-muted-foreground", children: subtitle }) : null
2308
2369
  ] }),
2309
- badge ? /* @__PURE__ */ jsx23("span", { className: "shrink-0 pt-0.5", children: badge }) : null
2370
+ badge ? /* @__PURE__ */ jsx24("span", { className: "shrink-0 pt-0.5", children: badge }) : null
2310
2371
  ] }),
2311
- footer || action ? /* @__PURE__ */ jsxs18("div", { className: "mt-auto flex items-center justify-between gap-3 border-t border-border/40 pt-3 text-xs font-normal text-muted-foreground", children: [
2312
- /* @__PURE__ */ jsx23("span", { className: "min-w-0 truncate", children: footer }),
2313
- action ? /* @__PURE__ */ jsx23("span", { className: "shrink-0 opacity-80", children: action }) : null
2372
+ footer || action ? /* @__PURE__ */ jsxs19("div", { className: "mt-auto flex items-center justify-between gap-3 border-t border-border/40 pt-3 text-xs font-normal text-muted-foreground", children: [
2373
+ /* @__PURE__ */ jsx24("span", { className: "min-w-0 truncate", children: footer }),
2374
+ action ? /* @__PURE__ */ jsx24("span", { className: "shrink-0 opacity-80", children: action }) : null
2314
2375
  ] }) : null
2315
2376
  ] });
2316
2377
  if (onClick) {
2317
- return /* @__PURE__ */ jsx23("button", { type: "button", onClick, "aria-label": ariaLabel, className: cn(resourceCardInteractiveClass, className), children: body });
2378
+ return /* @__PURE__ */ jsx24("button", { type: "button", onClick, "aria-label": ariaLabel, className: cn(resourceCardInteractiveClass, className), children: body });
2318
2379
  }
2319
- return /* @__PURE__ */ jsx23("article", { className: cn(resourceCardShellClass, className), children: body });
2380
+ return /* @__PURE__ */ jsx24("article", { className: cn(resourceCardShellClass, className), children: body });
2320
2381
  };
2321
2382
 
2322
2383
  // src/app/settings/SettingsSection.tsx
2323
- import { jsx as jsx24, jsxs as jsxs19 } from "react/jsx-runtime";
2384
+ import { jsx as jsx25, jsxs as jsxs20 } from "react/jsx-runtime";
2324
2385
  var SettingsSectionHeader = ({
2325
2386
  title,
2326
2387
  description,
2327
2388
  className
2328
- }) => /* @__PURE__ */ jsxs19("div", { className: cn("flex flex-col", className), children: [
2329
- /* @__PURE__ */ jsx24("h3", { className: "text-[17px] font-medium leading-tight text-foreground", children: title }),
2330
- description ? /* @__PURE__ */ jsx24("p", { className: "mt-1 text-sm text-muted-foreground", children: description }) : null
2389
+ }) => /* @__PURE__ */ jsxs20("div", { className: cn("flex flex-col", className), children: [
2390
+ /* @__PURE__ */ jsx25("h3", { className: "text-[17px] font-medium leading-tight text-foreground", children: title }),
2391
+ description ? /* @__PURE__ */ jsx25("p", { className: "mt-1 text-sm text-muted-foreground", children: description }) : null
2331
2392
  ] });
2332
2393
  var SettingsSection = ({
2333
2394
  title,
@@ -2336,7 +2397,7 @@ var SettingsSection = ({
2336
2397
  children,
2337
2398
  noBorderTop = false,
2338
2399
  className
2339
- }) => /* @__PURE__ */ jsxs19(
2400
+ }) => /* @__PURE__ */ jsxs20(
2340
2401
  "section",
2341
2402
  {
2342
2403
  className: cn(
@@ -2345,18 +2406,18 @@ var SettingsSection = ({
2345
2406
  className
2346
2407
  ),
2347
2408
  children: [
2348
- /* @__PURE__ */ jsxs19("div", { className: "min-w-0", children: [
2349
- /* @__PURE__ */ jsx24("h2", { className: "text-sm font-medium text-foreground", children: title }),
2350
- description ? /* @__PURE__ */ jsx24("p", { className: "mt-1 text-sm text-muted-foreground", children: description }) : null,
2351
- descriptionFooter ? /* @__PURE__ */ jsx24("div", { className: "mt-3 min-w-0", children: descriptionFooter }) : null
2409
+ /* @__PURE__ */ jsxs20("div", { className: "min-w-0", children: [
2410
+ /* @__PURE__ */ jsx25("h2", { className: "text-sm font-medium text-foreground", children: title }),
2411
+ description ? /* @__PURE__ */ jsx25("p", { className: "mt-1 text-sm text-muted-foreground", children: description }) : null,
2412
+ descriptionFooter ? /* @__PURE__ */ jsx25("div", { className: "mt-3 min-w-0", children: descriptionFooter }) : null
2352
2413
  ] }),
2353
- /* @__PURE__ */ jsx24("div", { className: "min-w-0 space-y-3", children })
2414
+ /* @__PURE__ */ jsx25("div", { className: "min-w-0 space-y-3", children })
2354
2415
  ]
2355
2416
  }
2356
2417
  );
2357
2418
 
2358
2419
  // src/app/settings/FieldRow.tsx
2359
- import { jsx as jsx25, jsxs as jsxs20 } from "react/jsx-runtime";
2420
+ import { jsx as jsx26, jsxs as jsxs21 } from "react/jsx-runtime";
2360
2421
  var FieldRow = ({
2361
2422
  label,
2362
2423
  children,
@@ -2366,7 +2427,7 @@ var FieldRow = ({
2366
2427
  className
2367
2428
  }) => {
2368
2429
  if (inline) {
2369
- return /* @__PURE__ */ jsxs20(
2430
+ return /* @__PURE__ */ jsxs21(
2370
2431
  "div",
2371
2432
  {
2372
2433
  className: cn(
@@ -2374,8 +2435,8 @@ var FieldRow = ({
2374
2435
  className
2375
2436
  ),
2376
2437
  children: [
2377
- /* @__PURE__ */ jsxs20("div", { className: "min-w-0", children: [
2378
- /* @__PURE__ */ jsx25(
2438
+ /* @__PURE__ */ jsxs21("div", { className: "min-w-0", children: [
2439
+ /* @__PURE__ */ jsx26(
2379
2440
  "label",
2380
2441
  {
2381
2442
  htmlFor,
@@ -2383,17 +2444,17 @@ var FieldRow = ({
2383
2444
  children: label
2384
2445
  }
2385
2446
  ),
2386
- description ? /* @__PURE__ */ jsx25("p", { className: "mt-0.5 text-xs text-muted-foreground", children: description }) : null
2447
+ description ? /* @__PURE__ */ jsx26("p", { className: "mt-0.5 text-xs text-muted-foreground", children: description }) : null
2387
2448
  ] }),
2388
- /* @__PURE__ */ jsx25("div", { className: "shrink-0", children })
2449
+ /* @__PURE__ */ jsx26("div", { className: "shrink-0", children })
2389
2450
  ]
2390
2451
  }
2391
2452
  );
2392
2453
  }
2393
- return /* @__PURE__ */ jsxs20("div", { className: cn("flex flex-col gap-1.5", className), children: [
2394
- /* @__PURE__ */ jsx25("label", { htmlFor, className: "text-sm font-medium text-foreground", children: label }),
2454
+ return /* @__PURE__ */ jsxs21("div", { className: cn("flex flex-col gap-1.5", className), children: [
2455
+ /* @__PURE__ */ jsx26("label", { htmlFor, className: "text-sm font-medium text-foreground", children: label }),
2395
2456
  children,
2396
- description ? /* @__PURE__ */ jsx25("p", { className: "text-xs text-muted-foreground", children: description }) : null
2457
+ description ? /* @__PURE__ */ jsx26("p", { className: "text-xs text-muted-foreground", children: description }) : null
2397
2458
  ] });
2398
2459
  };
2399
2460
 
@@ -2401,7 +2462,7 @@ var FieldRow = ({
2401
2462
  import { useEffect, useState as useState3 } from "react";
2402
2463
  import { createPortal } from "react-dom";
2403
2464
  import { AnimatePresence as AnimatePresence2, motion as motion3, useReducedMotion as useReducedMotion3 } from "motion/react";
2404
- import { jsx as jsx26, jsxs as jsxs21 } from "react/jsx-runtime";
2465
+ import { jsx as jsx27, jsxs as jsxs22 } from "react/jsx-runtime";
2405
2466
  var FloatingUnsavedChangesBar = ({
2406
2467
  visible,
2407
2468
  message = "Unsaved changes",
@@ -2419,7 +2480,7 @@ var FloatingUnsavedChangesBar = ({
2419
2480
  useEffect(() => setMounted(true), []);
2420
2481
  if (!mounted || typeof document === "undefined") return null;
2421
2482
  return createPortal(
2422
- /* @__PURE__ */ jsx26(AnimatePresence2, { children: visible ? /* @__PURE__ */ jsx26("div", { className: "pointer-events-none fixed inset-x-0 bottom-5 z-50 flex justify-center px-4", children: /* @__PURE__ */ jsxs21(
2483
+ /* @__PURE__ */ jsx27(AnimatePresence2, { children: visible ? /* @__PURE__ */ jsx27("div", { className: "pointer-events-none fixed inset-x-0 bottom-5 z-50 flex justify-center px-4", children: /* @__PURE__ */ jsxs22(
2423
2484
  motion3.div,
2424
2485
  {
2425
2486
  role: "region",
@@ -2433,10 +2494,10 @@ var FloatingUnsavedChangesBar = ({
2433
2494
  className
2434
2495
  ),
2435
2496
  children: [
2436
- /* @__PURE__ */ jsx26("span", { className: "text-sm text-muted-foreground", children: message }),
2437
- /* @__PURE__ */ jsxs21("span", { className: "flex items-center gap-1.5", children: [
2438
- /* @__PURE__ */ jsx26(Button, { variant: "ghost", size: "sm", onClick: onDiscard, disabled: isSaving, children: discardLabel }),
2439
- /* @__PURE__ */ jsx26(Button, { size: "sm", onClick: onSave, disabled: saveDisabled || isSaving, children: isSaving ? "Saving\u2026" : saveLabel })
2497
+ /* @__PURE__ */ jsx27("span", { className: "text-sm text-muted-foreground", children: message }),
2498
+ /* @__PURE__ */ jsxs22("span", { className: "flex items-center gap-1.5", children: [
2499
+ /* @__PURE__ */ jsx27(Button, { variant: "ghost", size: "sm", onClick: onDiscard, disabled: isSaving, children: discardLabel }),
2500
+ /* @__PURE__ */ jsx27(Button, { size: "sm", onClick: onSave, disabled: saveDisabled || isSaving, children: isSaving ? "Saving\u2026" : saveLabel })
2440
2501
  ] })
2441
2502
  ]
2442
2503
  }
@@ -2446,13 +2507,13 @@ var FloatingUnsavedChangesBar = ({
2446
2507
  };
2447
2508
 
2448
2509
  // src/app/settings/DangerZone.tsx
2449
- import { jsx as jsx27, jsxs as jsxs22 } from "react/jsx-runtime";
2510
+ import { jsx as jsx28, jsxs as jsxs23 } from "react/jsx-runtime";
2450
2511
  var DangerZoneAction = ({
2451
2512
  title,
2452
2513
  description,
2453
2514
  action,
2454
2515
  className
2455
- }) => /* @__PURE__ */ jsxs22(
2516
+ }) => /* @__PURE__ */ jsxs23(
2456
2517
  "div",
2457
2518
  {
2458
2519
  className: cn(
@@ -2460,11 +2521,11 @@ var DangerZoneAction = ({
2460
2521
  className
2461
2522
  ),
2462
2523
  children: [
2463
- /* @__PURE__ */ jsxs22("div", { className: "min-w-0", children: [
2464
- /* @__PURE__ */ jsx27("p", { className: "text-sm font-medium text-foreground", children: title }),
2465
- description ? /* @__PURE__ */ jsx27("p", { className: "mt-0.5 text-sm text-muted-foreground", children: description }) : null
2524
+ /* @__PURE__ */ jsxs23("div", { className: "min-w-0", children: [
2525
+ /* @__PURE__ */ jsx28("p", { className: "text-sm font-medium text-foreground", children: title }),
2526
+ description ? /* @__PURE__ */ jsx28("p", { className: "mt-0.5 text-sm text-muted-foreground", children: description }) : null
2466
2527
  ] }),
2467
- /* @__PURE__ */ jsx27("div", { className: "shrink-0", children: action })
2528
+ /* @__PURE__ */ jsx28("div", { className: "shrink-0", children: action })
2468
2529
  ]
2469
2530
  }
2470
2531
  );
@@ -2473,7 +2534,7 @@ var DangerZone = ({
2473
2534
  description,
2474
2535
  children,
2475
2536
  className
2476
- }) => /* @__PURE__ */ jsxs22(
2537
+ }) => /* @__PURE__ */ jsxs23(
2477
2538
  "section",
2478
2539
  {
2479
2540
  className: cn(
@@ -2481,18 +2542,18 @@ var DangerZone = ({
2481
2542
  className
2482
2543
  ),
2483
2544
  children: [
2484
- (title || description) && /* @__PURE__ */ jsxs22("header", { className: "border-b border-destructive/20 bg-destructive/5 px-4 py-3", children: [
2485
- title ? /* @__PURE__ */ jsx27("h3", { className: "text-sm font-semibold text-destructive", children: title }) : null,
2486
- description ? /* @__PURE__ */ jsx27("p", { className: "mt-0.5 text-sm text-muted-foreground", children: description }) : null
2545
+ (title || description) && /* @__PURE__ */ jsxs23("header", { className: "border-b border-destructive/20 bg-destructive/5 px-4 py-3", children: [
2546
+ title ? /* @__PURE__ */ jsx28("h3", { className: "text-sm font-semibold text-destructive", children: title }) : null,
2547
+ description ? /* @__PURE__ */ jsx28("p", { className: "mt-0.5 text-sm text-muted-foreground", children: description }) : null
2487
2548
  ] }),
2488
- /* @__PURE__ */ jsx27("div", { className: "divide-y divide-border bg-card", children })
2549
+ /* @__PURE__ */ jsx28("div", { className: "divide-y divide-border bg-card", children })
2489
2550
  ]
2490
2551
  }
2491
2552
  );
2492
2553
 
2493
2554
  // src/app/integrations/IntegrationCard.tsx
2494
2555
  import { useId as useId2 } from "react";
2495
- import { Fragment as Fragment4, jsx as jsx28, jsxs as jsxs23 } from "react/jsx-runtime";
2556
+ import { Fragment as Fragment4, jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
2496
2557
  var INTEGRATION_CATALOG_CARD_HEIGHT_CLASS = "h-[12.25rem] min-h-[12.25rem] max-h-[12.25rem]";
2497
2558
  var statusLabel = {
2498
2559
  available: null,
@@ -2533,12 +2594,12 @@ var IntegrationCard = ({
2533
2594
  const titleId = useId2();
2534
2595
  const locked = status === "locked";
2535
2596
  const dimmed = status === "disabled" || locked;
2536
- const body = /* @__PURE__ */ jsxs23("div", { className: "flex h-full min-h-0 flex-col", children: [
2537
- /* @__PURE__ */ jsxs23("div", { className: "flex shrink-0 items-start gap-3 pr-2", children: [
2538
- logo ? /* @__PURE__ */ jsx28("span", { className: logoShellClass, "aria-hidden": Boolean(ariaLabel), children: logo }) : null,
2539
- /* @__PURE__ */ jsx28("div", { className: "min-w-0 flex-1 pt-0.5", children: /* @__PURE__ */ jsxs23("div", { className: "flex items-start justify-between gap-2", children: [
2540
- /* @__PURE__ */ jsxs23("div", { className: "min-w-0", children: [
2541
- /* @__PURE__ */ jsx28(
2597
+ const body = /* @__PURE__ */ jsxs24("div", { className: "flex h-full min-h-0 flex-col", children: [
2598
+ /* @__PURE__ */ jsxs24("div", { className: "flex shrink-0 items-start gap-3 pr-2", children: [
2599
+ logo ? /* @__PURE__ */ jsx29("span", { className: logoShellClass, "aria-hidden": Boolean(ariaLabel), children: logo }) : null,
2600
+ /* @__PURE__ */ jsx29("div", { className: "min-w-0 flex-1 pt-0.5", children: /* @__PURE__ */ jsxs24("div", { className: "flex items-start justify-between gap-2", children: [
2601
+ /* @__PURE__ */ jsxs24("div", { className: "min-w-0", children: [
2602
+ /* @__PURE__ */ jsx29(
2542
2603
  "h4",
2543
2604
  {
2544
2605
  id: onClick && !action ? void 0 : titleId,
@@ -2546,12 +2607,12 @@ var IntegrationCard = ({
2546
2607
  children: name
2547
2608
  }
2548
2609
  ),
2549
- statusLabel[status] ? /* @__PURE__ */ jsx28("p", { className: "mt-0.5 text-xs text-muted-foreground", children: statusLabel[status] }) : null
2610
+ statusLabel[status] ? /* @__PURE__ */ jsx29("p", { className: "mt-0.5 text-xs text-muted-foreground", children: statusLabel[status] }) : null
2550
2611
  ] }),
2551
- badge ? /* @__PURE__ */ jsx28("span", { className: "shrink-0", children: badge }) : null
2612
+ badge ? /* @__PURE__ */ jsx29("span", { className: "shrink-0", children: badge }) : null
2552
2613
  ] }) })
2553
2614
  ] }),
2554
- description ? /* @__PURE__ */ jsx28(
2615
+ description ? /* @__PURE__ */ jsx29(
2555
2616
  "p",
2556
2617
  {
2557
2618
  className: cn(
@@ -2561,9 +2622,9 @@ var IntegrationCard = ({
2561
2622
  children: description
2562
2623
  }
2563
2624
  ) : null,
2564
- action ? /* @__PURE__ */ jsxs23(Fragment4, { children: [
2565
- /* @__PURE__ */ jsx28("div", { className: "min-h-0 flex-1", "aria-hidden": true }),
2566
- /* @__PURE__ */ jsx28("div", { className: "relative mt-3 shrink-0", children: action })
2625
+ action ? /* @__PURE__ */ jsxs24(Fragment4, { children: [
2626
+ /* @__PURE__ */ jsx29("div", { className: "min-h-0 flex-1", "aria-hidden": true }),
2627
+ /* @__PURE__ */ jsx29("div", { className: "relative mt-3 shrink-0", children: action })
2567
2628
  ] }) : null
2568
2629
  ] });
2569
2630
  const shellClass3 = cn(
@@ -2573,7 +2634,7 @@ var IntegrationCard = ({
2573
2634
  className
2574
2635
  );
2575
2636
  if (onClick && !action) {
2576
- return /* @__PURE__ */ jsx28(
2637
+ return /* @__PURE__ */ jsx29(
2577
2638
  "button",
2578
2639
  {
2579
2640
  type: "button",
@@ -2590,12 +2651,12 @@ var IntegrationCard = ({
2590
2651
  }
2591
2652
  );
2592
2653
  }
2593
- return /* @__PURE__ */ jsx28("article", { className: shellClass3, "aria-labelledby": titleId, children: body });
2654
+ return /* @__PURE__ */ jsx29("article", { className: shellClass3, "aria-labelledby": titleId, children: body });
2594
2655
  };
2595
2656
 
2596
2657
  // src/app/integrations/IntegrationsEmptyState.tsx
2597
2658
  import { useId as useId3 } from "react";
2598
- import { jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
2659
+ import { jsx as jsx30, jsxs as jsxs25 } from "react/jsx-runtime";
2599
2660
  var IntegrationsEmptyState = ({
2600
2661
  title = "No integrations yet",
2601
2662
  description = "Connect a provider to start syncing data and powering your workforce.",
@@ -2604,7 +2665,7 @@ var IntegrationsEmptyState = ({
2604
2665
  className
2605
2666
  }) => {
2606
2667
  const titleId = useId3();
2607
- return /* @__PURE__ */ jsxs24(
2668
+ return /* @__PURE__ */ jsxs25(
2608
2669
  "section",
2609
2670
  {
2610
2671
  className: cn(
@@ -2614,7 +2675,7 @@ var IntegrationsEmptyState = ({
2614
2675
  ),
2615
2676
  "aria-labelledby": titleId,
2616
2677
  children: [
2617
- icon ? /* @__PURE__ */ jsx29(
2678
+ icon ? /* @__PURE__ */ jsx30(
2618
2679
  "span",
2619
2680
  {
2620
2681
  className: cn(
@@ -2626,21 +2687,21 @@ var IntegrationsEmptyState = ({
2626
2687
  children: icon
2627
2688
  }
2628
2689
  ) : null,
2629
- /* @__PURE__ */ jsx29("h3", { id: titleId, className: "text-base font-normal text-foreground", children: title }),
2630
- description ? /* @__PURE__ */ jsx29("p", { className: "max-w-sm text-sm text-muted-foreground", children: description }) : null,
2631
- action ? /* @__PURE__ */ jsx29("div", { className: "mt-1", children: action }) : null
2690
+ /* @__PURE__ */ jsx30("h3", { id: titleId, className: "text-base font-normal text-foreground", children: title }),
2691
+ description ? /* @__PURE__ */ jsx30("p", { className: "max-w-sm text-sm text-muted-foreground", children: description }) : null,
2692
+ action ? /* @__PURE__ */ jsx30("div", { className: "mt-1", children: action }) : null
2632
2693
  ]
2633
2694
  }
2634
2695
  );
2635
2696
  };
2636
2697
 
2637
2698
  // src/app/integrations/PlanBadge.tsx
2638
- import { jsx as jsx30 } from "react/jsx-runtime";
2699
+ import { jsx as jsx31 } from "react/jsx-runtime";
2639
2700
  var planBadgeClass = "inline-flex h-5 max-w-full shrink-0 items-center rounded-md border border-border bg-muted/90 px-2 text-[11px] font-normal text-muted-foreground dark:border-white/10 dark:bg-white/5 dark:text-muted-foreground";
2640
- var PlanBadge = ({ children, className }) => /* @__PURE__ */ jsx30("span", { className: cn(planBadgeClass, className), children });
2701
+ var PlanBadge = ({ children, className }) => /* @__PURE__ */ jsx31("span", { className: cn(planBadgeClass, className), children });
2641
2702
 
2642
2703
  // src/app/integrations/ConnectionRow.tsx
2643
- import { Fragment as Fragment5, jsx as jsx31, jsxs as jsxs25 } from "react/jsx-runtime";
2704
+ import { Fragment as Fragment5, jsx as jsx32, jsxs as jsxs26 } from "react/jsx-runtime";
2644
2705
  var logoShellClass2 = cn(
2645
2706
  "flex size-9 shrink-0 items-center justify-center overflow-hidden rounded-lg",
2646
2707
  TIMBAL_V2_LOGO_TILE
@@ -2655,14 +2716,14 @@ var ConnectionRow = ({
2655
2716
  ariaLabel,
2656
2717
  className
2657
2718
  }) => {
2658
- const inner = /* @__PURE__ */ jsxs25(Fragment5, { children: [
2659
- logo ? /* @__PURE__ */ jsx31("span", { className: logoShellClass2, children: logo }) : null,
2660
- /* @__PURE__ */ jsxs25("div", { className: "min-w-0 flex-1", children: [
2661
- /* @__PURE__ */ jsx31("p", { className: "truncate text-sm font-normal text-foreground", children: name }),
2662
- meta ? /* @__PURE__ */ jsx31("p", { className: "truncate text-xs text-muted-foreground", children: meta }) : null
2719
+ const inner = /* @__PURE__ */ jsxs26(Fragment5, { children: [
2720
+ logo ? /* @__PURE__ */ jsx32("span", { className: logoShellClass2, children: logo }) : null,
2721
+ /* @__PURE__ */ jsxs26("div", { className: "min-w-0 flex-1", children: [
2722
+ /* @__PURE__ */ jsx32("p", { className: "truncate text-sm font-normal text-foreground", children: name }),
2723
+ meta ? /* @__PURE__ */ jsx32("p", { className: "truncate text-xs text-muted-foreground", children: meta }) : null
2663
2724
  ] }),
2664
- badge ? /* @__PURE__ */ jsx31("span", { className: "shrink-0", children: badge }) : null,
2665
- action ? /* @__PURE__ */ jsx31("span", { className: "shrink-0", children: action }) : null
2725
+ badge ? /* @__PURE__ */ jsx32("span", { className: "shrink-0", children: badge }) : null,
2726
+ action ? /* @__PURE__ */ jsx32("span", { className: "shrink-0", children: action }) : null
2666
2727
  ] });
2667
2728
  const rowClass2 = cn(
2668
2729
  "flex w-full items-center gap-3 px-4 py-3 text-left",
@@ -2670,7 +2731,7 @@ var ConnectionRow = ({
2670
2731
  className
2671
2732
  );
2672
2733
  if (onClick) {
2673
- return /* @__PURE__ */ jsx31(
2734
+ return /* @__PURE__ */ jsx32(
2674
2735
  "button",
2675
2736
  {
2676
2737
  type: "button",
@@ -2682,7 +2743,7 @@ var ConnectionRow = ({
2682
2743
  }
2683
2744
  );
2684
2745
  }
2685
- return /* @__PURE__ */ jsx31("div", { role: "listitem", className: rowClass2, children: inner });
2746
+ return /* @__PURE__ */ jsx32("div", { role: "listitem", className: rowClass2, children: inner });
2686
2747
  };
2687
2748
  var connectionRowListClass = cn(
2688
2749
  "overflow-hidden rounded-2xl",
@@ -2690,12 +2751,12 @@ var connectionRowListClass = cn(
2690
2751
  );
2691
2752
 
2692
2753
  // src/app/integrations/ConnectionRowList.tsx
2693
- import { jsx as jsx32 } from "react/jsx-runtime";
2754
+ import { jsx as jsx33 } from "react/jsx-runtime";
2694
2755
  var ConnectionRowList = ({
2695
2756
  children,
2696
2757
  "aria-label": ariaLabel = "Connected integrations",
2697
2758
  className
2698
- }) => /* @__PURE__ */ jsx32(
2759
+ }) => /* @__PURE__ */ jsx33(
2699
2760
  "div",
2700
2761
  {
2701
2762
  role: "list",
@@ -2706,7 +2767,7 @@ var ConnectionRowList = ({
2706
2767
  );
2707
2768
 
2708
2769
  // src/app/navigation/SubNav.tsx
2709
- import { jsx as jsx33 } from "react/jsx-runtime";
2770
+ import { jsx as jsx34 } from "react/jsx-runtime";
2710
2771
  var SubNav = ({
2711
2772
  items,
2712
2773
  activeId,
@@ -2715,7 +2776,7 @@ var SubNav = ({
2715
2776
  "aria-label": ariaLabel = "Section navigation",
2716
2777
  layoutId
2717
2778
  }) => {
2718
- return /* @__PURE__ */ jsx33("nav", { className: cn("aui-app-sub-nav", className), "aria-label": ariaLabel, children: /* @__PURE__ */ jsx33(
2779
+ return /* @__PURE__ */ jsx34("nav", { className: cn("aui-app-sub-nav", className), "aria-label": ariaLabel, children: /* @__PURE__ */ jsx34(
2719
2780
  PillSegmentedTabs,
2720
2781
  {
2721
2782
  value: activeId,
@@ -2729,13 +2790,13 @@ var SubNav = ({
2729
2790
  };
2730
2791
 
2731
2792
  // src/app/navigation/Breadcrumbs.tsx
2732
- import { jsx as jsx34, jsxs as jsxs26 } from "react/jsx-runtime";
2793
+ import { jsx as jsx35, jsxs as jsxs27 } from "react/jsx-runtime";
2733
2794
  var Breadcrumbs = ({ items, className }) => {
2734
- return /* @__PURE__ */ jsx34("nav", { className: cn("aui-app-breadcrumbs", appBreadcrumbsClass, className), "aria-label": "Breadcrumb", children: /* @__PURE__ */ jsx34("ol", { className: "flex flex-wrap items-center gap-1.5", children: items.map((item, index) => {
2795
+ return /* @__PURE__ */ jsx35("nav", { className: cn("aui-app-breadcrumbs", appBreadcrumbsClass, className), "aria-label": "Breadcrumb", children: /* @__PURE__ */ jsx35("ol", { className: "flex flex-wrap items-center gap-1.5", children: items.map((item, index) => {
2735
2796
  const isLast = index === items.length - 1;
2736
- return /* @__PURE__ */ jsxs26("li", { className: "inline-flex items-center gap-1.5", children: [
2737
- index > 0 ? /* @__PURE__ */ jsx34("span", { className: "text-muted-foreground/50", "aria-hidden": true, children: "/" }) : null,
2738
- isLast ? /* @__PURE__ */ jsx34("span", { className: "text-foreground", "aria-current": "page", children: item.label }) : item.href ? /* @__PURE__ */ jsx34("a", { href: item.href, className: appBreadcrumbLinkClass, children: item.label }) : /* @__PURE__ */ jsx34(
2797
+ return /* @__PURE__ */ jsxs27("li", { className: "inline-flex items-center gap-1.5", children: [
2798
+ index > 0 ? /* @__PURE__ */ jsx35("span", { className: "text-muted-foreground/50", "aria-hidden": true, children: "/" }) : null,
2799
+ isLast ? /* @__PURE__ */ jsx35("span", { className: "text-foreground", "aria-current": "page", children: item.label }) : item.href ? /* @__PURE__ */ jsx35("a", { href: item.href, className: appBreadcrumbLinkClass, children: item.label }) : /* @__PURE__ */ jsx35(
2739
2800
  "button",
2740
2801
  {
2741
2802
  type: "button",
@@ -2749,7 +2810,7 @@ var Breadcrumbs = ({ items, className }) => {
2749
2810
  };
2750
2811
 
2751
2812
  // src/app/forms/Field.tsx
2752
- import { jsx as jsx35, jsxs as jsxs27 } from "react/jsx-runtime";
2813
+ import { jsx as jsx36, jsxs as jsxs28 } from "react/jsx-runtime";
2753
2814
  var Field = ({
2754
2815
  label,
2755
2816
  hint,
@@ -2758,11 +2819,11 @@ var Field = ({
2758
2819
  className,
2759
2820
  htmlFor
2760
2821
  }) => {
2761
- return /* @__PURE__ */ jsxs27("div", { className: cn("aui-app-field", appFieldClass, className), children: [
2762
- /* @__PURE__ */ jsx35("label", { className: appFieldLabelClass, htmlFor, children: label }),
2822
+ return /* @__PURE__ */ jsxs28("div", { className: cn("aui-app-field", appFieldClass, className), children: [
2823
+ /* @__PURE__ */ jsx36("label", { className: appFieldLabelClass, htmlFor, children: label }),
2763
2824
  children,
2764
- hint && !error ? /* @__PURE__ */ jsx35("p", { className: appFieldHintClass, children: hint }) : null,
2765
- error ? /* @__PURE__ */ jsx35("p", { className: "text-xs text-destructive", role: "alert", children: error }) : null
2825
+ hint && !error ? /* @__PURE__ */ jsx36("p", { className: appFieldHintClass, children: hint }) : null,
2826
+ error ? /* @__PURE__ */ jsx36("p", { className: "text-xs text-destructive", role: "alert", children: error }) : null
2766
2827
  ] });
2767
2828
  };
2768
2829
  var FieldInput = ({
@@ -2775,7 +2836,7 @@ var FieldInput = ({
2775
2836
  ...inputProps
2776
2837
  }) => {
2777
2838
  const inputId = id ?? inputProps.name;
2778
- return /* @__PURE__ */ jsx35(
2839
+ return /* @__PURE__ */ jsx36(
2779
2840
  Field,
2780
2841
  {
2781
2842
  label,
@@ -2783,7 +2844,7 @@ var FieldInput = ({
2783
2844
  error,
2784
2845
  htmlFor: inputId,
2785
2846
  className: fieldClassName,
2786
- children: /* @__PURE__ */ jsx35(
2847
+ children: /* @__PURE__ */ jsx36(
2787
2848
  "input",
2788
2849
  {
2789
2850
  id: inputId,
@@ -2797,7 +2858,7 @@ var FieldInput = ({
2797
2858
  };
2798
2859
 
2799
2860
  // src/app/forms/FieldTextarea.tsx
2800
- import { jsx as jsx36 } from "react/jsx-runtime";
2861
+ import { jsx as jsx37 } from "react/jsx-runtime";
2801
2862
  var textareaClass = cn(
2802
2863
  appInputClass,
2803
2864
  "min-h-[5.5rem] resize-y py-2.5 leading-relaxed"
@@ -2812,7 +2873,7 @@ var FieldTextarea = ({
2812
2873
  ...props
2813
2874
  }) => {
2814
2875
  const textareaId = id ?? props.name;
2815
- return /* @__PURE__ */ jsx36(
2876
+ return /* @__PURE__ */ jsx37(
2816
2877
  Field,
2817
2878
  {
2818
2879
  label,
@@ -2820,7 +2881,7 @@ var FieldTextarea = ({
2820
2881
  error,
2821
2882
  htmlFor: textareaId,
2822
2883
  className: fieldClassName,
2823
- children: /* @__PURE__ */ jsx36(
2884
+ children: /* @__PURE__ */ jsx37(
2824
2885
  "textarea",
2825
2886
  {
2826
2887
  id: textareaId,
@@ -2835,7 +2896,7 @@ var FieldTextarea = ({
2835
2896
 
2836
2897
  // src/app/forms/FieldSelect.tsx
2837
2898
  import { ChevronDownIcon } from "lucide-react";
2838
- import { jsx as jsx37, jsxs as jsxs28 } from "react/jsx-runtime";
2899
+ import { jsx as jsx38, jsxs as jsxs29 } from "react/jsx-runtime";
2839
2900
  var selectWrapClass = "relative";
2840
2901
  var selectClass = cn(
2841
2902
  appInputClass,
@@ -2852,7 +2913,7 @@ var FieldSelect = ({
2852
2913
  ...props
2853
2914
  }) => {
2854
2915
  const selectId = id ?? props.name;
2855
- return /* @__PURE__ */ jsx37(
2916
+ return /* @__PURE__ */ jsx38(
2856
2917
  Field,
2857
2918
  {
2858
2919
  label,
@@ -2860,8 +2921,8 @@ var FieldSelect = ({
2860
2921
  error,
2861
2922
  htmlFor: selectId,
2862
2923
  className: fieldClassName,
2863
- children: /* @__PURE__ */ jsxs28("div", { className: selectWrapClass, children: [
2864
- /* @__PURE__ */ jsx37(
2924
+ children: /* @__PURE__ */ jsxs29("div", { className: selectWrapClass, children: [
2925
+ /* @__PURE__ */ jsx38(
2865
2926
  "select",
2866
2927
  {
2867
2928
  id: selectId,
@@ -2871,7 +2932,7 @@ var FieldSelect = ({
2871
2932
  children
2872
2933
  }
2873
2934
  ),
2874
- /* @__PURE__ */ jsx37(
2935
+ /* @__PURE__ */ jsx38(
2875
2936
  ChevronDownIcon,
2876
2937
  {
2877
2938
  className: "pointer-events-none absolute top-1/2 right-3 size-4 -translate-y-1/2 text-muted-foreground",
@@ -2884,7 +2945,7 @@ var FieldSelect = ({
2884
2945
  };
2885
2946
 
2886
2947
  // src/app/forms/FieldSwitch.tsx
2887
- import { jsx as jsx38, jsxs as jsxs29 } from "react/jsx-runtime";
2948
+ import { jsx as jsx39, jsxs as jsxs30 } from "react/jsx-runtime";
2888
2949
  var trackClass = cn(
2889
2950
  "relative inline-flex h-5 w-9 shrink-0 items-center rounded-full transition-[background,box-shadow,border-color] duration-200",
2890
2951
  "peer-focus-visible:ring-2 peer-focus-visible:ring-foreground/10",
@@ -2905,7 +2966,7 @@ var FieldSwitch = ({
2905
2966
  ...props
2906
2967
  }) => {
2907
2968
  const inputId = id ?? props.name ?? "switch";
2908
- return /* @__PURE__ */ jsxs29(
2969
+ return /* @__PURE__ */ jsxs30(
2909
2970
  "label",
2910
2971
  {
2911
2972
  className: cn(
@@ -2914,8 +2975,8 @@ var FieldSwitch = ({
2914
2975
  ),
2915
2976
  htmlFor: inputId,
2916
2977
  children: [
2917
- /* @__PURE__ */ jsxs29("span", { className: "relative mt-0.5", children: [
2918
- /* @__PURE__ */ jsx38(
2978
+ /* @__PURE__ */ jsxs30("span", { className: "relative mt-0.5", children: [
2979
+ /* @__PURE__ */ jsx39(
2919
2980
  "input",
2920
2981
  {
2921
2982
  id: inputId,
@@ -2925,11 +2986,11 @@ var FieldSwitch = ({
2925
2986
  ...props
2926
2987
  }
2927
2988
  ),
2928
- /* @__PURE__ */ jsx38("span", { className: trackClass, "aria-hidden": true, children: /* @__PURE__ */ jsx38("span", { className: thumbClass }) })
2989
+ /* @__PURE__ */ jsx39("span", { className: trackClass, "aria-hidden": true, children: /* @__PURE__ */ jsx39("span", { className: thumbClass }) })
2929
2990
  ] }),
2930
- /* @__PURE__ */ jsxs29("span", { className: "flex min-w-0 flex-col gap-0.5", children: [
2931
- /* @__PURE__ */ jsx38("span", { className: "text-sm font-medium text-foreground", children: label }),
2932
- description ? /* @__PURE__ */ jsx38("span", { className: "text-xs text-muted-foreground", children: description }) : null
2991
+ /* @__PURE__ */ jsxs30("span", { className: "flex min-w-0 flex-col gap-0.5", children: [
2992
+ /* @__PURE__ */ jsx39("span", { className: "text-sm font-medium text-foreground", children: label }),
2993
+ description ? /* @__PURE__ */ jsx39("span", { className: "text-xs text-muted-foreground", children: description }) : null
2933
2994
  ] })
2934
2995
  ]
2935
2996
  }
@@ -2938,13 +2999,13 @@ var FieldSwitch = ({
2938
2999
 
2939
3000
  // src/app/forms/SearchInput.tsx
2940
3001
  import { SearchIcon } from "lucide-react";
2941
- import { jsx as jsx39, jsxs as jsxs30 } from "react/jsx-runtime";
3002
+ import { jsx as jsx40, jsxs as jsxs31 } from "react/jsx-runtime";
2942
3003
  var SearchInput = ({
2943
3004
  className,
2944
3005
  placeholder = "Search\u2026",
2945
3006
  ...props
2946
3007
  }) => {
2947
- return /* @__PURE__ */ jsxs30(
3008
+ return /* @__PURE__ */ jsxs31(
2948
3009
  "label",
2949
3010
  {
2950
3011
  className: cn(
@@ -2953,8 +3014,8 @@ var SearchInput = ({
2953
3014
  className
2954
3015
  ),
2955
3016
  children: [
2956
- /* @__PURE__ */ jsx39(SearchIcon, { className: "size-4 shrink-0 text-muted-foreground", "aria-hidden": true }),
2957
- /* @__PURE__ */ jsx39(
3017
+ /* @__PURE__ */ jsx40(SearchIcon, { className: "size-4 shrink-0 text-muted-foreground", "aria-hidden": true }),
3018
+ /* @__PURE__ */ jsx40(
2958
3019
  "input",
2959
3020
  {
2960
3021
  type: "search",
@@ -2969,18 +3030,26 @@ var SearchInput = ({
2969
3030
  };
2970
3031
 
2971
3032
  // src/app/forms/FormSection.tsx
2972
- import { jsx as jsx40, jsxs as jsxs31 } from "react/jsx-runtime";
3033
+ import { jsx as jsx41, jsxs as jsxs32 } from "react/jsx-runtime";
2973
3034
  var FormSection = ({ title, children, className }) => {
2974
- return /* @__PURE__ */ jsxs31("fieldset", { className: cn("aui-app-form-section", appSectionClass, "border-0 p-0", className), children: [
2975
- title ? /* @__PURE__ */ jsx40("legend", { className: cn(appSectionTitleClass, "mb-3 px-0"), children: title }) : null,
2976
- /* @__PURE__ */ jsx40("div", { className: "flex flex-col gap-4", children })
2977
- ] });
3035
+ const density = useAppDensity();
3036
+ const sectionClass = useAppDensityClass("section");
3037
+ return /* @__PURE__ */ jsxs32(
3038
+ "fieldset",
3039
+ {
3040
+ className: cn("aui-app-form-section", sectionClass, "border-0 p-0", className),
3041
+ children: [
3042
+ title ? /* @__PURE__ */ jsx41("legend", { className: cn(appSectionTitleClass, "mb-3 px-0"), children: title }) : null,
3043
+ /* @__PURE__ */ jsx41("div", { className: cn("flex flex-col", density === "compact" ? "gap-2" : "gap-4"), children })
3044
+ ]
3045
+ }
3046
+ );
2978
3047
  };
2979
3048
 
2980
3049
  // src/app/data/FilterBar.tsx
2981
- import { jsx as jsx41 } from "react/jsx-runtime";
3050
+ import { jsx as jsx42 } from "react/jsx-runtime";
2982
3051
  var FilterBar = ({ children, className }) => {
2983
- return /* @__PURE__ */ jsx41(
3052
+ return /* @__PURE__ */ jsx42(
2984
3053
  "div",
2985
3054
  {
2986
3055
  className: cn("aui-app-filter-bar", appFilterBarClass, className),
@@ -2992,14 +3061,14 @@ var FilterBar = ({ children, className }) => {
2992
3061
  };
2993
3062
 
2994
3063
  // src/app/data/FilterField.tsx
2995
- import { jsx as jsx42, jsxs as jsxs32 } from "react/jsx-runtime";
3064
+ import { jsx as jsx43, jsxs as jsxs33 } from "react/jsx-runtime";
2996
3065
  var FilterField = ({
2997
3066
  label,
2998
3067
  children,
2999
3068
  className
3000
3069
  }) => {
3001
- return /* @__PURE__ */ jsxs32("div", { className: cn("aui-app-filter-field", appFieldClass, className), children: [
3002
- label ? /* @__PURE__ */ jsx42("span", { className: appFieldLabelClass, children: label }) : null,
3070
+ return /* @__PURE__ */ jsxs33("div", { className: cn("aui-app-filter-field", appFieldClass, className), children: [
3071
+ label ? /* @__PURE__ */ jsx43("span", { className: appFieldLabelClass, children: label }) : null,
3003
3072
  children
3004
3073
  ] });
3005
3074
  };
@@ -3013,19 +3082,20 @@ import {
3013
3082
  ChevronLeftIcon,
3014
3083
  ChevronRightIcon
3015
3084
  } from "lucide-react";
3016
- import { jsx as jsx43, jsxs as jsxs33 } from "react/jsx-runtime";
3017
- var shellClass2 = "overflow-hidden rounded-xl border border-border bg-card shadow-card";
3085
+ import { jsx as jsx44, jsxs as jsxs34 } from "react/jsx-runtime";
3086
+ var shellClass2 = "overflow-hidden rounded-xl border border-border bg-gradient-to-b from-elevated-from to-elevated-to shadow-card";
3018
3087
  var tableClass = "w-full border-collapse bg-transparent text-sm";
3019
- var headCellClass = "border-b border-border/60 bg-transparent px-4 py-2.5 text-left text-xs font-medium uppercase tracking-wide text-muted-foreground";
3088
+ var headRowClass = "bg-muted/40";
3089
+ var headCellClass = "border-b border-border/70 px-4 py-2.5 text-left text-[11px] font-semibold uppercase tracking-[0.04em] text-muted-foreground/90";
3020
3090
  var bodyCellClass = "border-b border-border/40 bg-transparent px-4 py-2.5 text-foreground";
3021
- var rowClass = "bg-transparent transition-colors hover:bg-foreground/[0.03] data-[clickable=true]:cursor-pointer data-[selected=true]:bg-primary/[0.04]";
3022
- var footCellClass = "border-t border-border/60 bg-transparent px-4 py-2.5 text-xs text-muted-foreground";
3091
+ var rowClass = "bg-transparent transition-colors hover:bg-muted/40 data-[clickable=true]:cursor-pointer data-[selected=true]:bg-primary/[0.06]";
3092
+ var footCellClass = "border-t border-border/60 bg-muted/20 px-4 py-2.5 text-xs text-muted-foreground";
3023
3093
  var footInnerClass = "flex flex-wrap items-center gap-2";
3024
3094
  var emptyCellClass = "bg-transparent px-4 py-10 text-center text-sm text-muted-foreground";
3025
- var sortButtonClass = "group inline-flex min-w-0 items-center gap-1.5 rounded-md -mx-1 px-1 py-0.5 text-left font-medium text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/10";
3026
- var stickyHeadClass = "sticky top-0 z-[1] bg-card/95 shadow-[0_1px_0_0_hsl(var(--border)/0.5)] backdrop-blur-sm [&_th]:bg-card/95";
3095
+ var sortButtonClass = "group inline-flex min-w-0 items-center gap-1.5 rounded-md -mx-1 px-1 py-0.5 text-left font-semibold text-muted-foreground/90 transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/10";
3096
+ var stickyHeadClass = "sticky top-0 z-[1] bg-muted/95 shadow-[0_1px_0_0_hsl(var(--border)/0.6)] backdrop-blur-sm";
3027
3097
  var selectCellClass = "w-10 px-4 py-2.5 align-middle";
3028
- var pagerButtonClass = "inline-flex size-7 items-center justify-center rounded-md border border-border bg-transparent text-muted-foreground transition-colors hover:bg-foreground/[0.04] hover:text-foreground disabled:pointer-events-none disabled:opacity-40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/10";
3098
+ var pagerButtonClass = "inline-flex size-7 items-center justify-center rounded-md border border-border bg-gradient-to-b from-elevated-from to-elevated-to text-muted-foreground shadow-card transition-colors hover:from-secondary-fill-hover-from hover:to-secondary-fill-hover-to hover:text-foreground disabled:pointer-events-none disabled:opacity-40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/10";
3029
3099
  var alignClass = {
3030
3100
  left: "text-left",
3031
3101
  center: "text-center",
@@ -3055,12 +3125,12 @@ function SortIndicator({
3055
3125
  }) {
3056
3126
  const iconClass = "size-3.5 shrink-0 opacity-60 group-hover:opacity-100";
3057
3127
  if (!active) {
3058
- return /* @__PURE__ */ jsx43(ArrowUpDownIcon, { className: iconClass, "aria-hidden": true });
3128
+ return /* @__PURE__ */ jsx44(ArrowUpDownIcon, { className: iconClass, "aria-hidden": true });
3059
3129
  }
3060
3130
  if (direction === "desc") {
3061
- return /* @__PURE__ */ jsx43(ArrowDownIcon, { className: iconClass, "aria-hidden": true });
3131
+ return /* @__PURE__ */ jsx44(ArrowDownIcon, { className: iconClass, "aria-hidden": true });
3062
3132
  }
3063
- return /* @__PURE__ */ jsx43(ArrowUpIcon, { className: iconClass, "aria-hidden": true });
3133
+ return /* @__PURE__ */ jsx44(ArrowUpIcon, { className: iconClass, "aria-hidden": true });
3064
3134
  }
3065
3135
  function DataTable({
3066
3136
  columns,
@@ -3158,7 +3228,7 @@ function DataTable({
3158
3228
  const headPad = dense ? "px-3 py-2" : void 0;
3159
3229
  const colSpan = columns.length + (selectable ? 1 : 0);
3160
3230
  if (!loading && rows.length === 0 && emptyMode === "replace") {
3161
- return /* @__PURE__ */ jsx43(EmptyState, { title: emptyTitle, description: emptyDescription, className });
3231
+ return /* @__PURE__ */ jsx44(EmptyState, { title: emptyTitle, description: emptyDescription, className });
3162
3232
  }
3163
3233
  const allKeys = sortedRows.map(getRowKey);
3164
3234
  const allSelected = allKeys.length > 0 && allKeys.every((k) => selectedSet.has(k));
@@ -3183,10 +3253,10 @@ function DataTable({
3183
3253
  const hasPager = paginated && !loading && sortedRows.length > 0;
3184
3254
  const hasFoot = (showRowCount || footer || hasPager) && (loading || sortedRows.length > 0);
3185
3255
  const skeletonCount = loadingRows ?? pageSize ?? 5;
3186
- return /* @__PURE__ */ jsx43("div", { className: cn("aui-app-data-table", shellClass2, className), children: /* @__PURE__ */ jsx43("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs33("table", { className: tableClass, children: [
3187
- caption ? /* @__PURE__ */ jsx43("caption", { className: "sr-only", children: caption }) : null,
3188
- /* @__PURE__ */ jsx43("thead", { className: cn(stickyHeader && stickyHeadClass), children: /* @__PURE__ */ jsxs33("tr", { children: [
3189
- selectable ? /* @__PURE__ */ jsx43("th", { scope: "col", className: cn(selectCellClass, headPad), children: /* @__PURE__ */ jsx43(
3256
+ return /* @__PURE__ */ jsx44("div", { className: cn("aui-app-data-table", shellClass2, className), children: /* @__PURE__ */ jsx44("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs34("table", { className: tableClass, children: [
3257
+ caption ? /* @__PURE__ */ jsx44("caption", { className: "sr-only", children: caption }) : null,
3258
+ /* @__PURE__ */ jsx44("thead", { className: cn(headRowClass, stickyHeader && stickyHeadClass), children: /* @__PURE__ */ jsxs34("tr", { children: [
3259
+ selectable ? /* @__PURE__ */ jsx44("th", { scope: "col", className: cn(selectCellClass, headPad), children: /* @__PURE__ */ jsx44(
3190
3260
  Checkbox,
3191
3261
  {
3192
3262
  checked: headerCheckedState,
@@ -3198,19 +3268,19 @@ function DataTable({
3198
3268
  columns.map((col) => {
3199
3269
  const isSorted = sort?.columnId === col.id;
3200
3270
  const ariaSort = col.sortable ? isSorted ? sort.direction === "asc" ? "ascending" : "descending" : "none" : void 0;
3201
- const headerContent = col.sortable ? /* @__PURE__ */ jsxs33(
3271
+ const headerContent = col.sortable ? /* @__PURE__ */ jsxs34(
3202
3272
  "button",
3203
3273
  {
3204
3274
  type: "button",
3205
3275
  className: sortButtonClass,
3206
3276
  onClick: () => setSort(nextSort(sort, col.id)),
3207
3277
  children: [
3208
- /* @__PURE__ */ jsx43("span", { className: "truncate", children: col.header }),
3209
- /* @__PURE__ */ jsx43(SortIndicator, { active: Boolean(isSorted), direction: sort?.direction })
3278
+ /* @__PURE__ */ jsx44("span", { className: "truncate", children: col.header }),
3279
+ /* @__PURE__ */ jsx44(SortIndicator, { active: Boolean(isSorted), direction: sort?.direction })
3210
3280
  ]
3211
3281
  }
3212
3282
  ) : col.header;
3213
- return /* @__PURE__ */ jsx43(
3283
+ return /* @__PURE__ */ jsx44(
3214
3284
  "th",
3215
3285
  {
3216
3286
  scope: "col",
@@ -3227,9 +3297,9 @@ function DataTable({
3227
3297
  );
3228
3298
  })
3229
3299
  ] }) }),
3230
- /* @__PURE__ */ jsx43("tbody", { className: cn(!hasFoot && "[&_tr:last-child_td]:border-b-0"), children: loading ? Array.from({ length: skeletonCount }).map((_, rowIdx) => /* @__PURE__ */ jsxs33("tr", { className: rowClass, "aria-hidden": true, children: [
3231
- selectable ? /* @__PURE__ */ jsx43("td", { className: cn(selectCellClass, cellPad), children: /* @__PURE__ */ jsx43(Skeleton, { className: "size-4 rounded-[4px]" }) }) : null,
3232
- columns.map((col) => /* @__PURE__ */ jsx43(
3300
+ /* @__PURE__ */ jsx44("tbody", { className: cn(!hasFoot && "[&_tr:last-child_td]:border-b-0"), children: loading ? Array.from({ length: skeletonCount }).map((_, rowIdx) => /* @__PURE__ */ jsxs34("tr", { className: rowClass, "aria-hidden": true, children: [
3301
+ selectable ? /* @__PURE__ */ jsx44("td", { className: cn(selectCellClass, cellPad), children: /* @__PURE__ */ jsx44(Skeleton, { className: "size-4 rounded-[4px]" }) }) : null,
3302
+ columns.map((col) => /* @__PURE__ */ jsx44(
3233
3303
  "td",
3234
3304
  {
3235
3305
  className: cn(
@@ -3238,17 +3308,17 @@ function DataTable({
3238
3308
  col.align && alignClass[col.align],
3239
3309
  col.className
3240
3310
  ),
3241
- children: /* @__PURE__ */ jsx43(Skeleton, { className: "h-4 w-[60%]" })
3311
+ children: /* @__PURE__ */ jsx44(Skeleton, { className: "h-4 w-[60%]" })
3242
3312
  },
3243
3313
  col.id
3244
3314
  ))
3245
- ] }, `skeleton-${rowIdx}`)) : visibleRows.length === 0 ? /* @__PURE__ */ jsx43("tr", { children: /* @__PURE__ */ jsx43("td", { colSpan, className: emptyCellClass, children: /* @__PURE__ */ jsxs33("div", { className: "flex flex-col items-center gap-1", children: [
3246
- /* @__PURE__ */ jsx43("p", { className: "font-medium text-foreground", children: emptyTitle }),
3247
- emptyDescription ? /* @__PURE__ */ jsx43("p", { className: "max-w-sm text-muted-foreground", children: emptyDescription }) : null
3315
+ ] }, `skeleton-${rowIdx}`)) : visibleRows.length === 0 ? /* @__PURE__ */ jsx44("tr", { children: /* @__PURE__ */ jsx44("td", { colSpan, className: emptyCellClass, children: /* @__PURE__ */ jsxs34("div", { className: "flex flex-col items-center gap-1", children: [
3316
+ /* @__PURE__ */ jsx44("p", { className: "font-medium text-foreground", children: emptyTitle }),
3317
+ emptyDescription ? /* @__PURE__ */ jsx44("p", { className: "max-w-sm text-muted-foreground", children: emptyDescription }) : null
3248
3318
  ] }) }) }) : visibleRows.map((row) => {
3249
3319
  const key = getRowKey(row);
3250
3320
  const isSelected = selectedSet.has(key);
3251
- return /* @__PURE__ */ jsxs33(
3321
+ return /* @__PURE__ */ jsxs34(
3252
3322
  "tr",
3253
3323
  {
3254
3324
  className: rowClass,
@@ -3264,12 +3334,12 @@ function DataTable({
3264
3334
  tabIndex: onRowClick ? 0 : void 0,
3265
3335
  role: onRowClick ? "button" : void 0,
3266
3336
  children: [
3267
- selectable ? /* @__PURE__ */ jsx43(
3337
+ selectable ? /* @__PURE__ */ jsx44(
3268
3338
  "td",
3269
3339
  {
3270
3340
  className: cn(selectCellClass, cellPad),
3271
3341
  onClick: (event) => event.stopPropagation(),
3272
- children: /* @__PURE__ */ jsx43(
3342
+ children: /* @__PURE__ */ jsx44(
3273
3343
  Checkbox,
3274
3344
  {
3275
3345
  checked: isSelected,
@@ -3279,16 +3349,17 @@ function DataTable({
3279
3349
  )
3280
3350
  }
3281
3351
  ) : null,
3282
- columns.map((col) => /* @__PURE__ */ jsx43(
3352
+ columns.map((col) => /* @__PURE__ */ jsx44(
3283
3353
  "td",
3284
3354
  {
3285
3355
  className: cn(
3286
3356
  bodyCellClass,
3287
3357
  cellPad,
3358
+ col.truncate && "max-w-0",
3288
3359
  col.align && alignClass[col.align],
3289
3360
  col.className
3290
3361
  ),
3291
- children: col.cell(row)
3362
+ children: col.truncate ? /* @__PURE__ */ jsx44("div", { className: "truncate", children: col.cell(row) }) : col.cell(row)
3292
3363
  },
3293
3364
  col.id
3294
3365
  ))
@@ -3297,7 +3368,7 @@ function DataTable({
3297
3368
  key
3298
3369
  );
3299
3370
  }) }),
3300
- hasFoot ? /* @__PURE__ */ jsx43("tfoot", { children: /* @__PURE__ */ jsx43("tr", { children: /* @__PURE__ */ jsx43("td", { colSpan, className: footCellClass, children: /* @__PURE__ */ jsxs33(
3371
+ hasFoot ? /* @__PURE__ */ jsx44("tfoot", { children: /* @__PURE__ */ jsx44("tr", { children: /* @__PURE__ */ jsx44("td", { colSpan, className: footCellClass, children: /* @__PURE__ */ jsxs34(
3301
3372
  "div",
3302
3373
  {
3303
3374
  className: cn(
@@ -3305,18 +3376,18 @@ function DataTable({
3305
3376
  (showRowCount || footer || hasPager) && "justify-between"
3306
3377
  ),
3307
3378
  children: [
3308
- /* @__PURE__ */ jsxs33("div", { className: footInnerClass, children: [
3309
- showRowCount ? /* @__PURE__ */ jsxs33("span", { children: [
3379
+ /* @__PURE__ */ jsxs34("div", { className: footInnerClass, children: [
3380
+ showRowCount ? /* @__PURE__ */ jsxs34("span", { children: [
3310
3381
  rowCountText,
3311
3382
  selectable && selectedSet.size > 0 ? ` \xB7 ${selectedSet.size} selected` : null
3312
- ] }) : selectable && selectedSet.size > 0 ? /* @__PURE__ */ jsxs33("span", { children: [
3383
+ ] }) : selectable && selectedSet.size > 0 ? /* @__PURE__ */ jsxs34("span", { children: [
3313
3384
  selectedSet.size,
3314
3385
  " selected"
3315
3386
  ] }) : null,
3316
3387
  footer
3317
3388
  ] }),
3318
- hasPager ? /* @__PURE__ */ jsxs33("div", { className: "flex items-center gap-2", children: [
3319
- /* @__PURE__ */ jsxs33("span", { className: "tabular-nums", children: [
3389
+ hasPager ? /* @__PURE__ */ jsxs34("div", { className: "flex items-center gap-2", children: [
3390
+ /* @__PURE__ */ jsxs34("span", { className: "tabular-nums", children: [
3320
3391
  pageIndex * pageSize + 1,
3321
3392
  "\u2013",
3322
3393
  Math.min(
@@ -3327,8 +3398,8 @@ function DataTable({
3327
3398
  "of ",
3328
3399
  sortedRows.length
3329
3400
  ] }),
3330
- /* @__PURE__ */ jsxs33("div", { className: "flex items-center gap-1", children: [
3331
- /* @__PURE__ */ jsx43(
3401
+ /* @__PURE__ */ jsxs34("div", { className: "flex items-center gap-1", children: [
3402
+ /* @__PURE__ */ jsx44(
3332
3403
  "button",
3333
3404
  {
3334
3405
  type: "button",
@@ -3336,10 +3407,10 @@ function DataTable({
3336
3407
  onClick: () => setPage(pageIndex - 1),
3337
3408
  disabled: pageIndex <= 0,
3338
3409
  "aria-label": "Previous page",
3339
- children: /* @__PURE__ */ jsx43(ChevronLeftIcon, { className: "size-4", "aria-hidden": true })
3410
+ children: /* @__PURE__ */ jsx44(ChevronLeftIcon, { className: "size-4", "aria-hidden": true })
3340
3411
  }
3341
3412
  ),
3342
- /* @__PURE__ */ jsx43(
3413
+ /* @__PURE__ */ jsx44(
3343
3414
  "button",
3344
3415
  {
3345
3416
  type: "button",
@@ -3347,7 +3418,7 @@ function DataTable({
3347
3418
  onClick: () => setPage(pageIndex + 1),
3348
3419
  disabled: pageIndex >= pageCount - 1,
3349
3420
  "aria-label": "Next page",
3350
- children: /* @__PURE__ */ jsx43(ChevronRightIcon, { className: "size-4", "aria-hidden": true })
3421
+ children: /* @__PURE__ */ jsx44(ChevronRightIcon, { className: "size-4", "aria-hidden": true })
3351
3422
  }
3352
3423
  )
3353
3424
  ] })
@@ -3360,28 +3431,32 @@ function DataTable({
3360
3431
 
3361
3432
  // src/app/data/ChartPanel.tsx
3362
3433
  import { useId as useId4 } from "react";
3363
- import { jsx as jsx44, jsxs as jsxs34 } from "react/jsx-runtime";
3434
+ import { jsx as jsx45, jsxs as jsxs35 } from "react/jsx-runtime";
3364
3435
  var ChartPanel = ({
3365
3436
  title,
3366
3437
  description,
3367
3438
  artifact,
3368
3439
  children,
3369
3440
  actions,
3370
- height = 300,
3441
+ height: heightProp,
3371
3442
  loading = false,
3372
3443
  className
3373
3444
  }) => {
3445
+ const density = useAppDensity();
3446
+ const height = heightProp ?? APP_DENSITY_CHART_HEIGHT[density];
3447
+ const metricChartPlotRegionClass = useAppDensityClass("metricChartPlotRegion");
3448
+ const chartPanelBodyClass = useAppDensityClass("chartPanelBody");
3374
3449
  const titleId = useId4();
3375
3450
  const resolvedTitle = title ?? artifact?.title;
3376
3451
  const hasHeader = Boolean(resolvedTitle || description || actions);
3377
- const body = loading ? /* @__PURE__ */ jsx44(Skeleton, { className: "w-full rounded-lg", style: { height }, "aria-hidden": true }) : children ?? (artifact ? /* @__PURE__ */ jsx44(ChartArtifactView, { artifact, embedded: true, height }) : null);
3378
- return /* @__PURE__ */ jsxs34(
3452
+ const body = loading ? /* @__PURE__ */ jsx45(Skeleton, { className: "w-full rounded-lg", style: { height }, "aria-hidden": true }) : children ?? (artifact ? /* @__PURE__ */ jsx45(ChartArtifactView, { artifact, embedded: true, height }) : null);
3453
+ return /* @__PURE__ */ jsxs35(
3379
3454
  "section",
3380
3455
  {
3381
3456
  className: cn(metricCardShellClass, "aui-app-chart-panel", className),
3382
3457
  "aria-labelledby": resolvedTitle ? titleId : void 0,
3383
3458
  children: [
3384
- /* @__PURE__ */ jsx44(
3459
+ /* @__PURE__ */ jsx45(
3385
3460
  MetricCardHeader,
3386
3461
  {
3387
3462
  title: resolvedTitle,
@@ -3390,14 +3465,14 @@ var ChartPanel = ({
3390
3465
  actions
3391
3466
  }
3392
3467
  ),
3393
- /* @__PURE__ */ jsx44(
3468
+ /* @__PURE__ */ jsx45(
3394
3469
  "div",
3395
3470
  {
3396
3471
  className: cn(
3397
3472
  "relative min-h-0 w-full",
3398
- hasHeader ? metricChartPlotRegionClass : "pt-2 pb-3"
3473
+ hasHeader ? metricChartPlotRegionClass : chartPanelBodyClass
3399
3474
  ),
3400
- children: body ?? /* @__PURE__ */ jsx44(
3475
+ children: body ?? /* @__PURE__ */ jsx45(
3401
3476
  "div",
3402
3477
  {
3403
3478
  className: "flex items-center justify-center text-sm font-normal text-muted-foreground",
@@ -3415,7 +3490,7 @@ var ChartPanel = ({
3415
3490
 
3416
3491
  // src/app/data/MetricRow.tsx
3417
3492
  import { useId as useId5, useState as useState5 } from "react";
3418
- import { jsx as jsx45, jsxs as jsxs35 } from "react/jsx-runtime";
3493
+ import { jsx as jsx46, jsxs as jsxs36 } from "react/jsx-runtime";
3419
3494
  var MetricRow = ({
3420
3495
  title,
3421
3496
  description,
@@ -3428,6 +3503,7 @@ var MetricRow = ({
3428
3503
  loading = false,
3429
3504
  className
3430
3505
  }) => {
3506
+ const metricTileClass = useAppDensityClass("metricTile");
3431
3507
  const titleId = useId5();
3432
3508
  const selectable = onMetricChange != null || activeMetricId != null;
3433
3509
  const [internalId, setInternalId] = useState5(
@@ -3438,13 +3514,13 @@ var MetricRow = ({
3438
3514
  if (activeMetricId == null) setInternalId(id);
3439
3515
  onMetricChange?.(id);
3440
3516
  };
3441
- return /* @__PURE__ */ jsxs35(
3517
+ return /* @__PURE__ */ jsxs36(
3442
3518
  "section",
3443
3519
  {
3444
3520
  className: cn(metricCardShellClass, className),
3445
3521
  "aria-labelledby": title ? titleId : void 0,
3446
3522
  children: [
3447
- /* @__PURE__ */ jsx45(
3523
+ /* @__PURE__ */ jsx46(
3448
3524
  MetricCardHeader,
3449
3525
  {
3450
3526
  title,
@@ -3453,7 +3529,7 @@ var MetricRow = ({
3453
3529
  actions
3454
3530
  }
3455
3531
  ),
3456
- /* @__PURE__ */ jsx45(
3532
+ /* @__PURE__ */ jsx46(
3457
3533
  "div",
3458
3534
  {
3459
3535
  role: selectable ? "group" : void 0,
@@ -3464,18 +3540,18 @@ var MetricRow = ({
3464
3540
  metricTilesGridColsClass(loading ? metrics.length || 4 : metrics.length),
3465
3541
  (title || description || actions) && "mt-3"
3466
3542
  ),
3467
- children: loading ? Array.from({ length: metrics.length || 4 }).map((_, index) => /* @__PURE__ */ jsxs35(
3543
+ children: loading ? Array.from({ length: metrics.length || 4 }).map((_, index) => /* @__PURE__ */ jsxs36(
3468
3544
  "div",
3469
3545
  {
3470
- className: "flex min-w-0 flex-1 flex-col gap-2 px-4 py-3",
3546
+ className: cn("flex min-w-0 flex-1 flex-col gap-2", metricTileClass),
3471
3547
  "aria-hidden": true,
3472
3548
  children: [
3473
- /* @__PURE__ */ jsx45(Skeleton, { className: "h-3 w-20" }),
3474
- /* @__PURE__ */ jsx45(Skeleton, { className: "h-7 w-24" })
3549
+ /* @__PURE__ */ jsx46(Skeleton, { className: "h-3 w-20" }),
3550
+ /* @__PURE__ */ jsx46(Skeleton, { className: "h-7 w-24" })
3475
3551
  ]
3476
3552
  },
3477
3553
  `skeleton-${index}`
3478
- )) : metrics.map((m, index) => /* @__PURE__ */ jsx45(
3554
+ )) : metrics.map((m, index) => /* @__PURE__ */ jsx46(
3479
3555
  MetricTile,
3480
3556
  {
3481
3557
  label: m.label,
@@ -3498,7 +3574,7 @@ var MetricRow = ({
3498
3574
 
3499
3575
  // src/app/data/MetricChartCard.tsx
3500
3576
  import { useId as useId6, useState as useState6 } from "react";
3501
- import { jsx as jsx46, jsxs as jsxs36 } from "react/jsx-runtime";
3577
+ import { jsx as jsx47, jsxs as jsxs37 } from "react/jsx-runtime";
3502
3578
  var MetricChartCard = ({
3503
3579
  title,
3504
3580
  description,
@@ -3509,7 +3585,7 @@ var MetricChartCard = ({
3509
3585
  onMetricChange,
3510
3586
  xKey = "date",
3511
3587
  variant = "area",
3512
- height = 300,
3588
+ height: heightProp,
3513
3589
  formatX,
3514
3590
  formatValue,
3515
3591
  emptyLabel = "No data yet",
@@ -3517,6 +3593,10 @@ var MetricChartCard = ({
3517
3593
  loading = false,
3518
3594
  className
3519
3595
  }) => {
3596
+ const density = useAppDensity();
3597
+ const height = heightProp ?? APP_DENSITY_CHART_HEIGHT[density];
3598
+ const metricChartRegionClass = useAppDensityClass("metricChartRegion");
3599
+ const metricTileClass = useAppDensityClass("metricTile");
3520
3600
  const titleId = useId6();
3521
3601
  const [internalId, setInternalId] = useState6(
3522
3602
  defaultActiveMetricId ?? metrics[0]?.id
@@ -3529,13 +3609,13 @@ var MetricChartCard = ({
3529
3609
  };
3530
3610
  const hasHeader = Boolean(title || description || actions);
3531
3611
  const chartAriaLabel = typeof active?.label === "string" ? `${active.label} over time` : "Metric chart";
3532
- return /* @__PURE__ */ jsxs36(
3612
+ return /* @__PURE__ */ jsxs37(
3533
3613
  "section",
3534
3614
  {
3535
3615
  className: cn(metricCardShellClass, className),
3536
3616
  "aria-labelledby": title ? titleId : void 0,
3537
3617
  children: [
3538
- /* @__PURE__ */ jsx46(
3618
+ /* @__PURE__ */ jsx47(
3539
3619
  MetricCardHeader,
3540
3620
  {
3541
3621
  title,
@@ -3544,7 +3624,7 @@ var MetricChartCard = ({
3544
3624
  actions
3545
3625
  }
3546
3626
  ),
3547
- /* @__PURE__ */ jsx46(
3627
+ /* @__PURE__ */ jsx47(
3548
3628
  "div",
3549
3629
  {
3550
3630
  role: "group",
@@ -3555,18 +3635,18 @@ var MetricChartCard = ({
3555
3635
  metricTilesGridColsClass(loading ? metrics.length || 4 : metrics.length),
3556
3636
  hasHeader && "mt-3"
3557
3637
  ),
3558
- children: loading ? Array.from({ length: metrics.length || 4 }).map((_, index) => /* @__PURE__ */ jsxs36(
3638
+ children: loading ? Array.from({ length: metrics.length || 4 }).map((_, index) => /* @__PURE__ */ jsxs37(
3559
3639
  "div",
3560
3640
  {
3561
- className: "flex min-w-0 flex-1 flex-col gap-2 px-4 py-3",
3641
+ className: cn("flex min-w-0 flex-1 flex-col gap-2", metricTileClass),
3562
3642
  "aria-hidden": true,
3563
3643
  children: [
3564
- /* @__PURE__ */ jsx46(Skeleton, { className: "h-3 w-20" }),
3565
- /* @__PURE__ */ jsx46(Skeleton, { className: "h-7 w-24" })
3644
+ /* @__PURE__ */ jsx47(Skeleton, { className: "h-3 w-20" }),
3645
+ /* @__PURE__ */ jsx47(Skeleton, { className: "h-7 w-24" })
3566
3646
  ]
3567
3647
  },
3568
3648
  `skeleton-${index}`
3569
- )) : metrics.map((m, index) => /* @__PURE__ */ jsx46(
3649
+ )) : metrics.map((m, index) => /* @__PURE__ */ jsx47(
3570
3650
  MetricTile,
3571
3651
  {
3572
3652
  label: m.label,
@@ -3582,14 +3662,14 @@ var MetricChartCard = ({
3582
3662
  ))
3583
3663
  }
3584
3664
  ),
3585
- /* @__PURE__ */ jsx46("div", { className: metricChartRegionClass, "aria-live": "polite", "aria-atomic": "true", children: loading ? /* @__PURE__ */ jsx46(
3665
+ /* @__PURE__ */ jsx47("div", { className: metricChartRegionClass, "aria-live": "polite", "aria-atomic": "true", children: loading ? /* @__PURE__ */ jsx47(
3586
3666
  Skeleton,
3587
3667
  {
3588
3668
  className: "w-full rounded-lg",
3589
3669
  style: { height },
3590
3670
  "aria-hidden": true
3591
3671
  }
3592
- ) : active?.data && active.data.length > 0 ? /* @__PURE__ */ jsx46(
3672
+ ) : active?.data && active.data.length > 0 ? /* @__PURE__ */ jsx47(
3593
3673
  LineAreaChart,
3594
3674
  {
3595
3675
  data: active.data,
@@ -3609,7 +3689,7 @@ var MetricChartCard = ({
3609
3689
  ariaLabel: chartAriaLabel
3610
3690
  },
3611
3691
  active.id
3612
- ) : /* @__PURE__ */ jsx46(
3692
+ ) : /* @__PURE__ */ jsx47(
3613
3693
  "div",
3614
3694
  {
3615
3695
  className: "flex w-full items-center justify-center text-sm font-normal text-muted-foreground",
@@ -3715,7 +3795,7 @@ function useLiveQuery(fetcher, options = {}) {
3715
3795
 
3716
3796
  // src/charts/sparkline.tsx
3717
3797
  import { useId as useId7 } from "react";
3718
- import { Fragment as Fragment6, jsx as jsx47, jsxs as jsxs37 } from "react/jsx-runtime";
3798
+ import { Fragment as Fragment6, jsx as jsx48, jsxs as jsxs38 } from "react/jsx-runtime";
3719
3799
  var Sparkline = ({
3720
3800
  data,
3721
3801
  dataKey = "value",
@@ -3730,7 +3810,7 @@ var Sparkline = ({
3730
3810
  const uid = useId7();
3731
3811
  const values = data.map((d) => typeof d === "number" ? d : toNum(d[dataKey]));
3732
3812
  if (values.length === 0) {
3733
- return /* @__PURE__ */ jsx47("span", { className: cn("inline-block", className), style: { width, height } });
3813
+ return /* @__PURE__ */ jsx48("span", { className: cn("inline-block", className), style: { width, height } });
3734
3814
  }
3735
3815
  const pad = strokeWidth + 1;
3736
3816
  const min = Math.min(...values);
@@ -3742,7 +3822,7 @@ var Sparkline = ({
3742
3822
  x: pad + (values.length > 1 ? i / (values.length - 1) * innerW : innerW / 2),
3743
3823
  y: pad + innerH - (v - min) / range * innerH
3744
3824
  }));
3745
- return /* @__PURE__ */ jsxs37(
3825
+ return /* @__PURE__ */ jsxs38(
3746
3826
  "svg",
3747
3827
  {
3748
3828
  width,
@@ -3753,14 +3833,14 @@ var Sparkline = ({
3753
3833
  "aria-label": ariaLabel,
3754
3834
  preserveAspectRatio: "none",
3755
3835
  children: [
3756
- area && /* @__PURE__ */ jsxs37(Fragment6, { children: [
3757
- /* @__PURE__ */ jsx47("defs", { children: /* @__PURE__ */ jsxs37("linearGradient", { id: `${uid}-spark`, x1: "0", x2: "0", y1: "0", y2: "1", children: [
3758
- /* @__PURE__ */ jsx47("stop", { offset: "0%", style: { stopColor: color, stopOpacity: 0.25 } }),
3759
- /* @__PURE__ */ jsx47("stop", { offset: "100%", style: { stopColor: color, stopOpacity: 0 } })
3836
+ area && /* @__PURE__ */ jsxs38(Fragment6, { children: [
3837
+ /* @__PURE__ */ jsx48("defs", { children: /* @__PURE__ */ jsxs38("linearGradient", { id: `${uid}-spark`, x1: "0", x2: "0", y1: "0", y2: "1", children: [
3838
+ /* @__PURE__ */ jsx48("stop", { offset: "0%", style: { stopColor: color, stopOpacity: 0.25 } }),
3839
+ /* @__PURE__ */ jsx48("stop", { offset: "100%", style: { stopColor: color, stopOpacity: 0 } })
3760
3840
  ] }) }),
3761
- /* @__PURE__ */ jsx47("path", { d: monotoneAreaPath(points, height - pad), fill: `url(#${uid}-spark)` })
3841
+ /* @__PURE__ */ jsx48("path", { d: monotoneAreaPath(points, height - pad), fill: `url(#${uid}-spark)` })
3762
3842
  ] }),
3763
- /* @__PURE__ */ jsx47(
3843
+ /* @__PURE__ */ jsx48(
3764
3844
  "path",
3765
3845
  {
3766
3846
  d: monotoneLinePath(points),
@@ -3799,8 +3879,6 @@ export {
3799
3879
  getStoredThemePreset,
3800
3880
  THEME_AGENT_INSTRUCTIONS,
3801
3881
  TimbalThemeStyle,
3802
- MetricTile,
3803
- ThemePresetGallery,
3804
3882
  appPageColumnClass,
3805
3883
  appShellTopbarInsetClass,
3806
3884
  appShellInsetTopClass,
@@ -3808,6 +3886,13 @@ export {
3808
3886
  appStatTileClass,
3809
3887
  appFilterBarClass,
3810
3888
  appSearchInputClass,
3889
+ APP_DENSITY_CHART_HEIGHT,
3890
+ APP_DENSITY_CLASSES,
3891
+ appDensityClass,
3892
+ AppDensityProvider,
3893
+ useAppDensity,
3894
+ useAppDensityClass,
3895
+ MetricTile,
3811
3896
  useAppShellChat,
3812
3897
  useAppShellNav,
3813
3898
  AppShell,