@cogenta/theme-association 0.3.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 +21 -0
  3. package/dist/src/index.d.ts.map +1 -0
  4. package/dist/src/index.js +21 -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 +16 -0
  9. package/dist/src/render/blocks/accordion.js.map +1 -0
  10. package/dist/src/render/blocks/collection-list.d.ts +12 -0
  11. package/dist/src/render/blocks/collection-list.d.ts.map +1 -0
  12. package/dist/src/render/blocks/collection-list.js +64 -0
  13. package/dist/src/render/blocks/collection-list.js.map +1 -0
  14. package/dist/src/render/blocks/cta.d.ts +9 -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 +76 -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 +21 -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 +27 -0
  29. package/dist/src/render/blocks/feature-grid.js.map +1 -0
  30. package/dist/src/render/blocks/gallery.d.ts +14 -0
  31. package/dist/src/render/blocks/gallery.d.ts.map +1 -0
  32. package/dist/src/render/blocks/gallery.js +27 -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 +16 -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 +22 -0
  45. package/dist/src/render/blocks/logos.js.map +1 -0
  46. package/dist/src/render/blocks/media-figure.d.ts +12 -0
  47. package/dist/src/render/blocks/media-figure.d.ts.map +1 -0
  48. package/dist/src/render/blocks/media-figure.js +27 -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 +9 -0
  55. package/dist/src/render/blocks/prose.d.ts.map +1 -0
  56. package/dist/src/render/blocks/prose.js +10 -0
  57. package/dist/src/render/blocks/prose.js.map +1 -0
  58. package/dist/src/render/blocks/quote.d.ts +13 -0
  59. package/dist/src/render/blocks/quote.d.ts.map +1 -0
  60. package/dist/src/render/blocks/quote.js +26 -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 +14 -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 +18 -0
  69. package/dist/src/render/blocks/stats.js.map +1 -0
  70. package/dist/src/render/blocks/testimonial.d.ts +11 -0
  71. package/dist/src/render/blocks/testimonial.d.ts.map +1 -0
  72. package/dist/src/render/blocks/testimonial.js +20 -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 +106 -0
  77. package/dist/src/render/chrome.js.map +1 -0
  78. package/dist/src/render/render-block.d.ts +21 -0
  79. package/dist/src/render/render-block.d.ts.map +1 -0
  80. package/dist/src/render/render-block.js +104 -0
  81. package/dist/src/render/render-block.js.map +1 -0
  82. package/dist/src/render/term-archive.d.ts +3 -0
  83. package/dist/src/render/term-archive.d.ts.map +1 -0
  84. package/dist/src/render/term-archive.js +42 -0
  85. package/dist/src/render/term-archive.js.map +1 -0
  86. package/dist/theme.config.d.ts +15 -0
  87. package/dist/theme.config.d.ts.map +1 -0
  88. package/dist/theme.config.js +45 -0
  89. package/dist/theme.config.js.map +1 -0
  90. package/package.json +57 -0
  91. package/src/index.ts +20 -0
  92. package/src/render/blocks/accordion.ts +47 -0
  93. package/src/render/blocks/collection-list.ts +144 -0
  94. package/src/render/blocks/cta.ts +37 -0
  95. package/src/render/blocks/embed.ts +98 -0
  96. package/src/render/blocks/faq.ts +52 -0
  97. package/src/render/blocks/feature-grid.ts +67 -0
  98. package/src/render/blocks/gallery.ts +47 -0
  99. package/src/render/blocks/hero.ts +60 -0
  100. package/src/render/blocks/logo-strip.ts +31 -0
  101. package/src/render/blocks/logos.ts +52 -0
  102. package/src/render/blocks/media-figure.ts +38 -0
  103. package/src/render/blocks/pricing-table.ts +73 -0
  104. package/src/render/blocks/prose.ts +15 -0
  105. package/src/render/blocks/quote.ts +39 -0
  106. package/src/render/blocks/stat-counter.ts +36 -0
  107. package/src/render/blocks/stats.ts +45 -0
  108. package/src/render/blocks/testimonial.ts +36 -0
  109. package/src/render/chrome.ts +134 -0
  110. package/src/render/render-block.ts +140 -0
  111. package/src/render/term-archive.ts +92 -0
  112. package/src/styles/archive.css +129 -0
  113. package/src/styles/base.css +842 -0
  114. package/src/styles/blocks.css +1002 -0
  115. package/src/styles/theme.css +31 -0
  116. package/src/styles/tokens.css +332 -0
  117. package/tokens.json +36 -0
