@nadicodeai/ui 0.10.1 → 0.11.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 (146) hide show
  1. package/AGENTS.md +23 -135
  2. package/README.md +39 -110
  3. package/dist/components/action-band.d.ts +5 -3
  4. package/dist/components/action-band.d.ts.map +1 -1
  5. package/dist/components/action-band.js +35 -21
  6. package/dist/components/agent-chat.d.ts.map +1 -1
  7. package/dist/components/agent-chat.js +1 -1
  8. package/dist/components/agent-composer.d.ts.map +1 -1
  9. package/dist/components/agent-composer.js +1 -1
  10. package/dist/components/ai-elements/code-block.d.ts.map +1 -1
  11. package/dist/components/ai-elements/code-block.js +9 -23
  12. package/dist/components/ai-elements/commit.d.ts.map +1 -1
  13. package/dist/components/ai-elements/commit.js +9 -23
  14. package/dist/components/ai-elements/environment-variables.d.ts.map +1 -1
  15. package/dist/components/ai-elements/environment-variables.js +4 -29
  16. package/dist/components/ai-elements/snippet.d.ts.map +1 -1
  17. package/dist/components/ai-elements/snippet.js +9 -23
  18. package/dist/components/ai-elements/stack-trace.d.ts.map +1 -1
  19. package/dist/components/ai-elements/stack-trace.js +8 -21
  20. package/dist/components/ai-elements/terminal.d.ts.map +1 -1
  21. package/dist/components/ai-elements/terminal.js +16 -29
  22. package/dist/components/alert-dialog.d.ts.map +1 -1
  23. package/dist/components/alert-dialog.js +3 -2
  24. package/dist/components/artifact-panel.d.ts.map +1 -1
  25. package/dist/components/artifact-panel.js +5 -5
  26. package/dist/components/badge.js +1 -1
  27. package/dist/components/bento.d.ts +14 -3
  28. package/dist/components/bento.d.ts.map +1 -1
  29. package/dist/components/bento.js +26 -5
  30. package/dist/components/brand.d.ts.map +1 -1
  31. package/dist/components/brand.js +29 -3
  32. package/dist/components/button.js +1 -1
  33. package/dist/components/chart-time-series.d.ts.map +1 -1
  34. package/dist/components/chart-time-series.js +2 -2
  35. package/dist/components/chart.js +1 -1
  36. package/dist/components/contact.d.ts +22 -10
  37. package/dist/components/contact.d.ts.map +1 -1
  38. package/dist/components/contact.js +34 -12
  39. package/dist/components/dialog.d.ts.map +1 -1
  40. package/dist/components/dialog.js +3 -2
  41. package/dist/components/diff-count.js +1 -1
  42. package/dist/components/dropdown-menu.d.ts.map +1 -1
  43. package/dist/components/dropdown-menu.js +2 -1
  44. package/dist/components/faq-item.js +2 -2
  45. package/dist/components/faq.d.ts +4 -1
  46. package/dist/components/faq.d.ts.map +1 -1
  47. package/dist/components/faq.js +5 -2
  48. package/dist/components/feature-grid.d.ts +23 -0
  49. package/dist/components/feature-grid.d.ts.map +1 -0
  50. package/dist/components/feature-grid.js +33 -0
  51. package/dist/components/feature-rows.d.ts +23 -0
  52. package/dist/components/feature-rows.d.ts.map +1 -0
  53. package/dist/components/feature-rows.js +27 -0
  54. package/dist/components/footer.d.ts +18 -12
  55. package/dist/components/footer.d.ts.map +1 -1
  56. package/dist/components/footer.js +32 -20
  57. package/dist/components/hero.d.ts +28 -0
  58. package/dist/components/hero.d.ts.map +1 -0
  59. package/dist/components/hero.js +45 -0
  60. package/dist/components/input-otp.js +1 -1
  61. package/dist/components/integration-flow.d.ts +36 -0
  62. package/dist/components/integration-flow.d.ts.map +1 -0
  63. package/dist/components/integration-flow.js +36 -0
  64. package/dist/components/live-demo.d.ts +31 -0
  65. package/dist/components/live-demo.d.ts.map +1 -0
  66. package/dist/components/live-demo.js +30 -0
  67. package/dist/components/logo-band.d.ts +12 -2
  68. package/dist/components/logo-band.d.ts.map +1 -1
  69. package/dist/components/logo-band.js +16 -1
  70. package/dist/components/logo-tile.d.ts.map +1 -1
  71. package/dist/components/logo-tile.js +5 -2
  72. package/dist/components/nav-bar.d.ts +14 -8
  73. package/dist/components/nav-bar.d.ts.map +1 -1
  74. package/dist/components/nav-bar.js +19 -13
  75. package/dist/components/popover.d.ts.map +1 -1
  76. package/dist/components/popover.js +2 -1
  77. package/dist/components/pricing-card.d.ts +10 -15
  78. package/dist/components/pricing-card.d.ts.map +1 -1
  79. package/dist/components/pricing-card.js +18 -29
  80. package/dist/components/pricing.d.ts +11 -14
  81. package/dist/components/pricing.d.ts.map +1 -1
  82. package/dist/components/pricing.js +5 -15
  83. package/dist/components/quote-card.d.ts +10 -2
  84. package/dist/components/quote-card.d.ts.map +1 -1
  85. package/dist/components/quote-card.js +15 -3
  86. package/dist/components/security-grid.d.ts +25 -0
  87. package/dist/components/security-grid.d.ts.map +1 -0
  88. package/dist/components/security-grid.js +31 -0
  89. package/dist/components/select.d.ts.map +1 -1
  90. package/dist/components/select.js +2 -1
  91. package/dist/components/sheet.d.ts.map +1 -1
  92. package/dist/components/sheet.js +3 -2
  93. package/dist/components/sidebar.js +1 -1
  94. package/dist/components/stat-block.d.ts +9 -5
  95. package/dist/components/stat-block.d.ts.map +1 -1
  96. package/dist/components/stat-block.js +12 -6
  97. package/dist/components/statement.d.ts +32 -0
  98. package/dist/components/statement.d.ts.map +1 -0
  99. package/dist/components/statement.js +40 -0
  100. package/dist/components/stats-band.d.ts +6 -2
  101. package/dist/components/stats-band.d.ts.map +1 -1
  102. package/dist/components/stats-band.js +10 -3
  103. package/dist/components/status-dot.js +4 -4
  104. package/dist/components/steps.d.ts +34 -0
  105. package/dist/components/steps.d.ts.map +1 -0
  106. package/dist/components/steps.js +40 -0
  107. package/dist/components/team-grid.d.ts +27 -0
  108. package/dist/components/team-grid.d.ts.map +1 -0
  109. package/dist/components/team-grid.js +30 -0
  110. package/dist/components/testimonials.d.ts +39 -12
  111. package/dist/components/testimonials.d.ts.map +1 -1
  112. package/dist/components/testimonials.js +46 -13
  113. package/dist/components/texture-strip.d.ts +22 -0
  114. package/dist/components/texture-strip.d.ts.map +1 -0
  115. package/dist/components/texture-strip.js +29 -0
  116. package/dist/components/toggle.js +1 -1
  117. package/dist/components/tooltip.d.ts.map +1 -1
  118. package/dist/components/tooltip.js +2 -1
  119. package/dist/index.d.ts +10 -0
  120. package/dist/index.d.ts.map +1 -1
  121. package/dist/index.js +10 -0
  122. package/dist/lib/message-scroller-primitive/geometry.d.ts +1 -5
  123. package/dist/lib/message-scroller-primitive/geometry.d.ts.map +1 -1
  124. package/dist/lib/message-scroller-primitive/geometry.js +1 -1
  125. package/dist/lib/message-scroller-primitive/stores.d.ts +2 -3
  126. package/dist/lib/message-scroller-primitive/stores.d.ts.map +1 -1
  127. package/dist/lib/message-scroller-primitive/stores.js +1 -1
  128. package/dist/lib/message-scroller-primitive/types.d.ts +1 -2
  129. package/dist/lib/message-scroller-primitive/types.d.ts.map +1 -1
  130. package/dist/lib/message-scroller-primitive/types.js +1 -1
  131. package/dist/lib/motion.d.ts +12 -0
  132. package/dist/lib/motion.d.ts.map +1 -0
  133. package/dist/lib/motion.js +11 -0
  134. package/dist/lib/use-copy-to-clipboard.d.ts +11 -0
  135. package/dist/lib/use-copy-to-clipboard.d.ts.map +1 -0
  136. package/dist/lib/use-copy-to-clipboard.js +27 -0
  137. package/dist/styles/globals.css +175 -300
  138. package/docs/agent-work-surfaces.md +6 -5
  139. package/docs/agents/nadicodeai-ui.md +42 -273
  140. package/docs/consuming-cross-repo.md +26 -33
  141. package/docs/contract.md +43 -0
  142. package/docs/migration/nadia-consumer-readiness.md +5 -10
  143. package/docs/terminal-tui-semantics.md +142 -181
  144. package/llms.txt +49 -84
  145. package/package.json +2 -3
  146. package/skills/nadicodeai-ui/SKILL.md +6 -30
