@cogenta/theme-portfolio 1.1.2

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 (117) hide show
  1. package/LICENSE +373 -0
  2. package/dist/src/index.d.ts +17 -0
  3. package/dist/src/index.d.ts.map +1 -0
  4. package/dist/src/index.js +20 -0
  5. package/dist/src/index.js.map +1 -0
  6. package/dist/src/render/blocks/accordion.d.ts +4 -0
  7. package/dist/src/render/blocks/accordion.d.ts.map +1 -0
  8. package/dist/src/render/blocks/accordion.js +24 -0
  9. package/dist/src/render/blocks/accordion.js.map +1 -0
  10. package/dist/src/render/blocks/collection-list.d.ts +25 -0
  11. package/dist/src/render/blocks/collection-list.d.ts.map +1 -0
  12. package/dist/src/render/blocks/collection-list.js +77 -0
  13. package/dist/src/render/blocks/collection-list.js.map +1 -0
  14. package/dist/src/render/blocks/cta.d.ts +10 -0
  15. package/dist/src/render/blocks/cta.d.ts.map +1 -0
  16. package/dist/src/render/blocks/cta.js +16 -0
  17. package/dist/src/render/blocks/cta.js.map +1 -0
  18. package/dist/src/render/blocks/embed.d.ts +4 -0
  19. package/dist/src/render/blocks/embed.d.ts.map +1 -0
  20. package/dist/src/render/blocks/embed.js +88 -0
  21. package/dist/src/render/blocks/embed.js.map +1 -0
  22. package/dist/src/render/blocks/faq.d.ts +4 -0
  23. package/dist/src/render/blocks/faq.d.ts.map +1 -0
  24. package/dist/src/render/blocks/faq.js +23 -0
  25. package/dist/src/render/blocks/faq.js.map +1 -0
  26. package/dist/src/render/blocks/feature-grid.d.ts +4 -0
  27. package/dist/src/render/blocks/feature-grid.d.ts.map +1 -0
  28. package/dist/src/render/blocks/feature-grid.js +30 -0
  29. package/dist/src/render/blocks/feature-grid.js.map +1 -0
  30. package/dist/src/render/blocks/gallery.d.ts +18 -0
  31. package/dist/src/render/blocks/gallery.d.ts.map +1 -0
  32. package/dist/src/render/blocks/gallery.js +34 -0
  33. package/dist/src/render/blocks/gallery.js.map +1 -0
  34. package/dist/src/render/blocks/hero.d.ts +15 -0
  35. package/dist/src/render/blocks/hero.d.ts.map +1 -0
  36. package/dist/src/render/blocks/hero.js +31 -0
  37. package/dist/src/render/blocks/hero.js.map +1 -0
  38. package/dist/src/render/blocks/logo-strip.d.ts +4 -0
  39. package/dist/src/render/blocks/logo-strip.d.ts.map +1 -0
  40. package/dist/src/render/blocks/logo-strip.js +23 -0
  41. package/dist/src/render/blocks/logo-strip.js.map +1 -0
  42. package/dist/src/render/blocks/logos.d.ts +4 -0
  43. package/dist/src/render/blocks/logos.d.ts.map +1 -0
  44. package/dist/src/render/blocks/logos.js +28 -0
  45. package/dist/src/render/blocks/logos.js.map +1 -0
  46. package/dist/src/render/blocks/media-figure.d.ts +19 -0
  47. package/dist/src/render/blocks/media-figure.d.ts.map +1 -0
  48. package/dist/src/render/blocks/media-figure.js +36 -0
  49. package/dist/src/render/blocks/media-figure.js.map +1 -0
  50. package/dist/src/render/blocks/pricing-table.d.ts +4 -0
  51. package/dist/src/render/blocks/pricing-table.d.ts.map +1 -0
  52. package/dist/src/render/blocks/pricing-table.js +29 -0
  53. package/dist/src/render/blocks/pricing-table.js.map +1 -0
  54. package/dist/src/render/blocks/prose.d.ts +16 -0
  55. package/dist/src/render/blocks/prose.d.ts.map +1 -0
  56. package/dist/src/render/blocks/prose.js +17 -0
  57. package/dist/src/render/blocks/prose.js.map +1 -0
  58. package/dist/src/render/blocks/quote.d.ts +18 -0
  59. package/dist/src/render/blocks/quote.d.ts.map +1 -0
  60. package/dist/src/render/blocks/quote.js +31 -0
  61. package/dist/src/render/blocks/quote.js.map +1 -0
  62. package/dist/src/render/blocks/stat-counter.d.ts +4 -0
  63. package/dist/src/render/blocks/stat-counter.d.ts.map +1 -0
  64. package/dist/src/render/blocks/stat-counter.js +18 -0
  65. package/dist/src/render/blocks/stat-counter.js.map +1 -0
  66. package/dist/src/render/blocks/stats.d.ts +4 -0
  67. package/dist/src/render/blocks/stats.d.ts.map +1 -0
  68. package/dist/src/render/blocks/stats.js +22 -0
  69. package/dist/src/render/blocks/stats.js.map +1 -0
  70. package/dist/src/render/blocks/testimonial.d.ts +20 -0
  71. package/dist/src/render/blocks/testimonial.d.ts.map +1 -0
  72. package/dist/src/render/blocks/testimonial.js +29 -0
  73. package/dist/src/render/blocks/testimonial.js.map +1 -0
  74. package/dist/src/render/chrome.d.ts +3 -0
  75. package/dist/src/render/chrome.d.ts.map +1 -0
  76. package/dist/src/render/chrome.js +114 -0
  77. package/dist/src/render/chrome.js.map +1 -0
  78. package/dist/src/render/render-block.d.ts +12 -0
  79. package/dist/src/render/render-block.d.ts.map +1 -0
  80. package/dist/src/render/render-block.js +111 -0
  81. package/dist/src/render/render-block.js.map +1 -0
  82. package/dist/src/render/term-archive.d.ts +14 -0
  83. package/dist/src/render/term-archive.d.ts.map +1 -0
  84. package/dist/src/render/term-archive.js +36 -0
  85. package/dist/src/render/term-archive.js.map +1 -0
  86. package/dist/theme.config.d.ts +26 -0
  87. package/dist/theme.config.d.ts.map +1 -0
  88. package/dist/theme.config.js +56 -0
  89. package/dist/theme.config.js.map +1 -0
  90. package/package.json +57 -0
  91. package/src/index.ts +19 -0
  92. package/src/render/blocks/accordion.ts +64 -0
  93. package/src/render/blocks/collection-list.ts +181 -0
  94. package/src/render/blocks/cta.ts +37 -0
  95. package/src/render/blocks/embed.ts +111 -0
  96. package/src/render/blocks/faq.ts +54 -0
  97. package/src/render/blocks/feature-grid.ts +68 -0
  98. package/src/render/blocks/gallery.ts +55 -0
  99. package/src/render/blocks/hero.ts +55 -0
  100. package/src/render/blocks/logo-strip.ts +38 -0
  101. package/src/render/blocks/logos.ts +63 -0
  102. package/src/render/blocks/media-figure.ts +51 -0
  103. package/src/render/blocks/pricing-table.ts +69 -0
  104. package/src/render/blocks/prose.ts +22 -0
  105. package/src/render/blocks/quote.ts +48 -0
  106. package/src/render/blocks/stat-counter.ts +49 -0
  107. package/src/render/blocks/stats.ts +49 -0
  108. package/src/render/blocks/testimonial.ts +45 -0
  109. package/src/render/chrome.ts +142 -0
  110. package/src/render/render-block.ts +155 -0
  111. package/src/render/term-archive.ts +88 -0
  112. package/src/styles/archive.css +40 -0
  113. package/src/styles/base.css +1056 -0
  114. package/src/styles/blocks.css +1468 -0
  115. package/src/styles/theme.css +20 -0
  116. package/src/styles/tokens.css +363 -0
  117. package/tokens.json +36 -0