@@ -0,0 +1,31 @@
1
+ /*
2
+ * `@cogenta/theme-association`'s stylesheet — the entry point, and nothing
3
+ * else.
4
+ *
5
+ * Three layers, in the only order that works:
6
+ *
7
+ * tokens.css the design system, derived entirely from the skin's
8
+ * `--cogenta-*` custom properties (contract D)
9
+ * base.css document, accessibility floor, page frame, chrome, actions
10
+ * blocks.css the seventeen vocabulary blocks
11
+ * archive.css the taxonomy-term archive
12
+ *
13
+ * Not one colour, font, radius, duration or shadow is written literally in
14
+ * any of the four: every value comes from a `--cogenta-<group>-<name>`
15
+ * property produced from the skin's tokens, or from a `--cg-*` property
16
+ * composed from those.
17
+ *
18
+ * The Google Fonts request for the two families `tokens.json` names —
19
+ * Nunito for headings (`tokens.json`'s `font.serif` slot, repurposed: it is
20
+ * a rounded humanist sans, not a literal serif, chosen for the warm,
21
+ * friendly display face the brief asks for) and Source Sans 3 for body copy
22
+ * (`font.sans`) — loaded here, once. Both fall back to a real system stack
23
+ * if Google Fonts is unreachable (`tokens.json`'s own fallback text).
24
+ */
25
+
26
+ @import url("https://fonts.googleapis.com/css2?family=Nunito:ital,wght@0,400;0,600;0,700;0,800;0,900;1,700&family=Source+Sans+3:ital,wght@0,400;0,500;0,600;0,700;1,400&display=swap");
27
+
28
+ @import "./tokens.css";
29
+ @import "./base.css";
30
+ @import "./blocks.css";
31
+ @import "./archive.css";
@@ -0,0 +1,332 @@
1
+ /*
2
+ * `@cogenta/theme-association`'s design system.
3
+ *
4
+ * Contract D fixes a *closed* skin token set — seven colours, five type
5
+ * tokens, two spacing tokens, three radii, three motion tokens, two shadows
6
+ * — and refuses any skin that adds one. So this layer adds nothing to the
7
+ * skin: every value below is *derived* from `--cogenta-*` by composition
8
+ * (`calc`, `color-mix`, relative colour syntax). A skin swap rewrites the
9
+ * generated `--cogenta-*` sheet and this whole system follows, with no
10
+ * build 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 scale.** The type steps come from `--cogenta-font-size-*`
17
+ * and the spacing multiplier from `--cogenta-space-scale`, both emitted
18
+ * by `renderSkin` from the same tokens the validator checked.
19
+ *
20
+ * The default skin (`tokens.json`) is a warm, human palette: a deep forest
21
+ * green on a warm ivory ground, generous rounded corners (`--cg-radius-lg`
22
+ * lands at 14px, the brief's own number) and soft shadows rather than
23
+ * hairlines — a community notice board, not a corporate report cover. The
24
+ * dark mode is designed on its own terms (see the colour section below for
25
+ * the choices that make it so), never a mechanical inversion.
26
+ */
27
+
28
+ :where(:root) {
29
+ color-scheme: light dark;
30
+ }
31
+
32
+ :where(:root[data-theme="dark"]) {
33
+ color-scheme: dark;
34
+ }
35
+
36
+ :where(:root[data-theme="light"]) {
37
+ color-scheme: light;
38
+ }
39
+
40
+ /* --------------------------------------------------------------------------
41
+ Space
42
+ -------------------------------------------------------------------------- */
43
+
44
+ :where(:root) {
45
+ --cg-density: var(--cogenta-space-scale, 1);
46
+ --cg-unit: calc(var(--cogenta-space-unit) * var(--cg-density));
47
+
48
+ --cg-s1: calc(var(--cg-unit) * 1);
49
+ --cg-s2: calc(var(--cg-unit) * 2);
50
+ --cg-s3: calc(var(--cg-unit) * 3);
51
+ --cg-s4: calc(var(--cg-unit) * 4);
52
+ --cg-s5: calc(var(--cg-unit) * 5);
53
+ --cg-s6: calc(var(--cg-unit) * 6);
54
+ --cg-s8: calc(var(--cg-unit) * 8);
55
+ --cg-s10: calc(var(--cg-unit) * 10);
56
+ --cg-s12: calc(var(--cg-unit) * 12);
57
+ --cg-s16: calc(var(--cg-unit) * 16);
58
+ --cg-s20: calc(var(--cg-unit) * 20);
59
+ --cg-s28: calc(var(--cg-unit) * 28);
60
+
61
+ --cg-gutter: var(--cg-s6);
62
+ --cg-gap-tight: var(--cg-s2);
63
+ --cg-gap: var(--cg-s5);
64
+ --cg-gap-loose: var(--cg-s10);
65
+ --cg-section-y: var(--cg-s20);
66
+
67
+ --cg-measure: 68ch;
68
+ --cg-measure-narrow: 44ch;
69
+ --cg-page: 76rem;
70
+ --cg-page-narrow: 50rem;
71
+ }
72
+
73
+ :where([data-density="compact"]) {
74
+ --cg-density: 0.85;
75
+ }
76
+
77
+ :where([data-density="comfortable"]) {
78
+ --cg-density: 1;
79
+ }
80
+
81
+ :where([data-density="spacious"]) {
82
+ --cg-density: 1.2;
83
+ }
84
+
85
+ /* --------------------------------------------------------------------------
86
+ Type — the skin's scale, named; plus the rhythm the scale does not carry.
87
+ -------------------------------------------------------------------------- */
88
+
89
+ :where(:root) {
90
+ --cg-text-xs: var(--cogenta-font-size-xs, 0.72rem);
91
+ --cg-text-sm: var(--cogenta-font-size-sm, 0.86rem);
92
+ --cg-text-md: var(--cogenta-font-size-md, var(--cogenta-font-base-size, 1rem));
93
+ --cg-text-lg: var(--cogenta-font-size-lg, 1.2rem);
94
+ --cg-text-xl: var(--cogenta-font-size-xl, 1.5rem);
95
+ --cg-text-2xl: var(--cogenta-font-size-2xl, 1.9rem);
96
+ --cg-text-3xl: var(--cogenta-font-size-3xl, 2.6rem);
97
+
98
+ --cg-leading-tight: 1.12;
99
+ --cg-leading-snug: 1.28;
100
+ --cg-leading-normal: 1.6;
101
+ --cg-leading-relaxed: 1.75;
102
+
103
+ --cg-tracking-tight: -0.01em;
104
+ --cg-tracking-snug: -0.004em;
105
+ --cg-tracking-normal: 0em;
106
+ --cg-tracking-wide: 0.08em;
107
+
108
+ --cg-weight-regular: 400;
109
+ --cg-weight-medium: 500;
110
+ --cg-weight-semibold: 600;
111
+ --cg-weight-bold: 800;
112
+
113
+ /* Headings use the theme's own display family (`tokens.json`'s
114
+ `font.serif` slot repurposed for Nunito — a rounded, humanist face, not
115
+ a literal serif; see `theme.css`'s own comment). Body text stays on
116
+ `font.sans` (Source Sans 3). */
117
+ --cg-font-display: var(--cogenta-font-serif);
118
+ }
119
+
120
+ /* --------------------------------------------------------------------------
121
+ Radius — generously rounded, the brief's own "14px cards": `--cg-radius-md`
122
+ is the skin's own `radius.md` (14px in `tokens.json`), used for cards;
123
+ `--cg-radius-lg` is bigger again for the hero frame and the impact band.
124
+ `--cg-radius-pill` is used freely for buttons, badges and the eyebrow tag.
125
+ -------------------------------------------------------------------------- */
126
+
127
+ :where(:root) {
128
+ --cg-radius-xs: calc(var(--cogenta-radius-sm) / 2);
129
+ --cg-radius-sm: var(--cogenta-radius-sm);
130
+ --cg-radius-md: var(--cogenta-radius-md);
131
+ --cg-radius-lg: var(--cogenta-radius-lg);
132
+ --cg-radius-xl: calc(var(--cogenta-radius-lg) * 1.4);
133
+ --cg-radius-pill: 999rem;
134
+ }
135
+
136
+ /* --------------------------------------------------------------------------
137
+ Motion
138
+ -------------------------------------------------------------------------- */
139
+
140
+ :where(:root) {
141
+ --cg-duration-fast: calc(var(--cogenta-motion-duration) * 0.65);
142
+ --cg-duration: var(--cogenta-motion-duration);
143
+ --cg-duration-slow: calc(var(--cogenta-motion-duration) * 2.6);
144
+ --cg-ease: var(--cogenta-motion-easing);
145
+ }
146
+
147
+ /* --------------------------------------------------------------------------
148
+ Colour — one palette per scheme, both derived from the same seven tokens.
149
+ --------------------------------------------------------------------------
150
+
151
+ The block below declares the **light** palette in plain terms; the
152
+ scheme-aware values live in the `@supports` block after it, guarded the
153
+ same way `theme-canonical` guards it: a browser that cannot parse
154
+ `light-dark()` still gets a usable light palette rather than an `unset`
155
+ custom property.
156
+
157
+ **This dark palette is designed on its own terms, not inverted:**
158
+
159
+ 1. *Canvas is forest, not charcoal.* Dark mode here is not "generic dark
160
+ mode grey" — it carries the accent's own hue at very low lightness, so
161
+ it reads as "the same warm place at night" rather than a different
162
+ product.
163
+ 2. *The accent is lifted and desaturated*, exactly the technique
164
+ `theme-entreprise` proved: a forest green pushed to the light mode's
165
+ own lightness on a dark canvas reads as neon; lifted to L 0.7 and pulled
166
+ back a third of its chroma it still reads as the same considered green.
167
+ 3. *The accent's foreground flips to ink* — light text on a lifted accent
168
+ fails contrast.
169
+ 4. *Ink carries a trace of warmth* rather than becoming a flat, colourless
170
+ off-white — this palette's whole identity is warmth, and losing it in
171
+ the one place text lives everywhere would be the mechanical-inversion
172
+ mistake in miniature.
173
+ 5. *A border lightens against its surface in dark, darkens in light* — a
174
+ darker line on dark ink is invisible.
175
+
176
+ Known limit, the same one every sibling theme records: the derivation
177
+ assumes a light-first skin (`bg` lighter than `fg`).
178
+ -------------------------------------------------------------------------- */
179
+
180
+ :where(:root) {
181
+ --cg-canvas: var(--cogenta-color-bg);
182
+ --cg-surface: var(--cogenta-color-bg);
183
+ --cg-surface-raised: var(--cogenta-color-bg);
184
+ --cg-surface-sunken: var(--cogenta-color-muted);
185
+ --cg-surface-tinted: color-mix(in oklab, var(--cogenta-color-accent) 8%, var(--cogenta-color-bg));
186
+
187
+ --cg-ink: var(--cogenta-color-fg);
188
+ --cg-ink-muted: var(--cogenta-color-muted-fg);
189
+ --cg-ink-subtle: color-mix(in oklab, var(--cogenta-color-muted-fg) 92%, var(--cogenta-color-bg));
190
+
191
+ --cg-accent: var(--cogenta-color-accent);
192
+ --cg-accent-fg: var(--cogenta-color-accent-fg);
193
+ --cg-accent-hover: color-mix(in oklab, var(--cogenta-color-accent) 85%, var(--cogenta-color-fg));
194
+ --cg-accent-soft: color-mix(in oklab, var(--cogenta-color-accent) 12%, var(--cogenta-color-bg));
195
+ --cg-accent-soft-fg: color-mix(
196
+ in oklab,
197
+ var(--cogenta-color-accent) 72%,
198
+ var(--cogenta-color-fg)
199
+ );
200
+
201
+ /* A warm secondary tint — sun-orange beside the deep-green accent, used
202
+ sparingly (the impact band's unit text, a decorative halo). Derived by
203
+ rotating the accent's own hue toward orange/red rather than a literal
204
+ colour, so a site with a different accent still gets a complementary
205
+ warm tint of *its own* accent. Pre-`@supports`, it is simply the accent
206
+ itself — the safest fallback a browser without relative colour gets. */
207
+ --cg-tint: var(--cogenta-color-accent);
208
+ --cg-tint-soft: color-mix(in oklab, var(--cogenta-color-accent) 14%, var(--cogenta-color-bg));
209
+
210
+ --cg-line: var(--cogenta-color-border);
211
+ --cg-line-soft: color-mix(in oklab, var(--cogenta-color-border) 55%, var(--cogenta-color-bg));
212
+ --cg-line-strong: color-mix(in oklab, var(--cogenta-color-border) 50%, var(--cogenta-color-fg));
213
+
214
+ --cg-scrim: color-mix(in oklab, var(--cogenta-color-fg) 55%, transparent);
215
+ }
216
+
217
+ @supports (color: light-dark(currentColor, currentColor)) and
218
+ (color: oklch(from currentColor l c h)) {
219
+ :where(:root) {
220
+ --cg-canvas: light-dark(
221
+ var(--cogenta-color-bg),
222
+ oklch(from var(--cogenta-color-accent) 0.16 calc(c * 0.45) h)
223
+ );
224
+ --cg-surface: light-dark(
225
+ var(--cogenta-color-bg),
226
+ oklch(from var(--cogenta-color-accent) 0.16 calc(c * 0.45) h)
227
+ );
228
+ --cg-surface-raised: light-dark(
229
+ var(--cogenta-color-bg),
230
+ oklch(from var(--cogenta-color-accent) 0.225 calc(c * 0.42) h)
231
+ );
232
+ --cg-surface-sunken: light-dark(
233
+ var(--cogenta-color-muted),
234
+ oklch(from var(--cogenta-color-accent) 0.125 calc(c * 0.5) h)
235
+ );
236
+ --cg-surface-tinted: light-dark(
237
+ color-mix(in oklab, var(--cogenta-color-accent) 8%, var(--cogenta-color-bg)),
238
+ oklch(from var(--cogenta-color-accent) 0.24 calc(c * 0.5) h)
239
+ );
240
+
241
+ --cg-ink: light-dark(
242
+ var(--cogenta-color-fg),
243
+ oklch(from var(--cogenta-color-accent) 0.94 0.014 h)
244
+ );
245
+ --cg-ink-muted: light-dark(
246
+ var(--cogenta-color-muted-fg),
247
+ oklch(from var(--cogenta-color-accent) 0.78 0.02 h)
248
+ );
249
+ --cg-ink-subtle: light-dark(
250
+ color-mix(in oklab, var(--cogenta-color-muted-fg) 92%, var(--cogenta-color-bg)),
251
+ oklch(from var(--cogenta-color-accent) 0.64 0.017 h)
252
+ );
253
+
254
+ --cg-accent: light-dark(
255
+ var(--cogenta-color-accent),
256
+ oklch(from var(--cogenta-color-accent) 0.7 calc(c * 0.68) h)
257
+ );
258
+ --cg-accent-fg: light-dark(
259
+ var(--cogenta-color-accent-fg),
260
+ oklch(from var(--cogenta-color-accent) 0.15 calc(c * 0.45) h)
261
+ );
262
+ --cg-accent-hover: light-dark(
263
+ color-mix(in oklab, var(--cogenta-color-accent) 85%, var(--cogenta-color-fg)),
264
+ oklch(from var(--cogenta-color-accent) 0.79 calc(c * 0.64) h)
265
+ );
266
+ --cg-accent-soft: light-dark(
267
+ color-mix(in oklab, var(--cogenta-color-accent) 12%, var(--cogenta-color-bg)),
268
+ oklch(from var(--cogenta-color-accent) 0.3 calc(c * 0.42) h)
269
+ );
270
+ --cg-accent-soft-fg: light-dark(
271
+ color-mix(in oklab, var(--cogenta-color-accent) 72%, var(--cogenta-color-fg)),
272
+ oklch(from var(--cogenta-color-accent) 0.89 calc(c * 0.36) h)
273
+ );
274
+
275
+ --cg-tint: light-dark(
276
+ oklch(from var(--cogenta-color-accent) l c calc(h - 150)),
277
+ oklch(from var(--cogenta-color-accent) 0.74 calc(c * 0.6) calc(h - 150))
278
+ );
279
+ --cg-tint-soft: light-dark(
280
+ color-mix(
281
+ in oklab,
282
+ oklch(from var(--cogenta-color-accent) l c calc(h - 150)) 14%,
283
+ var(--cogenta-color-bg)
284
+ ),
285
+ oklch(from var(--cogenta-color-accent) 0.32 calc(c * 0.4) calc(h - 150))
286
+ );
287
+
288
+ --cg-line: light-dark(
289
+ var(--cogenta-color-border),
290
+ oklch(from var(--cogenta-color-accent) 0.36 calc(c * 0.16) h)
291
+ );
292
+ --cg-line-soft: light-dark(
293
+ color-mix(in oklab, var(--cogenta-color-border) 55%, var(--cogenta-color-bg)),
294
+ oklch(from var(--cogenta-color-accent) 0.29 calc(c * 0.14) h)
295
+ );
296
+ --cg-line-strong: light-dark(
297
+ color-mix(in oklab, var(--cogenta-color-border) 50%, var(--cogenta-color-fg)),
298
+ oklch(from var(--cogenta-color-accent) 0.56 calc(c * 0.2) h)
299
+ );
300
+ }
301
+ }
302
+
303
+ /* --------------------------------------------------------------------------
304
+ Elevation — soft shadows over hairlines by default (the brief's own
305
+ "soft shadows"), reserved to a ring only where a shadow would not read
306
+ against the surface (dark mode).
307
+ -------------------------------------------------------------------------- */
308
+
309
+ :where(:root) {
310
+ --cg-ring: inset 0 0 0 1px var(--cg-line);
311
+ --cg-ring-accent: inset 0 0 0 1px var(--cg-accent);
312
+ --cg-ring-strong: inset 0 0 0 1px var(--cg-line-strong);
313
+
314
+ --cg-elevation-0: none;
315
+ --cg-elevation-1: var(--cogenta-shadow-sm);
316
+ --cg-elevation-2: var(--cogenta-shadow-sm);
317
+ --cg-elevation-3: var(--cogenta-shadow-md);
318
+ }
319
+
320
+ @media (prefers-color-scheme: dark) {
321
+ :where(:root:not([data-theme="light"])) {
322
+ --cg-elevation-1: var(--cg-ring);
323
+ --cg-elevation-2: var(--cg-ring-strong);
324
+ --cg-elevation-3: var(--cg-ring-strong), var(--cogenta-shadow-md);
325
+ }
326
+ }
327
+
328
+ :where(:root[data-theme="dark"]) {
329
+ --cg-elevation-1: var(--cg-ring);
330
+ --cg-elevation-2: var(--cg-ring-strong);
331
+ --cg-elevation-3: var(--cg-ring-strong), var(--cogenta-shadow-md);
332
+ }
package/tokens.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "color": {
3
+ "bg": "#FBF3E4",
4
+ "fg": "#22281F",
5
+ "accent": "#1F6B47",
6
+ "accentFg": "#FFFFFF",
7
+ "muted": "#F1E4C9",
8
+ "mutedFg": "#5B4E36",
9
+ "border": "#E3D2AC"
10
+ },
11
+ "font": {
12
+ "sans": "'Source Sans 3', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif",
13
+ "serif": "'Nunito', ui-rounded, 'Segoe UI', system-ui, sans-serif",
14
+ "mono": "ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace",
15
+ "scale": 1.25,
16
+ "baseSize": "1rem"
17
+ },
18
+ "space": {
19
+ "unit": "0.25rem",
20
+ "density": "comfortable"
21
+ },
22
+ "radius": {
23
+ "sm": "0.5rem",
24
+ "md": "0.875rem",
25
+ "lg": "1.5rem"
26
+ },
27
+ "motion": {
28
+ "duration": "220ms",
29
+ "easing": "cubic-bezier(0.16, 1, 0.3, 1)",
30
+ "reduced": true
31
+ },
32
+ "shadow": {
33
+ "sm": "0 2px 8px rgba(35, 25, 10, 0.09)",
34
+ "md": "0 14px 34px rgba(35, 25, 10, 0.16)"
35
+ }
36
+ }