anentrypoint-design 0.0.413 → 0.0.415

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 (103) hide show
  1. package/dist/247420.js +63 -13
  2. package/dist/app-shell.css +40 -594
  3. package/dist/colors_and_type.css +607 -47
  4. package/dist/index.html +227 -277
  5. package/dist/preview/buttons.html +39 -28
  6. package/dist/preview/colors-core.html +18 -8
  7. package/dist/preview/colors-lore.html +26 -17
  8. package/dist/preview/colors-semantic.html +24 -18
  9. package/dist/preview/dateline.html +6 -5
  10. package/dist/preview/dropzone.html +4 -3
  11. package/dist/preview/file-grid.html +10 -9
  12. package/dist/preview/file-row.html +14 -13
  13. package/dist/preview/file-toolbar.html +4 -3
  14. package/dist/preview/file-viewer.html +4 -3
  15. package/dist/preview/header.html +26 -24
  16. package/dist/preview/icons-unicode.html +8 -5
  17. package/dist/preview/index-row.html +17 -9
  18. package/dist/preview/inputs.html +4 -3
  19. package/dist/preview/manifesto.html +34 -17
  20. package/dist/preview/motion-default.js +77 -57
  21. package/dist/preview/rules.html +4 -3
  22. package/dist/preview/spacing.html +13 -12
  23. package/dist/preview/stamps-lore.html +5 -4
  24. package/dist/preview/stamps.html +4 -3
  25. package/dist/preview/theme-ink.html +7 -6
  26. package/dist/preview/type-display.html +14 -5
  27. package/dist/preview/type-mono.html +6 -5
  28. package/dist/preview/type-prose.html +12 -10
  29. package/dist/preview/type-scale.html +4 -3
  30. package/dist/preview/wordmarks.html +10 -7
  31. package/dist/site/content/globals/site.yaml +5 -3
  32. package/dist/site/content/pages/freddie.yaml +2 -2
  33. package/dist/site/content/pages/home.yaml +55 -55
  34. package/dist/site/theme.mjs +96 -348
  35. package/dist/slides/index.html +13 -13
  36. package/dist/src/bootstrap.js +10 -1
  37. package/dist/src/components/chat.js +43 -195
  38. package/dist/src/components/community.js +18 -166
  39. package/dist/src/components/content.js +30 -210
  40. package/dist/src/components/files-modals.js +14 -106
  41. package/dist/src/components/files.js +15 -116
  42. package/dist/src/components/freddie/helpers.js +53 -8
  43. package/dist/src/components/freddie.js +35 -25
  44. package/dist/src/components/shell.js +16 -114
  45. package/dist/src/components/theme-toggle.js +69 -25
  46. package/dist/src/components.js +92 -13
  47. package/dist/src/deck-stage.js +6 -4
  48. package/dist/src/highlight.js +51 -7
  49. package/dist/src/index.js +58 -12
  50. package/dist/src/kits/os/about-app.js +2 -3
  51. package/dist/src/kits/os/app-panes.css +46 -70
  52. package/dist/src/kits/os/browser-app.js +28 -1
  53. package/dist/src/kits/os/files-app.js +7 -0
  54. package/dist/src/kits/os/freddie/pages-chat.js +90 -75
  55. package/dist/src/kits/os/freddie/pages-core.js +9 -9
  56. package/dist/src/kits/os/freddie/pages-os.js +8 -8
  57. package/dist/src/kits/os/freddie/pages-tools.js +14 -14
  58. package/dist/src/kits/os/freddie/routes.js +21 -19
  59. package/dist/src/kits/os/freddie-dashboard.css +42 -21
  60. package/dist/src/kits/os/freddie-dashboard.js +6 -6
  61. package/dist/src/kits/os/icons.js +38 -16
  62. package/dist/src/kits/os/index.js +11 -0
  63. package/dist/src/kits/os/launcher.css +26 -10
  64. package/dist/src/kits/os/launcher.js +3 -0
  65. package/dist/src/kits/os/shell.js +72 -108
  66. package/dist/src/kits/os/terminal-app.js +1 -1
  67. package/dist/src/kits/os/theme.css +1330 -150
  68. package/dist/src/kits/os/wm.css +68 -15
  69. package/dist/src/kits/os/wm.js +93 -17
  70. package/dist/src/markdown.js +121 -12
  71. package/dist/src/motion.js +18 -2
  72. package/dist/src/page-html.js +62 -134
  73. package/dist/src/theme.js +106 -13
  74. package/dist/src/web-components/ds-chat.js +80 -9
  75. package/dist/ui_kits/aicat/app.js +54 -6
  76. package/dist/ui_kits/aicat/index.html +2 -0
  77. package/dist/ui_kits/blog/index.html +33 -17
  78. package/dist/ui_kits/chat/app.js +90 -22
  79. package/dist/ui_kits/chat/index.html +2 -0
  80. package/dist/ui_kits/community/app.js +86 -24
  81. package/dist/ui_kits/community/index.html +1 -0
  82. package/dist/ui_kits/dashboard/app.js +123 -34
  83. package/dist/ui_kits/dashboard/index.html +1 -0
  84. package/dist/ui_kits/docs/index.html +43 -33
  85. package/dist/ui_kits/error_404/app.js +78 -23
  86. package/dist/ui_kits/file_browser/README.md +1 -1
  87. package/dist/ui_kits/file_browser/app.js +45 -10
  88. package/dist/ui_kits/file_browser/index.html +1 -0
  89. package/dist/ui_kits/gallery/app.js +130 -51
  90. package/dist/ui_kits/homepage/app.js +156 -138
  91. package/dist/ui_kits/project_page/app.js +142 -125
  92. package/dist/ui_kits/project_page/index.html +2 -1
  93. package/dist/ui_kits/search/app.js +52 -15
  94. package/dist/ui_kits/settings/app.js +166 -39
  95. package/dist/ui_kits/signin/app.js +175 -49
  96. package/dist/ui_kits/signin/index.html +1 -0
  97. package/dist/ui_kits/slide_deck/app.js +83 -49
  98. package/dist/ui_kits/system_primer/app.js +57 -40
  99. package/dist/ui_kits/terminal/app.js +160 -43
  100. package/package.json +1 -1
  101. package/src/page-html/client-script.js +40 -11
  102. package/src/page-html/page-styles.js +22 -1
  103. package/src/page-html.js +10 -0
