@cogenta/theme-canonical 1.1.2 → 1.3.3

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 (71) hide show
  1. package/dist/src/index.d.ts +1 -0
  2. package/dist/src/index.d.ts.map +1 -1
  3. package/dist/src/index.js +1 -0
  4. package/dist/src/index.js.map +1 -1
  5. package/dist/src/render/arrow-link.d.ts +11 -0
  6. package/dist/src/render/arrow-link.d.ts.map +1 -0
  7. package/dist/src/render/arrow-link.js +29 -0
  8. package/dist/src/render/arrow-link.js.map +1 -0
  9. package/dist/src/render/blocks/collection-list.d.ts +15 -5
  10. package/dist/src/render/blocks/collection-list.d.ts.map +1 -1
  11. package/dist/src/render/blocks/collection-list.js +36 -13
  12. package/dist/src/render/blocks/collection-list.js.map +1 -1
  13. package/dist/src/render/blocks/embed.d.ts.map +1 -1
  14. package/dist/src/render/blocks/embed.js +3 -2
  15. package/dist/src/render/blocks/embed.js.map +1 -1
  16. package/dist/src/render/blocks/gallery.d.ts.map +1 -1
  17. package/dist/src/render/blocks/gallery.js +4 -1
  18. package/dist/src/render/blocks/gallery.js.map +1 -1
  19. package/dist/src/render/blocks/hero.d.ts.map +1 -1
  20. package/dist/src/render/blocks/hero.js +9 -2
  21. package/dist/src/render/blocks/hero.js.map +1 -1
  22. package/dist/src/render/blocks/pricing-table.d.ts.map +1 -1
  23. package/dist/src/render/blocks/pricing-table.js +17 -4
  24. package/dist/src/render/blocks/pricing-table.js.map +1 -1
  25. package/dist/src/render/chrome.d.ts +40 -1
  26. package/dist/src/render/chrome.d.ts.map +1 -1
  27. package/dist/src/render/chrome.js +103 -71
  28. package/dist/src/render/chrome.js.map +1 -1
  29. package/dist/src/render/dates.d.ts +9 -0
  30. package/dist/src/render/dates.d.ts.map +1 -0
  31. package/dist/src/render/dates.js +16 -0
  32. package/dist/src/render/dates.js.map +1 -0
  33. package/dist/src/render/render-block.d.ts.map +1 -1
  34. package/dist/src/render/render-block.js +7 -1
  35. package/dist/src/render/render-block.js.map +1 -1
  36. package/dist/src/render/strings.d.ts +25 -0
  37. package/dist/src/render/strings.d.ts.map +1 -0
  38. package/dist/src/render/strings.js +26 -0
  39. package/dist/src/render/strings.js.map +1 -0
  40. package/dist/src/render/term-archive.d.ts +5 -5
  41. package/dist/src/render/term-archive.d.ts.map +1 -1
  42. package/dist/src/render/term-archive.js +14 -12
  43. package/dist/src/render/term-archive.js.map +1 -1
  44. package/dist/src/render/widget-areas.d.ts +20 -0
  45. package/dist/src/render/widget-areas.d.ts.map +1 -0
  46. package/dist/src/render/widget-areas.js +40 -0
  47. package/dist/src/render/widget-areas.js.map +1 -0
  48. package/package.json +5 -5
  49. package/src/index.ts +1 -0
  50. package/src/render/arrow-link.ts +27 -0
  51. package/src/render/blocks/collection-list.ts +53 -15
  52. package/src/render/blocks/embed.ts +3 -2
  53. package/src/render/blocks/gallery.ts +4 -1
  54. package/src/render/blocks/hero.ts +9 -2
  55. package/src/render/blocks/pricing-table.ts +22 -4
  56. package/src/render/chrome.ts +156 -70
  57. package/src/render/dates.ts +14 -0
  58. package/src/render/render-block.ts +6 -0
  59. package/src/render/strings.ts +30 -0
  60. package/src/render/term-archive.ts +54 -32
  61. package/src/render/widget-areas.ts +44 -0
  62. package/src/styles/archive.css +66 -20
  63. package/src/styles/base.css +266 -680
  64. package/src/styles/blocks.css +678 -811
  65. package/src/styles/chrome.css +469 -0
  66. package/src/styles/listings.css +183 -0
  67. package/src/styles/theme.css +28 -14
  68. package/src/styles/tokens.css +192 -205
  69. package/src/styles/utility.css +295 -0
  70. package/src/styles/widgets.css +1064 -0
  71. package/tokens.json +15 -15
