@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,1468 @@
1
+ /*
2
+ * The seventeen vocabulary blocks — brutalist-meets-editorial.
3
+ *
4
+ * Nothing here declares a colour, a size, a radius or a duration of its own:
5
+ * a block composes the design system from `tokens.css` and nothing else.
6
+ */
7
+
8
+ /* --- hero ------------------------------------------------------------------
9
+ An asymmetric split with deliberate overlap: the media is pulled into the
10
+ title's own negative margin on wide screens, so the two compete for the
11
+ same strip rather than sitting in tidy, separate columns.
12
+ ------------------------------------------------------------------------- */
13
+
14
+ .cg-hero {
15
+ position: relative;
16
+ display: grid;
17
+ gap: var(--cg-gap-loose);
18
+ margin-block-start: var(--cg-s10);
19
+ }
20
+
21
+ .cg-hero__frame {
22
+ display: flex;
23
+ flex-direction: column;
24
+ align-items: flex-start;
25
+ }
26
+
27
+ @media (min-width: 64rem) {
28
+ .cg-hero {
29
+ grid-template-columns: 1.1fr 0.9fr;
30
+ align-items: center;
31
+ }
32
+
33
+ .cg-hero__media {
34
+ margin-inline-start: calc(var(--cg-gap-loose) * -1.4);
35
+ }
36
+ }
37
+
38
+ .cg-hero__eyebrow {
39
+ display: inline-flex;
40
+ align-items: center;
41
+ margin: 0 0 var(--cg-s6);
42
+ padding-inline-start: var(--cg-s5);
43
+ position: relative;
44
+ color: var(--cg-ink-muted);
45
+ font-family: var(--cogenta-font-mono);
46
+ font-size: var(--cg-text-xs);
47
+ font-weight: var(--cg-weight-medium);
48
+ letter-spacing: var(--cg-tracking-wider);
49
+ text-transform: uppercase;
50
+ }
51
+
52
+ .cg-hero__eyebrow::before {
53
+ content: "";
54
+ position: absolute;
55
+ inset-inline-start: 0;
56
+ inset-block: 0.35em;
57
+ inline-size: var(--cg-s3);
58
+ border-block-start: 1px solid var(--cg-accent);
59
+ }
60
+
61
+ .cg-hero__title {
62
+ margin: 0;
63
+ font-family: var(--cogenta-font-sans);
64
+ font-size: var(--cg-text-hero);
65
+ line-height: var(--cg-leading-tight);
66
+ letter-spacing: var(--cg-tracking-tighter);
67
+ font-weight: var(--cg-weight-black);
68
+ text-wrap: balance;
69
+ }
70
+
71
+ .cg-hero__subtitle {
72
+ margin: var(--cg-s6) 0 0;
73
+ max-inline-size: var(--cg-measure-narrow);
74
+ font-size: var(--cg-text-lg);
75
+ line-height: var(--cg-leading-relaxed);
76
+ color: var(--cg-ink-muted);
77
+ text-wrap: pretty;
78
+ }
79
+
80
+ .cg-hero__media {
81
+ position: relative;
82
+ }
83
+
84
+ .cg-hero__image {
85
+ inline-size: 100%;
86
+ border-radius: var(--cg-radius-md);
87
+ box-shadow: var(--cg-elevation-3);
88
+ }
89
+
90
+ /* --- prose -------------------------------------------------------------- */
91
+
92
+ .cg-prose {
93
+ max-inline-size: var(--cg-measure);
94
+ margin-inline: auto;
95
+ line-height: var(--cg-leading-relaxed);
96
+ }
97
+
98
+ .cg-prose > :first-child {
99
+ margin-block-start: 0;
100
+ }
101
+
102
+ .cg-prose > :last-child {
103
+ margin-block-end: 0;
104
+ }
105
+
106
+ /* The first paragraph of a prose block opens on a dropped capital — the
107
+ editorial signal that this is the start of a piece, not mid-flow. */
108
+ .cg-prose > p:first-child::first-letter {
109
+ float: inline-start;
110
+ padding: 0.02em var(--cg-s2) 0 0;
111
+ font-family: var(--cogenta-font-serif);
112
+ font-weight: var(--cg-weight-semibold);
113
+ font-size: 3.4em;
114
+ line-height: 0.82;
115
+ color: var(--cg-accent);
116
+ }
117
+
118
+ /* Found by looking at a real screenshot: the portfolio blueprint's own
119
+ auto-built "Role / Year" panel (a `prose` block with `variant.background:
120
+ "muted"`, `@cogenta/create-cogenta`'s `portfolio.ts`) inherited this same
121
+ editorial drop cap on its own first word ("Role"), reading as a giant "R"
122
+ rather than a small spec-sheet label. A `prose` block given a background
123
+ variant is a utility panel, not a piece of body copy, so it opts out of
124
+ the editorial capital — same reasoning as the two-value list below.
125
+ `[data-variant-background]` covers both "muted" and "image". */
126
+ .cg-prose[data-variant-background] > p:first-child::first-letter {
127
+ float: none;
128
+ padding: 0;
129
+ font: inherit;
130
+ color: inherit;
131
+ }
132
+
133
+ .cg-prose h2,
134
+ .cg-prose h3,
135
+ .cg-prose h4 {
136
+ font-family: var(--cogenta-font-sans);
137
+ letter-spacing: var(--cg-tracking-tight);
138
+ line-height: var(--cg-leading-snug);
139
+ font-weight: var(--cg-weight-black);
140
+ text-wrap: balance;
141
+ }
142
+
143
+ .cg-prose h2 {
144
+ margin-block: var(--cg-s16) var(--cg-s5);
145
+ font-size: var(--cg-text-2xl);
146
+ }
147
+
148
+ .cg-prose h3 {
149
+ margin-block: var(--cg-s12) var(--cg-s3);
150
+ font-size: var(--cg-text-xl);
151
+ }
152
+
153
+ .cg-prose h4 {
154
+ margin-block: var(--cg-s8) var(--cg-s2);
155
+ font-size: var(--cg-text-md);
156
+ text-transform: uppercase;
157
+ letter-spacing: var(--cg-tracking-wide);
158
+ }
159
+
160
+ .cg-prose p {
161
+ margin-block: var(--cg-s5);
162
+ text-wrap: pretty;
163
+ }
164
+
165
+ .cg-prose ul,
166
+ .cg-prose ol {
167
+ margin-block: var(--cg-s5);
168
+ padding-inline-start: var(--cg-s6);
169
+ }
170
+
171
+ .cg-prose li {
172
+ margin-block: var(--cg-s2);
173
+ padding-inline-start: var(--cg-s1);
174
+ }
175
+
176
+ .cg-prose li::marker {
177
+ color: var(--cg-accent);
178
+ font-family: var(--cogenta-font-mono);
179
+ }
180
+
181
+ .cg-prose strong {
182
+ font-weight: var(--cg-weight-bold);
183
+ color: var(--cg-ink);
184
+ }
185
+
186
+ .cg-prose blockquote {
187
+ margin-block: var(--cg-s10);
188
+ margin-inline: 0;
189
+ padding: var(--cg-s6) var(--cg-s6) var(--cg-s6) var(--cg-s8);
190
+ border-inline-start: 3px solid var(--cg-accent);
191
+ background: var(--cg-surface-sunken);
192
+ color: var(--cg-ink);
193
+ font-family: var(--cogenta-font-serif);
194
+ font-style: italic;
195
+ font-size: var(--cg-text-lg);
196
+ line-height: var(--cg-leading-normal);
197
+ }
198
+
199
+ .cg-prose blockquote > :first-child {
200
+ margin-block-start: 0;
201
+ }
202
+
203
+ .cg-prose blockquote > :last-child {
204
+ margin-block-end: 0;
205
+ }
206
+
207
+ .cg-prose code {
208
+ font-family: var(--cogenta-font-mono);
209
+ font-size: 0.875em;
210
+ background: var(--cg-surface-sunken);
211
+ border-radius: var(--cg-radius-xs);
212
+ box-shadow: var(--cg-ring);
213
+ padding: 0.15em 0.4em;
214
+ }
215
+
216
+ .cg-prose__figure {
217
+ margin-block: var(--cg-s10);
218
+ margin-inline: 0;
219
+ }
220
+
221
+ .cg-prose__figure img {
222
+ inline-size: 100%;
223
+ border-radius: var(--cg-radius-md);
224
+ box-shadow: var(--cg-elevation-2);
225
+ }
226
+
227
+ .cg-prose__figure figcaption {
228
+ margin-block-start: var(--cg-s3);
229
+ color: var(--cg-ink-subtle);
230
+ font-family: var(--cogenta-font-mono);
231
+ font-size: var(--cg-text-xs);
232
+ letter-spacing: var(--cg-tracking-wide);
233
+ line-height: var(--cg-leading-normal);
234
+ }
235
+
236
+ /* --- mediaFigure ----------------------------------------------------------
237
+ A museum-plate treatment: a numbered tag drawn from a page-wide CSS
238
+ counter precedes the caption, so figures number themselves in document
239
+ order without this package tracking an index anywhere.
240
+ ------------------------------------------------------------------------- */
241
+
242
+ .cg-figure {
243
+ margin-inline: auto;
244
+ counter-increment: cg-figure;
245
+ }
246
+
247
+ .cg-figure[data-align="start"],
248
+ .cg-figure[data-align="end"] {
249
+ max-inline-size: calc(var(--cg-measure) / 2);
250
+ }
251
+
252
+ .cg-figure[data-align="start"] {
253
+ float: inline-start;
254
+ margin-inline-end: var(--cg-s6);
255
+ }
256
+
257
+ .cg-figure[data-align="end"] {
258
+ float: inline-end;
259
+ margin-inline-start: var(--cg-s6);
260
+ }
261
+
262
+ .cg-figure[data-align="full"] {
263
+ max-inline-size: none;
264
+ padding-inline: 0;
265
+ }
266
+
267
+ .cg-figure__frame {
268
+ position: relative;
269
+ border: 1px solid var(--cg-line);
270
+ }
271
+
272
+ .cg-figure__media {
273
+ display: block;
274
+ inline-size: 100%;
275
+ aspect-ratio: var(--cg-ratio, auto);
276
+ }
277
+
278
+ .cg-figure[data-align="full"] .cg-figure__frame {
279
+ border-inline: 0;
280
+ }
281
+
282
+ .cg-figure__caption {
283
+ display: flex;
284
+ align-items: baseline;
285
+ gap: var(--cg-s3);
286
+ margin-block-start: var(--cg-s3);
287
+ color: var(--cg-ink-subtle);
288
+ font-size: var(--cg-text-sm);
289
+ line-height: var(--cg-leading-normal);
290
+ text-wrap: pretty;
291
+ }
292
+
293
+ .cg-figure[data-align="full"] .cg-figure__caption {
294
+ max-inline-size: var(--cg-measure);
295
+ margin-inline: auto;
296
+ padding-inline: var(--cg-gutter);
297
+ }
298
+
299
+ .cg-figure__plate {
300
+ flex: none;
301
+ color: var(--cg-ink);
302
+ }
303
+
304
+ .cg-figure__plate::before {
305
+ content: "Fig. " counter(cg-figure, decimal-leading-zero) " — ";
306
+ color: var(--cg-accent);
307
+ font-family: var(--cogenta-font-mono);
308
+ font-weight: var(--cg-weight-medium);
309
+ }
310
+
311
+ .cg-figure__credit {
312
+ color: var(--cg-ink-subtle);
313
+ font-family: var(--cogenta-font-mono);
314
+ font-size: 0.9em;
315
+ }
316
+
317
+ .cg-figure__credit::before {
318
+ content: "— ";
319
+ }
320
+
321
+ /* --- featureGrid ------------------------------------------------------- */
322
+
323
+ .cg-features__items {
324
+ display: grid;
325
+ gap: 1px;
326
+ background: var(--cg-line);
327
+ border: 1px solid var(--cg-line);
328
+ grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
329
+ counter-reset: cg-feature;
330
+ }
331
+
332
+ .cg-feature {
333
+ position: relative;
334
+ counter-increment: cg-feature;
335
+ padding: var(--cg-s8) var(--cg-s6) var(--cg-s6);
336
+ background: var(--cg-surface);
337
+ transition: background-color var(--cg-duration) var(--cg-ease);
338
+ }
339
+
340
+ .cg-feature:hover {
341
+ background: var(--cg-surface-tinted);
342
+ }
343
+
344
+ .cg-feature__link::after {
345
+ content: "";
346
+ position: absolute;
347
+ inset: 0;
348
+ }
349
+
350
+ .cg-feature__link {
351
+ color: inherit;
352
+ text-decoration: none;
353
+ }
354
+
355
+ .cg-feature:hover .cg-feature__link {
356
+ color: var(--cg-accent);
357
+ }
358
+
359
+ .cg-feature__icon {
360
+ display: block;
361
+ margin-block-end: var(--cg-s4);
362
+ color: var(--cg-accent);
363
+ }
364
+
365
+ .cg-feature__index {
366
+ display: block;
367
+ margin-block-end: var(--cg-s6);
368
+ color: var(--cg-line-strong);
369
+ font-family: var(--cogenta-font-mono);
370
+ font-size: var(--cg-text-xl);
371
+ font-weight: var(--cg-weight-medium);
372
+ transition: color var(--cg-duration) var(--cg-ease);
373
+ }
374
+
375
+ .cg-feature__index::before {
376
+ content: counter(cg-feature, decimal-leading-zero);
377
+ }
378
+
379
+ .cg-feature:hover .cg-feature__index {
380
+ color: var(--cg-accent);
381
+ }
382
+
383
+ .cg-feature__title {
384
+ position: relative;
385
+ margin: 0 0 var(--cg-s2);
386
+ font-family: var(--cogenta-font-sans);
387
+ font-size: var(--cg-text-lg);
388
+ font-weight: var(--cg-weight-bold);
389
+ line-height: var(--cg-leading-snug);
390
+ letter-spacing: var(--cg-tracking-snug);
391
+ text-wrap: balance;
392
+ }
393
+
394
+ .cg-feature__text {
395
+ margin: 0;
396
+ color: var(--cg-ink-muted);
397
+ line-height: var(--cg-leading-relaxed);
398
+ text-wrap: pretty;
399
+ }
400
+
401
+ /* --- cta --------------------------------------------------------------- */
402
+
403
+ .cg-cta {
404
+ background: var(--cg-surface-inverted);
405
+ color: var(--cg-surface-inverted-fg);
406
+ }
407
+
408
+ .cg-cta__frame {
409
+ padding: var(--cg-s20) var(--cg-s8);
410
+ text-align: center;
411
+ }
412
+
413
+ .cg-cta__title {
414
+ margin: 0;
415
+ font-family: var(--cogenta-font-sans);
416
+ font-size: var(--cg-text-cta);
417
+ line-height: var(--cg-leading-tight);
418
+ letter-spacing: var(--cg-tracking-tighter);
419
+ font-weight: var(--cg-weight-black);
420
+ text-wrap: balance;
421
+ }
422
+
423
+ .cg-cta__text {
424
+ margin: var(--cg-s5) auto 0;
425
+ max-inline-size: var(--cg-measure-narrow);
426
+ color: color-mix(in oklab, var(--cg-surface-inverted-fg) 78%, transparent);
427
+ font-size: var(--cg-text-lg);
428
+ line-height: var(--cg-leading-relaxed);
429
+ text-wrap: pretty;
430
+ }
431
+
432
+ .cg-cta .cg-actions {
433
+ justify-content: center;
434
+ }
435
+
436
+ .cg-cta .cg-action[data-emphasis="primary"] {
437
+ background: var(--cg-accent);
438
+ color: var(--cg-accent-fg);
439
+ }
440
+
441
+ .cg-cta .cg-action[data-emphasis="secondary"] {
442
+ border-color: currentColor;
443
+ color: inherit;
444
+ }
445
+
446
+ .cg-cta .cg-action[data-emphasis="secondary"]:hover {
447
+ background: var(--cg-surface-inverted-fg);
448
+ color: var(--cg-surface-inverted);
449
+ border-color: var(--cg-surface-inverted-fg);
450
+ }
451
+
452
+ /* --- gallery ------------------------------------------------------------- */
453
+
454
+ .cg-gallery__items {
455
+ display: grid;
456
+ gap: 1px;
457
+ background: var(--cg-line);
458
+ grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
459
+ counter-reset: cg-gallery;
460
+ }
461
+
462
+ .cg-gallery__item {
463
+ position: relative;
464
+ overflow: hidden;
465
+ background: var(--cg-surface);
466
+ counter-increment: cg-gallery;
467
+ }
468
+
469
+ .cg-gallery__index {
470
+ position: absolute;
471
+ inset-block-start: var(--cg-s3);
472
+ inset-inline-start: var(--cg-s3);
473
+ z-index: 1;
474
+ padding: 0.15em 0.5em;
475
+ background: var(--cg-surface-inverted);
476
+ color: var(--cg-surface-inverted-fg);
477
+ font-family: var(--cogenta-font-mono);
478
+ font-size: var(--cg-text-xs);
479
+ opacity: 0;
480
+ transform: translateY(-4px);
481
+ transition:
482
+ opacity var(--cg-duration) var(--cg-ease),
483
+ transform var(--cg-duration) var(--cg-ease);
484
+ }
485
+
486
+ .cg-gallery__index::before {
487
+ content: counter(cg-gallery, decimal-leading-zero);
488
+ }
489
+
490
+ .cg-gallery__item:hover .cg-gallery__index,
491
+ .cg-gallery__item:focus-within .cg-gallery__index {
492
+ opacity: 1;
493
+ transform: translateY(0);
494
+ }
495
+
496
+ .cg-gallery__image {
497
+ inline-size: 100%;
498
+ block-size: 100%;
499
+ filter: grayscale(45%) contrast(1.02);
500
+ transition:
501
+ transform var(--cg-duration-slow) var(--cg-ease),
502
+ filter var(--cg-duration-slow) var(--cg-ease);
503
+ }
504
+
505
+ .cg-gallery__item:hover .cg-gallery__image {
506
+ transform: scale(1.05);
507
+ filter: grayscale(0%) contrast(1.02);
508
+ }
509
+
510
+ .cg-gallery:not([data-layout="masonry"]) .cg-gallery__image {
511
+ aspect-ratio: 4 / 3;
512
+ }
513
+
514
+ .cg-gallery[data-layout="masonry"] .cg-gallery__items {
515
+ display: block;
516
+ columns: 3 14rem;
517
+ column-gap: 1px;
518
+ background: none;
519
+ }
520
+
521
+ .cg-gallery[data-layout="masonry"] .cg-gallery__item {
522
+ break-inside: avoid;
523
+ margin-block-end: 1px;
524
+ }
525
+
526
+ .cg-gallery[data-layout="carousel"] .cg-gallery__items {
527
+ grid-auto-flow: column;
528
+ grid-auto-columns: minmax(16rem, 40%);
529
+ }
530
+
531
+ .cg-gallery[data-layout="carousel"] .cg-gallery__item {
532
+ scroll-snap-align: start;
533
+ }
534
+
535
+ /* --- quote ----------------------------------------------------------------
536
+ Left-aligned at display scale, the way a feature breaks a quote out of the
537
+ column rather than centring it as an aside.
538
+ ------------------------------------------------------------------------- */
539
+
540
+ .cg-quote {
541
+ max-inline-size: var(--cg-page-narrow);
542
+ margin-inline: auto;
543
+ }
544
+
545
+ .cg-quote::before {
546
+ content: "\201C" / "";
547
+ display: block;
548
+ margin-block-end: calc(var(--cg-s6) * -1);
549
+ color: var(--cg-accent);
550
+ font-family: var(--cogenta-font-serif);
551
+ font-size: calc(var(--cg-text-quote) * 1.6);
552
+ line-height: 1;
553
+ }
554
+
555
+ .cg-quote__text {
556
+ margin: 0;
557
+ font-family: var(--cogenta-font-serif);
558
+ font-size: var(--cg-text-quote);
559
+ line-height: var(--cg-leading-snug);
560
+ letter-spacing: var(--cg-tracking-snug);
561
+ text-wrap: balance;
562
+ }
563
+
564
+ .cg-quote__attribution {
565
+ display: flex;
566
+ align-items: center;
567
+ gap: var(--cg-s3);
568
+ margin-block-start: var(--cg-s8);
569
+ padding-block-start: var(--cg-s5);
570
+ border-block-start: 1px solid var(--cg-line);
571
+ color: var(--cg-ink-muted);
572
+ font-family: var(--cogenta-font-mono);
573
+ font-size: var(--cg-text-sm);
574
+ }
575
+
576
+ .cg-quote__avatar {
577
+ inline-size: var(--cg-s12);
578
+ block-size: var(--cg-s12);
579
+ border-radius: var(--cg-radius-pill);
580
+ box-shadow: var(--cg-ring);
581
+ }
582
+
583
+ .cg-quote__names {
584
+ display: flex;
585
+ flex-wrap: wrap;
586
+ align-items: baseline;
587
+ gap: var(--cg-s2);
588
+ }
589
+
590
+ .cg-quote__author {
591
+ font-weight: var(--cg-weight-semibold);
592
+ color: var(--cg-ink);
593
+ text-transform: uppercase;
594
+ letter-spacing: var(--cg-tracking-wide);
595
+ }
596
+
597
+ .cg-quote__role::before {
598
+ content: "— ";
599
+ }
600
+
601
+ /* --- faq ------------------------------------------------------------------
602
+ A plus mark drawn from two rotated bars, replacing the native marker;
603
+ `[open]` rotates it into a cross.
604
+ ------------------------------------------------------------------------- */
605
+
606
+ .cg-faq {
607
+ max-inline-size: var(--cg-page-narrow);
608
+ margin-inline: auto;
609
+ }
610
+
611
+ .cg-faq__items {
612
+ border-block-start: 1px solid var(--cg-line);
613
+ }
614
+
615
+ .cg-faq__item {
616
+ border-block-end: 1px solid var(--cg-line);
617
+ }
618
+
619
+ .cg-faq__question {
620
+ display: flex;
621
+ align-items: center;
622
+ justify-content: space-between;
623
+ gap: var(--cg-s4);
624
+ padding: var(--cg-s6) 0;
625
+ font-family: var(--cogenta-font-sans);
626
+ font-size: var(--cg-text-lg);
627
+ font-weight: var(--cg-weight-bold);
628
+ cursor: pointer;
629
+ list-style: none;
630
+ transition: color var(--cg-duration) var(--cg-ease);
631
+ }
632
+
633
+ .cg-faq__question::-webkit-details-marker {
634
+ display: none;
635
+ }
636
+
637
+ .cg-faq__question:hover {
638
+ color: var(--cg-accent);
639
+ }
640
+
641
+ /* The plus/cross itself, clipped flat from a solid fill on the trailing
642
+ pseudo-element's own box rather than drawn from borders or a gradient, so
643
+ it stays perfectly centred at any font size. */
644
+ .cg-faq__question::after {
645
+ content: "";
646
+ flex: none;
647
+ inline-size: 0.9em;
648
+ block-size: 0.9em;
649
+ background: currentColor;
650
+ clip-path: polygon(
651
+ 43% 0%,
652
+ 57% 0%,
653
+ 57% 43%,
654
+ 100% 43%,
655
+ 100% 57%,
656
+ 57% 57%,
657
+ 57% 100%,
658
+ 43% 100%,
659
+ 43% 57%,
660
+ 0% 57%,
661
+ 0% 43%,
662
+ 43% 43%
663
+ );
664
+ transition: transform var(--cg-duration) var(--cg-ease);
665
+ }
666
+
667
+ .cg-faq__details[open] .cg-faq__question::after {
668
+ transform: rotate(90deg);
669
+ }
670
+
671
+ .cg-faq__details[open] .cg-faq__question {
672
+ color: var(--cg-accent);
673
+ }
674
+
675
+ .cg-faq__answer {
676
+ padding: 0 0 var(--cg-s6);
677
+ max-inline-size: var(--cg-measure-narrow);
678
+ color: var(--cg-ink-muted);
679
+ line-height: var(--cg-leading-relaxed);
680
+ }
681
+
682
+ .cg-faq__answer > :first-child {
683
+ margin-block-start: 0;
684
+ }
685
+
686
+ .cg-faq__answer > :last-child {
687
+ margin-block-end: 0;
688
+ }
689
+
690
+ /* --- stats --------------------------------------------------------------- */
691
+
692
+ .cg-stats__items {
693
+ display: grid;
694
+ gap: 1px;
695
+ background: var(--cg-line);
696
+ border: 1px solid var(--cg-line);
697
+ grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
698
+ margin: 0;
699
+ }
700
+
701
+ .cg-stat {
702
+ display: flex;
703
+ flex-direction: column-reverse;
704
+ gap: var(--cg-s2);
705
+ padding: var(--cg-s6);
706
+ background: var(--cg-surface);
707
+ }
708
+
709
+ .cg-stat__value {
710
+ display: flex;
711
+ align-items: baseline;
712
+ gap: var(--cg-s1);
713
+ margin: 0;
714
+ color: var(--cg-ink);
715
+ font-family: var(--cogenta-font-sans);
716
+ font-size: var(--cg-text-stat);
717
+ font-weight: var(--cg-weight-black);
718
+ line-height: var(--cg-leading-tight);
719
+ letter-spacing: var(--cg-tracking-tight);
720
+ font-variant-numeric: tabular-nums;
721
+ }
722
+
723
+ .cg-stat__unit {
724
+ color: var(--cg-accent);
725
+ font-family: var(--cogenta-font-mono);
726
+ font-size: var(--cg-text-md);
727
+ font-weight: var(--cg-weight-medium);
728
+ }
729
+
730
+ .cg-stat__label {
731
+ color: var(--cg-ink-muted);
732
+ font-family: var(--cogenta-font-mono);
733
+ font-size: var(--cg-text-xs);
734
+ font-weight: var(--cg-weight-medium);
735
+ letter-spacing: var(--cg-tracking-wide);
736
+ text-transform: uppercase;
737
+ }
738
+
739
+ /* --- logos ----------------------------------------------------------------
740
+ A single-row ledger: a running index beside each mark, desaturated until
741
+ hover or focus resolves it to full ink.
742
+ ------------------------------------------------------------------------- */
743
+
744
+ .cg-logos__items {
745
+ display: flex;
746
+ flex-wrap: wrap;
747
+ gap: 0;
748
+ border-block-start: 1px solid var(--cg-line);
749
+ }
750
+
751
+ .cg-logo {
752
+ display: flex;
753
+ align-items: center;
754
+ gap: var(--cg-s3);
755
+ padding: var(--cg-s5) var(--cg-s6);
756
+ flex: 1 1 12rem;
757
+ border-block-end: 1px solid var(--cg-line);
758
+ border-inline-end: 1px solid var(--cg-line);
759
+ }
760
+
761
+ .cg-logo__index {
762
+ flex: none;
763
+ color: var(--cg-line-strong);
764
+ font-family: var(--cogenta-font-mono);
765
+ font-size: var(--cg-text-xs);
766
+ }
767
+
768
+ .cg-logo__image {
769
+ block-size: var(--cg-s10);
770
+ inline-size: auto;
771
+ max-inline-size: 100%;
772
+ object-fit: contain;
773
+ filter: grayscale(100%);
774
+ opacity: 0.65;
775
+ transition:
776
+ opacity var(--cg-duration) var(--cg-ease),
777
+ filter var(--cg-duration) var(--cg-ease);
778
+ }
779
+
780
+ .cg-logo__link {
781
+ display: inline-flex;
782
+ align-items: center;
783
+ justify-content: center;
784
+ }
785
+
786
+ .cg-logo:hover .cg-logo__image,
787
+ .cg-logo__link:focus-visible .cg-logo__image {
788
+ opacity: 1;
789
+ filter: grayscale(0%);
790
+ }
791
+
792
+ .cg-logo:hover .cg-logo__index {
793
+ color: var(--cg-accent);
794
+ }
795
+
796
+ /* --- collectionList ---------------------------------------------------
797
+ An editorial index: numbered rows, the title set big, the date pushed to
798
+ the far edge. `data-layout="grid"`/`"carousel"` retile the same rows.
799
+ ------------------------------------------------------------------------- */
800
+
801
+ .cg-collection__items {
802
+ margin: 0;
803
+ padding: 0;
804
+ /* Found by looking at a real screenshot: without this, the browser's own
805
+ `<ol>` decimal marker ("1.") sat right beside this theme's own
806
+ `.cg-entry__index` badge ("01") — two numbering systems stacked, on
807
+ every layout, since this rule predates L25. */
808
+ list-style: none;
809
+ border-block-start: 1px solid var(--cg-line);
810
+ }
811
+
812
+ .cg-entry {
813
+ position: relative;
814
+ border-block-end: 1px solid var(--cg-line);
815
+ }
816
+
817
+ .cg-entry__body {
818
+ display: grid;
819
+ grid-template-columns: auto 1fr auto;
820
+ align-items: baseline;
821
+ column-gap: var(--cg-s5);
822
+ padding-block: var(--cg-s6);
823
+ transition: background-color var(--cg-duration) var(--cg-ease);
824
+ }
825
+
826
+ .cg-entry:hover .cg-entry__body {
827
+ background: var(--cg-surface-tinted);
828
+ }
829
+
830
+ .cg-entry__index {
831
+ grid-column: 1;
832
+ color: var(--cg-line-strong);
833
+ font-family: var(--cogenta-font-mono);
834
+ font-size: var(--cg-text-sm);
835
+ transition: color var(--cg-duration) var(--cg-ease);
836
+ }
837
+
838
+ .cg-entry:hover .cg-entry__index {
839
+ color: var(--cg-accent);
840
+ }
841
+
842
+ .cg-entry__title {
843
+ grid-column: 2;
844
+ margin: 0;
845
+ font-family: var(--cogenta-font-sans);
846
+ font-size: var(--cg-text-xl);
847
+ font-weight: var(--cg-weight-bold);
848
+ line-height: var(--cg-leading-snug);
849
+ letter-spacing: var(--cg-tracking-snug);
850
+ text-wrap: balance;
851
+ }
852
+
853
+ .cg-entry__link {
854
+ color: inherit;
855
+ text-decoration: none;
856
+ }
857
+
858
+ .cg-entry__link::after {
859
+ content: "";
860
+ position: absolute;
861
+ inset: 0;
862
+ }
863
+
864
+ .cg-entry:hover .cg-entry__link {
865
+ color: var(--cg-accent);
866
+ }
867
+
868
+ .cg-entry__date {
869
+ grid-column: 3;
870
+ color: var(--cg-ink-subtle);
871
+ font-family: var(--cogenta-font-mono);
872
+ font-size: var(--cg-text-xs);
873
+ letter-spacing: var(--cg-tracking-wide);
874
+ text-transform: uppercase;
875
+ white-space: nowrap;
876
+ }
877
+
878
+ .cg-entry__excerpt {
879
+ grid-column: 2 / span 1;
880
+ margin: var(--cg-s2) 0 0;
881
+ color: var(--cg-ink-muted);
882
+ font-size: var(--cg-text-sm);
883
+ line-height: var(--cg-leading-relaxed);
884
+ display: -webkit-box;
885
+ -webkit-box-orient: vertical;
886
+ -webkit-line-clamp: 2;
887
+ line-clamp: 2;
888
+ overflow: hidden;
889
+ }
890
+
891
+ .cg-collection__empty {
892
+ padding: var(--cg-s10);
893
+ border: 1px dashed var(--cg-line-strong);
894
+ color: var(--cg-ink-subtle);
895
+ text-align: center;
896
+ }
897
+
898
+ /* Tiled layouts (`grid`/`carousel`) retile the same entries into full-bleed
899
+ project cards — a cover, the index, the title in display type, and the
900
+ entry's own raw `role`/`year` meta line when the collection behind it has
901
+ them. `grid`: one column at 360, two full-bleed columns from 1280
902
+ (`--cg-page` is wide enough that "full-bleed" here means "no gutter
903
+ between the two", not "past the viewport edge"). `carousel`: the same
904
+ card, horizontally scroll-snapped. */
905
+ .cg-collection[data-layout="grid"] .cg-collection__items,
906
+ .cg-collection[data-layout="carousel"] .cg-collection__items {
907
+ display: grid;
908
+ gap: var(--cg-gap-loose);
909
+ border-block-start: 0;
910
+ }
911
+
912
+ .cg-collection[data-layout="grid"] .cg-collection__items {
913
+ grid-template-columns: 1fr;
914
+ }
915
+
916
+ @media (min-width: 80rem) {
917
+ .cg-collection[data-layout="grid"] .cg-collection__items {
918
+ grid-template-columns: 1fr 1fr;
919
+ }
920
+ }
921
+
922
+ .cg-collection[data-layout="carousel"] .cg-collection__items {
923
+ grid-auto-flow: column;
924
+ grid-auto-columns: minmax(20rem, 80%);
925
+ }
926
+
927
+ @media (min-width: 48rem) {
928
+ .cg-collection[data-layout="carousel"] .cg-collection__items {
929
+ grid-auto-columns: minmax(22rem, 45%);
930
+ }
931
+ }
932
+
933
+ .cg-collection[data-layout="carousel"] .cg-entry {
934
+ scroll-snap-align: start;
935
+ }
936
+
937
+ .cg-entry--card {
938
+ border-block-end: 0;
939
+ }
940
+
941
+ .cg-entry--card .cg-entry__body {
942
+ display: block;
943
+ padding-block: 0;
944
+ }
945
+
946
+ /* A flat offset shadow on hover/focus, never a blur — `translate` is the
947
+ only motion, gated by `prefers-reduced-motion` in `base.css`'s global
948
+ rule. */
949
+ .cg-entry--card .cg-entry__cover-link {
950
+ display: block;
951
+ position: relative;
952
+ margin-block-end: var(--cg-s5);
953
+ border: 1px solid var(--cg-line);
954
+ transition:
955
+ transform var(--cg-duration) var(--cg-ease),
956
+ box-shadow var(--cg-duration) var(--cg-ease);
957
+ }
958
+
959
+ .cg-entry--card:hover .cg-entry__cover-link,
960
+ .cg-entry--card:focus-within .cg-entry__cover-link {
961
+ transform: translate(-0.3rem, -0.3rem);
962
+ box-shadow: var(--cg-elevation-2);
963
+ }
964
+
965
+ .cg-entry__cover,
966
+ .cg-entry__cover-empty {
967
+ display: block;
968
+ inline-size: 100%;
969
+ aspect-ratio: 4 / 3;
970
+ object-fit: cover;
971
+ }
972
+
973
+ .cg-entry__cover-empty {
974
+ background: var(--cg-surface-tinted);
975
+ }
976
+
977
+ .cg-entry--card .cg-entry__index {
978
+ display: block;
979
+ margin-block-end: var(--cg-s2);
980
+ }
981
+
982
+ .cg-entry--card .cg-entry__title {
983
+ font-size: var(--cg-text-2xl);
984
+ }
985
+
986
+ .cg-entry--card .cg-entry__link::after {
987
+ /* The card link target is the cover, not this second copy of `::after` —
988
+ the base rule would otherwise stretch a second full-card hit target on
989
+ top of it and swallow the cover's own link. */
990
+ content: none;
991
+ }
992
+
993
+ .cg-collection__meta {
994
+ display: flex;
995
+ gap: var(--cg-s3);
996
+ margin: var(--cg-s2) 0 0;
997
+ color: var(--cg-ink-subtle);
998
+ font-family: var(--cogenta-font-mono);
999
+ font-size: var(--cg-text-xs);
1000
+ letter-spacing: var(--cg-tracking-wide);
1001
+ text-transform: uppercase;
1002
+ }
1003
+
1004
+ .cg-collection__meta-role::after {
1005
+ content: "·";
1006
+ margin-inline-start: var(--cg-s3);
1007
+ color: var(--cg-line-strong);
1008
+ }
1009
+
1010
+ .cg-collection[data-layout="grid"] .cg-entry__date,
1011
+ .cg-collection[data-layout="carousel"] .cg-entry__date {
1012
+ order: -1;
1013
+ margin-block-end: var(--cg-s2);
1014
+ }
1015
+
1016
+ /* --- embed ------------------------------------------------------------- */
1017
+
1018
+ .cg-embed {
1019
+ aspect-ratio: var(--cg-ratio, 16 / 9);
1020
+ max-inline-size: var(--cg-measure);
1021
+ margin-inline: auto;
1022
+ border: 1px solid var(--cg-line);
1023
+ }
1024
+
1025
+ .cg-embed__frame {
1026
+ inline-size: 100%;
1027
+ block-size: 100%;
1028
+ border: 0;
1029
+ }
1030
+
1031
+ .cg-embed__placeholder {
1032
+ display: flex;
1033
+ flex-direction: column;
1034
+ align-items: center;
1035
+ justify-content: center;
1036
+ gap: var(--cg-s4);
1037
+ block-size: 100%;
1038
+ padding: var(--cg-s8);
1039
+ background: var(--cg-surface-sunken);
1040
+ color: var(--cg-ink-muted);
1041
+ text-align: center;
1042
+ }
1043
+
1044
+ .cg-embed__tag {
1045
+ color: var(--cg-accent);
1046
+ font-family: var(--cogenta-font-mono);
1047
+ font-size: var(--cg-text-xs);
1048
+ letter-spacing: var(--cg-tracking-wide);
1049
+ text-transform: uppercase;
1050
+ }
1051
+
1052
+ .cg-embed__notice {
1053
+ margin: 0;
1054
+ max-inline-size: var(--cg-measure-narrow);
1055
+ line-height: var(--cg-leading-relaxed);
1056
+ text-wrap: pretty;
1057
+ }
1058
+
1059
+ .cg-embed__link {
1060
+ display: inline-flex;
1061
+ align-items: center;
1062
+ min-block-size: 44px;
1063
+ padding: var(--cg-s3) var(--cg-s6);
1064
+ border: 1px solid var(--cg-ink);
1065
+ color: var(--cg-ink);
1066
+ font-family: var(--cogenta-font-mono);
1067
+ font-size: var(--cg-text-sm);
1068
+ font-weight: var(--cg-weight-medium);
1069
+ text-decoration: none;
1070
+ transition:
1071
+ background-color var(--cg-duration) var(--cg-ease),
1072
+ color var(--cg-duration) var(--cg-ease),
1073
+ border-color var(--cg-duration) var(--cg-ease);
1074
+ }
1075
+
1076
+ .cg-embed__link:hover {
1077
+ background: var(--cg-accent);
1078
+ border-color: var(--cg-accent);
1079
+ color: var(--cg-accent-fg);
1080
+ }
1081
+
1082
+ /* --- testimonial (blocks@2.0, RFC 0001) ------------------------------------
1083
+ A bordered card rather than `quote`'s own full-bleed pull quote — this is
1084
+ the shape that survives sitting several-up in a wall, at a quieter scale.
1085
+ ------------------------------------------------------------------------- */
1086
+
1087
+ .cg-testimonial {
1088
+ max-inline-size: var(--cg-page-narrow);
1089
+ margin-inline: auto;
1090
+ padding: var(--cg-s8) var(--cg-s8) var(--cg-s6);
1091
+ border: 1px solid var(--cg-line);
1092
+ background: var(--cg-surface);
1093
+ }
1094
+
1095
+ .cg-testimonial__quote {
1096
+ position: relative;
1097
+ margin: 0;
1098
+ padding-inline-start: var(--cg-s6);
1099
+ font-family: var(--cogenta-font-serif);
1100
+ font-size: var(--cg-text-lg);
1101
+ line-height: var(--cg-leading-relaxed);
1102
+ text-wrap: pretty;
1103
+ }
1104
+
1105
+ .cg-testimonial__quote::before {
1106
+ content: "\201C";
1107
+ position: absolute;
1108
+ inset-inline-start: 0;
1109
+ inset-block-start: -0.1em;
1110
+ color: var(--cg-accent);
1111
+ font-family: var(--cogenta-font-serif);
1112
+ font-size: 1.6em;
1113
+ line-height: 1;
1114
+ }
1115
+
1116
+ .cg-testimonial__quote > :first-child {
1117
+ margin-block-start: 0;
1118
+ }
1119
+
1120
+ .cg-testimonial__quote > :last-child {
1121
+ margin-block-end: 0;
1122
+ }
1123
+
1124
+ .cg-testimonial__attribution {
1125
+ display: flex;
1126
+ align-items: center;
1127
+ gap: var(--cg-s3);
1128
+ margin-block-start: var(--cg-s6);
1129
+ padding-block-start: var(--cg-s5);
1130
+ border-block-start: 1px solid var(--cg-line);
1131
+ color: var(--cg-ink-muted);
1132
+ font-family: var(--cogenta-font-mono);
1133
+ font-size: var(--cg-text-sm);
1134
+ }
1135
+
1136
+ .cg-testimonial__avatar {
1137
+ inline-size: var(--cg-s10);
1138
+ block-size: var(--cg-s10);
1139
+ border-radius: var(--cg-radius-pill);
1140
+ box-shadow: var(--cg-ring);
1141
+ }
1142
+
1143
+ .cg-testimonial__names {
1144
+ display: flex;
1145
+ flex-wrap: wrap;
1146
+ align-items: baseline;
1147
+ gap: var(--cg-s2);
1148
+ }
1149
+
1150
+ .cg-testimonial__name {
1151
+ font-weight: var(--cg-weight-semibold);
1152
+ color: var(--cg-ink);
1153
+ text-transform: uppercase;
1154
+ letter-spacing: var(--cg-tracking-wide);
1155
+ }
1156
+
1157
+ .cg-testimonial__role::before {
1158
+ content: "— ";
1159
+ }
1160
+
1161
+ /* --- pricingTable (blocks@2.0, RFC 0001) -----------------------------------
1162
+ Tiers as bordered columns, the same "cut paper" grid `featureGrid` and
1163
+ `stats` use. The highlighted tier is signalled entirely through the frame
1164
+ (a heavier, accent-coloured border and a slight lift) — never a filled
1165
+ colour block, so the emphasis reads as structural rather than decorative.
1166
+ ------------------------------------------------------------------------- */
1167
+
1168
+ .cg-pricing__title {
1169
+ margin: 0 0 var(--cg-s8);
1170
+ font-family: var(--cogenta-font-sans);
1171
+ font-size: var(--cg-text-2xl);
1172
+ font-weight: var(--cg-weight-black);
1173
+ letter-spacing: var(--cg-tracking-tight);
1174
+ text-wrap: balance;
1175
+ }
1176
+
1177
+ .cg-pricing__tiers {
1178
+ display: grid;
1179
+ gap: var(--cg-s5);
1180
+ margin: 0;
1181
+ padding: 0;
1182
+ list-style: none;
1183
+ grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
1184
+ }
1185
+
1186
+ .cg-pricing__tier {
1187
+ display: flex;
1188
+ flex-direction: column;
1189
+ padding: var(--cg-s8) var(--cg-s6);
1190
+ border: 1px solid var(--cg-line);
1191
+ background: var(--cg-surface);
1192
+ }
1193
+
1194
+ .cg-pricing__tier[data-highlighted="true"] {
1195
+ border-color: var(--cg-accent);
1196
+ border-width: 2px;
1197
+ padding: calc(var(--cg-s8) - 1px) calc(var(--cg-s6) - 1px);
1198
+ box-shadow: var(--cg-elevation-2);
1199
+ }
1200
+
1201
+ .cg-pricing__name {
1202
+ margin: 0 0 var(--cg-s3);
1203
+ font-family: var(--cogenta-font-mono);
1204
+ font-size: var(--cg-text-xs);
1205
+ font-weight: var(--cg-weight-semibold);
1206
+ letter-spacing: var(--cg-tracking-wider);
1207
+ text-transform: uppercase;
1208
+ color: var(--cg-ink-muted);
1209
+ }
1210
+
1211
+ .cg-pricing__tier[data-highlighted="true"] .cg-pricing__name {
1212
+ color: var(--cg-accent);
1213
+ }
1214
+
1215
+ .cg-pricing__price {
1216
+ display: flex;
1217
+ align-items: baseline;
1218
+ gap: var(--cg-s1);
1219
+ margin: 0 0 var(--cg-s6);
1220
+ color: var(--cg-ink);
1221
+ font-family: var(--cogenta-font-sans);
1222
+ font-size: var(--cg-text-2xl);
1223
+ font-weight: var(--cg-weight-black);
1224
+ letter-spacing: var(--cg-tracking-tight);
1225
+ font-variant-numeric: tabular-nums;
1226
+ }
1227
+
1228
+ .cg-pricing__interval {
1229
+ color: var(--cg-ink-muted);
1230
+ font-family: var(--cogenta-font-mono);
1231
+ font-size: var(--cg-text-sm);
1232
+ font-weight: var(--cg-weight-medium);
1233
+ }
1234
+
1235
+ .cg-pricing__features {
1236
+ flex: 1;
1237
+ margin: 0 0 var(--cg-s6);
1238
+ padding: 0;
1239
+ list-style: none;
1240
+ border-block-start: 1px solid var(--cg-line-soft);
1241
+ }
1242
+
1243
+ .cg-pricing__features li {
1244
+ padding: var(--cg-s3) 0;
1245
+ border-block-end: 1px solid var(--cg-line-soft);
1246
+ color: var(--cg-ink-muted);
1247
+ font-size: var(--cg-text-sm);
1248
+ line-height: var(--cg-leading-normal);
1249
+ }
1250
+
1251
+ .cg-pricing__action .cg-action {
1252
+ inline-size: 100%;
1253
+ justify-content: center;
1254
+ }
1255
+
1256
+ /* --- accordion (blocks@2.0, RFC 0001) --------------------------------------
1257
+ `faq`'s own zero-JS mechanism, reused, but drawn as a numbered ledger
1258
+ rather than a wall of questions: a plain rotating caret, not the plus/cross
1259
+ `faq.ts` uses, so the two never look like restatements of one another.
1260
+ ------------------------------------------------------------------------- */
1261
+
1262
+ .cg-accordion {
1263
+ max-inline-size: var(--cg-page-narrow);
1264
+ margin-inline: auto;
1265
+ }
1266
+
1267
+ .cg-accordion__title {
1268
+ margin: 0 0 var(--cg-s2);
1269
+ font-family: var(--cogenta-font-sans);
1270
+ font-size: var(--cg-text-2xl);
1271
+ font-weight: var(--cg-weight-black);
1272
+ letter-spacing: var(--cg-tracking-tight);
1273
+ text-wrap: balance;
1274
+ }
1275
+
1276
+ .cg-accordion__items {
1277
+ margin: 0;
1278
+ padding: 0;
1279
+ list-style: none;
1280
+ border-block-start: 1px solid var(--cg-line);
1281
+ }
1282
+
1283
+ .cg-accordion__item {
1284
+ border-block-end: 1px solid var(--cg-line);
1285
+ }
1286
+
1287
+ .cg-accordion__question {
1288
+ display: flex;
1289
+ align-items: center;
1290
+ gap: var(--cg-s4);
1291
+ padding: var(--cg-s5) 0;
1292
+ cursor: pointer;
1293
+ list-style: none;
1294
+ transition: color var(--cg-duration) var(--cg-ease);
1295
+ }
1296
+
1297
+ .cg-accordion__question::-webkit-details-marker {
1298
+ display: none;
1299
+ }
1300
+
1301
+ .cg-accordion__question::after {
1302
+ content: "";
1303
+ order: 1;
1304
+ margin-inline-start: auto;
1305
+ flex: none;
1306
+ inline-size: 0.7em;
1307
+ block-size: 0.7em;
1308
+ border-inline-end: 2px solid currentColor;
1309
+ border-block-end: 2px solid currentColor;
1310
+ transform: rotate(45deg);
1311
+ transition: transform var(--cg-duration) var(--cg-ease);
1312
+ }
1313
+
1314
+ .cg-accordion__details[open] .cg-accordion__question::after {
1315
+ transform: rotate(225deg);
1316
+ }
1317
+
1318
+ .cg-accordion__details[open] .cg-accordion__question {
1319
+ color: var(--cg-accent);
1320
+ }
1321
+
1322
+ .cg-accordion__index {
1323
+ flex: none;
1324
+ color: var(--cg-line-strong);
1325
+ font-family: var(--cogenta-font-mono);
1326
+ font-size: var(--cg-text-xs);
1327
+ transition: color var(--cg-duration) var(--cg-ease);
1328
+ }
1329
+
1330
+ .cg-accordion__details[open] .cg-accordion__index {
1331
+ color: var(--cg-accent);
1332
+ }
1333
+
1334
+ .cg-accordion__label {
1335
+ font-family: var(--cogenta-font-sans);
1336
+ font-size: var(--cg-text-lg);
1337
+ font-weight: var(--cg-weight-bold);
1338
+ line-height: var(--cg-leading-snug);
1339
+ }
1340
+
1341
+ .cg-accordion__answer {
1342
+ padding: 0 0 var(--cg-s6) calc(var(--cg-s4) + 2ch);
1343
+ max-inline-size: var(--cg-measure-narrow);
1344
+ color: var(--cg-ink-muted);
1345
+ line-height: var(--cg-leading-relaxed);
1346
+ }
1347
+
1348
+ .cg-accordion__answer > :first-child {
1349
+ margin-block-start: 0;
1350
+ }
1351
+
1352
+ .cg-accordion__answer > :last-child {
1353
+ margin-block-end: 0;
1354
+ }
1355
+
1356
+ /* --- statCounter (blocks@2.0, RFC 0001) ------------------------------------
1357
+ A running strip of oversized digits, separated by hairlines — a spec
1358
+ sheet's masthead figures, not `stats`'s own boxed grid of labelled cards.
1359
+ ------------------------------------------------------------------------- */
1360
+
1361
+ .cg-counter__title {
1362
+ margin: 0 0 var(--cg-s8);
1363
+ font-family: var(--cogenta-font-sans);
1364
+ font-size: var(--cg-text-2xl);
1365
+ font-weight: var(--cg-weight-black);
1366
+ letter-spacing: var(--cg-tracking-tight);
1367
+ text-wrap: balance;
1368
+ }
1369
+
1370
+ .cg-counter__items {
1371
+ display: flex;
1372
+ flex-wrap: wrap;
1373
+ margin: 0;
1374
+ padding: 0;
1375
+ list-style: none;
1376
+ border-inline-start: 1px solid var(--cg-line);
1377
+ }
1378
+
1379
+ .cg-counter__item {
1380
+ position: relative;
1381
+ flex: 1 1 10rem;
1382
+ padding: 0 var(--cg-s6) var(--cg-s2);
1383
+ border-inline-end: 1px solid var(--cg-line);
1384
+ }
1385
+
1386
+ .cg-counter__index {
1387
+ display: block;
1388
+ margin-block-end: var(--cg-s3);
1389
+ color: var(--cg-line-strong);
1390
+ font-family: var(--cogenta-font-mono);
1391
+ font-size: var(--cg-text-xs);
1392
+ }
1393
+
1394
+ .cg-counter__value {
1395
+ display: block;
1396
+ color: var(--cg-ink);
1397
+ font-family: var(--cogenta-font-sans);
1398
+ font-size: var(--cg-text-stat);
1399
+ font-weight: var(--cg-weight-black);
1400
+ line-height: var(--cg-leading-tight);
1401
+ letter-spacing: var(--cg-tracking-tight);
1402
+ font-variant-numeric: tabular-nums;
1403
+ }
1404
+
1405
+ .cg-counter__label {
1406
+ display: block;
1407
+ margin-block-start: var(--cg-s2);
1408
+ color: var(--cg-ink-muted);
1409
+ font-family: var(--cogenta-font-mono);
1410
+ font-size: var(--cg-text-xs);
1411
+ font-weight: var(--cg-weight-medium);
1412
+ letter-spacing: var(--cg-tracking-wide);
1413
+ text-transform: uppercase;
1414
+ }
1415
+
1416
+ /* --- logoStrip (blocks@2.0, RFC 0001) --------------------------------------
1417
+ The lighter "as seen in" row: marks set edge to edge with no dividers and
1418
+ no index, unlike `logos`'s own numbered ledger — there is no name or link
1419
+ here to number.
1420
+ ------------------------------------------------------------------------- */
1421
+
1422
+ .cg-logostrip {
1423
+ margin: 0;
1424
+ }
1425
+
1426
+ .cg-logostrip__items {
1427
+ display: flex;
1428
+ flex-wrap: wrap;
1429
+ align-items: center;
1430
+ justify-content: center;
1431
+ gap: var(--cg-s8) var(--cg-s10);
1432
+ margin: 0;
1433
+ padding: 0;
1434
+ list-style: none;
1435
+ }
1436
+
1437
+ .cg-logostrip__item {
1438
+ display: flex;
1439
+ align-items: center;
1440
+ }
1441
+
1442
+ .cg-logostrip__image {
1443
+ block-size: var(--cg-s8);
1444
+ inline-size: auto;
1445
+ max-inline-size: 100%;
1446
+ object-fit: contain;
1447
+ filter: grayscale(100%);
1448
+ opacity: 0.6;
1449
+ transition:
1450
+ opacity var(--cg-duration) var(--cg-ease),
1451
+ filter var(--cg-duration) var(--cg-ease);
1452
+ }
1453
+
1454
+ .cg-logostrip__item:hover .cg-logostrip__image {
1455
+ opacity: 1;
1456
+ filter: grayscale(0%);
1457
+ }
1458
+
1459
+ .cg-logostrip__caption {
1460
+ margin-block-start: var(--cg-s6);
1461
+ color: var(--cg-ink-subtle);
1462
+ font-family: var(--cogenta-font-mono);
1463
+ font-size: var(--cg-text-xs);
1464
+ font-weight: var(--cg-weight-medium);
1465
+ letter-spacing: var(--cg-tracking-wide);
1466
+ text-transform: uppercase;
1467
+ text-align: center;
1468
+ }