@@ -1,38 +1,90 @@
1
1
  /* ============================================================
2
2
  247420 design system — colors + type
3
- Calm, readable, scope-prefixed at build time.
3
+ "Acid Editorial": confident display type, ink-on-paper with one
4
+ electric lead, print texture over glow. Scope-prefixed at build time.
4
5
  Source-of-truth tokens. Component sheet lives in app-shell.css.
5
6
  ============================================================ */
6
7
 
7
- @import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,400;0,500;0,600;0,700;1,400;1,700&family=Space+Grotesk:wght@300;400;500;600;700&display=swap');
8
+ /* System-font stack only — no web-font @import/@font-face. Every --ff-*
9
+ token below is the same fallback chain that used to sit after the custom
10
+ family names; removing the custom names just exposes it directly. */
8
11
 
9
12
  :root {
10
- /* Paper / Ink cool stone scale; lets lore palette pop. */
11
- --paper: #F6F5F1;
12
- --paper-2: #ECEBE6;
13
- --paper-3: #DFDED9;
14
- --ink: #131318;
15
- --ink-2: #25252C;
16
- --ink-3: #6A6A70;
17
-
18
- /* Lore palette */
13
+ /* Tree view indentation tokens */
14
+ --tree-indent: 12px;
15
+ --tree-base-indent: 6px;
16
+
17
+ /* Paper / Ink — warm newsprint paper against near-black ink. The warmer
18
+ paper + deeper ink widen the tonal range so the electric lead reads as
19
+ printed, not glowing. */
20
+ --paper: #F4F1E9;
21
+ --paper-2: #EAE6DA;
22
+ --paper-3: #DCD7C7;
23
+ --ink: #0E0E12;
24
+ --ink-2: #1F1F26;
25
+ --ink-3: #52525A; /* WCAG AAA on --paper (~7.1:1) */
26
+ --ink-3-dark: #464650; /* dark theme bg-3 (tier-3 surface) */
27
+ --paper-3-dark: #B4B4BC; /* dark theme fg-3 (tier-3 text) */
28
+
29
+ /* Lore palette. --acid is the electric lead — a printed-ink lime that sits
30
+ forward of the heritage green; green/purple/mascot demote to print-ink
31
+ category roles. */
32
+ --acid: #B6FF1B;
33
+ --acid-deep: #4E4200; /* AA text tone of the lead on paper (WCAG-verified: #4E7A00 measured 4.21:1 against --accent-tint's own color-mix() output, which derives FROM --acid-deep -- so a small darkening shifts both foreground and background together and converges too slowly; #4E4200 is the minimal shade that actually clears 4.5:1 against its own self-referential tint background) */
19
34
  --green: #247420;
20
35
  --green-2: #3A9A34;
21
36
  --green-deep: #133F10;
22
- --green-tint: #D9E5C8;
23
- --purple: #420247;
37
+ --green-tint: #D7E4C2;
38
+ --purple: #3A0140;
24
39
  --purple-2: #7F18A4;
25
- --purple-deep: #28002B;
26
- --purple-tint: #E4D3E5;
27
- --mascot: #E84B8A;
40
+ --purple-deep: #220026;
41
+ --purple-tint: #E2CFE4;
42
+ --mascot: #FF2E84;
28
43
  --mascot-2: #FF3CA7;
29
- --mascot-tint: #F5D2DF;
44
+ --mascot-tint: #F7CEDD;
45
+ --mascot-deep: #B81F63;
46
+ /* Fixed ink-surface mascot text tone (6.67:1 on --ink). Unlike
47
+ --mascot-deep, this NEVER follows the theme: it is for always-dark
48
+ surfaces like the .cli card, which stay ink under a light theme and so
49
+ need a tone chosen for ink rather than for the active theme. Same role
50
+ --paper-3-dark plays for the tier-3 text ramp. */
51
+ --mascot-on-ink: #FF5C9E;
30
52
 
31
53
  /* Signals */
32
54
  --sun: #F5C344;
33
- --flame: #FF5A1F;
55
+ /* Error/status tones are theme-tuned: the root values are the LIGHT (paper)
56
+ pair (flame 4.74:1, amber 4.5+:1 on paper); the dark blocks below restore
57
+ the originals (#FF5A1F / #D9A93A) which were tuned on ink and fail on
58
+ paper (2.9:1 / 2.0:1). */
59
+ --flame: #C53E00;
60
+ /* #8A6512 measured 4.5+:1 on --paper but only 4.26:1 on --bg-2, which the
61
+ dashboard card status text actually renders on - darkened for margin on
62
+ both backgrounds (5.21:1 on --bg-2). */
63
+ --amber: #7C570F;
34
64
  --sky: #3A6EFF;
35
- --warn: #E0241A;
65
+ /* --warn = interactive danger controls (buttons, banners, menus, error
66
+ inputs); --danger below = passive error/status text and metrics
67
+ (kpi/sparkline deltas, auth-error text). Two tokens, one convention.
68
+ #E0241A measured 4.19:1 on --paper — fails WCAG AA 4.5:1 for the many
69
+ TEXT usages (.field-error, .ds-btn-warn, .ds-stat-val.err-rate, toast/
70
+ session error labels), not just the interactive-control (>=3:1) usages.
71
+ Darkened to clear AA on --paper (5.29:1), --paper-2 (4.78:1), and the
72
+ thebird warm-paper preset (5.25:1) while staying visually a clear
73
+ warm red. */
74
+ --warn: #C41C0C;
75
+ /* Syntax-token aliases: light values pass 4.5:1 on paper; the dark blocks
76
+ restore the bright dark-tuned originals. Components reference ONLY these. */
77
+ --code-string: var(--green);
78
+ --code-keyword: #2453C9;
79
+ --code-fn: #B84300;
80
+ --code-str-alt: var(--mascot-deep);
81
+ --code-num: #946300;
82
+ /* 0.55 lightness measured 4.70:1 on --paper but only 4.25:1 on --bg-2 (the
83
+ auth-error banner's actual background) - darkened for AA margin on both.
84
+ --danger = passive error/status text and metrics; --warn above =
85
+ interactive danger controls. */
86
+ --danger: oklch(0.50 0.18 25);
87
+ --success: var(--green-2);
36
88
  --live: var(--green);
37
89
 
38
90
  /* Semantic surfaces */
@@ -43,15 +95,60 @@
43
95
  --fg-2: var(--ink-2);
44
96
  --fg-3: var(--ink-3);
45
97
 
46
- --accent: var(--green);
47
- --accent-fg: var(--paper);
48
- --accent-tint: color-mix(in oklab, var(--accent) 18%, var(--bg));
98
+ /* The electric lead. --accent is the FILL (sits behind ink text); --accent-ink
99
+ is the readable TEXT tone for links/eyebrows/accents on paper (the lime
100
+ itself is too light for text). --accent-fg is what sits ON an --accent fill. */
101
+ --accent: var(--acid);
102
+ --accent-fg: var(--ink);
103
+ --accent-ink: var(--acid-deep);
104
+ --accent-bright: var(--acid); /* base value so var(--accent-bright) never falls back empty; ink + [data-accent] retune it */
105
+ /* Blends --accent-ink (the readable/darker ink variant), not the raw
106
+ --accent fill, so light-theme active states clear contrast against --bg;
107
+ dark/ink and auto-dark restate the prior --accent-based value explicitly
108
+ below so this change does not leak into them via inheritance. */
109
+ --accent-tint: color-mix(in oklab, var(--accent-ink) 22%, var(--bg));
110
+
111
+ /* On-color foregrounds — text/icons that sit ON a saturated fill (accent,
112
+ danger, category chips). Theme-driven so white-on-color never hard-codes
113
+ #fff. --on-accent tracks --accent-fg; --on-color is the generic light
114
+ foreground for any colored fill. */
115
+ --on-accent: var(--accent-fg);
116
+ --on-color: #fff;
117
+
118
+ /* Scrims — modal/overlay backdrops. Derived from --fg so a dark theme dims
119
+ with its own ink rather than a baked rgba(0,0,0). */
120
+ --scrim: color-mix(in oklab, var(--fg) 40%, transparent);
121
+ --scrim-strong: color-mix(in oklab, var(--fg) 72%, transparent);
122
+ --scrim-media: color-mix(in oklab, var(--fg) 85%, transparent);
123
+
124
+ /* Category palette — surfaces (forum tags, project cards) that color-code by
125
+ category. Canonical so a theme/accent swap recolors categories instead of
126
+ drifting from a private --cat-* block. Derived from the base palette. */
127
+ --cat-green: var(--green-2);
128
+ --cat-purple: var(--purple-2);
129
+ --cat-mascot: var(--mascot);
130
+ --cat-sun: var(--sun);
131
+ --cat-flame: var(--flame);
132
+ --cat-sky: var(--sky);
133
+
134
+ /* Readable TEXT tones for the category hues — the same FILL/TEXT split the
135
+ lead accent already draws with --accent (fill) vs --accent-ink (text).
136
+ The bare --cat-* values are chroma-matched to sit behind ink on a swatch,
137
+ avatar, or tag; as `color:` on newsprint paper they land at ~3.1:1, under
138
+ the 4.5:1 floor. Any `color:` use of a category hue takes the -ink tone;
139
+ only background/border-color take the bare one. Each -deep source is
140
+ already remapped per-theme below, so these follow the theme too. */
141
+ --cat-green-ink: var(--green-deep);
142
+ --cat-purple-ink: var(--purple-deep);
143
+ --cat-mascot-ink: var(--mascot-deep);
49
144
 
50
145
  --panel-bg: var(--bg);
51
146
  --panel-bg-2: var(--bg-2);
52
147
  --panel-accent: var(--accent);
148
+ --panel-0: var(--bg);
53
149
  --panel-1: var(--bg-2);
54
150
  --panel-2: var(--bg-3);
151
+ --panel-hover: color-mix(in oklab, var(--fg) 4%, var(--panel-1));
55
152
  --panel-3: color-mix(in oklab, var(--fg) 12%, transparent);
56
153
  --panel-text: var(--fg);
57
154
  --panel-text-2: var(--fg-2);
@@ -59,18 +156,23 @@
59
156
  --panel-accent-2: var(--accent-bright, var(--accent));
60
157
  --panel-shadow: 0 1px 0 color-mix(in oklab, var(--fg) 6%, transparent), 0 4px 14px color-mix(in oklab, var(--fg) 8%, transparent);
61
158
 
62
- /* Type — one family, used purposefully. Space Grotesk for everything
63
- non-mono. The display/narrow aliases stay so consumers that reference
64
- them keep working; they just resolve to the body font now. */
65
- --ff-display: 'Space Grotesk', system-ui, sans-serif;
66
- --ff-narrow: 'Space Grotesk', system-ui, sans-serif;
67
- --ff-body: 'Space Grotesk', system-ui, sans-serif;
68
- --ff-mono: 'JetBrains Mono', ui-monospace, Menlo, Consolas, monospace;
69
-
70
- --fs-micro: 11px;
71
- --fs-tiny: 12px;
72
- --fs-xs: 13px;
73
- --fs-sm: 14px;
159
+ /* Type — system-font stack, no custom web fonts loaded. */
160
+ --ff-display: system-ui, sans-serif;
161
+ --ff-narrow: system-ui, sans-serif;
162
+ --ff-body: system-ui, sans-serif;
163
+ --ff-mono: ui-monospace, Menlo, Consolas, monospace;
164
+
165
+ /* Sub-12px tiers exist ONLY for dense OS/data chrome — taskbar strips,
166
+ session chips, tool-call headers, file-row metadata, ID/stat columns.
167
+ Never use them for body copy or ordinary UI text: at these sizes the
168
+ system stack loses its readable x-height, so they are reserved for
169
+ glanceable, secondary, non-prose material. --fs-pico is the floor. */
170
+ --fs-pico: 10px;
171
+ --fs-nano: 11px;
172
+ --fs-micro: 12px;
173
+ --fs-tiny: 13px;
174
+ --fs-xs: 14px;
175
+ --fs-sm: 15px;
74
176
  --fs-body: 16px;
75
177
  --fs-lg: 18px;
76
178
  --fs-xl: 21px;
@@ -81,6 +183,15 @@
81
183
  --fs-hero: clamp(42px, 7cqi, 96px);
82
184
  --fs-mega: clamp(56px, 11cqi, 168px);
83
185
 
186
+ /* App/chrome typescale: the default heading scale above is tuned for
187
+ marketing/hero layouts (h1 up to 64px). Application chrome — page titles,
188
+ panel headers — needs a compact ceiling so a PageHeader title doesn't
189
+ dwarf the content. Opt in with `data-typescale="app"` on a container. */
190
+ --fs-h1-app: clamp(22px, 2.4cqi, 30px);
191
+ --fs-h2-app: clamp(19px, 2cqi, 24px);
192
+ --fs-h3-app: clamp(17px, 1.8cqi, 20px);
193
+ --fs-h4-app: clamp(15px, 1.6cqi, 17px);
194
+
84
195
  --lh-tight: 1.05;
85
196
  --lh-snug: 1.2;
86
197
  --lh-base: 1.55;
@@ -92,16 +203,27 @@
92
203
  --tr-tighter: -0.03em;
93
204
 
94
205
  /* Spacing (8pt) */
206
+ /* Micro rungs below --space-1 — dense editor/inspector chrome (table cell
207
+ padding, pill gaps, tight toolbar gutters) needs finer steps than the 8pt
208
+ scale offers; same reasoning as --r-hair/--r-0 sitting below --r-1. */
209
+ --space-hair: 2px;
210
+ --space-half: 3px;
95
211
  --space-0: 0;
96
212
  --space-1: 4px;
213
+ --space-1-5: 5px;
214
+ --space-1-75: 6px;
97
215
  --space-2: 8px;
216
+ --space-2-5: 10px;
217
+ --space-2-75: 12px; /* fills the 10->16 hole (row-form gap, dense cell pad) */
98
218
  --space-3: 16px;
219
+ --space-3-5: 20px; /* fills the 16->24 hole (settings body, mono block pad) */
99
220
  --space-4: 24px;
100
221
  --space-5: 32px;
101
222
  --space-6: 48px;
102
223
  --space-7: 64px;
103
224
  --space-8: 96px;
104
225
  --space-9: 128px;
226
+ --space-10: 192px;
105
227
 
106
228
  --density: 1;
107
229
  --pad-y: calc(var(--space-5) * var(--density));
@@ -117,48 +239,296 @@
117
239
  --rule: color-mix(in oklab, currentColor 14%, transparent);
118
240
  --rule-strong: color-mix(in oklab, currentColor 28%, transparent);
119
241
 
242
+ /* Micro rungs below --r-1 — chips, badges, scrollbar thumbs, tick marks
243
+ genuinely want a tighter corner than 10px; without these two tokens the
244
+ component sheets fell back to raw px literals bypassing the scale. */
245
+ --r-hair: 2px;
246
+ --r-0: 4px;
120
247
  --r-1: 10px;
121
248
  --r-2: 14px;
122
249
  --r-3: 22px;
123
- --r-4: 32px;
124
250
  --r-pill: 999px;
125
251
 
126
252
  --dur-snap: 80ms;
127
253
  --dur-base: 160ms;
128
254
  --dur-slow: 280ms;
255
+ --dur-reveal: 560ms;
129
256
  --ease: cubic-bezier(0.2, 0, 0, 1);
257
+ /* Physical tier — a slight overshoot that reads as a printed stamp landing,
258
+ used by presses and signature reveals (not by routine UI fades). */
259
+ --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
260
+ --ease-exit: cubic-bezier(0.4, 0, 1, 1);
261
+
262
+ /* Print texture — the signature surface treatment. --grain is a tiled
263
+ fractal-noise data-URI, opt-in via the .ds-grain utility and tuned faint
264
+ so type stays crisp. */
265
+ --grain-opacity: 0.05;
266
+ --grain-blend: multiply;
267
+ --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
268
+ /* Offset-ink registration — the small print-mark offset used on editorial
269
+ edges (panel spine, expo numbering). A literal length, not a color. */
270
+ --ink-offset: 3px;
130
271
 
131
- --z-header: 100;
132
- --z-overlay: 1000;
272
+ /* ============================================================
273
+ Stacking scale — the ONE ordered set of layers anything may
274
+ paint into. Rungs are 100 apart so a future layer can be
275
+ inserted between two neighbours without renumbering the rest,
276
+ and so a component may locally offset (+1/+2) within its own
277
+ rung without colliding with the next one.
278
+
279
+ Order is the contract; the numbers are just how it is spelled.
280
+ Read top to bottom as "what paints over what":
281
+
282
+ --z-below -1 decorative texture UNDER its own content
283
+ (.ds-grain/.ds-halftone print layer)
284
+ --z-base 0 in-flow content; the default plane
285
+ --z-raised 100 a thing lifted above its siblings inside
286
+ one component (code-lang tab, timeline dot,
287
+ selection checkbox, resize handle)
288
+ --z-sticky 200 sticky-within-a-scroller chrome: section
289
+ labels, sticky table headers, save bars.
290
+ Above raised content it scrolls past.
291
+ --z-header 300 the app's own sticky chrome band
292
+ (.app-topbar/.app-chrome)
293
+ --z-drawer 400 off-canvas panels (sidebar/pane/session
294
+ drawers) and their scrim, which must cover
295
+ the header they slide over
296
+ --z-window 500 free-floating window-manager surfaces —
297
+ the OS kit's .wm-root canvas of draggable
298
+ windows. Above the shell, below all
299
+ transient popups.
300
+ --z-dock 600 persistent OS shell furniture that must
301
+ stay above windows: launcher dock, menubar,
302
+ taskbar, os-root
303
+ --z-dropdown 700 menus/popovers anchored to a trigger; they
304
+ must escape the dock that spawned them
305
+ --z-modal 800 blocking dialogs, lightboxes, command
306
+ palettes and their backdrops
307
+ --z-toast 900 transient notifications — above a modal,
308
+ because they report on what the modal did
309
+ --z-tooltip 1000 pointer-following hint; never blocked
310
+ --z-top 1100 last resort: boot/loading veils and
311
+ full-screen takeovers that outrank
312
+ everything, including a tooltip
313
+ ============================================================ */
314
+ --z-below: -1;
315
+ --z-base: 0;
316
+ --z-raised: 100;
317
+ --z-sticky: 200;
318
+ --z-header: 300;
319
+ --z-drawer: 400;
320
+ --z-window: 500;
321
+ --z-dock: 600;
322
+ --z-dropdown: 700;
323
+ --z-modal: 800;
324
+ --z-toast: 900;
325
+ --z-tooltip: 1000;
326
+ --z-top: 1100;
133
327
 
134
328
  --measure: 68ch;
329
+ --measure-wide: 940px;
330
+ --measure-narrow: 760px;
331
+ /* Page-stage ceiling — independent of --measure-wide (which stays the
332
+ narrower editorial hero/prose measure). Fluid so ultra-wide viewports
333
+ actually gain real estate instead of flat-lining at a fixed px cap.
334
+ Percentage, not vw: a stage nested in a sidebar shell or an embedded
335
+ window has no useful viewport of its own, and a vw term there resolves
336
+ against the browser instead of the container it actually sits in. */
337
+ --stage-wide: min(96%, 1600px);
338
+ /* Ultra-wide tier — past this the eye loses the line more than the layout
339
+ gains, so multi-column content takes the extra width instead of one
340
+ column growing without bound. */
341
+ --stage-ultra: min(96%, 2100px);
342
+
343
+ --sidebar-width: 220px;
344
+ --sidebar-width-collapsed: 64px;
345
+
346
+ --lh-tall: 1.4;
347
+
348
+ /* Control size scale — heights for status/topbar/crumb + controls. */
349
+ --size-sm: 32px;
350
+ --size-base: 42px;
351
+ --size-lg: 56px;
352
+
353
+ /* Dense control-height ladder — the actual heights front-door controls
354
+ (buttons, fields, rows) snap to, one rung tighter than the --size-*
355
+ chrome scale so app UI reads compact instead of marketing-scale. Density
356
+ scales them so [data-density=compact/spacious] moves every control at once.
357
+ Mirrors webgeist's 30/38/46 button ladder, retuned for this system. */
358
+ --ctl-sm: calc(28px * var(--density));
359
+ --ctl-md: calc(34px * var(--density));
360
+ --ctl-lg: calc(42px * var(--density));
361
+ /* The canonical single-line input/select/searchfield height (== --ctl-md)
362
+ and the default list-row min-height, both density-aware. */
363
+ --field-height: var(--ctl-md);
364
+ --row-height: calc(40px * var(--density));
365
+
366
+ /* Unified focus-ring tokens (single source for the design system). Outset
367
+ rings (the default) tokenize colour+width+offset; bordered text fields use
368
+ the inset variant. Deliberate negative offsets on edge-flush/clipping
369
+ containers stay literal. --focus-color uses --accent-ink (the readable
370
+ text/UI-boundary tone), never bare --accent (the lime FILL token, which
371
+ measures ~1.07:1 against --paper and is nearly invisible as an outline —
372
+ see AGENTS.md token-split rule). */
373
+ --focus-color: var(--accent-ink);
374
+ --focus-w: 2px;
375
+ --focus-offset: 2px;
376
+ --focus-ring-inset: inset 0 0 0 var(--focus-w) var(--focus-color);
135
377
  }
