@astralform/ui 0.0.0-stage → 0.3.7-next.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 (140) hide show
  1. package/DESIGN.md +243 -0
  2. package/LICENSE +21 -0
  3. package/README.md +128 -2
  4. package/dist/components/Alert.d.ts +7 -0
  5. package/dist/components/Alert.js +40 -0
  6. package/dist/components/Alert.js.map +1 -0
  7. package/dist/components/AvatarEditor.d.ts +13 -0
  8. package/dist/components/AvatarEditor.js +44 -0
  9. package/dist/components/AvatarEditor.js.map +1 -0
  10. package/dist/components/Badge.d.ts +16 -0
  11. package/dist/components/Badge.js +38 -0
  12. package/dist/components/Badge.js.map +1 -0
  13. package/dist/components/Button.d.ts +8 -0
  14. package/dist/components/Button.js +21 -0
  15. package/dist/components/Button.js.map +1 -0
  16. package/dist/components/Card.d.ts +10 -0
  17. package/dist/components/Card.js +22 -0
  18. package/dist/components/Card.js.map +1 -0
  19. package/dist/components/CompactResourceRow.d.ts +34 -0
  20. package/dist/components/CompactResourceRow.js +11 -0
  21. package/dist/components/CompactResourceRow.js.map +1 -0
  22. package/dist/components/ConfirmDialog.d.ts +12 -0
  23. package/dist/components/ConfirmDialog.js +7 -0
  24. package/dist/components/ConfirmDialog.js.map +1 -0
  25. package/dist/components/CookieConsent.d.ts +1 -0
  26. package/dist/components/CookieConsent.js +42 -0
  27. package/dist/components/CookieConsent.js.map +1 -0
  28. package/dist/components/DataTable.d.ts +53 -0
  29. package/dist/components/DataTable.js +79 -0
  30. package/dist/components/DataTable.js.map +1 -0
  31. package/dist/components/DevTools.d.ts +6 -0
  32. package/dist/components/DevTools.js +59 -0
  33. package/dist/components/DevTools.js.map +1 -0
  34. package/dist/components/EmptyState.d.ts +11 -0
  35. package/dist/components/EmptyState.js +6 -0
  36. package/dist/components/EmptyState.js.map +1 -0
  37. package/dist/components/ImageCropModal.d.ts +18 -0
  38. package/dist/components/ImageCropModal.js +67 -0
  39. package/dist/components/ImageCropModal.js.map +1 -0
  40. package/dist/components/InlineBanner.d.ts +20 -0
  41. package/dist/components/InlineBanner.js +53 -0
  42. package/dist/components/InlineBanner.js.map +1 -0
  43. package/dist/components/Input.d.ts +8 -0
  44. package/dist/components/Input.js +10 -0
  45. package/dist/components/Input.js.map +1 -0
  46. package/dist/components/InventoryCard.d.ts +20 -0
  47. package/dist/components/InventoryCard.js +22 -0
  48. package/dist/components/InventoryCard.js.map +1 -0
  49. package/dist/components/LoadingSpinner.d.ts +26 -0
  50. package/dist/components/LoadingSpinner.js +32 -0
  51. package/dist/components/LoadingSpinner.js.map +1 -0
  52. package/dist/components/Modal.d.ts +10 -0
  53. package/dist/components/Modal.js +38 -0
  54. package/dist/components/Modal.js.map +1 -0
  55. package/dist/components/PageHeader.d.ts +11 -0
  56. package/dist/components/PageHeader.js +5 -0
  57. package/dist/components/PageHeader.js.map +1 -0
  58. package/dist/components/PreviewModal.d.ts +24 -0
  59. package/dist/components/PreviewModal.js +69 -0
  60. package/dist/components/PreviewModal.js.map +1 -0
  61. package/dist/components/ProgressBar.d.ts +8 -0
  62. package/dist/components/ProgressBar.js +12 -0
  63. package/dist/components/ProgressBar.js.map +1 -0
  64. package/dist/components/ProviderIcon.d.ts +7 -0
  65. package/dist/components/ProviderIcon.js +34 -0
  66. package/dist/components/ProviderIcon.js.map +1 -0
  67. package/dist/components/ResizeHandle.d.ts +56 -0
  68. package/dist/components/ResizeHandle.js +166 -0
  69. package/dist/components/ResizeHandle.js.map +1 -0
  70. package/dist/components/SegmentedProgressBar.d.ts +9 -0
  71. package/dist/components/SegmentedProgressBar.js +23 -0
  72. package/dist/components/SegmentedProgressBar.js.map +1 -0
  73. package/dist/components/Select.d.ts +13 -0
  74. package/dist/components/Select.js +14 -0
  75. package/dist/components/Select.js.map +1 -0
  76. package/dist/components/SpotlightButton.d.ts +10 -0
  77. package/dist/components/SpotlightButton.js +51 -0
  78. package/dist/components/SpotlightButton.js.map +1 -0
  79. package/dist/components/StatCard.d.ts +9 -0
  80. package/dist/components/StatCard.js +8 -0
  81. package/dist/components/StatCard.js.map +1 -0
  82. package/dist/components/StatusBadge.d.ts +4 -0
  83. package/dist/components/StatusBadge.js +10 -0
  84. package/dist/components/StatusBadge.js.map +1 -0
  85. package/dist/components/TabNav.d.ts +39 -0
  86. package/dist/components/TabNav.js +25 -0
  87. package/dist/components/TabNav.js.map +1 -0
  88. package/dist/components/TableShell.d.ts +21 -0
  89. package/dist/components/TableShell.js +19 -0
  90. package/dist/components/TableShell.js.map +1 -0
  91. package/dist/components/Textarea.d.ts +7 -0
  92. package/dist/components/Textarea.js +10 -0
  93. package/dist/components/Textarea.js.map +1 -0
  94. package/dist/components/Toggle.d.ts +16 -0
  95. package/dist/components/Toggle.js +25 -0
  96. package/dist/components/Toggle.js.map +1 -0
  97. package/dist/components/Toolbar.d.ts +34 -0
  98. package/dist/components/Toolbar.js +30 -0
  99. package/dist/components/Toolbar.js.map +1 -0
  100. package/dist/components/TypeToConfirmModal.d.ts +15 -0
  101. package/dist/components/TypeToConfirmModal.js +14 -0
  102. package/dist/components/TypeToConfirmModal.js.map +1 -0
  103. package/dist/components/UnsavedChangesModal.d.ts +7 -0
  104. package/dist/components/UnsavedChangesModal.js +7 -0
  105. package/dist/components/UnsavedChangesModal.js.map +1 -0
  106. package/dist/components/UsageCard.d.ts +11 -0
  107. package/dist/components/UsageCard.js +9 -0
  108. package/dist/components/UsageCard.js.map +1 -0
  109. package/dist/components/avatar.d.ts +79 -0
  110. package/dist/components/avatar.js +88 -0
  111. package/dist/components/avatar.js.map +1 -0
  112. package/dist/components/badge-config.d.ts +16 -0
  113. package/dist/components/badge-config.js +48 -0
  114. package/dist/components/badge-config.js.map +1 -0
  115. package/dist/components/glowing-effect.d.ts +14 -0
  116. package/dist/components/glowing-effect.js +108 -0
  117. package/dist/components/glowing-effect.js.map +1 -0
  118. package/dist/index.d.ts +39 -0
  119. package/dist/index.js +42 -0
  120. package/dist/index.js.map +1 -0
  121. package/dist/lib/cookies.d.ts +36 -0
  122. package/dist/lib/cookies.js +78 -0
  123. package/dist/lib/cookies.js.map +1 -0
  124. package/dist/lib/environment.d.ts +24 -0
  125. package/dist/lib/environment.js +52 -0
  126. package/dist/lib/environment.js.map +1 -0
  127. package/dist/lib/utils.d.ts +4 -0
  128. package/dist/lib/utils.js +8 -0
  129. package/dist/lib/utils.js.map +1 -0
  130. package/dist/types.d.ts +12 -0
  131. package/dist/types.js +12 -0
  132. package/dist/types.js.map +1 -0
  133. package/package.json +89 -4
  134. package/src/styles/base.css +779 -0
  135. package/src/styles/fonts.css +25 -0
  136. package/src/styles/theme-default.css +164 -0
  137. package/src/styles/theme-default.generated.css +79 -0
  138. package/src/styles/tokens/_foundations.css +28 -0
  139. package/src/styles/tokens/_semantics.css +72 -0
  140. package/themes/chat.DESIGN.md +197 -0