@@ -2,7 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Button as ButtonPrimitive } from "@base-ui/react/button";
3
3
  import { cva } from "class-variance-authority";
4
4
  import { cn } from "../lib/utils.js";
5
- const buttonVariants = cva("group/button inline-flex min-h-touch-target min-w-touch-target shrink-0 items-center justify-center rounded-md border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-focus focus-visible:ring-ring active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-focus aria-invalid:ring-destructive [@media(hover:hover)_and_(pointer:fine)]:min-h-0 [@media(hover:hover)_and_(pointer:fine)]:min-w-0 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", {
5
+ const buttonVariants = cva("group/button inline-flex min-h-touch-target min-w-touch-target shrink-0 items-center justify-center rounded-md border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-[background-color,border-color,color] duration-[var(--nc-duration-confirm)] ease-[var(--nc-ease-out-strong)] outline-none select-none focus-visible:border-ring focus-visible:ring-focus focus-visible:ring-ring active:not-aria-[haspopup]:opacity-90 motion-reduce:transition-none disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-focus aria-invalid:ring-destructive [@media(hover:hover)_and_(pointer:fine)]:min-h-0 [@media(hover:hover)_and_(pointer:fine)]:min-w-0 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", {
6
6
  variants: {
7
7
  variant: {
8
8
  default: "bg-primary text-primary-foreground hover:bg-primary-hover active:bg-primary-active",
@@ -1 +1 @@
1
- {"version":3,"file":"chart-time-series.d.ts","sourceRoot":"","sources":["../../src/components/chart-time-series.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAY/B,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,kCAAkC,CAAC;AAsD1C,KAAK,gBAAgB,GAAG;IACtB,2EAA2E;IAC3E,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,KAAK,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;AAEvD,KAAK,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAC,GAAG;IACxE,IAAI,EAAE,SAAS,eAAe,EAAE,CAAC;IACjC,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACpC,2DAA2D;IAC3D,cAAc,EAAE,cAAc,CAAC;IAC/B,wEAAwE;IACxE,KAAK,EAAE,MAAM,CAAC;IACd,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAC3C;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAsJF,iBAAS,cAAc,CAAC,EACtB,IAAI,EACJ,IAAI,EACJ,MAAM,EACN,cAAc,EACd,KAAK,EACL,MAAiB,EACjB,cAA8B,EAC9B,UAAU,EACV,UAAoB,EACpB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,eAAe,qBA8CjB;AAED,iBAAS,cAAc,CAAC,EACtB,IAAI,EACJ,IAAI,EACJ,MAAM,EACN,cAAc,EACd,KAAK,EACL,MAAiB,EACjB,cAA8B,EAC9B,UAAU,EACV,UAAoB,EACpB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,eAAe,qBAuDjB;AAED,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,CAAC;AAC1C,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,gBAAgB,EAAE,CAAC"}
1
+ {"version":3,"file":"chart-time-series.d.ts","sourceRoot":"","sources":["../../src/components/chart-time-series.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAY/B,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,kCAAkC,CAAC;AAsD1C,KAAK,gBAAgB,GAAG;IACtB,2EAA2E;IAC3E,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,KAAK,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;AAEvD,KAAK,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAC,GAAG;IACxE,IAAI,EAAE,SAAS,eAAe,EAAE,CAAC;IACjC,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACpC,2DAA2D;IAC3D,cAAc,EAAE,cAAc,CAAC;IAC/B,wEAAwE;IACxE,KAAK,EAAE,MAAM,CAAC;IACd,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAC3C;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAsJF,iBAAS,cAAc,CAAC,EACtB,IAAI,EACJ,IAAI,EACJ,MAAM,EACN,cAAc,EACd,KAAK,EACL,MAAiB,EACjB,cAA8B,EAC9B,UAAU,EACV,UAAoB,EACpB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,eAAe,qBA+CjB;AAED,iBAAS,cAAc,CAAC,EACtB,IAAI,EACJ,IAAI,EACJ,MAAM,EACN,cAAc,EACd,KAAK,EACL,MAAiB,EACjB,cAA8B,EAC9B,UAAU,EACV,UAAoB,EACpB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,eAAe,qBAwDjB;AAED,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,CAAC;AAC1C,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,gBAAgB,EAAE,CAAC"}
@@ -114,14 +114,14 @@ function TimeSeriesFrame({ label, className, children, ...props }) {
114
114
  function TimeSeriesBars({ data, xKey, series, entityColorMap, label, xLabel = "Period", valueFormatter = defaultFormat, yAxisWidth, otherLabel = "Other", className, ...props }) {
115
115
  const folded = foldNeutralSeries(series, entityColorMap, data, otherLabel);
116
116
  const config = seriesChartConfig(folded.series, entityColorMap);
117
- return (_jsxs(TimeSeriesFrame, { "data-slot": "time-series-bars", label: label, className: className, ...props, children: [_jsx(ChartContainer, { config: config, className: cn("w-full", CHART_SURFACE_FOCUS_CLASS), children: _jsxs(BarChart, { accessibilityLayer: true, title: label, data: folded.data, children: [_jsx(CartesianGrid, { vertical: false }), _jsx(XAxis, { dataKey: xKey, tickLine: false, axisLine: false, tickMargin: 8 }), _jsx(YAxis, { tickLine: false, axisLine: false, width: yAxisWidth ?? "auto", tickFormatter: (value) => valueFormatter(Number(value)) }), _jsx(ChartTooltip, { content: _jsx(ChartTooltipContent, { formatter: tooltipRowFormatter(folded.series, valueFormatter) }) }), folded.series.length > 1 ? _jsx(ChartLegend, { content: _jsx(ChartLegendContent, {}) }) : null, _jsx(BarStack, { stackId: "stacked", radius: [4, 4, 0, 0], children: folded.series.map((entry) => (_jsx(Bar, { dataKey: entry.id, maxBarSize: 24, fill: entityColor(entityColorMap, entry.id), stroke: "var(--background)", strokeWidth: 2 }, entry.id))) })] }) }), _jsx(TimeSeriesTableAlternative, { data: folded.data, xKey: xKey, xLabel: xLabel, series: folded.series, label: label, valueFormatter: valueFormatter })] }));
117
+ return (_jsxs(TimeSeriesFrame, { "data-slot": "time-series-bars", label: label, className: className, ...props, children: [_jsx(ChartContainer, { config: config, className: cn("w-full", CHART_SURFACE_FOCUS_CLASS), children: _jsxs(BarChart, { accessibilityLayer: true, title: label, data: folded.data, children: [_jsx(CartesianGrid, { vertical: false }), _jsx(XAxis, { dataKey: xKey, tickLine: false, axisLine: false, tickMargin: 8 }), _jsx(YAxis, { tickLine: false, axisLine: false, width: yAxisWidth ?? "auto", tickFormatter: (value) => valueFormatter(Number(value)) }), _jsx(ChartTooltip, { content: _jsx(ChartTooltipContent, { formatter: tooltipRowFormatter(folded.series, valueFormatter) }) }), folded.series.length > 1 ? _jsx(ChartLegend, { content: _jsx(ChartLegendContent, {}) }) : null, _jsx(BarStack, { stackId: "stacked", radius: [4, 4, 0, 0], children: folded.series.map((entry) => (_jsx(Bar, { dataKey: entry.id, isAnimationActive: false, maxBarSize: 24, fill: entityColor(entityColorMap, entry.id), stroke: "var(--background)", strokeWidth: 2 }, entry.id))) })] }) }), _jsx(TimeSeriesTableAlternative, { data: folded.data, xKey: xKey, xLabel: xLabel, series: folded.series, label: label, valueFormatter: valueFormatter })] }));
118
118
  }
119
119
  function TimeSeriesArea({ data, xKey, series, entityColorMap, label, xLabel = "Period", valueFormatter = defaultFormat, yAxisWidth, otherLabel = "Other", className, ...props }) {
120
120
  const folded = foldNeutralSeries(series, entityColorMap, data, otherLabel);
121
121
  const config = seriesChartConfig(folded.series, entityColorMap);
122
122
  return (_jsxs(TimeSeriesFrame, { "data-slot": "time-series-area", label: label, className: className, ...props, children: [_jsx(ChartContainer, { config: config, className: cn("w-full", CHART_SURFACE_FOCUS_CLASS), children: _jsxs(AreaChart, { accessibilityLayer: true, title: label, data: folded.data, children: [_jsx(CartesianGrid, { vertical: false }), _jsx(XAxis, { dataKey: xKey, tickLine: false, axisLine: false, tickMargin: 8 }), _jsx(YAxis, { tickLine: false, axisLine: false, width: yAxisWidth ?? "auto", tickFormatter: (value) => valueFormatter(Number(value)) }), _jsx(ChartTooltip, { content: _jsx(ChartTooltipContent, { formatter: tooltipRowFormatter(folded.series, valueFormatter) }) }), folded.series.length > 1 ? _jsx(ChartLegend, { content: _jsx(ChartLegendContent, {}) }) : null, folded.series.map((entry) => {
123
123
  const color = entityColor(entityColorMap, entry.id);
124
- return (_jsx(Area, { type: "monotone", dataKey: entry.id, stackId: "stacked", stroke: color, strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", fill: color, fillOpacity: 0.1,
124
+ return (_jsx(Area, { type: "monotone", dataKey: entry.id, isAnimationActive: false, stackId: "stacked", stroke: color, strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", fill: color, fillOpacity: 0.1,
125
125
  // Recharts' default activeDot ring is stroke #fff, which the
126
126
  // chart foundation remaps to transparent — an explicit surface
127
127
  // ring keeps the DESIGN.md 2px marker-ring spec on hover/focus.
@@ -8,7 +8,7 @@ const THEMES = { light: "", dark: ".dark" };
8
8
  const INITIAL_DIMENSION = { width: 320, height: 200 };
9
9
  // Deviates from stock base-nova (raw interpolation): chart id and color values
10
10
  // are sanitized before they reach the injected <style> tag, closing the CSS
11
- // injection surface. Pinned by tests/chart-style.test.ts; see ADR 0010.
11
+ // injection surface. Exercised through hostile-input rendering tests; see ADR 0010.
12
12
  function sanitizeChartToken(value) {
13
13
  const sanitized = value
14
14
  .trim()
@@ -1,20 +1,32 @@
1
1
  import * as React from "react";
2
2
  /**
3
- * contact — contact-form section (replaces the retired `sections/contact.css` + its
4
- * coupled form controls).
3
+ * contact — the closing contact section (V5 B18).
5
4
  *
6
- * Composition pattern: a centered intro over a field stack ending in a submit
7
- * button. It owns NO structural seam every visible border is the caller's
8
- * control perimeter. The frame/lane/row perimeter is owned by the kept geometry
9
- * layer this composes inside. `<ContactForm columns={2}>` splits the field stack
10
- * into two whitespace-gapped columns on desktop (a `Field` can span both via
11
- * `className="sm:col-span-2"`); the gap is whitespace, never a hairline, so no seam
12
- * is introduced. Token-only; no `dark:` styling.
5
+ * A 5fr / 7fr split: a text column (`ContactIntro` eyebrow/title/body/location)
6
+ * beside a form column (`ContactForm`) that sits on its own soft, bordered panel.
7
+ * The split is a whitespace gap, never a hairline, so `Contact` owns NO structural
8
+ * seam the frame/lane/row perimeter is owned by the kept geometry layer this
9
+ * composes inside, and every visible border is a control/panel perimeter.
10
+ *
11
+ * The form is presentational only (no submit wiring): consumers own the action and
12
+ * state. Fields use the package `Input`/`Textarea` primitives; labels use the mono
13
+ * uppercase `ContactLabel`. `ContactFieldRow` is the 2-up Name/Company row.
14
+ * Token-only; no `dark:` styling.
13
15
  */
14
16
  declare function Contact({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
17
+ /** ContactIntro — the text column: eyebrow/title/body/location, centered vertically. */
18
+ declare function ContactIntro({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
19
+ /** ContactLocation — the mono location line under the intro body. */
20
+ declare function ContactLocation({ className, ...props }: React.ComponentProps<"p">): React.JSX.Element;
15
21
  declare function ContactForm({ className, columns, ...props }: React.ComponentProps<"form"> & {
16
22
  columns?: 1 | 2;
17
23
  }): React.JSX.Element;
24
+ /** ContactFieldRow — the 2-up Name/Company row inside a single-column form. */
25
+ declare function ContactFieldRow({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
26
+ /** ContactField — one label-over-control field cell. */
27
+ declare function ContactField({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
28
+ /** ContactLabel — mono uppercase form label (server-safe plain `<label>`). */
29
+ declare function ContactLabel({ className, ...props }: React.ComponentProps<"label">): React.JSX.Element;
18
30
  declare function ContactActions({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
19
- export { Contact, ContactForm, ContactActions };
31
+ export { Contact, ContactIntro, ContactLocation, ContactForm, ContactFieldRow, ContactField, ContactLabel, ContactActions, };
20
32
  //# sourceMappingURL=contact.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"contact.d.ts","sourceRoot":"","sources":["../../src/components/contact.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B;;;;;;;;;;;GAWG;AAEH,iBAAS,OAAO,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAWpE;AAED,iBAAS,WAAW,CAAC,EACnB,SAAS,EACT,OAAW,EACX,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG;IAAE,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;CAAE,qBAapD;AAED,iBAAS,cAAc,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAQ3E;AAED,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,CAAC"}
1
+ {"version":3,"file":"contact.d.ts","sourceRoot":"","sources":["../../src/components/contact.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B;;;;;;;;;;;;;GAaG;AAEH,iBAAS,OAAO,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAWpE;AAED,wFAAwF;AACxF,iBAAS,YAAY,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAQzE;AAED,qEAAqE;AACrE,iBAAS,eAAe,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,qBAW1E;AAED,iBAAS,WAAW,CAAC,EACnB,SAAS,EACT,OAAW,EACX,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG;IAAE,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;CAAE,qBAapD;AAED,+EAA+E;AAC/E,iBAAS,eAAe,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAQ5E;AAED,wDAAwD;AACxD,iBAAS,YAAY,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAIzE;AAED,8EAA8E;AAC9E,iBAAS,YAAY,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,qBAW3E;AAED,iBAAS,cAAc,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAQ3E;AAED,OAAO,EACL,OAAO,EACP,YAAY,EACZ,eAAe,EACf,WAAW,EACX,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,cAAc,GACf,CAAC"}
@@ -1,24 +1,46 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { cn } from "../lib/utils.js";
3
3
  /**
4
- * contact — contact-form section (replaces the retired `sections/contact.css` + its
5
- * coupled form controls).
4
+ * contact — the closing contact section (V5 B18).
6
5
  *
7
- * Composition pattern: a centered intro over a field stack ending in a submit
8
- * button. It owns NO structural seam every visible border is the caller's
9
- * control perimeter. The frame/lane/row perimeter is owned by the kept geometry
10
- * layer this composes inside. `<ContactForm columns={2}>` splits the field stack
11
- * into two whitespace-gapped columns on desktop (a `Field` can span both via
12
- * `className="sm:col-span-2"`); the gap is whitespace, never a hairline, so no seam
13
- * is introduced. Token-only; no `dark:` styling.
6
+ * A 5fr / 7fr split: a text column (`ContactIntro` eyebrow/title/body/location)
7
+ * beside a form column (`ContactForm`) that sits on its own soft, bordered panel.
8
+ * The split is a whitespace gap, never a hairline, so `Contact` owns NO structural
9
+ * seam the frame/lane/row perimeter is owned by the kept geometry layer this
10
+ * composes inside, and every visible border is a control/panel perimeter.
11
+ *
12
+ * The form is presentational only (no submit wiring): consumers own the action and
13
+ * state. Fields use the package `Input`/`Textarea` primitives; labels use the mono
14
+ * uppercase `ContactLabel`. `ContactFieldRow` is the 2-up Name/Company row.
15
+ * Token-only; no `dark:` styling.
14
16
  */
15
17
  function Contact({ className, ...props }) {
16
- return (_jsx("div", { "data-slot": "contact", className: cn("grid min-h-full min-w-0 content-center justify-items-center bg-card py-[clamp(40px,6vw,96px)]", className), ...props }));
18
+ return (_jsx("div", { "data-slot": "contact", className: cn("grid min-w-0 grid-cols-1 items-stretch gap-x-[clamp(32px,5vw,72px)] gap-y-10 lg:grid-cols-[5fr_7fr]", className), ...props }));
19
+ }
20
+ /** ContactIntro — the text column: eyebrow/title/body/location, centered vertically. */
21
+ function ContactIntro({ className, ...props }) {
22
+ return (_jsx("div", { "data-slot": "contact-intro", className: cn("grid min-w-0 content-center gap-4", className), ...props }));
23
+ }
24
+ /** ContactLocation — the mono location line under the intro body. */
25
+ function ContactLocation({ className, ...props }) {
26
+ return (_jsx("p", { "data-slot": "contact-location", className: cn("m-0 font-mono text-xs uppercase tracking-[0.1em] text-muted-foreground", className), ...props }));
17
27
  }
18
28
  function ContactForm({ className, columns = 1, ...props }) {
19
- return (_jsx("form", { "data-slot": "contact-form", "data-columns": columns, className: cn("mt-2 grid w-full max-w-[560px] gap-4 text-left", columns === 2 && "sm:grid-cols-2", className), ...props }));
29
+ return (_jsx("form", { "data-slot": "contact-form", "data-columns": columns, className: cn("grid min-w-0 gap-4 rounded-md border border-border bg-muted p-[clamp(20px,3vw,32px)] text-left", columns === 2 && "sm:grid-cols-2", className), ...props }));
30
+ }
31
+ /** ContactFieldRow — the 2-up Name/Company row inside a single-column form. */
32
+ function ContactFieldRow({ className, ...props }) {
33
+ return (_jsx("div", { "data-slot": "contact-field-row", className: cn("grid grid-cols-1 gap-4 sm:grid-cols-2", className), ...props }));
34
+ }
35
+ /** ContactField — one label-over-control field cell. */
36
+ function ContactField({ className, ...props }) {
37
+ return (_jsx("div", { "data-slot": "contact-field", className: cn("grid min-w-0 gap-1.5", className), ...props }));
38
+ }
39
+ /** ContactLabel — mono uppercase form label (server-safe plain `<label>`). */
40
+ function ContactLabel({ className, ...props }) {
41
+ return (_jsx("label", { "data-slot": "contact-label", className: cn("font-mono text-[9.5px] font-medium uppercase tracking-[0.12em] text-muted-foreground", className), ...props }));
20
42
  }
21
43
  function ContactActions({ className, ...props }) {
22
44
  return (_jsx("div", { "data-slot": "contact-actions", className: cn("mt-1 grid sm:col-span-2 [&>button]:w-full", className), ...props }));
23
45
  }
24
- export { Contact, ContactForm, ContactActions };
46
+ export { Contact, ContactIntro, ContactLocation, ContactForm, ContactFieldRow, ContactField, ContactLabel, ContactActions, };
@@ -1 +1 @@
1
- {"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../src/components/dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAMlE,iBAAS,MAAM,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,CAAC,IAAI,CAAC,KAAK,qBAEvD;AAED,iBAAS,aAAa,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,CAAC,OAAO,CAAC,KAAK,qBAEjE;AAED,iBAAS,YAAY,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,CAAC,MAAM,CAAC,KAAK,qBAE/D;AAED,iBAAS,WAAW,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,CAAC,KAAK,CAAC,KAAK,qBAE7D;AAED,iBAAS,aAAa,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,CAAC,QAAQ,CAAC,KAAK,qBAW7E;AAED,KAAK,kBAAkB,GAAG,eAAe,CAAC,KAAK,CAAC,KAAK,GAAG;IACtD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC9B,CAAC;AAEF,iBAAS,aAAa,CAAC,EACrB,SAAS,EACT,QAAQ,EACR,eAAsB,EACtB,UAAoB,EACpB,GAAG,KAAK,EACT,EAAE,kBAAkB,qBA+BpB;AAED,iBAAS,YAAY,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAIzE;AAED,KAAK,iBAAiB,GAAG,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG;IACrD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC9B,CAAC;AAEF,iBAAS,YAAY,CAAC,EACpB,SAAS,EACT,eAAuB,EACvB,UAAoB,EACpB,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,iBAAiB,qBAkBnB;AAED,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,CAAC,KAAK,CAAC,KAAK,qBAQxE;AAED,iBAAS,iBAAiB,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,CAAC,WAAW,CAAC,KAAK,qBAWpF;AAED,OAAO,EACL,MAAM,EACN,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,WAAW,EACX,aAAa,GACd,CAAC"}
1
+ {"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../src/components/dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAOlE,iBAAS,MAAM,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,CAAC,IAAI,CAAC,KAAK,qBAEvD;AAED,iBAAS,aAAa,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,CAAC,OAAO,CAAC,KAAK,qBAEjE;AAED,iBAAS,YAAY,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,CAAC,MAAM,CAAC,KAAK,qBAE/D;AAED,iBAAS,WAAW,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,CAAC,KAAK,CAAC,KAAK,qBAE7D;AAED,iBAAS,aAAa,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,CAAC,QAAQ,CAAC,KAAK,qBAQ7E;AAED,KAAK,kBAAkB,GAAG,eAAe,CAAC,KAAK,CAAC,KAAK,GAAG;IACtD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC9B,CAAC;AAEF,iBAAS,aAAa,CAAC,EACrB,SAAS,EACT,QAAQ,EACR,eAAsB,EACtB,UAAoB,EACpB,GAAG,KAAK,EACT,EAAE,kBAAkB,qBAgCpB;AAED,iBAAS,YAAY,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAIzE;AAED,KAAK,iBAAiB,GAAG,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG;IACrD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC9B,CAAC;AAEF,iBAAS,YAAY,CAAC,EACpB,SAAS,EACT,eAAuB,EACvB,UAAoB,EACpB,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,iBAAiB,qBAkBnB;AAED,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,CAAC,KAAK,CAAC,KAAK,qBAQxE;AAED,iBAAS,iBAAiB,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,CAAC,WAAW,CAAC,KAAK,qBAWpF;AAED,OAAO,EACL,MAAM,EACN,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,WAAW,EACX,aAAa,GACd,CAAC"}
@@ -1,6 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Dialog as DialogPrimitive } from "@base-ui/react/dialog";
3
3
  import { cn } from "../lib/utils.js";
4
+ import { modalOverlayMotion, overlayBackdropMotion } from "../lib/motion.js";
4
5
  import { Button } from "./button.js";
5
6
  import { XIcon } from "lucide-react";
6
7
  function Dialog({ ...props }) {
@@ -16,10 +17,10 @@ function DialogClose({ ...props }) {
16
17
  return _jsx(DialogPrimitive.Close, { "data-slot": "dialog-close", ...props });
17
18
  }
18
19
  function DialogOverlay({ className, ...props }) {
19
- return (_jsx(DialogPrimitive.Backdrop, { "data-slot": "dialog-overlay", className: cn("fixed inset-0 isolate z-50 bg-scrim/scrim duration-100 data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0", className), ...props }));
20
+ return (_jsx(DialogPrimitive.Backdrop, { "data-slot": "dialog-overlay", className: cn("fixed inset-0 isolate z-50 bg-scrim/scrim", overlayBackdropMotion, className), ...props }));
20
21
  }
21
22
  function DialogContent({ className, children, showCloseButton = true, closeLabel = "Close", ...props }) {
22
- return (_jsxs(DialogPortal, { children: [_jsx(DialogOverlay, {}), _jsxs(DialogPrimitive.Popup, { "data-slot": "dialog-content", className: cn("fixed top-1/2 left-1/2 z-50 grid w-full max-w-[calc(100%-var(--nc-xl))] -translate-x-1/2 -translate-y-1/2 gap-nadicode-md rounded-2xl border border-border bg-popover p-nadicode-lg text-sm text-popover-foreground shadow-dialog duration-100 outline-none sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className), ...props, children: [children, showCloseButton && (_jsxs(DialogPrimitive.Close, { "data-slot": "dialog-close", render: _jsx(Button, { variant: "ghost", className: "absolute top-nadicode-md right-nadicode-md", size: "icon-sm" }), children: [_jsx(XIcon, {}), _jsx("span", { className: "sr-only", children: closeLabel })] }))] })] }));
23
+ return (_jsxs(DialogPortal, { children: [_jsx(DialogOverlay, {}), _jsxs(DialogPrimitive.Popup, { "data-slot": "dialog-content", className: cn("fixed top-1/2 left-1/2 z-50 grid w-full max-w-[calc(100%-var(--nc-xl))] -translate-x-1/2 -translate-y-1/2 gap-nadicode-md rounded-2xl border border-border bg-popover p-nadicode-lg text-sm text-popover-foreground shadow-dialog outline-none sm:max-w-sm", modalOverlayMotion, className), ...props, children: [children, showCloseButton && (_jsxs(DialogPrimitive.Close, { "data-slot": "dialog-close", render: _jsx(Button, { variant: "ghost", className: "absolute top-nadicode-md right-nadicode-md", size: "icon-sm" }), children: [_jsx(XIcon, {}), _jsx("span", { className: "sr-only", children: closeLabel })] }))] })] }));
23
24
  }
24
25
  function DialogHeader({ className, ...props }) {
25
26
  return (_jsx("div", { "data-slot": "dialog-header", className: cn("flex flex-col gap-2", className), ...props }));
@@ -21,6 +21,6 @@ function AnimatedInt({ value }) {
21
21
  function DiffCount({ added, removed, className, ...props }) {
22
22
  if (!added && !removed)
23
23
  return null;
24
- return (_jsxs("span", { className: cn("flex shrink-0 items-center gap-1 tabular-nums", className), "data-slot": "diff-count", ...props, children: [added > 0 ? (_jsxs("span", { className: "text-(--nc-diff-added-word)", children: ["+", _jsx(AnimatedInt, { value: added })] })) : null, removed > 0 ? (_jsxs("span", { className: "text-(--nc-diff-removed-word)", children: ["\u2212", _jsx(AnimatedInt, { value: removed })] })) : null] }));
24
+ return (_jsxs("span", { className: cn("flex shrink-0 items-center gap-1 tabular-nums", className), "data-slot": "diff-count", ...props, children: [added > 0 ? (_jsxs("span", { className: "text-[var(--nc-link-deep)]", children: ["+", _jsx(AnimatedInt, { value: added })] })) : null, removed > 0 ? (_jsxs("span", { className: "text-[var(--nc-error-deep)]", children: ["\u2212", _jsx(AnimatedInt, { value: removed })] })) : null] }));
25
25
  }
26
26
  export { DiffCount };
@@ -1 +1 @@
1
- {"version":3,"file":"dropdown-menu.d.ts","sourceRoot":"","sources":["../../src/components/dropdown-menu.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dropdown-menu.d.ts","sourceRoot":"","sources":["../../src/components/dropdown-menu.tsx"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Menu as MenuPrimitive } from "@base-ui/react/menu";
3
3
  import { cn } from "../lib/utils.js";
4
+ import { anchoredOverlayMotion } from "../lib/motion.js";
4
5
  import { ChevronRightIcon, CheckIcon } from "lucide-react";
5
6
  function DropdownMenu({ ...props }) {
6
7
  return _jsx(MenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
@@ -12,7 +13,7 @@ function DropdownMenuTrigger({ ...props }) {
12
13
  return _jsx(MenuPrimitive.Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
13
14
  }
14
15
  function DropdownMenuContent({ align = "start", alignOffset = 0, side = "bottom", sideOffset = 4, className, ...props }) {
15
- return (_jsx(MenuPrimitive.Portal, { children: _jsx(MenuPrimitive.Positioner, { className: "isolate z-50 outline-none", align: align, alignOffset: alignOffset, side: side, sideOffset: sideOffset, children: _jsx(MenuPrimitive.Popup, { "data-slot": "dropdown-menu-content", className: cn("z-50 max-h-(--available-height) w-(--anchor-width) min-w-32 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-2xl border border-border bg-popover p-nadicode-xxs text-popover-foreground shadow-menu duration-100 outline-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:overflow-hidden data-closed:fade-out-0 data-closed:zoom-out-95", className), ...props }) }) }));
16
+ return (_jsx(MenuPrimitive.Portal, { children: _jsx(MenuPrimitive.Positioner, { className: "isolate z-50 outline-none", align: align, alignOffset: alignOffset, side: side, sideOffset: sideOffset, children: _jsx(MenuPrimitive.Popup, { "data-slot": "dropdown-menu-content", className: cn("z-50 max-h-(--available-height) w-(--anchor-width) min-w-32 overflow-x-hidden overflow-y-auto rounded-2xl border border-border bg-popover p-nadicode-xxs text-popover-foreground shadow-menu outline-none data-closed:overflow-hidden", anchoredOverlayMotion, className), ...props }) }) }));
16
17
  }
17
18
  function DropdownMenuGroup({ ...props }) {
18
19
  return _jsx(MenuPrimitive.Group, { "data-slot": "dropdown-menu-group", ...props });
@@ -18,8 +18,8 @@ import { cn } from "../lib/utils.js";
18
18
  * no `dark:` styling.
19
19
  */
20
20
  function FaqItem({ className, question, name, open, children, ...props }) {
21
- return (_jsxs("details", { "data-slot": "faq-item", name: name, open: open, className: cn("group bg-card [&_summary::-webkit-details-marker]:hidden", className), ...props, children: [_jsx("summary", { className: cn("flex min-h-16 cursor-pointer list-none items-center justify-between gap-4 px-5 py-[18px]", "text-base font-medium text-foreground", "outline-none focus-visible:outline-2 focus-visible:[outline-color:var(--ring)] focus-visible:-outline-offset-2",
21
+ return (_jsxs("details", { "data-slot": "faq-item", name: name, open: open, className: cn("group bg-muted [&_summary::-webkit-details-marker]:hidden", className), ...props, children: [_jsx("summary", { className: cn("flex min-h-16 cursor-pointer list-none items-center justify-between gap-4 px-5 py-[18px]", "text-base font-medium text-foreground transition-colors hover:text-[var(--nc-link)]", "outline-none focus-visible:outline-2 focus-visible:[outline-color:var(--ring)] focus-visible:-outline-offset-2",
22
22
  // +/- marker: two crossed bars; the vertical bar hides when open (+ -> -)
23
- "after:size-3 after:flex-none after:bg-[length:12px_1px,1px_12px] after:bg-center after:bg-no-repeat", "after:[background-image:linear-gradient(var(--nc-body),var(--nc-body)),linear-gradient(var(--nc-body),var(--nc-body))]", "group-open:after:bg-[length:12px_1px] group-open:after:[background-image:linear-gradient(var(--nc-body),var(--nc-body))]"), children: question }), _jsx("div", { "data-slot": "faq-item-answer", className: "border-t border-border px-5 pt-4 pb-5 text-sm text-[var(--nc-body)]", children: children })] }));
23
+ "after:size-3 after:flex-none after:bg-[length:12px_1px,1px_12px] after:bg-center after:bg-no-repeat", "after:[background-image:linear-gradient(var(--muted-foreground),var(--muted-foreground)),linear-gradient(var(--muted-foreground),var(--muted-foreground))]", "group-open:after:bg-[length:12px_1px] group-open:after:[background-image:linear-gradient(var(--muted-foreground),var(--muted-foreground))]"), children: question }), _jsx("div", { "data-slot": "faq-item-answer", className: "border-t border-border px-5 pt-4 pb-5 text-sm text-muted-foreground", children: children })] }));
24
24
  }
25
25
  export { FaqItem };
@@ -10,7 +10,10 @@ import * as React from "react";
10
10
  * not here). A faq is one column at every breakpoint — no column count, no dark
11
11
  * inversion (matching the retired section's variants:none).
12
12
  *
13
- * Token-only; no `dark:` styling.
13
+ * READING COLUMN (V5 B16): the faq is centered in a narrow 760px reading column
14
+ * (`max-w-[760px] mx-auto`) rather than spanning the full lane. The soft surface is
15
+ * carried by the `FaqItem` fills (`bg-muted`), so the column reads as a soft stack of
16
+ * hairline-separated questions. Token-only; no `dark:` styling.
14
17
  */
15
18
  declare function Faq({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
16
19
  export { Faq };
@@ -1 +1 @@
1
- {"version":3,"file":"faq.d.ts","sourceRoot":"","sources":["../../src/components/faq.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B;;;;;;;;;;;;GAYG;AAEH,iBAAS,GAAG,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAEhE;AAED,OAAO,EAAE,GAAG,EAAE,CAAC"}
1
+ {"version":3,"file":"faq.d.ts","sourceRoot":"","sources":["../../src/components/faq.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B;;;;;;;;;;;;;;;GAeG;AAEH,iBAAS,GAAG,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAQhE;AAED,OAAO,EAAE,GAAG,EAAE,CAAC"}
@@ -12,9 +12,12 @@ import { SeamGrid } from "./seam-grid.js";
12
12
  * not here). A faq is one column at every breakpoint — no column count, no dark
13
13
  * inversion (matching the retired section's variants:none).
14
14
  *
15
- * Token-only; no `dark:` styling.
15
+ * READING COLUMN (V5 B16): the faq is centered in a narrow 760px reading column
16
+ * (`max-w-[760px] mx-auto`) rather than spanning the full lane. The soft surface is
17
+ * carried by the `FaqItem` fills (`bg-muted`), so the column reads as a soft stack of
18
+ * hairline-separated questions. Token-only; no `dark:` styling.
16
19
  */
17
20
  function Faq({ className, ...props }) {
18
- return _jsx(SeamGrid, { "data-slot": "faq", className: cn("h-full grid-cols-1", className), ...props });
21
+ return (_jsx(SeamGrid, { "data-slot": "faq", className: cn("mx-auto h-full max-w-[760px] grid-cols-1", className), ...props }));
19
22
  }
20
23
  export { Faq };
@@ -0,0 +1,23 @@
1
+ import * as React from "react";
2
+ declare function FeatureGrid({ eyebrow, intro, closing, link, columns, children, className, ...props }: React.ComponentProps<"div"> & {
3
+ eyebrow?: React.ReactNode;
4
+ intro?: React.ReactNode;
5
+ closing?: React.ReactNode;
6
+ link?: React.ReactNode;
7
+ columns?: 2 | 3 | 4;
8
+ }): React.JSX.Element;
9
+ /**
10
+ * FeatureCard — one peer card: a verde-accent index chip using the canonical
11
+ * `--nc-link-deep` pair (deep verde on light, bright verde on dark), a title, a body
12
+ * paragraph, and an optional bottom visual slot pinned to the card's foot
13
+ * (`mt-auto`). Every part renders only when its content is present; with no visual
14
+ * the card sizes to its copy over a modest min-height so a peer row stays balanced
15
+ * (no cavernous empty foot).
16
+ */
17
+ declare function FeatureCard({ index, title, visual, children, className, ...props }: React.ComponentProps<"div"> & {
18
+ index?: React.ReactNode;
19
+ title?: React.ReactNode;
20
+ visual?: React.ReactNode;
21
+ }): React.JSX.Element;
22
+ export { FeatureGrid, FeatureCard };
23
+ //# sourceMappingURL=feature-grid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feature-grid.d.ts","sourceRoot":"","sources":["../../src/components/feature-grid.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAsB/B,iBAAS,WAAW,CAAC,EACnB,OAAO,EACP,KAAK,EACL,OAAO,EACP,IAAI,EACJ,OAAW,EACX,QAAQ,EACR,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG;IAC/B,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;CACrB,qBA+BA;AAED;;;;;;;GAOG;AACH,iBAAS,WAAW,CAAC,EACnB,KAAK,EACL,KAAK,EACL,MAAM,EACN,QAAQ,EACR,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG;IAC/B,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC1B,qBAmCA;AAED,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from "../lib/utils.js";
3
+ import { SeamGrid } from "./seam-grid.js";
4
+ /**
5
+ * feature-grid — an indexed head row over a wall of seamed peer cards, closed by
6
+ * a line of copy and an arrow-link slot (V5 B06).
7
+ *
8
+ * The head (mono eyebrow + intro paragraph) and the close (a trailing line plus a
9
+ * caller-supplied link) are optional slots; absent, they render nothing. The cards
10
+ * are `FeatureCard` peers laid in a SINGLE-OWNER SEAM grid (`SeamGrid`, `gap-px
11
+ * bg-border`), so every divider is owned once and the cards stay borderless fills.
12
+ * Token-only; no `dark:` styling.
13
+ */
14
+ const columnClasses = {
15
+ 2: "grid-cols-1 md:grid-cols-2",
16
+ 3: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3",
17
+ 4: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-4",
18
+ };
19
+ function FeatureGrid({ eyebrow, intro, closing, link, columns = 3, children, className, ...props }) {
20
+ return (_jsxs("div", { "data-slot": "feature-grid", className: cn("grid gap-8", className), ...props, children: [eyebrow != null || intro != null ? (_jsxs("div", { "data-slot": "feature-grid-head", className: "grid gap-3", children: [eyebrow != null ? (_jsx("p", { className: "nc-type-caption-mono uppercase text-muted-foreground", children: eyebrow })) : null, intro != null ? (_jsx("p", { className: "nc-type-body-md max-w-[64ch] text-muted-foreground", children: intro })) : null] })) : null, _jsx(SeamGrid, { "data-slot": "feature-grid-cards", className: columnClasses[columns], children: children }), closing != null || link != null ? (_jsxs("div", { "data-slot": "feature-grid-close", className: "flex flex-wrap items-baseline gap-x-3 gap-y-2", children: [closing != null ? (_jsx("span", { className: "nc-type-body-md text-muted-foreground", children: closing })) : null, link] })) : null] }));
21
+ }
22
+ /**
23
+ * FeatureCard — one peer card: a verde-accent index chip using the canonical
24
+ * `--nc-link-deep` pair (deep verde on light, bright verde on dark), a title, a body
25
+ * paragraph, and an optional bottom visual slot pinned to the card's foot
26
+ * (`mt-auto`). Every part renders only when its content is present; with no visual
27
+ * the card sizes to its copy over a modest min-height so a peer row stays balanced
28
+ * (no cavernous empty foot).
29
+ */
30
+ function FeatureCard({ index, title, visual, children, className, ...props }) {
31
+ return (_jsxs("div", { "data-slot": "feature-card", className: cn("flex min-h-[200px] flex-col gap-4 bg-card p-[clamp(20px,2.4vw,32px)]", className), ...props, children: [index != null ? (_jsx("span", { "data-slot": "feature-card-index", className: "nc-type-caption-mono text-[var(--nc-link-deep)]", children: index })) : null, title != null ? (_jsx("h3", { "data-slot": "feature-card-title", className: "nc-type-title-sm text-foreground", children: title })) : null, children != null ? (_jsx("p", { "data-slot": "feature-card-body", className: "nc-type-body-sm text-muted-foreground", children: children })) : null, visual != null ? (_jsx("div", { "data-slot": "feature-card-visual", className: "mt-auto", children: visual })) : null] }));
32
+ }
33
+ export { FeatureGrid, FeatureCard };
@@ -0,0 +1,23 @@
1
+ import * as React from "react";
2
+ /**
3
+ * feature-rows — alternating text↔art rows (V5 B07).
4
+ *
5
+ * Each `FeatureRow` is a two-cell split: a copy cell and a dotted-texture art
6
+ * panel. The default row runs text (narrow, 5fr) beside art (wide, 7fr); `flip`
7
+ * swaps the visual order so the art sits on the wide left track and the text on
8
+ * the narrow right — while text always leads in the DOM so it reads first when the
9
+ * row stacks to one column.
10
+ *
11
+ * SINGLE-OWNER SEAM: the split divider is the `SeamGrid` gap-as-seam. The art panel
12
+ * is a container-only slot — the chat/export specimens are caller content, never
13
+ * baked in; an empty panel is just the dotted texture. Token-only; no `dark:`
14
+ * styling.
15
+ */
16
+ declare function FeatureRows({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
17
+ declare function FeatureRow({ flip, text, art, className, ...props }: React.ComponentProps<"div"> & {
18
+ flip?: boolean;
19
+ text?: React.ReactNode;
20
+ art?: React.ReactNode;
21
+ }): React.JSX.Element;
22
+ export { FeatureRows, FeatureRow };
23
+ //# sourceMappingURL=feature-rows.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feature-rows.d.ts","sourceRoot":"","sources":["../../src/components/feature-rows.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B;;;;;;;;;;;;;GAaG;AAEH,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAExE;AAED,iBAAS,UAAU,CAAC,EAClB,IAAY,EACZ,IAAI,EACJ,GAAG,EACH,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG;IAC/B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,GAAG,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACvB,qBA+BA;AAED,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC"}
@@ -0,0 +1,27 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from "../lib/utils.js";
3
+ import { SeamGrid } from "./seam-grid.js";
4
+ /**
5
+ * feature-rows — alternating text↔art rows (V5 B07).
6
+ *
7
+ * Each `FeatureRow` is a two-cell split: a copy cell and a dotted-texture art
8
+ * panel. The default row runs text (narrow, 5fr) beside art (wide, 7fr); `flip`
9
+ * swaps the visual order so the art sits on the wide left track and the text on
10
+ * the narrow right — while text always leads in the DOM so it reads first when the
11
+ * row stacks to one column.
12
+ *
13
+ * SINGLE-OWNER SEAM: the split divider is the `SeamGrid` gap-as-seam. The art panel
14
+ * is a container-only slot — the chat/export specimens are caller content, never
15
+ * baked in; an empty panel is just the dotted texture. Token-only; no `dark:`
16
+ * styling.
17
+ */
18
+ function FeatureRows({ className, ...props }) {
19
+ return _jsx("div", { "data-slot": "feature-rows", className: cn("grid", className), ...props });
20
+ }
21
+ function FeatureRow({ flip = false, text, art, className, ...props }) {
22
+ return (_jsxs(SeamGrid, { "data-slot": "feature-row", "data-flip": flip || undefined, className: cn("min-h-[520px] grid-cols-1", flip ? "lg:grid-cols-[7fr_5fr]" : "lg:grid-cols-[5fr_7fr]", className), ...props, children: [_jsx("div", { "data-slot": "feature-row-text", className: cn("nc-panel-cell bg-card", flip && "lg:order-2"), children: text }), _jsx("div", { "data-slot": "feature-row-art", className: cn(
23
+ // The semantic card fill and the raw `--nc-*` tokens used by
24
+ // `nc-dotted-field` both flip under any `.dark` ancestor.
25
+ "nc-dotted-field grid place-items-center overflow-hidden bg-card p-[clamp(24px,4vw,56px)]", flip && "lg:order-1"), children: art })] }));
26
+ }
27
+ export { FeatureRows, FeatureRow };
@@ -1,18 +1,21 @@
1
1
  import * as React from "react";
2
2
  /**
3
- * footer — bottom footer/navigation row chrome (replaces the retired `.nc-footer`
4
- * + its `data-variant="mega"`).
3
+ * footer — the always-dark site footer (V5 · B20).
5
4
  *
6
- * SINGLE-OWNER SEAM: the only edge the footer owns is its top border
7
- * (`border-t border-border`) on a canvas surface it draws no other line. The flat
8
- * inner row is a wrapping flex line capped to the frame measure with
9
- * `justify-between`: brand leading, meta trailing, nav between. The `variant="mega"`
10
- * adds exactly ONE extra inner seam — a hairline above the meta strip
11
- * (`FooterMegaMeta`'s top border) — owned once there; the link columns separate by
12
- * whitespace gaps, never rails, so no coordinate carries two borders.
5
+ * A brandline + identity paragraph beside two link columns, a meta row
6
+ * (copyright · clock slot · locations), and a giant faint ghost wordmark behind it
7
+ * all. The footer is ALWAYS dark, so the root carries its own `dark` ancestor class
8
+ * and resolves every colour from semantic roles (`bg-card`, `text-foreground`,
9
+ * `text-muted-foreground`, `border-border`, `text-primary`).
13
10
  *
14
- * A11y: nav links expose a `--ring` (link-green) focus outline; the consumer wraps
15
- * link groups in `<nav aria-label>`. Token-only; no `dark:` styling.
11
+ * SINGLE-OWNER SEAM: the footer owns its top border (`border-t border-border`); the
12
+ * `mega` variant adds exactly ONE inner seam, the hairline above the meta strip
13
+ * (`FooterMegaMeta`). Link columns separate by whitespace, never rails.
14
+ *
15
+ * The ghost wordmark and clock are CONTENT slots: `FooterGhost` takes the wordmark
16
+ * text/renderer, `FooterClock` takes a pre-formatted time string (a value, not a
17
+ * live timer — no client JS in this pass). Token-only; the root sets its own `dark`
18
+ * class (an accepted ancestor-class remap), never `dark:` utilities.
16
19
  */
17
20
  declare function Footer({ className, variant, ...props }: React.ComponentProps<"footer"> & {
18
21
  variant?: "flat" | "mega";
@@ -21,12 +24,15 @@ declare function FooterInner({ className, variant, ...props }: React.ComponentPr
21
24
  variant?: "flat" | "mega";
22
25
  }): React.JSX.Element;
23
26
  declare function FooterBrand({ className, ...props }: React.ComponentProps<"a">): React.JSX.Element;
27
+ declare function FooterIdentity({ className, ...props }: React.ComponentProps<"p">): React.JSX.Element;
24
28
  declare function FooterNav({ className, ...props }: React.ComponentProps<"nav">): React.JSX.Element;
25
29
  declare function FooterMeta({ className, ...props }: React.ComponentProps<"p">): React.JSX.Element;
30
+ declare function FooterClock({ className, ...props }: React.ComponentProps<"span">): React.JSX.Element;
31
+ declare function FooterGhost({ className, ...props }: React.ComponentProps<"span">): React.JSX.Element;
26
32
  declare function FooterMegaTop({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
27
33
  declare function FooterMegaCols({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
28
34
  declare function FooterMegaCol({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
29
35
  declare function FooterMegaColTitle({ className, ...props }: React.ComponentProps<"p">): React.JSX.Element;
30
36
  declare function FooterMegaMeta({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
31
- export { Footer, FooterInner, FooterBrand, FooterNav, FooterMeta, FooterMegaTop, FooterMegaCols, FooterMegaCol, FooterMegaColTitle, FooterMegaMeta, };
37
+ export { Footer, FooterInner, FooterBrand, FooterIdentity, FooterNav, FooterMeta, FooterClock, FooterGhost, FooterMegaTop, FooterMegaCols, FooterMegaCol, FooterMegaColTitle, FooterMegaMeta, };
32
38
  //# sourceMappingURL=footer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"footer.d.ts","sourceRoot":"","sources":["../../src/components/footer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B;;;;;;;;;;;;;;GAcG;AAEH,iBAAS,MAAM,CAAC,EACd,SAAS,EACT,OAAgB,EAChB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,GAAG;IAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,qBAahE;AAED,iBAAS,WAAW,CAAC,EACnB,SAAS,EACT,OAAgB,EAChB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG;IAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,qBAY7D;AAED,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,qBAWtE;AAED,iBAAS,SAAS,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAWtE;AAED,iBAAS,UAAU,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,qBAQrE;AAID,iBAAS,aAAa,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAW1E;AAED,iBAAS,cAAc,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAW3E;AAED,iBAAS,aAAa,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAW1E;AAED,iBAAS,kBAAkB,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,qBAQ7E;AAED,iBAAS,cAAc,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAY3E;AAED,OAAO,EACL,MAAM,EACN,WAAW,EACX,WAAW,EACX,SAAS,EACT,UAAU,EACV,aAAa,EACb,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,cAAc,GACf,CAAC"}
1
+ {"version":3,"file":"footer.d.ts","sourceRoot":"","sources":["../../src/components/footer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B;;;;;;;;;;;;;;;;;GAiBG;AAEH,iBAAS,MAAM,CAAC,EACd,SAAS,EACT,OAAgB,EAChB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,GAAG;IAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,qBAahE;AAED,iBAAS,WAAW,CAAC,EACnB,SAAS,EACT,OAAgB,EAChB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG;IAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,qBAY7D;AAED,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,qBAWtE;AAED,iBAAS,cAAc,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,qBAQzE;AAED,iBAAS,SAAS,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAWtE;AAED,iBAAS,UAAU,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,qBAQrE;AAED,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,qBAQzE;AAED,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,qBAYzE;AAID,iBAAS,aAAa,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAW1E;AAED,iBAAS,cAAc,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAW3E;AAED,iBAAS,aAAa,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAW1E;AAED,iBAAS,kBAAkB,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,qBAQ7E;AAED,iBAAS,cAAc,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAY3E;AAED,OAAO,EACL,MAAM,EACN,WAAW,EACX,WAAW,EACX,cAAc,EACd,SAAS,EACT,UAAU,EACV,WAAW,EACX,WAAW,EACX,aAAa,EACb,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,cAAc,GACf,CAAC"}
@@ -1,51 +1,63 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { cn } from "../lib/utils.js";
3
3
  /**
4
- * footer — bottom footer/navigation row chrome (replaces the retired `.nc-footer`
5
- * + its `data-variant="mega"`).
4
+ * footer — the always-dark site footer (V5 · B20).
6
5
  *
7
- * SINGLE-OWNER SEAM: the only edge the footer owns is its top border
8
- * (`border-t border-border`) on a canvas surface it draws no other line. The flat
9
- * inner row is a wrapping flex line capped to the frame measure with
10
- * `justify-between`: brand leading, meta trailing, nav between. The `variant="mega"`
11
- * adds exactly ONE extra inner seam — a hairline above the meta strip
12
- * (`FooterMegaMeta`'s top border) — owned once there; the link columns separate by
13
- * whitespace gaps, never rails, so no coordinate carries two borders.
6
+ * A brandline + identity paragraph beside two link columns, a meta row
7
+ * (copyright · clock slot · locations), and a giant faint ghost wordmark behind it
8
+ * all. The footer is ALWAYS dark, so the root carries its own `dark` ancestor class
9
+ * and resolves every colour from semantic roles (`bg-card`, `text-foreground`,
10
+ * `text-muted-foreground`, `border-border`, `text-primary`).
14
11
  *
15
- * A11y: nav links expose a `--ring` (link-green) focus outline; the consumer wraps
16
- * link groups in `<nav aria-label>`. Token-only; no `dark:` styling.
12
+ * SINGLE-OWNER SEAM: the footer owns its top border (`border-t border-border`); the
13
+ * `mega` variant adds exactly ONE inner seam, the hairline above the meta strip
14
+ * (`FooterMegaMeta`). Link columns separate by whitespace, never rails.
15
+ *
16
+ * The ghost wordmark and clock are CONTENT slots: `FooterGhost` takes the wordmark
17
+ * text/renderer, `FooterClock` takes a pre-formatted time string (a value, not a
18
+ * live timer — no client JS in this pass). Token-only; the root sets its own `dark`
19
+ * class (an accepted ancestor-class remap), never `dark:` utilities.
17
20
  */
18
21
  function Footer({ className, variant = "flat", ...props }) {
19
- return (_jsx("footer", { "data-slot": "footer", "data-variant": variant, className: cn("border-t border-border bg-card px-6 py-8 [&_a]:no-underline", "[&_a:focus-visible]:outline [&_a:focus-visible]:outline-1 [&_a:focus-visible]:[outline-color:var(--ring)] [&_a:focus-visible]:outline-offset-2", className), ...props }));
22
+ return (_jsx("footer", { "data-slot": "footer", "data-variant": variant, className: cn("dark relative isolate overflow-hidden border-t border-border bg-card px-6 py-12 text-foreground [&_a]:no-underline", "[&_a:focus-visible]:outline [&_a:focus-visible]:outline-1 [&_a:focus-visible]:[outline-color:var(--ring)] [&_a:focus-visible]:outline-offset-2", className), ...props }));
20
23
  }
21
24
  function FooterInner({ className, variant = "flat", ...props }) {
22
- return (_jsx("div", { "data-slot": "footer-inner", className: cn("mx-auto w-full max-w-[1200px]", variant === "mega" ? "grid gap-8" : "flex flex-wrap items-center justify-between gap-4", className), ...props }));
25
+ return (_jsx("div", { "data-slot": "footer-inner", className: cn("relative z-10 mx-auto w-full max-w-[1200px]", variant === "mega" ? "grid gap-8" : "flex flex-wrap items-center justify-between gap-4", className), ...props }));
23
26
  }
24
27
  function FooterBrand({ className, ...props }) {
25
28
  return (_jsx("a", { "data-slot": "footer-brand", className: cn("inline-flex items-center gap-2.5 text-sm font-semibold text-foreground [&_img]:block [&_img]:h-6 [&_img]:w-auto [&_svg]:block [&_svg]:h-6 [&_svg]:w-auto", className), ...props }));
26
29
  }
30
+ function FooterIdentity({ className, ...props }) {
31
+ return (_jsx("p", { "data-slot": "footer-identity", className: cn("nc-type-body-md m-0 max-w-[52ch] text-muted-foreground", className), ...props }));
32
+ }
27
33
  function FooterNav({ className, ...props }) {
28
- return (_jsx("nav", { "data-slot": "footer-nav", className: cn("flex flex-wrap gap-3 text-sm text-[var(--nc-body)] [&_a]:text-inherit [&_a:hover]:text-foreground", className), ...props }));
34
+ return (_jsx("nav", { "data-slot": "footer-nav", className: cn("flex flex-wrap gap-3 text-sm text-muted-foreground [&_a]:text-inherit [&_a:hover]:text-foreground", className), ...props }));
29
35
  }
30
36
  function FooterMeta({ className, ...props }) {
31
37
  return (_jsx("p", { "data-slot": "footer-meta", className: cn("m-0 text-sm text-muted-foreground", className), ...props }));
32
38
  }
39
+ function FooterClock({ className, ...props }) {
40
+ return (_jsx("span", { "data-slot": "footer-clock", className: cn("nc-type-caption-mono text-primary", className), ...props }));
41
+ }
42
+ function FooterGhost({ className, ...props }) {
43
+ return (_jsx("span", { "data-slot": "footer-ghost", "aria-hidden": "true", className: cn("pointer-events-none absolute inset-x-0 bottom-0 z-0 select-none overflow-hidden whitespace-nowrap text-[clamp(90px,14vw,210px)] font-semibold leading-[0.8] tracking-tight text-foreground/5", className), ...props }));
44
+ }
33
45
  /* ── mega variant slots ────────────────────────────────────────────────── */
34
46
  function FooterMegaTop({ className, ...props }) {
35
- return (_jsx("div", { "data-slot": "footer-mega-top", className: cn("grid grid-cols-1 items-start gap-8 sm:grid-cols-[minmax(0,220px)_minmax(0,1fr)] sm:gap-x-12", className), ...props }));
47
+ return (_jsx("div", { "data-slot": "footer-mega-top", className: cn("grid grid-cols-1 items-start gap-8 sm:grid-cols-[minmax(0,7fr)_minmax(0,5fr)] sm:gap-x-12", className), ...props }));
36
48
  }
37
49
  function FooterMegaCols({ className, ...props }) {
38
- return (_jsx("div", { "data-slot": "footer-mega-cols", className: cn("grid grid-cols-1 gap-6 sm:grid-cols-[repeat(auto-fit,minmax(140px,1fr))] sm:gap-x-8", className), ...props }));
50
+ return (_jsx("div", { "data-slot": "footer-mega-cols", className: cn("grid grid-cols-1 gap-6 sm:grid-cols-[repeat(auto-fit,minmax(140px,1fr))] sm:justify-end sm:gap-x-8", className), ...props }));
39
51
  }
40
52
  function FooterMegaCol({ className, ...props }) {
41
- return (_jsx("div", { "data-slot": "footer-mega-col", className: cn("grid content-start gap-2 [&_a]:text-sm [&_a]:text-[var(--nc-body)] [&_a:hover]:text-foreground", className), ...props }));
53
+ return (_jsx("div", { "data-slot": "footer-mega-col", className: cn("grid content-start gap-2 [&_a]:text-sm [&_a]:text-muted-foreground [&_a:hover]:text-foreground", className), ...props }));
42
54
  }
43
55
  function FooterMegaColTitle({ className, ...props }) {
44
- return (_jsx("p", { "data-slot": "footer-mega-col-title", className: cn("m-0 font-mono text-xs uppercase text-muted-foreground", className), ...props }));
56
+ return (_jsx("p", { "data-slot": "footer-mega-col-title", className: cn("nc-type-caption-mono m-0 uppercase text-muted-foreground", className), ...props }));
45
57
  }
46
58
  function FooterMegaMeta({ className, ...props }) {
47
59
  return (_jsx("div", { "data-slot": "footer-mega-meta", className: cn(
48
60
  // the single inner seam the mega variant adds: a top hairline, owned once.
49
- "flex flex-wrap items-center justify-between gap-x-6 gap-y-3 border-t border-border pt-6", className), ...props }));
61
+ "flex flex-wrap items-center justify-between gap-x-6 gap-y-3 border-t border-border pt-6 text-muted-foreground", className), ...props }));
50
62
  }
51
- export { Footer, FooterInner, FooterBrand, FooterNav, FooterMeta, FooterMegaTop, FooterMegaCols, FooterMegaCol, FooterMegaColTitle, FooterMegaMeta, };
63
+ export { Footer, FooterInner, FooterBrand, FooterIdentity, FooterNav, FooterMeta, FooterClock, FooterGhost, FooterMegaTop, FooterMegaCols, FooterMegaCol, FooterMegaColTitle, FooterMegaMeta, };