136
378
 
137
- [data-theme="ink"] {
379
+ /* ============================================================
380
+ Focus-visible styles for keyboard navigation
381
+ ============================================================ */
382
+ :focus-visible {
383
+ outline: var(--focus-w) solid var(--focus-color);
384
+ outline-offset: var(--focus-offset);
385
+ }
386
+
387
+ /* Button variants with focus-visible */
388
+ .btn:focus-visible,
389
+ .btn-primary:focus-visible,
390
+ .btn-ghost:focus-visible {
391
+ outline: var(--focus-w) solid var(--focus-color);
392
+ outline-offset: var(--focus-offset);
393
+ }
394
+
395
+ /* Link focus-visible — all route through the single --focus-* token set so a
396
+ focus retune (colour/width/offset) happens in one place, never per selector. */
397
+ a:focus-visible,
398
+ [role="link"]:focus-visible {
399
+ outline: var(--focus-w) solid var(--focus-color);
400
+ outline-offset: var(--focus-offset);
401
+ }
402
+
403
+ /* Form inputs with focus-visible */
404
+ input:focus-visible,
405
+ textarea:focus-visible,
406
+ select:focus-visible {
407
+ outline: var(--focus-w) solid var(--focus-color);
408
+ outline-offset: var(--focus-offset);
409
+ }
410
+
411
+ /* Interactive element focus-visible */
412
+ [tabindex]:focus-visible {
413
+ outline: var(--focus-w) solid var(--focus-color);
414
+ outline-offset: var(--focus-offset);
415
+ }
416
+
417
+ [data-theme="ink"],
418
+ [data-theme="dark"] {
419
+ color-scheme: dark;
138
420
  --bg: var(--ink);
139
421
  --bg-2: var(--ink-2);
140
- --bg-3: #34343C;
422
+ --bg-3: var(--ink-3-dark);
141
423
  --fg: var(--paper);
142
424
  --fg-2: var(--paper-2);
143
- --fg-3: #9A9AA2;
425
+ --fg-3: var(--paper-3-dark);
144
426
  --panel-bg: var(--bg);
145
427
  --panel-bg-2: var(--bg-2);
146
- --accent: var(--accent-bright, var(--green-2));
428
+ --panel-0: var(--bg);
429
+ --panel-1: var(--bg-2);
430
+ --panel-2: var(--bg-3);
431
+ --panel-3: color-mix(in oklab, var(--fg) 20%, transparent);
432
+ --panel-text: var(--fg);
433
+ --panel-text-2: var(--fg-2);
434
+ --panel-text-3: var(--fg-3);
435
+ --accent: var(--acid);
147
436
  --accent-fg: var(--ink);
437
+ --accent-ink: var(--acid); /* on ink, the lime itself reads as bright text */
438
+ --accent-bright: var(--acid);
439
+ /* Preserves the prior --accent-based blend for dark; the :root light-theme
440
+ value above was retuned to blend --accent-ink instead. */
441
+ --accent-tint: color-mix(in oklab, var(--accent) 30%, var(--bg));
442
+ --danger: oklch(0.68 0.19 25);
443
+ --flame: #FF5A1F;
444
+ --amber: #D9A93A;
445
+ /* warn/sky dark-tuned pairs (mirror flame/amber): the :root paper values
446
+ (#E0241A / #3A6EFF) are too dark on ink; these clear AA 4.5:1 on --ink. */
447
+ --warn: #FF5A52;
448
+ --sky: #6E9BFF;
449
+ /* Category/heritage dark-tuned pairs (same convention as flame/amber/warn/
450
+ sky above): the :root values are the PAPER tones and go dark-on-dark here.
451
+ Measured on --ink (#0E0E12) / --bg-2 (#1F1F26): mascot-deep #B81F63 was
452
+ 3.13:1 / 2.66:1, purple-2 #7F18A4 2.36:1 / 2.00:1, green #247420 3.30:1 /
453
+ 2.80:1 — all failing AA for the text roles they carry (aicat/community
454
+ author names, kpi deltas, stamps, rails). The replacements clear 4.5:1 on
455
+ BOTH ink surfaces: #FF5C9E 6.67/5.67, #C277FF 6.77/5.75, #5CBF52 8.28/7.04.
456
+ These are text-tone retunes only — the paper values are untouched. */
457
+ --mascot-deep: #FF5C9E;
458
+ --purple-2: #C277FF;
459
+ --green: #5CBF52;
460
+ /* --cat-*-ink text tones for dark. The :root sources (--green-deep #133F10,
461
+ --purple-deep #220026) are near-black PAPER tones — on ink they land at
462
+ 1.60:1 / 1.01:1, i.e. invisible. Repoint them at the dark-tuned values
463
+ already proven above: #5CBF52 8.28:1 on ink / 7.04:1 on --bg-2, #C277FF
464
+ 6.77:1 / 5.75:1. --cat-mascot-ink needs no entry here: it tracks
465
+ --mascot-deep, which this same block already remaps to #FF5C9E. */
466
+ --cat-green-ink: #5CBF52;
467
+ --cat-purple-ink: #C277FF;
468
+ --code-string: var(--green-2);
469
+ --code-keyword: var(--sky);
470
+ --code-fn: var(--flame);
471
+ --code-str-alt: var(--mascot);
472
+ --code-num: var(--sun);
473
+ }
474
+
475
+ /* Restores the pre-existing (weaker) dark-theme selection tint after the
476
+ light-theme-only bump in app-shell.css's base ::selection rule. */
477
+ [data-theme="ink"] ::selection,
478
+ [data-theme="dark"] ::selection {
479
+ background: color-mix(in oklab, var(--accent) 24%, var(--bg-2));
480
+ color: var(--fg);
148
481
  }
149
482
 
483
+ /* NOTE: the [data-theme="auto"] block below mirrors the
484
+ [data-theme="ink"/"dark"] block above token-for-token. 'auto + OS-dark' and
485
+ 'explicit dark' are the same visual context and resolve every token —
486
+ including --danger — identically. The two are kept as separate selectors
487
+ only because one is media-gated; a future de-drift can consolidate them into
488
+ a shared selector list once a build step can hoist the media query. */
150
489
  @media (prefers-color-scheme: dark) {
151
490
  [data-theme="auto"] {
152
491
  --bg: var(--ink);
153
492
  --bg-2: var(--ink-2);
154
- --bg-3: #34343C;
493
+ --bg-3: var(--ink-3-dark);
155
494
  --fg: var(--paper);
156
495
  --fg-2: var(--paper-2);
157
- --fg-3: #9A9AA2;
496
+ --fg-3: var(--paper-3-dark);
158
497
  --panel-bg: var(--bg);
159
498
  --panel-bg-2: var(--bg-2);
160
- --accent: var(--accent-bright, var(--green-2));
499
+ --panel-0: var(--bg);
500
+ --panel-1: var(--bg-2);
501
+ --panel-2: var(--bg-3);
502
+ --panel-3: color-mix(in oklab, var(--fg) 20%, transparent);
503
+ --panel-text: var(--fg);
504
+ --panel-text-2: var(--fg-2);
505
+ --panel-text-3: var(--fg-3);
506
+ --accent: var(--acid);
161
507
  --accent-fg: var(--ink);
508
+ --accent-ink: var(--acid);
509
+ --accent-bright: var(--acid);
510
+ --accent-tint: color-mix(in oklab, var(--accent) 30%, var(--bg));
511
+ --danger: oklch(0.68 0.19 25);
512
+ --flame: #FF5A1F;
513
+ --amber: #D9A93A;
514
+ --warn: #FF5A52;
515
+ --sky: #6E9BFF;
516
+ /* Mirrors the [data-theme="ink"] category retune above token-for-token —
517
+ see that block for the measured before/after ratios. */
518
+ --mascot-deep: #FF5C9E;
519
+ --purple-2: #C277FF;
520
+ --green: #5CBF52;
521
+ --cat-green-ink: #5CBF52;
522
+ --cat-purple-ink: #C277FF;
523
+ --code-string: var(--green-2);
524
+ --code-keyword: var(--sky);
525
+ --code-fn: var(--flame);
526
+ --code-str-alt: var(--mascot);
527
+ --code-num: var(--sun);
528
+ }
529
+ [data-theme="auto"] ::selection {
530
+ background: color-mix(in oklab, var(--accent) 24%, var(--bg-2));
531
+ color: var(--fg);
162
532
  }
163
533
  }
164
534
 
@@ -178,6 +548,7 @@
178
548
  --panel-bg-2: inherit;
179
549
  --accent: inherit;
180
550
  --accent-fg: inherit;
551
+ --accent-ink: inherit;
181
552
  --panel-1: inherit;
182
553
  --panel-2: inherit;
183
554
  --panel-3: inherit;
@@ -186,12 +557,201 @@
186
557
  --panel-text-3: inherit;
187
558
  --panel-accent-2: inherit;
188
559
  --panel-shadow: inherit;
560
+ --on-accent: inherit;
561
+ --on-color: inherit;
562
+ --scrim: inherit;
563
+ --scrim-strong: inherit;
564
+ --scrim-media: inherit;
565
+ --cat-green: inherit;
566
+ --cat-purple: inherit;
567
+ --cat-mascot: inherit;
568
+ --cat-green-ink: inherit;
569
+ --cat-purple-ink: inherit;
570
+ --cat-mascot-ink: inherit;
571
+ --mascot-on-ink: inherit;
572
+ --cat-sun: inherit;
573
+ --cat-flame: inherit;
574
+ --cat-sky: inherit;
575
+ --code-string: inherit;
576
+ --code-keyword: inherit;
577
+ --code-fn: inherit;
578
+ --code-str-alt: inherit;
579
+ --code-num: inherit;
580
+ }
581
+
582
+ /* ============================================================
583
+ Named-theme preset contract
584
+ ------------------------------------------------------------
585
+ A theme is one [data-theme="X"] block that overrides ONLY the semantic
586
+ surface tokens — never component rules, never raw literals in component
587
+ sheets. The base :root above IS the "paper" theme; [data-theme="paper"]
588
+ restates it so the attribute is explicit and round-trippable. To add a
589
+ theme: copy a block, rename the attr, retune the ~8 semantic tokens.
590
+ ============================================================ */
591
+ [data-theme="paper"] {
592
+ color-scheme: light;
593
+ --bg: var(--paper); --bg-2: var(--paper-2); --bg-3: var(--paper-3);
594
+ --fg: var(--ink); --fg-2: var(--ink-2); --fg-3: var(--ink-3);
595
+ --accent: var(--acid); --accent-fg: var(--ink); --accent-ink: var(--acid-deep);
596
+ --accent-tint: color-mix(in oklab, var(--accent-ink) 22%, var(--bg));
597
+ /* A paper island under a dark ancestor must not inherit the dark signal pair. */
598
+ --flame: #C53E00; --amber: #7C570F; --warn: #C41C0C; --sky: #3A6EFF;
599
+ }
600
+
601
+ /* thebird — warm-paper brand preset. A first-class swappable theme: it lives
602
+ here in the canonical layer (not as a global :root override) so any consumer
603
+ can opt in with data-theme="thebird". The OS-shell chrome (bar heights,
604
+ window controls) stays in src/kits/os/theme.css; only color lives here. */
605
+ [data-theme="thebird"] {
606
+ color-scheme: light;
607
+ --paper: #F5F0E4;
608
+ --paper-2: #EFE9DB;
609
+ --paper-3: #E3DAC7;
610
+ --bg: var(--paper); --bg-2: var(--paper-2); --bg-3: var(--paper-3);
611
+ --fg: var(--ink); --fg-2: var(--ink-2); --fg-3: var(--ink-3);
612
+ --accent: var(--green); --accent-fg: var(--paper); --accent-ink: var(--green);
613
+ }
614
+
615
+ /* github-dark — pi-web's GitHub-dark theme. Cool dark palette with blue accent,
616
+ ported from pi-web (https://github.com/jmfederico/pi-web). */
617
+ [data-theme="github-dark"] {
618
+ color-scheme: dark;
619
+ --bg: #0d1117;
620
+ --bg-2: #161b22;
621
+ --bg-3: #21262d;
622
+ --fg: #e6edf3;
623
+ --fg-2: #c9d1d9;
624
+ --fg-3: #8b949e;
625
+ --panel-bg: var(--bg);
626
+ --panel-bg-2: var(--bg-2);
627
+ --panel-0: var(--bg);
628
+ --panel-1: var(--bg-2);
629
+ --panel-2: var(--bg-3);
630
+ --panel-3: color-mix(in oklab, var(--fg) 20%, transparent);
631
+ --panel-text: var(--fg);
632
+ --panel-text-2: var(--fg-2);
633
+ --panel-text-3: var(--fg-3);
634
+ --accent: #58a6ff;
635
+ --accent-fg: #ffffff;
636
+ --accent-ink: #58a6ff;
637
+ --accent-bright: #79c0ff;
638
+ --accent-tint: color-mix(in oklab, var(--accent) 30%, var(--bg));
639
+ --danger: #ff7b72;
640
+ --flame: #ff7b72;
641
+ --amber: #d29922;
642
+ --warn: #ff7b72;
643
+ --sky: #58a6ff;
644
+ --mascot-deep: #ff7b72;
645
+ --purple-2: #d2a8ff;
646
+ --green: #3fb950;
647
+ --green-2: #3fb950;
648
+ --cat-green-ink: #3fb950;
649
+ --cat-purple-ink: #d2a8ff;
650
+ --code-string: var(--green-2);
651
+ --code-keyword: var(--sky);
652
+ --code-fn: var(--flame);
653
+ --code-str-alt: var(--mascot-deep);
654
+ --code-num: var(--amber);
655
+ }
656
+
657
+ [data-theme="github-dark"] ::selection {
658
+ background: #0d2847;
659
+ color: var(--fg);
189
660
  }