@@ -0,0 +1,25 @@
1
+ /* ==============================================
2
+ Self-hosted brand fonts — Outfit + Plus Jakarta Sans
3
+ ==============================================
4
+
5
+ Import this INSTEAD of the Google Fonts CDN `@import`. Font files are
6
+ bundled from the @fontsource packages (deps of this package), so there's
7
+ no third-party request, no render-blocking CDN round-trip, and no CSP
8
+ allowance for fonts.googleapis.com / fonts.gstatic.com.
9
+
10
+ Usage (consumer index.css):
11
+ @import "@astralform/ui/styles/fonts.css";
12
+ ============================================== */
13
+
14
+ /* Outfit — headings (--font-heading). Weights 400–800. */
15
+ @import "@fontsource/outfit/400.css";
16
+ @import "@fontsource/outfit/500.css";
17
+ @import "@fontsource/outfit/600.css";
18
+ @import "@fontsource/outfit/700.css";
19
+ @import "@fontsource/outfit/800.css";
20
+
21
+ /* Plus Jakarta Sans — body (--font-body). Weights 400–700. */
22
+ @import "@fontsource/plus-jakarta-sans/400.css";
23
+ @import "@fontsource/plus-jakarta-sans/500.css";
24
+ @import "@fontsource/plus-jakarta-sans/600.css";
25
+ @import "@fontsource/plus-jakarta-sans/700.css";
@@ -0,0 +1,164 @@
1
+ /* ==============================================
2
+ Theme: Astralform Dashboard (default) — orange on near-black
3
+ ==============================================
4
+
5
+ The BRAND layer. Everything here is product-specific: font families,
6
+ the color source scales, and the @theme inline color mappings that
7
+ Tailwind turns into utilities (bg-accent, text-text-primary, ...).
8
+
9
+ This file is the canonical hand-authored artifact for the dashboard
10
+ brand and the reference output of `npm run design:gen` (which derives
11
+ the same values from DESIGN.md). To re-skin a product, ship a sibling
12
+ theme file (see themes/chat.DESIGN.md → theme-chat.css) instead of
13
+ editing components.
14
+
15
+ Pairs with styles/base.css (brand-agnostic structure + utilities).
16
+ ============================================== */
17
+
18
+ :root {
19
+ /* ---- Font Families ---- */
20
+ --font-heading: 'Outfit', system-ui, sans-serif;
21
+ --font-body: 'Plus Jakarta Sans', system-ui, sans-serif;
22
+
23
+ /* ---- Color Source Scales (7-tier) ----
24
+ hover → lightest (hover text) bold → filled controls
25
+ default → primary (text/icons) dim → borders
26
+ muted → focus rings / dots subtle → badge/alert bg
27
+ surface → deep bg panels */
28
+
29
+ /* Accent (orange) */
30
+ --_accent-hover: #fdba74; /* orange-300 */
31
+ --_accent: #fb923c; /* orange-400 */
32
+ --_accent-muted: #f97316; /* orange-500 */
33
+ --_accent-bold: #ea580c; /* orange-600 */
34
+ --_accent-dim: #c2410c; /* orange-700 */
35
+ --_accent-subtle: #7c2d12; /* orange-900 */
36
+ --_accent-surface: #431407; /* orange-950 */
37
+
38
+ /* Success (emerald) */
39
+ --_success-hover: #6ee7b7;
40
+ --_success: #34d399;
41
+ --_success-muted: #10b981;
42
+ --_success-bold: #059669;
43
+ --_success-dim: #047857;
44
+ --_success-subtle: #064e3b;
45
+ --_success-surface: #022c22;
46
+
47
+ /* Warning (amber) */
48
+ --_warning-hover: #fcd34d;
49
+ --_warning: #fbbf24;
50
+ --_warning-muted: #f59e0b;
51
+ --_warning-bold: #d97706;
52
+ --_warning-dim: #b45309;
53
+ --_warning-subtle: #78350f;
54
+ --_warning-surface: #451a03;
55
+
56
+ /* Danger (red) */
57
+ --_danger-hover: #fca5a5;
58
+ --_danger: #f87171;
59
+ --_danger-muted: #ef4444;
60
+ --_danger-bold: #dc2626;
61
+ --_danger-dim: #b91c1c;
62
+ --_danger-subtle: #7f1d1d;
63
+ --_danger-surface: #450a0a;
64
+
65
+ /* Info (blue) */
66
+ --_info-hover: #93c5fd;
67
+ --_info: #60a5fa;
68
+ --_info-muted: #3b82f6;
69
+ --_info-bold: #2563eb;
70
+ --_info-dim: #1d4ed8;
71
+ --_info-subtle: #1e3a5f;
72
+ --_info-surface: #0c1929;
73
+
74
+ /* Sonner toast colors */
75
+ --_toast-success-bg: #052e16;
76
+ --_toast-success-border: #14532d;
77
+ --_toast-success-text: #bbf7d0;
78
+ --_toast-error-bg: var(--_danger-surface);
79
+ --_toast-error-border: var(--_danger-subtle);
80
+ --_toast-error-text: #fecaca;
81
+ --_toast-warning-bg: #291800;
82
+ --_toast-warning-border: var(--_warning-subtle);
83
+ --_toast-warning-text: #fde68a;
84
+ --_toast-info-bg: var(--_info-surface);
85
+ --_toast-info-border: var(--_info-subtle);
86
+ --_toast-info-text: #bfdbfe;
87
+ }
88
+
89
+ @theme inline {
90
+ /* Surfaces */
91
+ --color-surface-base: #000000;
92
+ --color-surface-primary: #09090b;
93
+ --color-surface-secondary: #18181b;
94
+ --color-surface-tertiary: #27272a;
95
+ --color-surface-inset: #3f3f46;
96
+ --color-surface-overlay: rgba(0, 0, 0, 0.8);
97
+
98
+ /* Borders */
99
+ --color-border-primary: #27272a;
100
+ --color-border-secondary: #3f3f46;
101
+ --color-border-focus: #52525b;
102
+
103
+ /* Text */
104
+ --color-text-primary: #ffffff;
105
+ --color-text-secondary: #d4d4d8;
106
+ --color-text-tertiary: #a1a1aa;
107
+ --color-text-muted: #71717a;
108
+ --color-text-disabled: #52525b;
109
+ --color-text-inverse: #000000;
110
+
111
+ /* Status */
112
+ --color-status-error: #f87171;
113
+
114
+ /* Buttons */
115
+ --color-btn-primary-bg: #ffffff;
116
+ --color-btn-primary-hover: #f4f4f5;
117
+ --color-btn-danger-bg: #dc2626;
118
+ --color-btn-danger-hover: #b91c1c;
119
+
120
+ /* Accent scale → source vars */
121
+ --color-accent-hover: var(--_accent-hover);
122
+ --color-accent: var(--_accent);
123
+ --color-accent-muted: var(--_accent-muted);
124
+ --color-accent-bold: var(--_accent-bold);
125
+ --color-accent-dim: var(--_accent-dim);
126
+ --color-accent-subtle: var(--_accent-subtle);
127
+ --color-accent-surface: var(--_accent-surface);
128
+
129
+ /* Success scale */
130
+ --color-success-hover: var(--_success-hover);
131
+ --color-success: var(--_success);
132
+ --color-success-muted: var(--_success-muted);
133
+ --color-success-bold: var(--_success-bold);
134
+ --color-success-dim: var(--_success-dim);
135
+ --color-success-subtle: var(--_success-subtle);
136
+ --color-success-surface: var(--_success-surface);
137
+
138
+ /* Warning scale */
139
+ --color-warning-hover: var(--_warning-hover);
140
+ --color-warning: var(--_warning);
141
+ --color-warning-muted: var(--_warning-muted);
142
+ --color-warning-bold: var(--_warning-bold);
143
+ --color-warning-dim: var(--_warning-dim);
144
+ --color-warning-subtle: var(--_warning-subtle);
145
+ --color-warning-surface: var(--_warning-surface);
146
+
147
+ /* Danger scale */
148
+ --color-danger-hover: var(--_danger-hover);
149
+ --color-danger: var(--_danger);
150
+ --color-danger-muted: var(--_danger-muted);
151
+ --color-danger-bold: var(--_danger-bold);
152
+ --color-danger-dim: var(--_danger-dim);
153
+ --color-danger-subtle: var(--_danger-subtle);
154
+ --color-danger-surface: var(--_danger-surface);
155
+
156
+ /* Info scale */
157
+ --color-info-hover: var(--_info-hover);
158
+ --color-info: var(--_info);
159
+ --color-info-muted: var(--_info-muted);
160
+ --color-info-bold: var(--_info-bold);
161
+ --color-info-dim: var(--_info-dim);
162
+ --color-info-subtle: var(--_info-subtle);
163
+ --color-info-surface: var(--_info-surface);
164
+ }
@@ -0,0 +1,79 @@
1
+ /* AUTO-GENERATED from DESIGN.md via `npm run design:gen`.
2
+ Reference only — the hand-authored theme-default.css is the shipped artifact. */
3
+
4
+ @theme {
5
+ --color-primary: #fb923c;
6
+ --color-accent-hover: #fdba74;
7
+ --color-accent: #fb923c;
8
+ --color-accent-muted: #f97316;
9
+ --color-accent-bold: #ea580c;
10
+ --color-accent-dim: #c2410c;
11
+ --color-accent-subtle: #7c2d12;
12
+ --color-accent-surface: #431407;
13
+ --color-surface-base: #000000;
14
+ --color-surface-primary: #09090b;
15
+ --color-surface-secondary: #18181b;
16
+ --color-surface-tertiary: #27272a;
17
+ --color-surface-inset: #3f3f46;
18
+ --color-border-primary: #27272a;
19
+ --color-border-secondary: #3f3f46;
20
+ --color-border-focus: #52525b;
21
+ --color-text-primary: #ffffff;
22
+ --color-text-secondary: #d4d4d8;
23
+ --color-text-tertiary: #a1a1aa;
24
+ --color-text-muted: #71717a;
25
+ --color-text-disabled: #52525b;
26
+ --color-text-inverse: #000000;
27
+ --color-btn-primary-bg: #ffffff;
28
+ --color-btn-primary-hover: #f4f4f5;
29
+ --color-btn-danger-bg: #dc2626;
30
+ --color-btn-danger-hover: #b91c1c;
31
+ --color-success: #34d399;
32
+ --color-success-subtle: #064e3b;
33
+ --color-success-dim: #047857;
34
+ --color-warning: #fbbf24;
35
+ --color-warning-subtle: #78350f;
36
+ --color-warning-dim: #b45309;
37
+ --color-danger: #f87171;
38
+ --color-danger-subtle: #7f1d1d;
39
+ --color-danger-dim: #b91c1c;
40
+ --color-info: #60a5fa;
41
+ --color-info-subtle: #1e3a5f;
42
+ --color-info-dim: #1d4ed8;
43
+ --font-page-title: "Outfit";
44
+ --font-section-heading: "Outfit";
45
+ --font-card-title: "Outfit";
46
+ --font-body: "Plus Jakarta Sans";
47
+ --font-label: "Plus Jakarta Sans";
48
+ --font-caption: "Plus Jakarta Sans";
49
+ --font-overline: "Plus Jakarta Sans";
50
+ --text-page-title: 24px;
51
+ --text-section-heading: 18px;
52
+ --text-card-title: 18px;
53
+ --text-body: 14px;
54
+ --text-label: 14px;
55
+ --text-caption: 12px;
56
+ --text-overline: 12px;
57
+ --tracking-card-title: -0.025em;
58
+ --tracking-overline: 0.05em;
59
+ --font-weight-page-title: 700;
60
+ --font-weight-section-heading: 600;
61
+ --font-weight-card-title: 600;
62
+ --font-weight-body: 400;
63
+ --font-weight-label: 500;
64
+ --font-weight-caption: 400;
65
+ --font-weight-overline: 600;
66
+ --radius-input: 8px;
67
+ --radius-button: 8px;
68
+ --radius-alert: 8px;
69
+ --radius-modal: 12px;
70
+ --radius-card: 20px;
71
+ --radius-badge: 9999px;
72
+ --spacing-xs: 4px;
73
+ --spacing-sm: 8px;
74
+ --spacing-md: 16px;
75
+ --spacing-lg: 24px;
76
+ --spacing-xl: 32px;
77
+ --spacing-xxl: 48px;
78
+ }
79
+
@@ -0,0 +1,28 @@
1
+ /* ==============================================
2
+ Layer 1: Foundation Primitives — brand-agnostic
3
+ ==============================================
4
+
5
+ Raw, non-color primitive scales shared by every Astralform
6
+ product regardless of brand. Color primitives and font families
7
+ are brand-specific and live in the active theme file
8
+ (e.g. theme-default.css), NOT here.
9
+
10
+ Never reference these directly in components — use the semantic
11
+ tokens (_semantics.css) or Tailwind utilities instead.
12
+ ============================================== */
13
+
14
+ :root {
15
+ /* ---- Durations ---- */
16
+ --duration-fast: 100ms;
17
+ --duration-normal: 200ms;
18
+ --duration-moderate: 300ms;
19
+ --duration-slow: 500ms;
20
+
21
+ /* ---- Easings ---- */
22
+ --ease-out: cubic-bezier(0, 0, 0.2, 1);
23
+ --ease-in: cubic-bezier(0.4, 0, 1, 1);
24
+ --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
25
+ --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
26
+ --ease-out-back: cubic-bezier(0.34, 1.56, 0.64, 1);
27
+ --ease-in-out-circ: cubic-bezier(0.85, 0, 0.15, 1);
28
+ }
@@ -0,0 +1,72 @@
1
+ /* ==============================================
2
+ Layer 2: Semantic Structure Tokens — brand-agnostic
3
+ ==============================================
4
+
5
+ Purpose-mapped aliases for STRUCTURE (shadows, motion, focus,
6
+ typography rhythm). These describe HOW the system behaves, not
7
+ WHICH brand colors it uses — so they are shared across products.
8
+
9
+ Typography roles reference --font-heading / --font-body, which are
10
+ supplied by the active theme file. Colors referenced here resolve
11
+ at runtime from the theme.
12
+ ============================================== */
13
+
14
+ :root {
15
+ /* ---- Component Shadows (built on Tailwind v4's --shadow-* scale) ---- */
16
+ --shadow-card: var(--shadow-sm);
17
+ --shadow-modal: var(--shadow-xl);
18
+ --shadow-dropdown: var(--shadow-lg);
19
+ --shadow-input: var(--shadow-xs);
20
+ --shadow-button-hover: var(--shadow-md);
21
+
22
+ /* ---- Motion Roles ---- */
23
+ --duration-hover: var(--duration-normal); /* 200ms */
24
+ --duration-enter: var(--duration-moderate); /* 300ms */
25
+
26
+ /* ---- Focus Ring ---- */
27
+ --focus-ring-width: 2px;
28
+ --focus-ring-color: rgba(255, 255, 255, 0.3);
29
+ --focus-ring-offset: 2px;
30
+
31
+ /* ---- Typography Roles ---- */
32
+
33
+ /* Page Title (h1) */
34
+ --type-page-title-size: 1.5rem; /* 24px */
35
+ --type-page-title-weight: 700;
36
+ --type-page-title-leading: 1.25;
37
+ --type-page-title-family: var(--font-heading);
38
+
39
+ /* Section Heading */
40
+ --type-section-heading-size: 1.125rem; /* 18px */
41
+ --type-section-heading-weight: 600;
42
+ --type-section-heading-leading: 1.25;
43
+ --type-section-heading-family: var(--font-heading);
44
+
45
+ /* Card Title */
46
+ --type-card-title-size: 1.125rem; /* 18px */
47
+ --type-card-title-weight: 600;
48
+ --type-card-title-leading: 1;
49
+ --type-card-title-tracking: -0.025em;
50
+ --type-card-title-family: var(--font-heading);
51
+
52
+ /* Body */
53
+ --type-body-size: 0.875rem; /* 14px */
54
+ --type-body-weight: 400;
55
+ --type-body-leading: 1.5;
56
+
57
+ /* Label */
58
+ --type-label-size: 0.875rem; /* 14px */
59
+ --type-label-weight: 500;
60
+ --type-label-leading: 1.5;
61
+
62
+ /* Caption */
63
+ --type-caption-size: 0.75rem; /* 12px */
64
+ --type-caption-weight: 400;
65
+ --type-caption-leading: 1.5;
66
+
67
+ /* Overline */
68
+ --type-overline-size: 0.75rem; /* 12px */
69
+ --type-overline-weight: 600;
70
+ --type-overline-tracking: 0.05em;
71
+ --type-overline-transform: uppercase;
72
+ }
@@ -0,0 +1,197 @@
1
+ ---
2
+ version: alpha
3
+ name: AstralChat
4
+ description: Conversational, focused chat surface — indigo accent on a warm-dark base. Same token contract as the dashboard, a different brand.
5
+
6
+ colors:
7
+ # ---- Brand accent (indigo) ----
8
+ primary: "#818cf8"
9
+ accent-hover: "#a5b4fc"
10
+ accent: "#818cf8"
11
+ accent-muted: "#6366f1"
12
+ accent-bold: "#4f46e5"
13
+ accent-dim: "#4338ca"
14
+ accent-subtle: "#3730a3"
15
+ accent-surface: "#1e1b4b"
16
+
17
+ # ---- Surfaces (warm-dark brand base) ----
18
+ surface-base: "#272737"
19
+ surface-primary: "#18181b"
20
+ surface-secondary: "#27272a"
21
+ surface-tertiary: "#3f3f46"
22
+ surface-inset: "#52525b"
23
+
24
+ # ---- Borders ----
25
+ border-primary: "#27272a"
26
+ border-secondary: "#3f3f46"
27
+ border-focus: "#52525b"
28
+
29
+ # ---- Text ----
30
+ text-primary: "#fafafa"
31
+ text-secondary: "#d4d4d8"
32
+ text-tertiary: "#a1a1aa"
33
+ text-muted: "#71717a"
34
+ text-disabled: "#52525b"
35
+ text-inverse: "#09090b"
36
+
37
+ # ---- Buttons ----
38
+ btn-primary-bg: "#fafafa"
39
+ btn-primary-hover: "#e4e4e7"
40
+ btn-danger-bg: "#dc2626"
41
+ btn-danger-hover: "#b91c1c"
42
+
43
+ # ---- Status (semantic — sky-tinted info to match chat) ----
44
+ success: "#34d399"
45
+ success-subtle: "#064e3b"
46
+ success-dim: "#065f46"
47
+ warning: "#fbbf24"
48
+ warning-subtle: "#78350f"
49
+ warning-dim: "#92400e"
50
+ danger: "#f87171"
51
+ danger-subtle: "#7f1d1d"
52
+ danger-dim: "#991b1b"
53
+ info: "#38bdf8"
54
+ info-subtle: "#0c4a6e"
55
+ info-dim: "#0369a1"
56
+
57
+ typography:
58
+ page-title:
59
+ fontFamily: Outfit
60
+ fontSize: 24px
61
+ fontWeight: 700
62
+ lineHeight: 1.25
63
+ section-heading:
64
+ fontFamily: Outfit
65
+ fontSize: 18px
66
+ fontWeight: 600
67
+ lineHeight: 1.25
68
+ card-title:
69
+ fontFamily: Outfit
70
+ fontSize: 18px
71
+ fontWeight: 600
72
+ lineHeight: 1
73
+ letterSpacing: -0.025em
74
+ body:
75
+ fontFamily: Plus Jakarta Sans
76
+ fontSize: 14px
77
+ fontWeight: 400
78
+ lineHeight: 1.5
79
+ label:
80
+ fontFamily: Plus Jakarta Sans
81
+ fontSize: 14px
82
+ fontWeight: 500
83
+ lineHeight: 1.5
84
+ caption:
85
+ fontFamily: Plus Jakarta Sans
86
+ fontSize: 12px
87
+ fontWeight: 400
88
+ lineHeight: 1.5
89
+ overline:
90
+ fontFamily: Plus Jakarta Sans
91
+ fontSize: 12px
92
+ fontWeight: 600
93
+ letterSpacing: 0.05em
94
+
95
+ spacing:
96
+ xs: 4px
97
+ sm: 8px
98
+ md: 16px
99
+ lg: 24px
100
+ xl: 32px
101
+ xxl: 48px
102
+
103
+ rounded:
104
+ input: 8px
105
+ button: 8px
106
+ alert: 8px
107
+ modal: 12px
108
+ card: 20px
109
+ badge: 9999px
110
+
111
+ components:
112
+ button-primary:
113
+ backgroundColor: "{colors.btn-primary-bg}"
114
+ textColor: "{colors.text-inverse}"
115
+ rounded: "{rounded.button}"
116
+ button-danger:
117
+ backgroundColor: "{colors.btn-danger-bg}"
118
+ textColor: "{colors.text-primary}"
119
+ rounded: "{rounded.button}"
120
+ card:
121
+ backgroundColor: "{colors.surface-primary}"
122
+ rounded: "{rounded.card}"
123
+ badge-accent:
124
+ backgroundColor: "{colors.accent-subtle}"
125
+ textColor: "{colors.accent-hover}"
126
+ rounded: "{rounded.badge}"
127
+ input:
128
+ backgroundColor: "{colors.surface-secondary}"
129
+ textColor: "{colors.text-primary}"
130
+ rounded: "{rounded.input}"
131
+ ---
132
+
133
+ ## Overview
134
+
135
+ AstralChat is the **conversational front door** to Astralform. It shares the dashboard's
136
+ structure, rhythm, and component set, but wears a **different brand**: a cooler **indigo
137
+ accent** on a **warm-dark base** (`#272737`) rather than the dashboard's pure black. The
138
+ feel is approachable and focused — a place to talk to an agent, not a control panel.
139
+
140
+ This file exists to prove the contract: it changes **only token values**. The same
141
+ `@astralform/ui` components, the same `base.css` structure, render as AstralChat purely
142
+ because this DESIGN.md swaps the palette. No component is forked.
143
+
144
+ ## Colors
145
+
146
+ Indigo replaces orange as the single system tint — links, the send affordance, active
147
+ threads, focus rings. The surface stack starts from a warm near-black (`#272737`) so the
148
+ chat canvas feels softer than the dashboard's instrument-black, then steps up through the
149
+ same zinc greys for bubbles, inputs, and insets.
150
+
151
+ Status hues stay semantic and largely shared (emerald / amber / red), with **info shifted
152
+ to sky** (`#38bdf8`) to sit comfortably beside the indigo accent rather than competing
153
+ with it.
154
+
155
+ ## Typography
156
+
157
+ Identical role system to the dashboard — **Outfit** for titles, **Plus Jakarta Sans** for
158
+ body — because legibility and hierarchy are product-wide concerns, not brand ones. A
159
+ shared type scale keeps a message, a card title, and a label reading the same in both
160
+ products.
161
+
162
+ ## Layout
163
+
164
+ A **conversation-centric** layout: a thread list rail, a message canvas, and a composer
165
+ docked at the bottom. It reuses the dashboard's `page-content` padding rhythm and 4px
166
+ spacing scale so shared components (cards, inputs, badges) drop in without bespoke gutters.
167
+
168
+ ## Elevation & Depth
169
+
170
+ **Flat-first**, like the dashboard. Message bubbles and cards separate via the surface
171
+ scale rather than shadows; the composer and any popovers float with the role-named
172
+ `shadow-dropdown` / `shadow-modal` only when they must sit above the canvas.
173
+
174
+ ## Shapes
175
+
176
+ The same radius progression (input/button 8px → modal 12px → card 20px → badge pill).
177
+ Chat bubbles inherit the card-scale softness, reinforcing that a message is a unit of
178
+ grouping in the same way a card is on the dashboard.
179
+
180
+ ## Components
181
+
182
+ Every atom is the shared `@astralform/ui` component, unchanged. The **accent-driven**
183
+ pieces — toggles, the active-thread highlight, focus rings, primary affordances — simply
184
+ resolve indigo here instead of orange. Badges keep their semantic status colors exactly
185
+ as on the dashboard.
186
+
187
+ ## Do's and Don'ts
188
+
189
+ **Do**
190
+ - Keep indigo as the single interactive tint; let the warm base carry the calm.
191
+ - Reuse the shared components and `base.css` verbatim — brand lives only in this file.
192
+ - Keep status colors semantic and consistent with the dashboard.
193
+
194
+ **Don't**
195
+ - Don't fork a component to "make it chat-flavored" — change a token here instead.
196
+ - Don't reintroduce pure black surfaces; the warm `#272737` base is part of the brand.
197
+ - Don't let info-sky and accent-indigo blur together — keep info for genuine information.