@@ -0,0 +1,20 @@
1
+ /*
2
+ * The portfolio theme's stylesheet — the entry point, and nothing else.
3
+ *
4
+ * Three layers, in the only order that works:
5
+ *
6
+ * tokens.css the design system, derived entirely from the skin's
7
+ * `--cogenta-*` custom properties (contract D)
8
+ * base.css document, accessibility floor, page frame, chrome, actions
9
+ * blocks.css the seventeen vocabulary blocks
10
+ *
11
+ * Not one colour, font, radius, duration or shadow is written literally in any
12
+ * of the three: every value comes from a `--cogenta-<group>-<name>` property
13
+ * produced from the skin's tokens, or from a `--cg-*` property composed from
14
+ * those.
15
+ */
16
+
17
+ @import "./tokens.css";
18
+ @import "./base.css";
19
+ @import "./blocks.css";
20
+ @import "./archive.css";
@@ -0,0 +1,363 @@
1
+ /*
2
+ * The portfolio theme's design system.
3
+ *
4
+ * Contract D fixes a *closed* skin token set — seven colours, five type tokens,
5
+ * two spacing tokens, three radii, three motion tokens, two shadows — and
6
+ * refuses any skin that adds one. So this layer adds nothing to the skin: every
7
+ * value below is *derived* from `--cogenta-*` by composition (`calc`,
8
+ * `color-mix`, relative colour syntax, `clamp`). A skin swap rewrites the
9
+ * generated `--cogenta-*` sheet and this whole system follows, with no build
10
+ * step.
11
+ *
12
+ * Two rules hold everywhere in this file and the two that import it:
13
+ *
14
+ * 1. **No colour literal.** Not one hex, `rgb()`, `hsl()` or bare `oklch()`.
15
+ * Every colour is either a skin token or a function *of* a skin token.
16
+ * 2. **No second colour or type scale.** The type steps come from
17
+ * `--cogenta-font-size-*` and the spacing multiplier from
18
+ * `--cogenta-space-scale`. The display headline sizes below (`--cg-text-
19
+ * hero`, `--cg-text-jumbo`, …) are `clamp()` *lengths*, not colours — the
20
+ * isolation rule is about colour, and a viewport-responsive headline scale
21
+ * is exactly the "risk-taking" this theme's brief asks for, tied to the
22
+ * same weight/tracking/leading tokens as the rest of the system.
23
+ */
24
+
25
+ /* Google Fonts — a real fallback stack accompanies every one, so the theme
26
+ degrades to a system stack rather than to invisible text when the network
27
+ is unavailable (`font-display: swap` is the default for this endpoint). */
28
+ @import url("https://fonts.googleapis.com/css2?family=Bricolage+Grotesque:opsz,wght@12..96,200..800&family=Fraunces:ital,opsz,wght@0,9..144,300..700;1,9..144,300..700&family=JetBrains+Mono:wght@400;500;600&display=swap");
29
+
30
+ :where(:root) {
31
+ /* Lets the browser paint native controls, scrollbars and form widgets in the
32
+ right scheme, and is what makes `light-dark()` below resolve at all. */
33
+ color-scheme: light dark;
34
+ }
35
+
36
+ :where(:root[data-theme="dark"]) {
37
+ color-scheme: dark;
38
+ }
39
+
40
+ :where(:root[data-theme="light"]) {
41
+ color-scheme: light;
42
+ }
43
+
44
+ /* --------------------------------------------------------------------------
45
+ Space
46
+ -------------------------------------------------------------------------- */
47
+
48
+ :where(:root) {
49
+ --cg-density: var(--cogenta-space-scale, 1);
50
+ --cg-unit: calc(var(--cogenta-space-unit) * var(--cg-density));
51
+
52
+ --cg-s1: calc(var(--cg-unit) * 1);
53
+ --cg-s2: calc(var(--cg-unit) * 2);
54
+ --cg-s3: calc(var(--cg-unit) * 3);
55
+ --cg-s4: calc(var(--cg-unit) * 4);
56
+ --cg-s5: calc(var(--cg-unit) * 5);
57
+ --cg-s6: calc(var(--cg-unit) * 6);
58
+ --cg-s8: calc(var(--cg-unit) * 8);
59
+ --cg-s10: calc(var(--cg-unit) * 10);
60
+ --cg-s12: calc(var(--cg-unit) * 12);
61
+ --cg-s16: calc(var(--cg-unit) * 16);
62
+ --cg-s20: calc(var(--cg-unit) * 20);
63
+ --cg-s24: calc(var(--cg-unit) * 24);
64
+ --cg-s32: calc(var(--cg-unit) * 32);
65
+
66
+ --cg-gutter: var(--cg-s5);
67
+ --cg-gap-tight: var(--cg-s2);
68
+ --cg-gap: var(--cg-s4);
69
+ --cg-gap-loose: var(--cg-s10);
70
+ --cg-section-y: var(--cg-s24);
71
+
72
+ --cg-measure: 66ch;
73
+ --cg-measure-narrow: 44ch;
74
+ --cg-page: 84rem;
75
+ --cg-page-narrow: 52rem;
76
+ }
77
+
78
+ /* --------------------------------------------------------------------------
79
+ Type — the skin's scale, named, plus the display tier a portfolio's
80
+ headlines need. `renderSkin` only ever emits seven steps up to `3xl`; the
81
+ display tier is composed on top of `3xl` with `calc`, so a skin with a
82
+ flatter scale still produces a *bigger* display size than its own body
83
+ text, in proportion — never a fixed number disconnected from the skin.
84
+ -------------------------------------------------------------------------- */
85
+
86
+ :where(:root) {
87
+ --cg-text-xs: var(--cogenta-font-size-xs, 0.64rem);
88
+ --cg-text-sm: var(--cogenta-font-size-sm, 0.8rem);
89
+ --cg-text-md: var(--cogenta-font-size-md, var(--cogenta-font-base-size, 1rem));
90
+ --cg-text-lg: var(--cogenta-font-size-lg, 1.25rem);
91
+ --cg-text-xl: var(--cogenta-font-size-xl, 1.5625rem);
92
+ --cg-text-2xl: var(--cogenta-font-size-2xl, 1.9531rem);
93
+ --cg-text-3xl: var(--cogenta-font-size-3xl, 2.4414rem);
94
+
95
+ /* Fluid display tiers — clamped between a floor that still reads as
96
+ "headline" on a phone and a ceiling this theme's brief asks for outright
97
+ (8-12rem worth of visual weight once line-height and tracking are
98
+ applied). Each is anchored to `--cg-text-3xl` so a skin with a smaller
99
+ base type still gets a proportionally smaller, never a fixed, display
100
+ size. */
101
+ --cg-text-jumbo: clamp(calc(var(--cg-text-3xl) * 1.6), 11vw, calc(var(--cg-text-3xl) * 4.1));
102
+ --cg-text-hero: clamp(
103
+ calc(var(--cg-text-3xl) * 1.35),
104
+ 7vw +
105
+ 1rem,
106
+ calc(var(--cg-text-3xl) * 2.85)
107
+ );
108
+ --cg-text-cta: clamp(
109
+ calc(var(--cg-text-3xl) * 1.1),
110
+ 5vw +
111
+ 0.5rem,
112
+ calc(var(--cg-text-3xl) * 1.95)
113
+ );
114
+ --cg-text-quote: clamp(
115
+ calc(var(--cg-text-3xl) * 0.85),
116
+ 3vw +
117
+ 0.75rem,
118
+ calc(var(--cg-text-3xl) * 1.35)
119
+ );
120
+ --cg-text-stat: clamp(
121
+ calc(var(--cg-text-3xl) * 0.95),
122
+ 3.5vw +
123
+ 0.5rem,
124
+ calc(var(--cg-text-3xl) * 1.7)
125
+ );
126
+
127
+ --cg-leading-tight: 1.02;
128
+ --cg-leading-snug: 1.15;
129
+ --cg-leading-normal: 1.5;
130
+ --cg-leading-relaxed: 1.68;
131
+
132
+ --cg-tracking-tighter: -0.035em;
133
+ --cg-tracking-tight: -0.02em;
134
+ --cg-tracking-snug: -0.01em;
135
+ --cg-tracking-normal: 0em;
136
+ --cg-tracking-wide: 0.09em;
137
+ --cg-tracking-wider: 0.16em;
138
+
139
+ --cg-weight-regular: 400;
140
+ --cg-weight-medium: 500;
141
+ --cg-weight-semibold: 600;
142
+ --cg-weight-bold: 700;
143
+ --cg-weight-black: 800;
144
+ }
145
+
146
+ /* --------------------------------------------------------------------------
147
+ Radius — kept small and mostly square: a brutalist-editorial system draws
148
+ its softness from generous space and huge type, not from rounded corners.
149
+ -------------------------------------------------------------------------- */
150
+
151
+ :where(:root) {
152
+ --cg-radius-xs: calc(var(--cogenta-radius-sm) / 2);
153
+ --cg-radius-sm: var(--cogenta-radius-sm);
154
+ --cg-radius-md: var(--cogenta-radius-md);
155
+ --cg-radius-lg: var(--cogenta-radius-lg);
156
+ --cg-radius-pill: 999rem;
157
+ }
158
+
159
+ /* --------------------------------------------------------------------------
160
+ Motion
161
+ -------------------------------------------------------------------------- */
162
+
163
+ :where(:root) {
164
+ --cg-duration-fast: calc(var(--cogenta-motion-duration) * 0.55);
165
+ --cg-duration: var(--cogenta-motion-duration);
166
+ --cg-duration-slow: calc(var(--cogenta-motion-duration) * 3.2);
167
+ --cg-ease: var(--cogenta-motion-easing);
168
+ }
169
+
170
+ /* --------------------------------------------------------------------------
171
+ Colour — one palette per scheme, both derived from the same seven tokens.
172
+ --------------------------------------------------------------------------
173
+
174
+ The block below declares the **light** palette in plain terms; the scheme
175
+ aware values live in the `@supports` block after it.
176
+
177
+ **The dark palette is designed, not inverted — this theme's own five
178
+ decisions, not a restatement of any other theme's:**
179
+
180
+ 1. *Elevation changes colour, never shape (L25 D5, binding: no glow).* In
181
+ light, this is a brutalist system: a raised surface carries a hard,
182
+ unblurred offset shadow straight from the skin's own `shadow.sm`/
183
+ `shadow.md` tokens — a shape that reads as "cut paper laid on paper".
184
+ A near-black shadow is invisible on a dark ground, so dark elevation
185
+ keeps the *exact same* hard, zero-blur offset geometry and only
186
+ recolours it in `--cg-line-strong` — the same brighter-than-surface
187
+ line this palette already uses for depth (decision 5, below). An
188
+ earlier version of this system read that shadow as a soft accent glow
189
+ instead; that is precisely the generic "AI-generated" register the
190
+ product owner ruled out, so elevation now stays flat in both schemes.
191
+ 2. *The accent is pushed toward neon, not merely lifted.* Dark ink makes a
192
+ mid-saturation accent read as merely "lighter"; this palette both lifts
193
+ *and* re-saturates it (`calc(c * 1.05)` against light mode's own
194
+ chroma), because a portfolio in dark mode is exactly the context an
195
+ "electric" accent is chosen for in the first place.
196
+ 3. *The accent foreground follows, ink-dark and warmed by the same hue*, so
197
+ a button never reads as a light chip pasted onto a light accent.
198
+ 4. *Text carries the accent's own warmth, not a neutral grey.* Ink in dark
199
+ mode is not merely "off white" — its hue is drawn from the accent, so
200
+ the whole dark page reads as one lit surface rather than white text
201
+ dropped onto an unrelated background.
202
+ 5. *Borders in dark mode are drawn brighter than the surface they outline*,
203
+ because this system replaces shadow-as-depth with line-as-depth in dark
204
+ mode (decision 1) — the border is doing elevation's job, so it has to be
205
+ visible on its own, not merely "a shade darker than the panel".
206
+
207
+ Every ratio below is computed for real, from this file, by
208
+ `test/design-system.test.ts` — in both schemes, against the AA body
209
+ threshold.
210
+
211
+ Known limit, matching the same one `theme-canonical` records: the
212
+ derivation assumes a light-first skin (`bg` lighter than `fg`), which is
213
+ contract D's default and every current blueprint. A skin that is already
214
+ dark would need a second colour group in the contract — a `theme@2.0`
215
+ bump, not a change this theme can make on its own.
216
+ -------------------------------------------------------------------------- */
217
+
218
+ :where(:root) {
219
+ --cg-canvas: var(--cogenta-color-bg);
220
+ --cg-surface: var(--cogenta-color-bg);
221
+ --cg-surface-raised: var(--cogenta-color-bg);
222
+ --cg-surface-sunken: var(--cogenta-color-muted);
223
+ --cg-surface-tinted: color-mix(in oklab, var(--cogenta-color-accent) 9%, var(--cogenta-color-bg));
224
+ --cg-surface-inverted: var(--cogenta-color-fg);
225
+ --cg-surface-inverted-fg: var(--cogenta-color-bg);
226
+
227
+ --cg-ink: var(--cogenta-color-fg);
228
+ --cg-ink-muted: var(--cogenta-color-muted-fg);
229
+ --cg-ink-subtle: color-mix(in oklab, var(--cogenta-color-muted-fg) 86%, var(--cogenta-color-bg));
230
+
231
+ --cg-accent: var(--cogenta-color-accent);
232
+ --cg-accent-fg: var(--cogenta-color-accent-fg);
233
+ --cg-accent-hover: color-mix(in oklab, var(--cogenta-color-accent) 88%, var(--cogenta-color-fg));
234
+ --cg-accent-soft: color-mix(in oklab, var(--cogenta-color-accent) 11%, var(--cogenta-color-bg));
235
+ --cg-accent-soft-fg: color-mix(
236
+ in oklab,
237
+ var(--cogenta-color-accent) 70%,
238
+ var(--cogenta-color-fg)
239
+ );
240
+
241
+ --cg-line: var(--cogenta-color-border);
242
+ --cg-line-soft: color-mix(in oklab, var(--cogenta-color-border) 55%, var(--cogenta-color-bg));
243
+ --cg-line-strong: color-mix(in oklab, var(--cogenta-color-border) 60%, var(--cogenta-color-fg));
244
+
245
+ --cg-scrim: color-mix(in oklab, var(--cogenta-color-fg) 64%, transparent);
246
+ }
247
+
248
+ @supports (color: light-dark(currentColor, currentColor)) and
249
+ (color: oklch(from currentColor l c h)) {
250
+ :where(:root) {
251
+ --cg-canvas: light-dark(
252
+ var(--cogenta-color-bg),
253
+ oklch(from var(--cogenta-color-fg) 0.155 calc(c * 0.65) h)
254
+ );
255
+ --cg-surface: light-dark(
256
+ var(--cogenta-color-bg),
257
+ oklch(from var(--cogenta-color-fg) 0.195 calc(c * 0.6) h)
258
+ );
259
+ --cg-surface-raised: light-dark(
260
+ var(--cogenta-color-bg),
261
+ oklch(from var(--cogenta-color-fg) 0.24 calc(c * 0.52) h)
262
+ );
263
+ --cg-surface-sunken: light-dark(
264
+ var(--cogenta-color-muted),
265
+ oklch(from var(--cogenta-color-fg) 0.12 calc(c * 0.75) h)
266
+ );
267
+ --cg-surface-tinted: light-dark(
268
+ color-mix(in oklab, var(--cogenta-color-accent) 9%, var(--cogenta-color-bg)),
269
+ oklch(from var(--cogenta-color-accent) 0.24 calc(c * 0.48) h)
270
+ );
271
+ --cg-surface-inverted: light-dark(
272
+ var(--cogenta-color-fg),
273
+ oklch(from var(--cogenta-color-bg) 0.94 calc(c * 0.4) h)
274
+ );
275
+ --cg-surface-inverted-fg: light-dark(
276
+ var(--cogenta-color-bg),
277
+ oklch(from var(--cogenta-color-fg) 0.14 calc(c * 0.5) h)
278
+ );
279
+
280
+ --cg-ink: light-dark(
281
+ var(--cogenta-color-fg),
282
+ oklch(from var(--cogenta-color-accent) 0.93 0.018 h)
283
+ );
284
+ --cg-ink-muted: light-dark(
285
+ var(--cogenta-color-muted-fg),
286
+ oklch(from var(--cogenta-color-accent) 0.76 0.024 h)
287
+ );
288
+ --cg-ink-subtle: light-dark(
289
+ color-mix(in oklab, var(--cogenta-color-muted-fg) 86%, var(--cogenta-color-bg)),
290
+ oklch(from var(--cogenta-color-accent) 0.65 0.02 h)
291
+ );
292
+
293
+ --cg-accent: light-dark(
294
+ var(--cogenta-color-accent),
295
+ oklch(from var(--cogenta-color-accent) 0.78 calc(c * 1.05) h)
296
+ );
297
+ --cg-accent-fg: light-dark(
298
+ var(--cogenta-color-accent-fg),
299
+ oklch(from var(--cogenta-color-accent) 0.16 calc(c * 0.6) h)
300
+ );
301
+ --cg-accent-hover: light-dark(
302
+ color-mix(in oklab, var(--cogenta-color-accent) 88%, var(--cogenta-color-fg)),
303
+ oklch(from var(--cogenta-color-accent) 0.87 calc(c * 0.95) h)
304
+ );
305
+ --cg-accent-soft: light-dark(
306
+ color-mix(in oklab, var(--cogenta-color-accent) 11%, var(--cogenta-color-bg)),
307
+ oklch(from var(--cogenta-color-accent) 0.32 calc(c * 0.55) h)
308
+ );
309
+ --cg-accent-soft-fg: light-dark(
310
+ color-mix(in oklab, var(--cogenta-color-accent) 70%, var(--cogenta-color-fg)),
311
+ oklch(from var(--cogenta-color-accent) 0.92 calc(c * 0.5) h)
312
+ );
313
+ --cg-line: light-dark(
314
+ var(--cogenta-color-border),
315
+ oklch(from var(--cogenta-color-accent) 0.4 calc(c * 0.24) h)
316
+ );
317
+ --cg-line-soft: light-dark(
318
+ color-mix(in oklab, var(--cogenta-color-border) 55%, var(--cogenta-color-bg)),
319
+ oklch(from var(--cogenta-color-accent) 0.3 calc(c * 0.22) h)
320
+ );
321
+ --cg-line-strong: light-dark(
322
+ color-mix(in oklab, var(--cogenta-color-border) 60%, var(--cogenta-color-fg)),
323
+ oklch(from var(--cogenta-color-accent) 0.62 calc(c * 0.28) h)
324
+ );
325
+ }
326
+ }
327
+
328
+ /* --------------------------------------------------------------------------
329
+ Elevation — a hard, zero-blur offset shadow in both schemes (L25 D5,
330
+ binding: "never glows"). Light reads it in the skin's own near-black
331
+ `--cogenta-shadow-sm`/`-md`; dark cannot reuse those (a near-black shadow
332
+ is invisible on a near-black surface), so it draws the *same* offset
333
+ geometry in `--cg-line-strong` instead — the brighter-than-surface line
334
+ colour this file already uses to do elevation's job in dark mode (see the
335
+ colour system's own decision 5, above). Two literal card corners stacking
336
+ behind one another, never a halo: this replaces what used to be an
337
+ accent-tinted `blur()` glow, which is exactly the "100% AI" look the
338
+ product owner ruled out.
339
+ -------------------------------------------------------------------------- */
340
+
341
+ :where(:root) {
342
+ --cg-ring: inset 0 0 0 1px var(--cg-line);
343
+ --cg-ring-accent: inset 0 0 0 1px var(--cg-accent);
344
+
345
+ --cg-elevation-0: none;
346
+ --cg-elevation-1: var(--cogenta-shadow-sm);
347
+ --cg-elevation-2: var(--cogenta-shadow-md);
348
+ --cg-elevation-3: var(--cogenta-shadow-md), var(--cg-ring);
349
+ }
350
+
351
+ @media (prefers-color-scheme: dark) {
352
+ :where(:root:not([data-theme="light"])) {
353
+ --cg-elevation-1: var(--cg-ring), 0.125rem 0.125rem 0 var(--cg-line-strong);
354
+ --cg-elevation-2: var(--cg-ring), 0.25rem 0.25rem 0 var(--cg-line-strong);
355
+ --cg-elevation-3: var(--cg-ring), 0.4rem 0.4rem 0 var(--cg-line-strong);
356
+ }
357
+ }
358
+
359
+ :where(:root[data-theme="dark"]) {
360
+ --cg-elevation-1: var(--cg-ring), 0.125rem 0.125rem 0 var(--cg-line-strong);
361
+ --cg-elevation-2: var(--cg-ring), 0.25rem 0.25rem 0 var(--cg-line-strong);
362
+ --cg-elevation-3: var(--cg-ring), 0.4rem 0.4rem 0 var(--cg-line-strong);
363
+ }
package/tokens.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "color": {
3
+ "bg": "#fafaf7",
4
+ "fg": "#0a0a0b",
5
+ "accent": "#6d28d9",
6
+ "accentFg": "#ffffff",
7
+ "muted": "#efede7",
8
+ "mutedFg": "#4a4640",
9
+ "border": "#dad7ce"
10
+ },
11
+ "font": {
12
+ "sans": "'Bricolage Grotesque', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Arial, sans-serif",
13
+ "serif": "'Fraunces', ui-serif, Georgia, Cambria, 'Times New Roman', serif",
14
+ "mono": "'JetBrains Mono', ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace",
15
+ "scale": 1.333,
16
+ "baseSize": "1rem"
17
+ },
18
+ "space": {
19
+ "unit": "0.25rem",
20
+ "density": "comfortable"
21
+ },
22
+ "radius": {
23
+ "sm": "0.125rem",
24
+ "md": "0.25rem",
25
+ "lg": "0.5rem"
26
+ },
27
+ "motion": {
28
+ "duration": "180ms",
29
+ "easing": "cubic-bezier(0.16, 1, 0.3, 1)",
30
+ "reduced": true
31
+ },
32
+ "shadow": {
33
+ "sm": "0.125rem 0.125rem 0 rgba(10, 10, 11, 0.9)",
34
+ "md": "0.4rem 0.4rem 0 rgba(10, 10, 11, 0.9)"
35
+ }
36
+ }