190
661
 
191
662
  [data-density="compact"] { --density: 0.75; }
192
663
  [data-density="comfortable"] { --density: 1; }
193
664
  [data-density="spacious"] { --density: 1.35; }
194
665
 
195
- [data-accent="green"] { --accent: var(--green); --accent-bright: var(--green-2); --accent-fg: var(--paper); --panel-accent: var(--green); }
196
- [data-accent="purple"] { --accent: var(--purple); --accent-bright: #C277FF; --accent-fg: var(--paper); --panel-accent: var(--purple); }
197
- [data-accent="mascot"] { --accent: var(--mascot); --accent-bright: var(--mascot-2); --accent-fg: var(--ink); --panel-accent: var(--mascot); }
666
+ [data-accent="acid"] { --accent: var(--acid); --accent-bright: var(--acid); --accent-fg: var(--ink); --accent-ink: var(--acid-deep); --panel-accent: var(--acid); }
667
+ [data-accent="green"] { --accent: var(--green); --accent-bright: var(--green-2); --accent-fg: var(--paper); --accent-ink: var(--green); --panel-accent: var(--green); }
668
+ [data-accent="purple"] { --accent: var(--purple); --accent-bright: #C277FF; --accent-fg: var(--paper); --accent-ink: var(--purple-2); --panel-accent: var(--purple); }
669
+ [data-accent="mascot"] { --accent: var(--mascot); --accent-bright: var(--mascot-2); --accent-fg: var(--ink); --accent-ink: var(--mascot-deep);--panel-accent: var(--mascot); }
670
+
671
+ /* Type-scale modifier — opt-in body/lg/xl bump for surfaces that want denser
672
+ or larger reading sizes without a custom override. */
673
+ [data-typescale="sm"] { --fs-body: 15px; --fs-lg: 17px; --fs-xl: 20px; }
674
+ [data-typescale="lg"] { --fs-body: 17px; --fs-lg: 20px; --fs-xl: 24px; }
675
+
676
+ /* Debug grid overlay — 8px mascot grid. Toggle via class on any container. */
677
+ .with-grid-overlay {
678
+ background-image:
679
+ linear-gradient(to right, rgba(232,75,138,0.15) 1px, transparent 1px),
680
+ linear-gradient(to bottom, rgba(232,75,138,0.15) 1px, transparent 1px);
681
+ background-size: 8px 8px;
682
+ }
683
+
684
+ /* Reduced-motion guard — neutralizes every transition/animation/transform
685
+ inside the design-system scope when the user requests reduced motion.
686
+ Components remain free to opt back in with
687
+ `@media (prefers-reduced-motion: no-preference) { ... }`. */
688
+ @media (prefers-reduced-motion: reduce) {
689
+ .ds-247420 *,
690
+ .ds-247420 *::before,
691
+ .ds-247420 *::after {
692
+ animation-duration: 0.001ms !important;
693
+ animation-iteration-count: 1 !important;
694
+ transition-duration: 0.001ms !important;
695
+ scroll-behavior: auto !important;
696
+ }
697
+ }
698
+
699
+ /* ============================================================
700
+ Semantic alias tier — primitive -> semantic -> component
701
+ ------------------------------------------------------------
702
+ Three layers, in order:
703
+ 1. PRIMITIVE (above) raw palette values: --acid, --green, --sky, --warn,
704
+ --panel-1/2/3, --paper/--ink, etc. These are the only tokens that ever
705
+ carry a literal color/length. A re-brand edits primitives.
706
+ 2. SEMANTIC (here) named-by-INTENT aliases that resolve to a primitive
707
+ (e.g. --accent: var(--panel-accent)). A component or a future re-brand
708
+ can retune ONE semantic variable (say, --rail-danger) without hunting
709
+ through every primitive it happens to reuse elsewhere.
710
+ 3. COMPONENT (app-shell.css, community.css, etc.) component sheets keep
711
+ consuming primitives directly today (--accent, --panel-*, --green,
712
+ --warn, ...) exactly as before — this tier does not repoint any
713
+ existing component rule. It exists so a FUTURE swap has a semantic
714
+ layer ready to migrate onto, one component sheet at a time, without
715
+ a flag-day rewrite. Purely additive: no primitive token's name or
716
+ value changes here, and no component references these new names yet.
717
+
718
+ Naming matches vocabulary already established elsewhere in this system:
719
+ --surface-1/2 mirror the --panel-1/--panel-2 tonal-surface steps already
720
+ used across app-shell.css/community.css; --rail-info/-success/-warning/-error
721
+ mirror the canonical .tone-info/.tone-success/.tone-warning/.tone-error
722
+ banner/badge/chip severity names (app-shell.css L592, community.css
723
+ .cm-banner.tone-*) rather than inventing a new severity vocabulary.
724
+ ============================================================ */
725
+ :root {
726
+ /* --accent already exists as a primitive-facing alias (var(--acid)) above;
727
+ restated here under the semantic tier for discoverability alongside its
728
+ siblings. Same value, same token — not a second definition. */
729
+ --surface-1: var(--panel-1);
730
+ --surface-2: var(--panel-2);
731
+
732
+ /* Rail/status severity aliases — map onto the same color choices the
733
+ existing .cm-banner.tone-* rules in community.css already use, so a
734
+ future rail/indicator component can consume one semantic name instead
735
+ of picking the right primitive per severity by hand. */
736
+ --rail-info: var(--sky);
737
+ --rail-success: var(--green-2);
738
+ --rail-warning: var(--amber);
739
+ --rail-error: var(--warn);
740
+ }
741
+
742
+ /* Elevation tokens consumed by overlays (Tooltip, Popover, Dropdown, Dialog). */
743
+ :root {
744
+ --shadow-1: 0 1px 2px color-mix(in oklab, var(--fg) 8%, transparent);
745
+ --shadow-2: 0 4px 12px color-mix(in oklab, var(--fg) 10%, transparent),
746
+ 0 2px 4px color-mix(in oklab, var(--fg) 6%, transparent);
747
+ --shadow-3: 0 12px 32px color-mix(in oklab, var(--fg) 14%, transparent),
748
+ 0 4px 8px color-mix(in oklab, var(--fg) 8%, transparent);
749
+ /* Overlay elevation — the float for dialogs/lightboxes that sit above a
750
+ scrim; heavier than --shadow-3 and theme-driven (was raw rgba(0,0,0,.4)). */
751
+ --shadow-overlay: 0 12px 40px color-mix(in oklab, var(--fg) 28%, transparent),
752
+ 0 4px 12px color-mix(in oklab, var(--fg) 16%, transparent);
753
+ /* --z-popover is an alias, not a rung: popovers and dropdowns are the
754
+ same anchored-to-a-trigger layer and must never be able to drift
755
+ apart. The rungs themselves live with the stacking scale above. */
756
+ --z-popover: var(--z-dropdown);
757
+ }