@cogenta/theme-canonical 0.2.0 → 1.1.0
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.
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +4 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/render/actions.d.ts +2 -16
- package/dist/src/render/actions.d.ts.map +1 -1
- package/dist/src/render/actions.js +2 -42
- package/dist/src/render/actions.js.map +1 -1
- package/dist/src/render/blocks/accordion.d.ts +5 -0
- package/dist/src/render/blocks/accordion.d.ts.map +1 -0
- package/dist/src/render/blocks/accordion.js +19 -0
- package/dist/src/render/blocks/accordion.js.map +1 -0
- package/dist/src/render/blocks/collection-list.d.ts +9 -7
- package/dist/src/render/blocks/collection-list.d.ts.map +1 -1
- package/dist/src/render/blocks/collection-list.js +8 -14
- package/dist/src/render/blocks/collection-list.js.map +1 -1
- package/dist/src/render/blocks/feature-grid.d.ts.map +1 -1
- package/dist/src/render/blocks/feature-grid.js +7 -2
- package/dist/src/render/blocks/feature-grid.js.map +1 -1
- package/dist/src/render/blocks/logo-strip.d.ts +5 -0
- package/dist/src/render/blocks/logo-strip.d.ts.map +1 -0
- package/dist/src/render/blocks/logo-strip.js +18 -0
- package/dist/src/render/blocks/logo-strip.js.map +1 -0
- package/dist/src/render/blocks/pricing-table.d.ts +5 -0
- package/dist/src/render/blocks/pricing-table.d.ts.map +1 -0
- package/dist/src/render/blocks/pricing-table.js +29 -0
- package/dist/src/render/blocks/pricing-table.js.map +1 -0
- package/dist/src/render/blocks/stat-counter.d.ts +5 -0
- package/dist/src/render/blocks/stat-counter.d.ts.map +1 -0
- package/dist/src/render/blocks/stat-counter.js +17 -0
- package/dist/src/render/blocks/stat-counter.js.map +1 -0
- package/dist/src/render/blocks/testimonial.d.ts +14 -0
- package/dist/src/render/blocks/testimonial.d.ts.map +1 -0
- package/dist/src/render/blocks/testimonial.js +24 -0
- package/dist/src/render/blocks/testimonial.js.map +1 -0
- package/dist/src/render/chrome.d.ts +3 -0
- package/dist/src/render/chrome.d.ts.map +1 -0
- package/dist/src/render/chrome.js +82 -0
- package/dist/src/render/chrome.js.map +1 -0
- package/dist/src/render/comments.d.ts +3 -0
- package/dist/src/render/comments.d.ts.map +1 -0
- package/dist/src/render/comments.js +3 -0
- package/dist/src/render/comments.js.map +1 -0
- package/dist/src/render/entry.d.ts +2 -6
- package/dist/src/render/entry.d.ts.map +1 -1
- package/dist/src/render/entry.js +2 -34
- package/dist/src/render/entry.js.map +1 -1
- package/dist/src/render/heading.d.ts +2 -13
- package/dist/src/render/heading.d.ts.map +1 -1
- package/dist/src/render/heading.js +2 -33
- package/dist/src/render/heading.js.map +1 -1
- package/dist/src/render/html.d.ts +2 -43
- package/dist/src/render/html.d.ts.map +1 -1
- package/dist/src/render/html.js +2 -95
- package/dist/src/render/html.js.map +1 -1
- package/dist/src/render/icons.d.ts +3 -0
- package/dist/src/render/icons.d.ts.map +1 -0
- package/dist/src/render/icons.js +3 -0
- package/dist/src/render/icons.js.map +1 -0
- package/dist/src/render/media.d.ts +2 -31
- package/dist/src/render/media.d.ts.map +1 -1
- package/dist/src/render/media.js +2 -41
- package/dist/src/render/media.js.map +1 -1
- package/dist/src/render/render-block.d.ts +11 -22
- package/dist/src/render/render-block.d.ts.map +1 -1
- package/dist/src/render/render-block.js +63 -62
- package/dist/src/render/render-block.js.map +1 -1
- package/dist/src/render/rich-text.d.ts +2 -4
- package/dist/src/render/rich-text.d.ts.map +1 -1
- package/dist/src/render/rich-text.js +2 -104
- package/dist/src/render/rich-text.js.map +1 -1
- package/dist/src/render/term-archive.d.ts +12 -0
- package/dist/src/render/term-archive.d.ts.map +1 -0
- package/dist/src/render/term-archive.js +39 -0
- package/dist/src/render/term-archive.js.map +1 -0
- package/dist/src/theme-contract.d.ts +10 -162
- package/dist/src/theme-contract.d.ts.map +1 -1
- package/dist/src/theme-contract.js +9 -17
- package/dist/src/theme-contract.js.map +1 -1
- package/dist/theme.config.d.ts +5 -16
- package/dist/theme.config.d.ts.map +1 -1
- package/dist/theme.config.js +16 -5
- package/dist/theme.config.js.map +1 -1
- package/package.json +4 -2
- package/src/index.ts +4 -0
- package/src/render/actions.ts +2 -57
- package/src/render/blocks/accordion.ts +44 -0
- package/src/render/blocks/collection-list.ts +9 -15
- package/src/render/blocks/feature-grid.ts +11 -2
- package/src/render/blocks/logo-strip.ts +38 -0
- package/src/render/blocks/pricing-table.ts +65 -0
- package/src/render/blocks/stat-counter.ts +34 -0
- package/src/render/blocks/testimonial.ts +41 -0
- package/src/render/chrome.ts +105 -0
- package/src/render/comments.ts +6 -0
- package/src/render/entry.ts +2 -40
- package/src/render/heading.ts +7 -44
- package/src/render/html.ts +15 -122
- package/src/render/icons.ts +2 -0
- package/src/render/media.ts +2 -62
- package/src/render/render-block.ts +85 -75
- package/src/render/rich-text.ts +2 -150
- package/src/render/term-archive.ts +85 -0
- package/src/styles/archive.css +40 -0
- package/src/styles/base.css +525 -3
- package/src/styles/blocks.css +344 -14
- package/src/styles/theme.css +1 -0
- package/src/theme-contract.ts +23 -155
package/src/styles/base.css
CHANGED
|
@@ -176,6 +176,64 @@ img {
|
|
|
176
176
|
padding-inline: var(--cg-gutter);
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
+
/* --- per-block visual variant (blocks@2.0, RFC 0002) ----------------------
|
|
180
|
+
`withBlockVariant` (`@cogenta/theme-kit`) stamps one `data-variant-<axis>`
|
|
181
|
+
attribute per axis an author actually set — never all four, never one this
|
|
182
|
+
theme does not resolve. Two attribute selectors give every rule here the
|
|
183
|
+
same specificity, (0,2,0), which is what lets it override `.cg-block`
|
|
184
|
+
above regardless of source order, without `!important` anywhere.
|
|
185
|
+
|
|
186
|
+
`background: 'image'` has no theme mechanism to attach an actual image to
|
|
187
|
+
a block instance (RFC 0002 adds only the semantic token, not a media
|
|
188
|
+
field) — resolved to the same tinted surface as the closest honest
|
|
189
|
+
approximation this theme has, rather than silently doing nothing with a
|
|
190
|
+
stated author intent.
|
|
191
|
+
------------------------------------------------------------------------- */
|
|
192
|
+
|
|
193
|
+
[data-block][data-variant-background="muted"],
|
|
194
|
+
[data-block][data-variant-background="image"] {
|
|
195
|
+
padding-block: var(--cg-s10);
|
|
196
|
+
border-radius: var(--cg-radius-lg);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
[data-block][data-variant-background="muted"] {
|
|
200
|
+
background: var(--cg-surface-sunken);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
[data-block][data-variant-background="image"] {
|
|
204
|
+
background: var(--cg-surface-tinted);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
[data-block][data-variant-spacing="compact"] {
|
|
208
|
+
margin-block: calc(var(--cg-section-y) / 2);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/* No rule for "comfortable": it names this theme's existing default, so an
|
|
212
|
+
author who picks it explicitly gets exactly what an absent `variant`
|
|
213
|
+
already gave them — the whole point of "theme default" being a real,
|
|
214
|
+
selectable option and not only the absence of a choice. */
|
|
215
|
+
|
|
216
|
+
[data-block][data-variant-spacing="spacious"] {
|
|
217
|
+
margin-block: calc(var(--cg-section-y) * 1.6);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
[data-block][data-variant-align="start"] {
|
|
221
|
+
text-align: start;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
[data-block][data-variant-align="center"] {
|
|
225
|
+
text-align: center;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
[data-block][data-variant-align="end"] {
|
|
229
|
+
text-align: end;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
[data-block][data-variant-width="full"] {
|
|
233
|
+
max-inline-size: none;
|
|
234
|
+
padding-inline: 0;
|
|
235
|
+
}
|
|
236
|
+
|
|
179
237
|
.cg-page__title {
|
|
180
238
|
max-inline-size: var(--cg-page);
|
|
181
239
|
margin-inline: auto;
|
|
@@ -188,15 +246,100 @@ img {
|
|
|
188
246
|
text-wrap: balance;
|
|
189
247
|
}
|
|
190
248
|
|
|
249
|
+
/* --------------------------------------------------------------------------
|
|
250
|
+
Entry header (`renderEntryHeader`, `@cogenta/theme-kit`, contract D
|
|
251
|
+
`theme@1.4`) — the article furniture (`PageContent.entry`) a `richText`
|
|
252
|
+
entry carries beyond its blocks: an eyebrow of taxonomy terms, the title
|
|
253
|
+
(replacing the bare `.cg-page__title` this same page would otherwise get
|
|
254
|
+
— `render-block.ts` renders exactly one of the two), an excerpt, a meta
|
|
255
|
+
line, a cover image.
|
|
256
|
+
-------------------------------------------------------------------------- */
|
|
257
|
+
|
|
258
|
+
.cg-entry-header {
|
|
259
|
+
max-inline-size: var(--cg-page);
|
|
260
|
+
margin-inline: auto;
|
|
261
|
+
margin-block: var(--cg-section-y) var(--cg-s6);
|
|
262
|
+
padding-inline: var(--cg-gutter);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
.cg-entry-header__terms {
|
|
266
|
+
display: flex;
|
|
267
|
+
flex-wrap: wrap;
|
|
268
|
+
gap: var(--cg-s2);
|
|
269
|
+
margin: 0 0 var(--cg-s3);
|
|
270
|
+
padding: 0;
|
|
271
|
+
list-style: none;
|
|
272
|
+
font-size: var(--cg-text-sm);
|
|
273
|
+
font-weight: var(--cg-weight-semibold);
|
|
274
|
+
letter-spacing: var(--cg-tracking-wide);
|
|
275
|
+
text-transform: uppercase;
|
|
276
|
+
color: var(--cg-accent);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.cg-entry-header__terms a {
|
|
280
|
+
color: inherit;
|
|
281
|
+
text-decoration: none;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
.cg-entry-header__terms li:not(:last-child)::after {
|
|
285
|
+
content: "·";
|
|
286
|
+
margin-inline-start: var(--cg-s2);
|
|
287
|
+
color: var(--cg-ink-muted);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
.cg-entry-header__title {
|
|
291
|
+
margin: 0 0 var(--cg-s4);
|
|
292
|
+
font-size: var(--cg-text-3xl);
|
|
293
|
+
line-height: var(--cg-leading-tight);
|
|
294
|
+
letter-spacing: var(--cg-tracking-tight);
|
|
295
|
+
font-weight: var(--cg-weight-bold);
|
|
296
|
+
text-wrap: balance;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
.cg-entry-header__excerpt {
|
|
300
|
+
margin: 0 0 var(--cg-s4);
|
|
301
|
+
font-size: var(--cg-text-lg);
|
|
302
|
+
color: var(--cg-ink-muted);
|
|
303
|
+
text-wrap: pretty;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.cg-entry-header__meta {
|
|
307
|
+
display: flex;
|
|
308
|
+
flex-wrap: wrap;
|
|
309
|
+
gap: var(--cg-s3);
|
|
310
|
+
margin: 0 0 var(--cg-s6);
|
|
311
|
+
font-size: var(--cg-text-sm);
|
|
312
|
+
color: var(--cg-ink-muted);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
.cg-entry-header__meta > :not(:last-child)::after {
|
|
316
|
+
content: "·";
|
|
317
|
+
margin-inline-start: var(--cg-s3);
|
|
318
|
+
color: var(--cg-line-strong);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
.cg-entry-header__cover {
|
|
322
|
+
margin: 0;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
.cg-entry-header__cover img,
|
|
326
|
+
.cg-entry-header__cover video {
|
|
327
|
+
inline-size: 100%;
|
|
328
|
+
aspect-ratio: 16 / 9;
|
|
329
|
+
border-radius: var(--cg-radius-lg);
|
|
330
|
+
object-fit: cover;
|
|
331
|
+
}
|
|
332
|
+
|
|
191
333
|
.cg-site-header {
|
|
192
334
|
position: sticky;
|
|
193
335
|
inset-block-start: 0;
|
|
194
336
|
z-index: 5;
|
|
195
337
|
padding: var(--cg-s4) var(--cg-gutter);
|
|
196
|
-
|
|
338
|
+
/* Flat and fully opaque, not a frosted-glass blur: a sticky header reads
|
|
339
|
+
as a solid plane sitting above the page, with a hairline marking where
|
|
340
|
+
it ends. */
|
|
341
|
+
background: var(--cg-canvas);
|
|
197
342
|
border-block-end: 1px solid var(--cg-line-soft);
|
|
198
|
-
/* Progressive: a browser without it simply gets the translucent ground. */
|
|
199
|
-
backdrop-filter: saturate(1.4) blur(12px);
|
|
200
343
|
}
|
|
201
344
|
|
|
202
345
|
.cg-site-header__inner,
|
|
@@ -218,6 +361,19 @@ img {
|
|
|
218
361
|
margin-inline-end: auto;
|
|
219
362
|
}
|
|
220
363
|
|
|
364
|
+
/* The uploaded site logo, when there is one. Height-constrained rather than
|
|
365
|
+
width-constrained: a wordmark logo and a square mark have wildly different
|
|
366
|
+
aspect ratios, and only a fixed height keeps the header bar the same
|
|
367
|
+
height for both. `max-inline-size` is the guard against a very wide
|
|
368
|
+
wordmark pushing the navigation off the row. */
|
|
369
|
+
.cg-site-header__logo {
|
|
370
|
+
display: block;
|
|
371
|
+
block-size: 2rem;
|
|
372
|
+
inline-size: auto;
|
|
373
|
+
max-inline-size: 14rem;
|
|
374
|
+
object-fit: contain;
|
|
375
|
+
}
|
|
376
|
+
|
|
221
377
|
.cg-site-footer {
|
|
222
378
|
padding: var(--cg-s12) var(--cg-gutter);
|
|
223
379
|
background: var(--cg-surface-sunken);
|
|
@@ -226,6 +382,173 @@ img {
|
|
|
226
382
|
font-size: var(--cg-text-sm);
|
|
227
383
|
}
|
|
228
384
|
|
|
385
|
+
/* `theme@1.4` (L25 D2) — a button-styled link at the end of the header nav.
|
|
386
|
+
Reuses `.cg-action`'s own look (see "Actions" below) rather than a second
|
|
387
|
+
button style. */
|
|
388
|
+
.cg-site-header__action {
|
|
389
|
+
margin-inline-start: var(--cg-s2);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/* The manual light/dark/system control (`renderThemeToggle`, `@cogenta/
|
|
393
|
+
theme-kit`) — a plain icon button, not the block vocabulary's `.cg-action`
|
|
394
|
+
style, so it never reads as a call-to-action competing with a real one. */
|
|
395
|
+
.cg-theme-toggle {
|
|
396
|
+
display: inline-flex;
|
|
397
|
+
align-items: center;
|
|
398
|
+
justify-content: center;
|
|
399
|
+
block-size: 2.25rem;
|
|
400
|
+
inline-size: 2.25rem;
|
|
401
|
+
flex-shrink: 0;
|
|
402
|
+
border-radius: var(--cg-radius-pill);
|
|
403
|
+
border: 1px solid var(--cg-line-soft);
|
|
404
|
+
background: transparent;
|
|
405
|
+
color: var(--cg-ink);
|
|
406
|
+
cursor: pointer;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
.cg-theme-toggle:hover {
|
|
410
|
+
background: var(--cg-surface-sunken);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
.cg-theme-toggle__icon {
|
|
414
|
+
block-size: 1.1rem;
|
|
415
|
+
inline-size: 1.1rem;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
.cg-theme-toggle__icon--moon {
|
|
419
|
+
display: none;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/* Icon reflects the *current* effective appearance — sun while light, moon
|
|
423
|
+
while dark — from the same `[data-theme]`/`prefers-color-scheme` signals
|
|
424
|
+
`tokens.css` already keys the whole palette on. */
|
|
425
|
+
@media (prefers-color-scheme: dark) {
|
|
426
|
+
:where(:root:not([data-theme='light'])) .cg-theme-toggle__icon--sun {
|
|
427
|
+
display: none;
|
|
428
|
+
}
|
|
429
|
+
:where(:root:not([data-theme='light'])) .cg-theme-toggle__icon--moon {
|
|
430
|
+
display: block;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
:where(:root[data-theme='dark']) .cg-theme-toggle__icon--sun {
|
|
435
|
+
display: none;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
:where(:root[data-theme='dark']) .cg-theme-toggle__icon--moon {
|
|
439
|
+
display: block;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/* `general.tagline`, shown right after the site name in the footer — prose,
|
|
443
|
+
never a heading, so it stays the same visual weight as the credit line
|
|
444
|
+
beside it. */
|
|
445
|
+
.cg-site-footer__tagline {
|
|
446
|
+
margin: var(--cg-s1) 0 0;
|
|
447
|
+
max-inline-size: 28rem;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
.cg-site-footer__social {
|
|
451
|
+
display: flex;
|
|
452
|
+
flex-wrap: wrap;
|
|
453
|
+
gap: var(--cg-s3);
|
|
454
|
+
margin: var(--cg-s4) 0 0;
|
|
455
|
+
padding: 0;
|
|
456
|
+
list-style: none;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
.cg-site-footer__social-item a {
|
|
460
|
+
display: flex;
|
|
461
|
+
align-items: center;
|
|
462
|
+
justify-content: center;
|
|
463
|
+
inline-size: 2.25rem;
|
|
464
|
+
block-size: 2.25rem;
|
|
465
|
+
border-radius: var(--cg-radius-md);
|
|
466
|
+
color: var(--cg-ink-muted);
|
|
467
|
+
background: var(--cg-surface);
|
|
468
|
+
box-shadow: var(--cg-ring);
|
|
469
|
+
transition:
|
|
470
|
+
color var(--cg-duration-fast) var(--cg-ease),
|
|
471
|
+
background-color var(--cg-duration-fast) var(--cg-ease);
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
.cg-site-footer__social-item a:hover,
|
|
475
|
+
.cg-site-footer__social-item a:focus-visible {
|
|
476
|
+
color: var(--cg-accent-fg);
|
|
477
|
+
background: var(--cg-accent);
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
.cg-social__icon {
|
|
481
|
+
inline-size: 1.1rem;
|
|
482
|
+
block-size: 1.1rem;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/* `general.footerNote` — a short "about" column, visually distinct from the
|
|
486
|
+
tagline (which sits with the site name) and from Cogenta's own credit
|
|
487
|
+
(which stays pinned to the far end of the row, see
|
|
488
|
+
`.cg-site-footer__branding` above). */
|
|
489
|
+
.cg-site-footer__about {
|
|
490
|
+
margin-inline-end: auto;
|
|
491
|
+
max-inline-size: 24rem;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
.cg-site-footer__about p {
|
|
495
|
+
margin: 0;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
/* The standard clip-to-1px technique — visible to assistive tech, invisible
|
|
499
|
+
on screen, unlike `display:none` (which removes it from both). Every
|
|
500
|
+
social icon link's own text label (`renderSocialLinks`,
|
|
501
|
+
`@cogenta/theme-kit`) depends on this class existing here: theme-kit ships
|
|
502
|
+
no CSS of its own (contract D, R5 — a theme owns its own stylesheet). */
|
|
503
|
+
.cg-visually-hidden {
|
|
504
|
+
position: absolute;
|
|
505
|
+
inline-size: 1px;
|
|
506
|
+
block-size: 1px;
|
|
507
|
+
padding: 0;
|
|
508
|
+
margin: -1px;
|
|
509
|
+
overflow: hidden;
|
|
510
|
+
clip: rect(0, 0, 0, 0);
|
|
511
|
+
white-space: nowrap;
|
|
512
|
+
border: 0;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
/* Cogenta's own credit, or its white-label replacement (fiche L21 task 8) —
|
|
516
|
+
pushed to the far end of the footer row, after the site name and its own
|
|
517
|
+
navigation, never competing with either for space. */
|
|
518
|
+
.cg-site-footer__branding {
|
|
519
|
+
margin-inline-start: auto;
|
|
520
|
+
display: flex;
|
|
521
|
+
align-items: center;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
.cg-site-footer__branding a {
|
|
525
|
+
display: flex;
|
|
526
|
+
align-items: center;
|
|
527
|
+
gap: 0.4em;
|
|
528
|
+
opacity: 0.7;
|
|
529
|
+
transition: opacity 0.15s ease;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
/* `@cogenta/core`'s package version, next to the logo (fiche 22 tâche 8) — only rendered at all when Cogenta's own credit is on. */
|
|
533
|
+
.cg-site-footer__version {
|
|
534
|
+
font-variant-numeric: tabular-nums;
|
|
535
|
+
font-size: 0.9em;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
.cg-site-footer__branding a:hover,
|
|
539
|
+
.cg-site-footer__branding a:focus-visible {
|
|
540
|
+
opacity: 1;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
.cg-site-footer__brand-logo {
|
|
544
|
+
display: block;
|
|
545
|
+
/* Explicit pixels, not `em`: a footer's own small font-size cascaded into
|
|
546
|
+
this and made the credit mark unreadably tiny — the same class of bug
|
|
547
|
+
the admin shell's own logo had before its fix. */
|
|
548
|
+
block-size: 25px;
|
|
549
|
+
inline-size: auto;
|
|
550
|
+
}
|
|
551
|
+
|
|
229
552
|
/* --------------------------------------------------------------------------
|
|
230
553
|
Actions — the theme's only control
|
|
231
554
|
-------------------------------------------------------------------------- */
|
|
@@ -339,3 +662,202 @@ img {
|
|
|
339
662
|
padding-block: var(--cg-s2);
|
|
340
663
|
margin-block: calc(var(--cg-s2) * -1);
|
|
341
664
|
}
|
|
665
|
+
|
|
666
|
+
/* --------------------------------------------------------------------------
|
|
667
|
+
Search, forms, comments — public utility pages and post-content furniture
|
|
668
|
+
|
|
669
|
+
`/search` (`search-page.ts`), `/forms/{name}` (`forms-page.ts`) and the
|
|
670
|
+
comment thread appended after an entry page (`comments.ts`) all render
|
|
671
|
+
real markup with real `cg-*` classes, but none of it had a single rule
|
|
672
|
+
here (L20 audit, points 8-9) — the stylesheet loaded, the class names were
|
|
673
|
+
right there in the HTML, and nothing matched. These three follow the same
|
|
674
|
+
page-width measure `.cg-page__title` already sets, so a search result list
|
|
675
|
+
or a form lines up under its own heading rather than running edge to edge.
|
|
676
|
+
-------------------------------------------------------------------------- */
|
|
677
|
+
|
|
678
|
+
.cg-search__form,
|
|
679
|
+
.cg-search__results,
|
|
680
|
+
.cg-search__empty,
|
|
681
|
+
.cg-search__error,
|
|
682
|
+
.cg-form,
|
|
683
|
+
.cg-form__confirmation,
|
|
684
|
+
.cg-comments {
|
|
685
|
+
max-inline-size: var(--cg-page);
|
|
686
|
+
margin-inline: auto;
|
|
687
|
+
padding-inline: var(--cg-gutter);
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
.cg-search__form {
|
|
691
|
+
display: flex;
|
|
692
|
+
flex-wrap: wrap;
|
|
693
|
+
align-items: end;
|
|
694
|
+
gap: var(--cg-s3);
|
|
695
|
+
margin-block-end: var(--cg-s8);
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
.cg-search__form label {
|
|
699
|
+
display: block;
|
|
700
|
+
font-size: var(--cg-text-sm);
|
|
701
|
+
font-weight: var(--cg-weight-semibold);
|
|
702
|
+
margin-block-end: var(--cg-s2);
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
.cg-search__form input[type="search"] {
|
|
706
|
+
flex: 1 1 16rem;
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
.cg-search__results {
|
|
710
|
+
margin: 0 auto;
|
|
711
|
+
padding-inline-start: var(--cg-gutter);
|
|
712
|
+
display: grid;
|
|
713
|
+
gap: var(--cg-s4);
|
|
714
|
+
font-size: var(--cg-text-lg);
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
.cg-search__empty,
|
|
718
|
+
.cg-comments__empty,
|
|
719
|
+
.cg-comments__closed {
|
|
720
|
+
color: var(--cg-ink-muted);
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
/* No skin exposes a "danger" colour (contract D has none), so an error reads
|
|
724
|
+
through weight and a stronger border rather than a hue no skin can change —
|
|
725
|
+
the same constraint that keeps every other value in this file a function of
|
|
726
|
+
a token. */
|
|
727
|
+
.cg-search__error,
|
|
728
|
+
.cg-form__error,
|
|
729
|
+
.cg-form__field-error {
|
|
730
|
+
color: var(--cg-ink);
|
|
731
|
+
font-weight: var(--cg-weight-bold);
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
/* Text controls, shared by `/forms/{name}` and the comment form — the same
|
|
735
|
+
input surface `.cg-search__form input` above uses. */
|
|
736
|
+
.cg-search__form input,
|
|
737
|
+
.cg-form__field input,
|
|
738
|
+
.cg-form__field select,
|
|
739
|
+
.cg-form__field textarea,
|
|
740
|
+
.cg-comment__form input,
|
|
741
|
+
.cg-comment__form textarea {
|
|
742
|
+
inline-size: 100%;
|
|
743
|
+
padding: var(--cg-s3) var(--cg-s4);
|
|
744
|
+
border: 1px solid var(--cg-line);
|
|
745
|
+
border-radius: var(--cg-radius-md);
|
|
746
|
+
background: var(--cg-surface);
|
|
747
|
+
color: var(--cg-ink);
|
|
748
|
+
font: inherit;
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
.cg-form__field input[aria-invalid="true"],
|
|
752
|
+
.cg-form__field select[aria-invalid="true"],
|
|
753
|
+
.cg-form__field textarea[aria-invalid="true"] {
|
|
754
|
+
border-width: 2px;
|
|
755
|
+
border-color: var(--cg-line-strong);
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
.cg-search__form button,
|
|
759
|
+
.cg-form button[type="submit"],
|
|
760
|
+
.cg-comment__form button[type="submit"] {
|
|
761
|
+
padding: var(--cg-s3) var(--cg-s6);
|
|
762
|
+
border: 0;
|
|
763
|
+
border-radius: var(--cg-radius-md);
|
|
764
|
+
background: var(--cg-accent);
|
|
765
|
+
color: var(--cg-accent-fg);
|
|
766
|
+
font-weight: var(--cg-weight-semibold);
|
|
767
|
+
cursor: pointer;
|
|
768
|
+
transition: background-color var(--cg-duration) var(--cg-ease);
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
.cg-search__form button:hover,
|
|
772
|
+
.cg-form button[type="submit"]:hover,
|
|
773
|
+
.cg-comment__form button[type="submit"]:hover {
|
|
774
|
+
background: var(--cg-accent-hover);
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
.cg-form__field,
|
|
778
|
+
.cg-comment__form p {
|
|
779
|
+
display: block;
|
|
780
|
+
margin-block-end: var(--cg-s5);
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
.cg-form__field label,
|
|
784
|
+
.cg-comment__form label {
|
|
785
|
+
display: block;
|
|
786
|
+
font-size: var(--cg-text-sm);
|
|
787
|
+
font-weight: var(--cg-weight-semibold);
|
|
788
|
+
margin-block-end: var(--cg-s2);
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
.cg-form__help {
|
|
792
|
+
margin: var(--cg-s2) 0 0;
|
|
793
|
+
font-size: var(--cg-text-sm);
|
|
794
|
+
color: var(--cg-ink-muted);
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
.cg-form__choice {
|
|
798
|
+
display: inline-flex;
|
|
799
|
+
align-items: center;
|
|
800
|
+
gap: var(--cg-s2);
|
|
801
|
+
margin-inline-end: var(--cg-s4);
|
|
802
|
+
font-weight: normal;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
/* Visually hidden, not `display:none`: the honeypot must stay reachable by a
|
|
806
|
+
naive bot's "fill every input" script while never appearing for anyone
|
|
807
|
+
else — the same reasoning the inline style already carried before this
|
|
808
|
+
class existed to do it declaratively for `comments.ts`. */
|
|
809
|
+
.cg-form__honeypot,
|
|
810
|
+
.cg-comment__honeypot {
|
|
811
|
+
position: absolute;
|
|
812
|
+
inline-size: 1px;
|
|
813
|
+
block-size: 1px;
|
|
814
|
+
overflow: hidden;
|
|
815
|
+
inset-inline-start: -9999px;
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
.cg-comments {
|
|
819
|
+
margin-block-start: var(--cg-section-y);
|
|
820
|
+
padding-block-start: var(--cg-s8);
|
|
821
|
+
padding-block-end: var(--cg-section-y);
|
|
822
|
+
border-block-start: 1px solid var(--cg-line-soft);
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
.cg-comments__list,
|
|
826
|
+
.cg-comment__replies {
|
|
827
|
+
margin: 0;
|
|
828
|
+
padding: 0;
|
|
829
|
+
list-style: none;
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
.cg-comment {
|
|
833
|
+
padding-block: var(--cg-s5);
|
|
834
|
+
border-block-end: 1px solid var(--cg-line-soft);
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
.cg-comment__replies {
|
|
838
|
+
padding-block-start: var(--cg-s5);
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
.cg-comment__replies .cg-comment {
|
|
842
|
+
padding-inline-start: var(--cg-s6);
|
|
843
|
+
border-inline-start: 2px solid var(--cg-line-soft);
|
|
844
|
+
border-block-end: 0;
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
.cg-comment__meta {
|
|
848
|
+
display: flex;
|
|
849
|
+
gap: var(--cg-s3);
|
|
850
|
+
align-items: baseline;
|
|
851
|
+
font-size: var(--cg-text-sm);
|
|
852
|
+
color: var(--cg-ink-muted);
|
|
853
|
+
margin-block-end: var(--cg-s2);
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
.cg-comment__author {
|
|
857
|
+
font-weight: var(--cg-weight-semibold);
|
|
858
|
+
color: var(--cg-ink);
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
.cg-comment__body {
|
|
862
|
+
margin: 0;
|
|
863
|
+
}
|