@@ -0,0 +1,469 @@
1
+ /*
2
+ * The site header, its CSS-only menu, and the footer (`src/render/chrome.ts`).
3
+ */
4
+
5
+ /* --------------------------------------------------------------------------
6
+ Header
7
+ -------------------------------------------------------------------------- */
8
+
9
+ .cg-site-header {
10
+ position: relative;
11
+ padding-inline: var(--cg-inset);
12
+ background: var(--cg-canvas);
13
+ border-block-end: var(--cg-rule) solid var(--cg-line);
14
+ }
15
+
16
+ /* Padded rather than given a minimum height: the bar keeps its height when
17
+ the menu panel opens under it. */
18
+ .cg-site-header__inner {
19
+ display: flex;
20
+ flex-wrap: wrap;
21
+ align-items: center;
22
+ align-content: flex-start;
23
+ column-gap: var(--cg-s3);
24
+ padding-block: var(--cg-s3);
25
+ }
26
+
27
+ .cg-site-header__home {
28
+ display: inline-flex;
29
+ align-items: center;
30
+ min-block-size: 2.75rem;
31
+ margin-inline-end: auto;
32
+ color: var(--cg-ink);
33
+ font-size: var(--cg-text-lg);
34
+ font-weight: var(--cg-weight-semibold);
35
+ letter-spacing: var(--cg-tracking-heading);
36
+ line-height: var(--cg-leading-heading);
37
+ text-decoration: none;
38
+ }
39
+
40
+ .cg-site-header__home:hover {
41
+ color: var(--cg-ink);
42
+ }
43
+
44
+ /* The uploaded logo: a fixed height keeps the bar the same for a wide
45
+ wordmark and a square mark, and a maximum width stops a long wordmark from
46
+ pushing the pages off the row. */
47
+ .cg-site-header__logo {
48
+ display: block;
49
+ block-size: 2rem;
50
+ inline-size: auto;
51
+ max-inline-size: 14rem;
52
+ object-fit: contain;
53
+ filter: none;
54
+ }
55
+
56
+ .cg-site-header__nav .cg-menu {
57
+ margin: 0;
58
+ padding: 0;
59
+ list-style: none;
60
+ }
61
+
62
+ .cg-site-header__nav a {
63
+ color: var(--cg-ink);
64
+ font-weight: var(--cg-weight-medium);
65
+ text-decoration-line: none;
66
+ }
67
+
68
+ .cg-site-header__nav a:hover {
69
+ color: var(--cg-accent);
70
+ text-decoration-line: underline;
71
+ }
72
+
73
+ .cg-site-header__nav span {
74
+ color: var(--cg-ink-muted);
75
+ font-weight: var(--cg-weight-medium);
76
+ }
77
+
78
+ .cg-site-header__end {
79
+ display: flex;
80
+ align-items: center;
81
+ gap: var(--cg-s3);
82
+ }
83
+
84
+ .cg-site-header__action {
85
+ min-block-size: 2.5rem;
86
+ padding-inline: var(--cg-s4);
87
+ font-size: var(--cg-text-sm);
88
+ }
89
+
90
+ /* The light/dark control: an outlined square icon button, quieter than the
91
+ header's action so the two never compete. */
92
+ .cg-theme-toggle {
93
+ display: inline-flex;
94
+ align-items: center;
95
+ justify-content: center;
96
+ flex-shrink: 0;
97
+ inline-size: 2.5rem;
98
+ block-size: 2.5rem;
99
+ padding: 0;
100
+ border: var(--cg-rule) solid var(--cg-line);
101
+ border-radius: var(--cg-radius-control);
102
+ background: transparent;
103
+ color: var(--cg-ink);
104
+ cursor: pointer;
105
+ transition:
106
+ background-color var(--cg-duration) var(--cg-ease),
107
+ border-color var(--cg-duration) var(--cg-ease);
108
+ }
109
+
110
+ .cg-theme-toggle:hover {
111
+ border-color: var(--cg-line-strong);
112
+ background: var(--cg-band);
113
+ }
114
+
115
+ .cg-theme-toggle__icon {
116
+ inline-size: 1.125rem;
117
+ block-size: 1.125rem;
118
+ }
119
+
120
+ .cg-theme-toggle__icon--moon {
121
+ display: none;
122
+ }
123
+
124
+ /* The icon shows the appearance in effect: a sun while light, a moon while
125
+ dark, from the same two signals the palette follows. */
126
+ @media (prefers-color-scheme: dark) {
127
+ :where(:root:not([data-theme="light"])) .cg-theme-toggle__icon--sun {
128
+ display: none;
129
+ }
130
+
131
+ :where(:root:not([data-theme="light"])) .cg-theme-toggle__icon--moon {
132
+ display: block;
133
+ }
134
+ }
135
+
136
+ :where(:root[data-theme="dark"]) .cg-theme-toggle__icon--sun {
137
+ display: none;
138
+ }
139
+
140
+ :where(:root[data-theme="dark"]) .cg-theme-toggle__icon--moon {
141
+ display: block;
142
+ }
143
+
144
+ /* --- the menu below the wide breakpoint ----------------------------------- */
145
+
146
+ /* Out of sight, still focusable: the label draws its focus ring instead. */
147
+ .cg-nav-toggle {
148
+ position: absolute;
149
+ inset-block-start: var(--cg-s4);
150
+ inset-inline-end: var(--cg-inset);
151
+ inline-size: 1px;
152
+ block-size: 1px;
153
+ margin: -1px;
154
+ overflow: hidden;
155
+ clip-path: inset(50%);
156
+ white-space: nowrap;
157
+ }
158
+
159
+ .cg-nav-toggle__label {
160
+ display: inline-flex;
161
+ align-items: center;
162
+ min-block-size: 2.5rem;
163
+ padding-inline: var(--cg-s3);
164
+ border: var(--cg-rule) solid var(--cg-line);
165
+ border-radius: var(--cg-radius-control);
166
+ color: var(--cg-ink);
167
+ font-size: var(--cg-text-sm);
168
+ font-weight: var(--cg-weight-semibold);
169
+ cursor: pointer;
170
+ user-select: none;
171
+ transition: border-color var(--cg-duration) var(--cg-ease);
172
+ }
173
+
174
+ .cg-nav-toggle__label:hover {
175
+ border-color: var(--cg-line-strong);
176
+ }
177
+
178
+ .cg-nav-toggle:focus-visible + .cg-nav-toggle__label {
179
+ outline: var(--cg-rule-strong) solid var(--cg-accent);
180
+ outline-offset: 3px;
181
+ }
182
+
183
+ .cg-nav-toggle:checked + .cg-nav-toggle__label {
184
+ border-color: var(--cg-ink);
185
+ }
186
+
187
+ .cg-site-header__nav {
188
+ display: none;
189
+ order: 3;
190
+ flex-basis: 100%;
191
+ margin-block-start: var(--cg-s3);
192
+ border-block-start: var(--cg-rule) solid var(--cg-line);
193
+ }
194
+
195
+ .cg-nav-toggle:checked ~ .cg-site-header__nav {
196
+ display: block;
197
+ }
198
+
199
+ .cg-site-header__nav li + li {
200
+ border-block-start: var(--cg-rule) solid var(--cg-line);
201
+ }
202
+
203
+ .cg-site-header__nav li > a,
204
+ .cg-site-header__nav li > span {
205
+ display: flex;
206
+ align-items: center;
207
+ min-block-size: 3.25rem;
208
+ font-size: var(--cg-text-lg);
209
+ }
210
+
211
+ .cg-site-header__end {
212
+ order: 2;
213
+ }
214
+
215
+ /* With a menu, the action waits at the foot of the panel on a phone. */
216
+ .cg-site-header[data-nav="links"] .cg-site-header__end .cg-site-header__action {
217
+ display: none;
218
+ }
219
+
220
+ .cg-site-header__menu-action {
221
+ padding-block: var(--cg-s4) var(--cg-s6);
222
+ border-block-start: var(--cg-rule) solid var(--cg-line);
223
+ }
224
+
225
+ .cg-site-header__menu-action .cg-action {
226
+ inline-size: 100%;
227
+ }
228
+
229
+ @media (min-width: 56rem) {
230
+ .cg-site-header__inner {
231
+ flex-wrap: nowrap;
232
+ column-gap: var(--cg-s8);
233
+ padding-block: var(--cg-s4);
234
+ }
235
+
236
+ .cg-nav-toggle,
237
+ .cg-nav-toggle__label {
238
+ display: none;
239
+ }
240
+
241
+ .cg-site-header__nav {
242
+ display: block;
243
+ order: 0;
244
+ flex-basis: auto;
245
+ margin: 0;
246
+ padding: 0;
247
+ border: 0;
248
+ }
249
+
250
+ .cg-site-header__nav .cg-menu {
251
+ display: flex;
252
+ flex-wrap: wrap;
253
+ column-gap: var(--cg-s6);
254
+ }
255
+
256
+ .cg-site-header__nav li + li {
257
+ border: 0;
258
+ }
259
+
260
+ .cg-site-header__nav li > a,
261
+ .cg-site-header__nav li > span {
262
+ min-block-size: 2.75rem;
263
+ font-size: var(--cg-text-md);
264
+ }
265
+
266
+ .cg-site-header__end {
267
+ order: 0;
268
+ gap: var(--cg-s4);
269
+ }
270
+
271
+ .cg-site-header[data-nav="links"] .cg-site-header__end .cg-site-header__action {
272
+ display: inline-flex;
273
+ }
274
+
275
+ .cg-site-header__menu-action {
276
+ display: none;
277
+ }
278
+ }
279
+
280
+ /* --------------------------------------------------------------------------
281
+ Footer
282
+ -------------------------------------------------------------------------- */
283
+
284
+ .cg-site-footer {
285
+ padding-block: var(--cg-s16) var(--cg-s8);
286
+ padding-inline: var(--cg-inset);
287
+ background: var(--cg-footer);
288
+ color: var(--cg-ink-muted);
289
+ font-size: var(--cg-text-sm);
290
+ }
291
+
292
+ .cg-site-footer__inner {
293
+ display: grid;
294
+ grid-template-columns: repeat(var(--cg-columns), minmax(0, 1fr));
295
+ column-gap: var(--cg-column-gap);
296
+ row-gap: var(--cg-s12);
297
+ }
298
+
299
+ .cg-site-footer__inner > * {
300
+ grid-column: 1 / -1;
301
+ min-inline-size: 0;
302
+ }
303
+
304
+ .cg-site-footer__name {
305
+ color: var(--cg-ink);
306
+ font-size: var(--cg-text-lg);
307
+ font-weight: var(--cg-weight-semibold);
308
+ letter-spacing: var(--cg-tracking-heading);
309
+ line-height: var(--cg-leading-heading);
310
+ }
311
+
312
+ .cg-site-footer__tagline {
313
+ margin-block-start: var(--cg-s2);
314
+ max-inline-size: var(--cg-measure-narrow);
315
+ color: var(--cg-ink);
316
+ font-size: var(--cg-text-md);
317
+ }
318
+
319
+ .cg-site-footer__about {
320
+ margin-block-start: var(--cg-s6);
321
+ }
322
+
323
+ .cg-site-footer__note {
324
+ max-inline-size: var(--cg-measure-narrow);
325
+ }
326
+
327
+ .cg-site-footer__note + .cg-site-footer__note {
328
+ margin-block-start: var(--cg-s3);
329
+ }
330
+
331
+ .cg-site-footer__social {
332
+ display: flex;
333
+ flex-wrap: wrap;
334
+ gap: var(--cg-s2);
335
+ margin-block-start: var(--cg-s6);
336
+ padding: 0;
337
+ list-style: none;
338
+ }
339
+
340
+ .cg-site-footer__social-item a {
341
+ display: flex;
342
+ align-items: center;
343
+ justify-content: center;
344
+ inline-size: 2.75rem;
345
+ block-size: 2.75rem;
346
+ border: var(--cg-rule) solid var(--cg-line-strong);
347
+ border-radius: var(--cg-radius-control);
348
+ color: var(--cg-ink);
349
+ transition:
350
+ color var(--cg-duration) var(--cg-ease),
351
+ border-color var(--cg-duration) var(--cg-ease);
352
+ }
353
+
354
+ .cg-site-footer__social-item a:hover {
355
+ border-color: var(--cg-ink);
356
+ color: var(--cg-accent);
357
+ }
358
+
359
+ .cg-social__icon {
360
+ inline-size: 1.25rem;
361
+ block-size: 1.25rem;
362
+ }
363
+
364
+ .cg-site-footer__nav {
365
+ display: grid;
366
+ grid-template-columns: repeat(2, minmax(0, 1fr));
367
+ gap: var(--cg-s10) var(--cg-column-gap);
368
+ }
369
+
370
+ .cg-site-footer__heading {
371
+ margin-block-end: var(--cg-s3);
372
+ color: var(--cg-ink);
373
+ font-weight: var(--cg-weight-semibold);
374
+ }
375
+
376
+ .cg-site-footer__nav .cg-menu {
377
+ margin: 0;
378
+ padding: 0;
379
+ list-style: none;
380
+ }
381
+
382
+ .cg-site-footer__nav li + li {
383
+ margin-block-start: var(--cg-s1);
384
+ }
385
+
386
+ .cg-site-footer__nav a,
387
+ .cg-site-footer__nav span {
388
+ display: inline-block;
389
+ padding-block: var(--cg-s1);
390
+ color: var(--cg-ink);
391
+ }
392
+
393
+ .cg-site-footer__nav a {
394
+ text-decoration-line: none;
395
+ }
396
+
397
+ .cg-site-footer__nav a:hover {
398
+ color: var(--cg-accent);
399
+ text-decoration-line: underline;
400
+ }
401
+
402
+ .cg-site-footer__legal {
403
+ display: flex;
404
+ flex-wrap: wrap;
405
+ align-items: center;
406
+ justify-content: space-between;
407
+ gap: var(--cg-s3) var(--cg-s8);
408
+ padding-block-start: var(--cg-s6);
409
+ border-block-start: var(--cg-rule) solid var(--cg-line);
410
+ }
411
+
412
+ .cg-site-footer__copyright {
413
+ font-variant-numeric: tabular-nums;
414
+ }
415
+
416
+ /* Cogenta's credit, or its white-label replacement, as the host sends it. */
417
+ .cg-site-footer__branding {
418
+ display: flex;
419
+ align-items: center;
420
+ }
421
+
422
+ .cg-site-footer__branding a {
423
+ display: flex;
424
+ align-items: center;
425
+ gap: 0.4em;
426
+ color: var(--cg-ink-muted);
427
+ text-decoration-line: none;
428
+ }
429
+
430
+ .cg-site-footer__branding a:hover {
431
+ color: var(--cg-ink);
432
+ }
433
+
434
+ .cg-site-footer__version {
435
+ font-variant-numeric: tabular-nums;
436
+ }
437
+
438
+ .cg-site-footer__brand-logo {
439
+ display: block;
440
+ /* Pixels, not `em`: the footer's small text size would otherwise shrink
441
+ the mark below legibility. */
442
+ block-size: 24px;
443
+ inline-size: auto;
444
+ filter: none;
445
+ }
446
+
447
+ @media (min-width: 48rem) {
448
+ .cg-site-footer__identity {
449
+ grid-column: 1 / span 6;
450
+ }
451
+
452
+ .cg-site-footer__nav {
453
+ grid-column: 7 / -1;
454
+ }
455
+
456
+ .cg-site-footer__nav[data-columns="3"] {
457
+ grid-template-columns: repeat(3, minmax(0, 1fr));
458
+ }
459
+
460
+ .cg-site-footer__legal {
461
+ grid-column: 1 / -1;
462
+ }
463
+ }
464
+
465
+ @media (min-width: 64rem) {
466
+ .cg-site-footer__identity {
467
+ grid-column: 1 / span 5;
468
+ }
469
+ }
@@ -0,0 +1,183 @@
1
+ /*
2
+ * Lists of entries: the `collectionList` block in its three layouts, and the
3
+ * index the term archive shares with it (`src/render/term-archive.ts`).
4
+ *
5
+ * The markup reads title, date, summary, picture; the paint shows the picture
6
+ * first, then the date, then the title (`order`), so a screen reader hears
7
+ * the title first and a sighted reader scans a list by its dates.
8
+ */
9
+
10
+ .cg-collection__items {
11
+ margin: 0;
12
+ padding: 0;
13
+ list-style: none;
14
+ }
15
+
16
+ .cg-entry__body {
17
+ display: flex;
18
+ flex-direction: column;
19
+ }
20
+
21
+ .cg-entry__media {
22
+ order: 0;
23
+ display: block;
24
+ margin-block-end: var(--cg-s5);
25
+ }
26
+
27
+ .cg-entry__image {
28
+ inline-size: 100%;
29
+ aspect-ratio: 3 / 2;
30
+ }
31
+
32
+ .cg-entry__date {
33
+ order: 1;
34
+ margin-block-end: var(--cg-s2);
35
+ color: var(--cg-ink-muted);
36
+ font-size: var(--cg-text-sm);
37
+ }
38
+
39
+ .cg-entry__title {
40
+ order: 2;
41
+ font-size: var(--cg-text-lg);
42
+ line-height: var(--cg-leading-heading);
43
+ }
44
+
45
+ .cg-entry__link {
46
+ color: var(--cg-ink);
47
+ text-decoration-line: none;
48
+ }
49
+
50
+ .cg-entry__link:hover {
51
+ color: var(--cg-accent);
52
+ text-decoration-line: underline;
53
+ }
54
+
55
+ .cg-entry__excerpt {
56
+ order: 3;
57
+ margin-block-start: var(--cg-s3);
58
+ max-inline-size: var(--cg-measure);
59
+ color: var(--cg-ink-muted);
60
+ }
61
+
62
+ /* An empty list says so in a sentence on the reading columns, between
63
+ hairlines, rather than leaving a hole in the page. */
64
+ .cg-collection__empty {
65
+ padding-block: var(--cg-s6);
66
+ border-block: var(--cg-rule) solid var(--cg-line);
67
+ color: var(--cg-ink-muted);
68
+ }
69
+
70
+ /* --- list: an index --------------------------------------------------------- */
71
+
72
+ .cg-collection[data-layout="list"] .cg-entry {
73
+ padding-block: var(--cg-s6);
74
+ border-block-start: var(--cg-rule) solid var(--cg-line);
75
+ }
76
+
77
+ .cg-collection[data-layout="list"] .cg-entry:last-child {
78
+ border-block-end: var(--cg-rule) solid var(--cg-line);
79
+ }
80
+
81
+ .cg-collection[data-layout="list"] .cg-entry__title {
82
+ font-size: var(--cg-text-heading);
83
+ }
84
+
85
+ @media (min-width: 48rem) {
86
+ .cg-collection[data-layout="list"] .cg-collection__items,
87
+ .cg-collection[data-layout="list"] .cg-entry,
88
+ .cg-collection[data-layout="list"] .cg-entry__body {
89
+ display: grid;
90
+ grid-template-columns: subgrid;
91
+ grid-column: 1 / -1;
92
+ }
93
+
94
+ .cg-collection[data-layout="list"] .cg-entry__body {
95
+ align-items: baseline;
96
+ }
97
+
98
+ .cg-collection[data-layout="list"] .cg-entry__date {
99
+ grid-column: 1 / span 3;
100
+ grid-row: 1;
101
+ margin: 0;
102
+ }
103
+
104
+ .cg-collection[data-layout="list"] .cg-entry__title,
105
+ .cg-collection[data-layout="list"] .cg-entry__excerpt {
106
+ grid-column: 4 / span 7;
107
+ }
108
+
109
+ .cg-collection[data-layout="list"] .cg-entry__title {
110
+ grid-row: 1;
111
+ }
112
+ }
113
+
114
+ @media (min-width: 64rem) {
115
+ .cg-collection__empty {
116
+ grid-column: 1 / span 8;
117
+ }
118
+ }
119
+
120
+ /* --- grid: columns of entries ---------------------------------------------- */
121
+
122
+ .cg-collection[data-layout="grid"] .cg-collection__items {
123
+ display: grid;
124
+ grid-template-columns: subgrid;
125
+ row-gap: var(--cg-s12);
126
+ }
127
+
128
+ .cg-collection[data-layout="grid"] .cg-entry {
129
+ grid-column: span 12;
130
+ }
131
+
132
+ /* An entry without a picture opens on a rule, at the height a picture's top
133
+ edge would be. */
134
+ .cg-collection:not([data-layout="list"]) .cg-entry[data-picture="false"] {
135
+ padding-block-start: var(--cg-s4);
136
+ border-block-start: var(--cg-rule) solid var(--cg-line);
137
+ }
138
+
139
+ @media (min-width: 40rem) {
140
+ .cg-collection[data-layout="grid"] .cg-entry {
141
+ grid-column: span 6;
142
+ }
143
+ }
144
+
145
+ @media (min-width: 64rem) {
146
+ .cg-collection[data-layout="grid"] .cg-entry {
147
+ grid-column: span 4;
148
+ }
149
+
150
+ .cg-collection[data-layout="grid"] .cg-entry:first-child:nth-last-child(2),
151
+ .cg-collection[data-layout="grid"] .cg-entry:first-child:nth-last-child(2) ~ .cg-entry,
152
+ .cg-collection[data-layout="grid"] .cg-entry:first-child:nth-last-child(4),
153
+ .cg-collection[data-layout="grid"] .cg-entry:first-child:nth-last-child(4) ~ .cg-entry {
154
+ grid-column: span 6;
155
+ }
156
+ }
157
+
158
+ /* --- carousel: the grid as a row -------------------------------------------- */
159
+
160
+ /* A little more than three entries across on a wide screen and a little more
161
+ than one on a phone: the one cut at the edge is what says the row scrolls. */
162
+ .cg-collection[data-layout="carousel"] .cg-collection__items {
163
+ display: grid;
164
+ grid-auto-flow: column;
165
+ grid-auto-columns: 78%;
166
+ gap: var(--cg-column-gap);
167
+ }
168
+
169
+ @media (min-width: 40rem) {
170
+ .cg-collection[data-layout="carousel"] .cg-collection__items {
171
+ grid-auto-columns: calc((100% - 2 * var(--cg-column-gap)) / 2.4);
172
+ }
173
+ }
174
+
175
+ @media (min-width: 64rem) {
176
+ .cg-collection[data-layout="carousel"] .cg-collection__items {
177
+ grid-auto-columns: calc((100% - 3 * var(--cg-column-gap)) / 3.4);
178
+ }
179
+ }
180
+
181
+ .cg-collection[data-layout="carousel"] .cg-entry {
182
+ scroll-snap-align: start;
183
+ }
@@ -1,26 +1,40 @@
1
1
  /*
2
2
  * The canonical theme's stylesheet — the entry point, and nothing else.
3
3
  *
4
- * Three layers, in the only order that works:
4
+ * tokens.css the design system, derived entirely from the skin's
5
+ * `--cogenta-*` custom properties (contract D)
6
+ * base.css document, accessibility floor, the page frame and grid,
7
+ * page and entry titles, actions, block variants
8
+ * chrome.css the header, its CSS-only menu, and the footer
9
+ * blocks.css the vocabulary blocks
10
+ * listings.css lists of entries: the collection list and its index
11
+ * archive.css the taxonomy-term archive
12
+ * utility.css the search page, a public form, the comment thread
13
+ * widgets.css the widget areas: the sidebar of a reading page, the bands
14
+ * before and after the content, the footer's widget row
5
15
  *
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, actions
9
- * blocks.css the twelve vocabulary blocks
16
+ * Not one colour is written literally in any of them: every value comes from
17
+ * a `--cogenta-*` property or from a `--cg-*` property composed from those.
10
18
  *
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. That is what makes changing skin a rewrite of one generated file with
15
- * no build (L3, "Skins et changement à chaud"). A single hard-coded hex would
16
- * be a colour no skin can change.
19
+ * The one thing this file adds on its own is the Google Fonts request for the
20
+ * two families the default skin names: Instrument Sans for everything a
21
+ * visitor reads, Instrument Serif for the display line of a page and for
22
+ * quotations. A skin only names a family; it never fetches one. A site whose
23
+ * skin names other families simply never uses these faces, and a browser does
24
+ * not download a face nothing uses. `display=swap` keeps text visible while
25
+ * they load, and `cogenta serve` hoists this `@import` above the skin's rules.
17
26
  *
18
- * `@import` is resolved at build time by Astro, and by `@cogenta/cli`'s own
19
- * inliner when `cogenta serve` renders without a build. Both flatten these
20
- * three into one sheet, so no visitor ever pays for three round trips.
27
+ * The relative `@import`s are flattened at build time by Astro, and by
28
+ * `@cogenta/cli`'s inliner when `cogenta serve` renders without a build.
21
29
  */
22
30
 
31
+ @import url("https://fonts.googleapis.com/css2?family=Instrument+Sans:ital,wght@0,400..700;1,400..700&family=Instrument+Serif:ital@0;1&display=swap");
32
+
23
33
  @import "./tokens.css";
24
34
  @import "./base.css";
35
+ @import "./chrome.css";
25
36
  @import "./blocks.css";
37
+ @import "./listings.css";
26
38
  @import "./archive.css";
39
+ @import "./utility.css";
40
+ @import "./widgets.css";