@cogenta/theme-canonical 1.1.3 → 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.
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/render/arrow-link.d.ts +11 -0
- package/dist/src/render/arrow-link.d.ts.map +1 -0
- package/dist/src/render/arrow-link.js +29 -0
- package/dist/src/render/arrow-link.js.map +1 -0
- package/dist/src/render/blocks/collection-list.d.ts +15 -5
- package/dist/src/render/blocks/collection-list.d.ts.map +1 -1
- package/dist/src/render/blocks/collection-list.js +36 -13
- package/dist/src/render/blocks/collection-list.js.map +1 -1
- package/dist/src/render/blocks/embed.d.ts.map +1 -1
- package/dist/src/render/blocks/embed.js +3 -2
- package/dist/src/render/blocks/embed.js.map +1 -1
- package/dist/src/render/blocks/gallery.d.ts.map +1 -1
- package/dist/src/render/blocks/gallery.js +4 -1
- package/dist/src/render/blocks/gallery.js.map +1 -1
- package/dist/src/render/blocks/hero.d.ts.map +1 -1
- package/dist/src/render/blocks/hero.js +9 -2
- package/dist/src/render/blocks/hero.js.map +1 -1
- package/dist/src/render/blocks/pricing-table.d.ts.map +1 -1
- package/dist/src/render/blocks/pricing-table.js +17 -4
- package/dist/src/render/blocks/pricing-table.js.map +1 -1
- package/dist/src/render/chrome.d.ts +40 -1
- package/dist/src/render/chrome.d.ts.map +1 -1
- package/dist/src/render/chrome.js +103 -71
- package/dist/src/render/chrome.js.map +1 -1
- package/dist/src/render/dates.d.ts +9 -0
- package/dist/src/render/dates.d.ts.map +1 -0
- package/dist/src/render/dates.js +16 -0
- package/dist/src/render/dates.js.map +1 -0
- package/dist/src/render/render-block.d.ts.map +1 -1
- package/dist/src/render/render-block.js +7 -1
- package/dist/src/render/render-block.js.map +1 -1
- package/dist/src/render/strings.d.ts +25 -0
- package/dist/src/render/strings.d.ts.map +1 -0
- package/dist/src/render/strings.js +26 -0
- package/dist/src/render/strings.js.map +1 -0
- package/dist/src/render/term-archive.d.ts +5 -5
- package/dist/src/render/term-archive.d.ts.map +1 -1
- package/dist/src/render/term-archive.js +14 -12
- package/dist/src/render/term-archive.js.map +1 -1
- package/dist/src/render/widget-areas.d.ts +20 -0
- package/dist/src/render/widget-areas.d.ts.map +1 -0
- package/dist/src/render/widget-areas.js +40 -0
- package/dist/src/render/widget-areas.js.map +1 -0
- package/package.json +5 -5
- package/src/index.ts +1 -0
- package/src/render/arrow-link.ts +27 -0
- package/src/render/blocks/collection-list.ts +53 -15
- package/src/render/blocks/embed.ts +3 -2
- package/src/render/blocks/gallery.ts +4 -1
- package/src/render/blocks/hero.ts +9 -2
- package/src/render/blocks/pricing-table.ts +22 -4
- package/src/render/chrome.ts +156 -70
- package/src/render/dates.ts +14 -0
- package/src/render/render-block.ts +6 -0
- package/src/render/strings.ts +30 -0
- package/src/render/term-archive.ts +54 -32
- package/src/render/widget-areas.ts +44 -0
- package/src/styles/archive.css +66 -20
- package/src/styles/base.css +266 -680
- package/src/styles/blocks.css +678 -811
- package/src/styles/chrome.css +469 -0
- package/src/styles/listings.css +183 -0
- package/src/styles/theme.css +28 -14
- package/src/styles/tokens.css +192 -205
- package/src/styles/utility.css +295 -0
- package/src/styles/widgets.css +1064 -0
- package/tokens.json +15 -15
package/src/styles/base.css
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Document, accessibility floor, page frame and
|
|
3
|
-
*
|
|
4
|
-
* `tokens.css
|
|
5
|
-
* that needs changing is changed in one place.
|
|
2
|
+
* Document, accessibility floor, the page frame, page and entry titles,
|
|
3
|
+
* actions and the four per-block variants. Everything here reads the design
|
|
4
|
+
* system from `tokens.css`.
|
|
6
5
|
*/
|
|
7
6
|
|
|
8
7
|
/* --------------------------------------------------------------------------
|
|
@@ -15,206 +14,218 @@
|
|
|
15
14
|
box-sizing: border-box;
|
|
16
15
|
}
|
|
17
16
|
|
|
17
|
+
html {
|
|
18
|
+
-webkit-text-size-adjust: 100%;
|
|
19
|
+
text-size-adjust: 100%;
|
|
20
|
+
}
|
|
21
|
+
|
|
18
22
|
body {
|
|
19
23
|
margin: 0;
|
|
20
24
|
background: var(--cg-canvas);
|
|
21
25
|
color: var(--cg-ink);
|
|
22
|
-
font-family: var(--
|
|
26
|
+
font-family: var(--cg-font-text);
|
|
23
27
|
font-size: var(--cg-text-md);
|
|
24
|
-
line-height: var(--cg-leading-
|
|
25
|
-
/* Two opt-in font features rather than a font choice: `kern` is what stops
|
|
26
|
-
display type looking loose, `liga` what stops "fi" breaking apart. Both
|
|
27
|
-
are no-ops on a font that lacks them. */
|
|
28
|
+
line-height: var(--cg-leading-body);
|
|
28
29
|
font-kerning: normal;
|
|
29
30
|
font-variant-ligatures: common-ligatures;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
-
|
|
31
|
+
/* A family that lacks a weight or an italic shows the real face, never a
|
|
32
|
+
smeared imitation of one. */
|
|
33
|
+
font-synthesis: none;
|
|
34
|
+
text-rendering: optimizeLegibility;
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
::selection {
|
|
36
|
-
background: var(--cg-
|
|
37
|
-
color: var(--cg-
|
|
38
|
+
background: var(--cg-selection);
|
|
39
|
+
color: var(--cg-ink);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
:where(h1, h2, h3, h4, h5, h6) {
|
|
43
|
+
margin: 0;
|
|
44
|
+
font-family: var(--cg-font-text);
|
|
45
|
+
font-weight: var(--cg-weight-semibold);
|
|
46
|
+
line-height: var(--cg-leading-heading);
|
|
47
|
+
letter-spacing: var(--cg-tracking-heading);
|
|
48
|
+
text-wrap: balance;
|
|
38
49
|
}
|
|
39
50
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
51
|
+
:where(p, li, dd, figcaption, blockquote) {
|
|
52
|
+
text-wrap: pretty;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
:where(p, ul, ol, dl, dd, figure, blockquote) {
|
|
56
|
+
margin: 0;
|
|
45
57
|
}
|
|
46
58
|
|
|
47
|
-
|
|
59
|
+
/* Dates, years, prices and figures keep their width from one line to the
|
|
60
|
+
next. */
|
|
61
|
+
:where(data, time) {
|
|
62
|
+
font-variant-numeric: tabular-nums;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
:where(img, video, iframe) {
|
|
48
66
|
display: block;
|
|
67
|
+
max-inline-size: 100%;
|
|
68
|
+
block-size: auto;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
:where(img, video) {
|
|
49
72
|
object-fit: cover;
|
|
73
|
+
filter: brightness(var(--cg-image-brightness));
|
|
50
74
|
}
|
|
51
75
|
|
|
52
76
|
:where(a) {
|
|
53
77
|
color: var(--cg-accent);
|
|
54
|
-
text-decoration-
|
|
78
|
+
text-decoration-line: underline;
|
|
79
|
+
text-decoration-thickness: var(--cg-rule);
|
|
80
|
+
text-decoration-color: color-mix(in oklab, currentColor 45%, transparent);
|
|
81
|
+
text-underline-offset: 0.2em;
|
|
82
|
+
text-decoration-skip-ink: auto;
|
|
55
83
|
transition:
|
|
56
|
-
color var(--cg-duration
|
|
57
|
-
text-decoration-color var(--cg-duration
|
|
84
|
+
color var(--cg-duration) var(--cg-ease),
|
|
85
|
+
text-decoration-color var(--cg-duration) var(--cg-ease);
|
|
58
86
|
}
|
|
59
87
|
|
|
60
|
-
:where(a:hover
|
|
88
|
+
:where(a):hover {
|
|
61
89
|
color: var(--cg-accent-hover);
|
|
62
90
|
text-decoration-color: currentColor;
|
|
63
91
|
}
|
|
64
92
|
|
|
65
93
|
:where(hr) {
|
|
66
|
-
block-size:
|
|
94
|
+
block-size: 0;
|
|
95
|
+
margin: 0;
|
|
67
96
|
border: 0;
|
|
68
|
-
|
|
69
|
-
background: var(--cg-line);
|
|
97
|
+
border-block-start: var(--cg-rule) solid var(--cg-line);
|
|
70
98
|
}
|
|
71
99
|
|
|
72
100
|
/* --------------------------------------------------------------------------
|
|
73
|
-
Focus, targets,
|
|
101
|
+
Focus, targets, the skip link
|
|
74
102
|
-------------------------------------------------------------------------- */
|
|
75
103
|
|
|
76
|
-
:where(a, button, summary, [tabindex]):focus-visible {
|
|
77
|
-
/*
|
|
78
|
-
|
|
79
|
-
outline: 2px solid var(--cg-accent);
|
|
104
|
+
:where(a, button, summary, input, select, textarea, [tabindex]):focus-visible {
|
|
105
|
+
/* An outline, not a shadow: it survives forced-colours mode. */
|
|
106
|
+
outline: var(--cg-rule-strong) solid var(--cg-accent);
|
|
80
107
|
outline-offset: 3px;
|
|
81
|
-
border-radius: var(--cg-radius-sm);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/* WCAG 2.2 asks 24x24 minimum (2.5.8); 44x44 is the comfortable target and
|
|
85
|
-
costs nothing here. Applied to the theme's own controls only — an inline link
|
|
86
|
-
inside a paragraph is exempt, and padding it would break the text flow. */
|
|
87
|
-
:where(.cg-action, .cg-faq__question, .cg-logo__link) {
|
|
88
|
-
min-block-size: 44px;
|
|
89
|
-
min-inline-size: 44px;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/* The entrance animation the blocks opt into. Scroll-driven, so it plays as a
|
|
93
|
-
block arrives rather than firing eleven at once on load, and wrapped in a
|
|
94
|
-
feature query because the starting state is `opacity: 0`: a browser without
|
|
95
|
-
`animation-timeline` must never be left holding an invisible page. */
|
|
96
|
-
@supports (animation-timeline: view()) {
|
|
97
|
-
@media (prefers-reduced-motion: no-preference) {
|
|
98
|
-
@keyframes cg-rise {
|
|
99
|
-
from {
|
|
100
|
-
opacity: 0;
|
|
101
|
-
transform: translateY(var(--cg-s4));
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
to {
|
|
105
|
-
opacity: 1;
|
|
106
|
-
transform: none;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
.cg-block {
|
|
111
|
-
animation: cg-rise linear both;
|
|
112
|
-
animation-timeline: view();
|
|
113
|
-
/* Fully in by the time the block is a fifth of the way up the viewport;
|
|
114
|
-
it never animates back out on the way past. */
|
|
115
|
-
animation-range: entry 0% cover 22%;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
@media (prefers-reduced-motion: reduce) {
|
|
121
|
-
/* The `motion.reduced` token says the skin's motion may be removed. Nothing
|
|
122
|
-
in this theme conveys meaning through movement, so removing all of it is
|
|
123
|
-
safe — including the smooth scroll of the carousel, which is the one people
|
|
124
|
-
forget and which triggers vestibular symptoms. */
|
|
125
|
-
*,
|
|
126
|
-
*::before,
|
|
127
|
-
*::after {
|
|
128
|
-
animation-duration: 1ms !important;
|
|
129
|
-
animation-iteration-count: 1 !important;
|
|
130
|
-
transition-duration: 1ms !important;
|
|
131
|
-
scroll-behavior: auto !important;
|
|
132
|
-
}
|
|
133
108
|
}
|
|
134
109
|
|
|
135
110
|
.cg-skip-link {
|
|
136
111
|
position: absolute;
|
|
137
|
-
inset-inline-start: var(--cg-
|
|
138
|
-
inset-block-start:
|
|
112
|
+
inset-inline-start: var(--cg-gutter);
|
|
113
|
+
inset-block-start: var(--cg-s2);
|
|
139
114
|
z-index: 10;
|
|
140
|
-
padding: var(--cg-
|
|
141
|
-
background: var(--cg-
|
|
142
|
-
color: var(--cg-
|
|
143
|
-
border-radius: var(--cg-radius-md);
|
|
144
|
-
box-shadow: var(--cg-elevation-2);
|
|
115
|
+
padding: var(--cg-s3) var(--cg-s5);
|
|
116
|
+
background: var(--cg-action);
|
|
117
|
+
color: var(--cg-action-fg);
|
|
145
118
|
font-weight: var(--cg-weight-semibold);
|
|
146
119
|
text-decoration: none;
|
|
147
|
-
/* Moved, never hidden: `display:none` would take it out of the
|
|
148
|
-
which is the whole point of a skip link (WCAG 2.4.1). */
|
|
149
|
-
|
|
120
|
+
/* Moved off screen, never hidden: `display: none` would take it out of the
|
|
121
|
+
tab order, which is the whole point of a skip link (WCAG 2.4.1). */
|
|
122
|
+
translate: 0 -200%;
|
|
150
123
|
}
|
|
151
124
|
|
|
152
125
|
.cg-skip-link:focus-visible {
|
|
153
|
-
|
|
126
|
+
translate: 0 0;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/* The standard clip technique: read by assistive technology, not drawn.
|
|
130
|
+
`renderSocialLinks` (`@cogenta/theme-kit`) depends on this class existing
|
|
131
|
+
in every theme that renders it. */
|
|
132
|
+
.cg-visually-hidden {
|
|
133
|
+
position: absolute;
|
|
134
|
+
inline-size: 1px;
|
|
135
|
+
block-size: 1px;
|
|
136
|
+
padding: 0;
|
|
137
|
+
margin: -1px;
|
|
138
|
+
overflow: hidden;
|
|
139
|
+
clip-path: inset(50%);
|
|
140
|
+
white-space: nowrap;
|
|
141
|
+
border: 0;
|
|
154
142
|
}
|
|
155
143
|
|
|
156
144
|
/* --------------------------------------------------------------------------
|
|
157
|
-
|
|
145
|
+
The page frame
|
|
146
|
+
--------------------------------------------------------------------------
|
|
147
|
+
|
|
148
|
+
Every block is as wide as the page and centres its content with side
|
|
149
|
+
padding (`--cg-inset`), so a band colour can reach both edges of the
|
|
150
|
+
window while the content keeps to the page width. A block that lays out
|
|
151
|
+
more than one thing is a twelve-column grid on that content box, which is
|
|
152
|
+
what puts a section title, a card and a caption on the same left edge.
|
|
158
153
|
-------------------------------------------------------------------------- */
|
|
159
154
|
|
|
160
|
-
/* `flow-root`, so the first and last block's own margins stay inside `<main>`
|
|
161
|
-
instead of collapsing through it and pushing the header and footer around.
|
|
162
|
-
That also means no padding is needed here: the last block already carries a
|
|
163
|
-
section's worth of space below itself, and adding more produced a dead band
|
|
164
|
-
three times too tall between the last block and the footer. */
|
|
165
155
|
.cg-main {
|
|
166
156
|
display: flow-root;
|
|
167
157
|
}
|
|
168
158
|
|
|
169
|
-
/* The one measurement every block shares. A block that wants to break out of
|
|
170
|
-
it says so itself (`.cg-figure[data-align="full"]`), so the default stays
|
|
171
|
-
one rule instead of eleven. */
|
|
172
159
|
.cg-block {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
160
|
+
padding-block: calc(var(--cg-section) / 2);
|
|
161
|
+
padding-inline: var(--cg-inset);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.cg-grid,
|
|
165
|
+
.cg-features,
|
|
166
|
+
.cg-cta,
|
|
167
|
+
.cg-gallery,
|
|
168
|
+
.cg-quote,
|
|
169
|
+
.cg-faq,
|
|
170
|
+
.cg-stats,
|
|
171
|
+
.cg-logos,
|
|
172
|
+
.cg-collection,
|
|
173
|
+
.cg-embed,
|
|
174
|
+
.cg-testimonial,
|
|
175
|
+
.cg-pricing,
|
|
176
|
+
.cg-accordion,
|
|
177
|
+
.cg-stat-counters,
|
|
178
|
+
.cg-logo-strip,
|
|
179
|
+
.cg-figure,
|
|
180
|
+
.cg-hero {
|
|
181
|
+
display: grid;
|
|
182
|
+
grid-template-columns: repeat(var(--cg-columns), minmax(0, 1fr));
|
|
183
|
+
column-gap: var(--cg-column-gap);
|
|
184
|
+
align-content: start;
|
|
177
185
|
}
|
|
178
186
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
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);
|
|
187
|
+
.cg-block > * {
|
|
188
|
+
grid-column: 1 / -1;
|
|
189
|
+
min-inline-size: 0;
|
|
197
190
|
}
|
|
198
191
|
|
|
199
|
-
|
|
200
|
-
|
|
192
|
+
/* The heading of a section: in the text face, from the first column, under
|
|
193
|
+
a rule in ink that spans what the section spans. */
|
|
194
|
+
.cg-section-title,
|
|
195
|
+
.cg-features__title,
|
|
196
|
+
.cg-faq__title,
|
|
197
|
+
.cg-stats__title,
|
|
198
|
+
.cg-logos__title,
|
|
199
|
+
.cg-collection__title,
|
|
200
|
+
.cg-pricing__title,
|
|
201
|
+
.cg-accordion__title,
|
|
202
|
+
.cg-stat-counters__title {
|
|
203
|
+
padding-block-start: var(--cg-s5);
|
|
204
|
+
margin-block-end: var(--cg-s10);
|
|
205
|
+
border-block-start: var(--cg-rule) solid var(--cg-ink);
|
|
206
|
+
font-size: var(--cg-text-heading);
|
|
201
207
|
}
|
|
202
208
|
|
|
209
|
+
/* --- per-block variant (blocks@2.0, RFC 0002) -----------------------------
|
|
210
|
+
`withBlockVariant` stamps one `data-variant-<axis>` attribute per axis an
|
|
211
|
+
author set. `background: image` has no image to show (RFC 0002 carries the
|
|
212
|
+
intent, not a media field), so it resolves to the same band as `muted`,
|
|
213
|
+
the closest honest rendering this theme has.
|
|
214
|
+
------------------------------------------------------------------------- */
|
|
215
|
+
|
|
216
|
+
[data-block][data-variant-background="muted"],
|
|
203
217
|
[data-block][data-variant-background="image"] {
|
|
204
|
-
background: var(--cg-
|
|
218
|
+
background: var(--cg-band);
|
|
205
219
|
}
|
|
206
220
|
|
|
207
221
|
[data-block][data-variant-spacing="compact"] {
|
|
208
|
-
|
|
222
|
+
padding-block: calc(var(--cg-section) / 4);
|
|
209
223
|
}
|
|
210
224
|
|
|
211
|
-
/* No rule for "comfortable": it names this theme's
|
|
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. */
|
|
225
|
+
/* No rule for "comfortable": it names this theme's default rhythm. */
|
|
215
226
|
|
|
216
227
|
[data-block][data-variant-spacing="spacious"] {
|
|
217
|
-
|
|
228
|
+
padding-block: calc(var(--cg-section) * 0.8);
|
|
218
229
|
}
|
|
219
230
|
|
|
220
231
|
[data-block][data-variant-align="start"] {
|
|
@@ -230,634 +241,209 @@ img {
|
|
|
230
241
|
}
|
|
231
242
|
|
|
232
243
|
[data-block][data-variant-width="full"] {
|
|
233
|
-
|
|
234
|
-
padding-inline: 0;
|
|
244
|
+
padding-inline: var(--cg-gutter);
|
|
235
245
|
}
|
|
236
246
|
|
|
247
|
+
/* --------------------------------------------------------------------------
|
|
248
|
+
Page title — a page without a hero and without entry furniture, and the
|
|
249
|
+
search, form and archive pages the host renders
|
|
250
|
+
-------------------------------------------------------------------------- */
|
|
251
|
+
|
|
237
252
|
.cg-page__title {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
font-
|
|
243
|
-
line-height: var(--cg-leading-
|
|
244
|
-
letter-spacing: var(--cg-tracking-
|
|
245
|
-
|
|
246
|
-
|
|
253
|
+
padding-block: calc(var(--cg-section) * 0.6) calc(var(--cg-section) / 4);
|
|
254
|
+
padding-inline: var(--cg-inset);
|
|
255
|
+
font-family: var(--cg-font-display);
|
|
256
|
+
font-size: var(--cg-text-title);
|
|
257
|
+
font-weight: var(--cg-weight-regular);
|
|
258
|
+
line-height: var(--cg-leading-display);
|
|
259
|
+
letter-spacing: var(--cg-tracking-display);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
@media (min-width: 64rem) {
|
|
263
|
+
.cg-page__title {
|
|
264
|
+
/* Ten columns at most, so a long title breaks into lines a reader takes
|
|
265
|
+
in at once. */
|
|
266
|
+
padding-inline-end: calc(var(--cg-inset) + (100% - 2 * var(--cg-inset)) / 6);
|
|
267
|
+
}
|
|
247
268
|
}
|
|
248
269
|
|
|
249
270
|
/* --------------------------------------------------------------------------
|
|
250
|
-
Entry header (`renderEntryHeader`, `@cogenta/theme-kit`,
|
|
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.
|
|
271
|
+
Entry header (`renderEntryHeader`, `@cogenta/theme-kit`, `theme@1.4`)
|
|
256
272
|
-------------------------------------------------------------------------- */
|
|
257
273
|
|
|
258
274
|
.cg-entry-header {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
padding-
|
|
275
|
+
display: grid;
|
|
276
|
+
grid-template-columns: repeat(var(--cg-columns), minmax(0, 1fr));
|
|
277
|
+
column-gap: var(--cg-column-gap);
|
|
278
|
+
padding-block: calc(var(--cg-section) * 0.6) calc(var(--cg-section) / 4);
|
|
279
|
+
padding-inline: var(--cg-inset);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
.cg-entry-header > * {
|
|
283
|
+
grid-column: 1 / -1;
|
|
263
284
|
}
|
|
264
285
|
|
|
265
286
|
.cg-entry-header__terms {
|
|
266
287
|
display: flex;
|
|
267
288
|
flex-wrap: wrap;
|
|
268
|
-
gap: var(--cg-
|
|
269
|
-
margin:
|
|
289
|
+
gap: var(--cg-s1) var(--cg-s4);
|
|
290
|
+
margin-block-end: var(--cg-s6);
|
|
270
291
|
padding: 0;
|
|
271
292
|
list-style: none;
|
|
272
|
-
font-size: var(--cg-text-
|
|
273
|
-
font-weight: var(--cg-weight-
|
|
274
|
-
letter-spacing: var(--cg-tracking-wide);
|
|
275
|
-
text-transform: uppercase;
|
|
276
|
-
color: var(--cg-accent);
|
|
293
|
+
font-size: var(--cg-text-label);
|
|
294
|
+
font-weight: var(--cg-weight-medium);
|
|
277
295
|
}
|
|
278
296
|
|
|
279
297
|
.cg-entry-header__terms a {
|
|
280
|
-
color:
|
|
281
|
-
text-decoration:
|
|
298
|
+
color: var(--cg-ink);
|
|
299
|
+
text-decoration-color: var(--cg-underline);
|
|
282
300
|
}
|
|
283
301
|
|
|
284
|
-
.cg-entry-header__terms
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
color: var(--cg-ink-muted);
|
|
302
|
+
.cg-entry-header__terms a:hover {
|
|
303
|
+
color: var(--cg-accent);
|
|
304
|
+
text-decoration-color: currentColor;
|
|
288
305
|
}
|
|
289
306
|
|
|
290
307
|
.cg-entry-header__title {
|
|
291
|
-
|
|
292
|
-
font-size: var(--cg-text-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
text-wrap: balance;
|
|
308
|
+
font-family: var(--cg-font-display);
|
|
309
|
+
font-size: var(--cg-text-title);
|
|
310
|
+
font-weight: var(--cg-weight-regular);
|
|
311
|
+
line-height: var(--cg-leading-display);
|
|
312
|
+
letter-spacing: var(--cg-tracking-display);
|
|
297
313
|
}
|
|
298
314
|
|
|
299
315
|
.cg-entry-header__excerpt {
|
|
300
|
-
margin:
|
|
301
|
-
|
|
316
|
+
margin-block-start: var(--cg-s6);
|
|
317
|
+
max-inline-size: var(--cg-measure);
|
|
302
318
|
color: var(--cg-ink-muted);
|
|
303
|
-
|
|
319
|
+
font-size: var(--cg-text-lg);
|
|
320
|
+
line-height: var(--cg-leading-snug);
|
|
304
321
|
}
|
|
305
322
|
|
|
306
323
|
.cg-entry-header__meta {
|
|
307
324
|
display: flex;
|
|
308
325
|
flex-wrap: wrap;
|
|
309
|
-
gap: var(--cg-
|
|
310
|
-
margin:
|
|
311
|
-
|
|
326
|
+
gap: var(--cg-s1) var(--cg-s5);
|
|
327
|
+
margin-block-start: var(--cg-s8);
|
|
328
|
+
padding-block-start: var(--cg-s4);
|
|
329
|
+
border-block-start: var(--cg-rule) solid var(--cg-line);
|
|
312
330
|
color: var(--cg-ink-muted);
|
|
331
|
+
font-size: var(--cg-text-label);
|
|
332
|
+
font-variant-numeric: tabular-nums;
|
|
313
333
|
}
|
|
314
334
|
|
|
315
|
-
.cg-entry-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
color: var(--cg-line-strong);
|
|
335
|
+
.cg-entry-header__author {
|
|
336
|
+
color: var(--cg-ink);
|
|
337
|
+
font-weight: var(--cg-weight-medium);
|
|
319
338
|
}
|
|
320
339
|
|
|
321
340
|
.cg-entry-header__cover {
|
|
322
|
-
margin:
|
|
341
|
+
margin-block-start: var(--cg-s10);
|
|
323
342
|
}
|
|
324
343
|
|
|
325
344
|
.cg-entry-header__cover img,
|
|
326
345
|
.cg-entry-header__cover video {
|
|
327
346
|
inline-size: 100%;
|
|
328
|
-
aspect-ratio:
|
|
329
|
-
border-radius: var(--cg-radius-lg);
|
|
330
|
-
object-fit: cover;
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
.cg-site-header {
|
|
334
|
-
position: sticky;
|
|
335
|
-
inset-block-start: 0;
|
|
336
|
-
z-index: 5;
|
|
337
|
-
padding: var(--cg-s4) var(--cg-gutter);
|
|
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);
|
|
342
|
-
border-block-end: 1px solid var(--cg-line-soft);
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
.cg-site-header__inner,
|
|
346
|
-
.cg-site-footer__inner {
|
|
347
|
-
display: flex;
|
|
348
|
-
flex-wrap: wrap;
|
|
349
|
-
align-items: center;
|
|
350
|
-
gap: var(--cg-gap);
|
|
351
|
-
max-inline-size: var(--cg-page);
|
|
352
|
-
margin-inline: auto;
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
.cg-site-header__home {
|
|
356
|
-
color: var(--cg-ink);
|
|
357
|
-
font-weight: var(--cg-weight-semibold);
|
|
358
|
-
font-size: var(--cg-text-lg);
|
|
359
|
-
letter-spacing: var(--cg-tracking-snug);
|
|
360
|
-
text-decoration: none;
|
|
361
|
-
margin-inline-end: auto;
|
|
362
|
-
}
|
|
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
|
-
|
|
377
|
-
.cg-site-footer {
|
|
378
|
-
padding: var(--cg-s12) var(--cg-gutter);
|
|
379
|
-
background: var(--cg-surface-sunken);
|
|
380
|
-
color: var(--cg-ink-muted);
|
|
381
|
-
border-block-start: 1px solid var(--cg-line-soft);
|
|
382
|
-
font-size: var(--cg-text-sm);
|
|
383
|
-
}
|
|
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;
|
|
347
|
+
aspect-ratio: 3 / 2;
|
|
416
348
|
}
|
|
417
349
|
|
|
418
|
-
|
|
419
|
-
|
|
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;
|
|
350
|
+
@media (min-width: 64rem) {
|
|
351
|
+
.cg-entry-header__title {
|
|
352
|
+
grid-column: 1 / span 10;
|
|
428
353
|
}
|
|
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
354
|
|
|
494
|
-
.cg-
|
|
495
|
-
|
|
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
|
-
}
|
|
355
|
+
.cg-entry-header__excerpt {
|
|
356
|
+
grid-column: 1 / span 8;
|
|
357
|
+
}
|
|
542
358
|
|
|
543
|
-
.cg-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
the admin shell's own logo had before its fix. */
|
|
548
|
-
block-size: 25px;
|
|
549
|
-
inline-size: auto;
|
|
359
|
+
.cg-entry-header__cover img,
|
|
360
|
+
.cg-entry-header__cover video {
|
|
361
|
+
aspect-ratio: 2 / 1;
|
|
362
|
+
}
|
|
550
363
|
}
|
|
551
364
|
|
|
552
365
|
/* --------------------------------------------------------------------------
|
|
553
|
-
Actions
|
|
366
|
+
Actions
|
|
554
367
|
-------------------------------------------------------------------------- */
|
|
555
368
|
|
|
556
369
|
.cg-actions {
|
|
557
370
|
display: flex;
|
|
558
371
|
flex-wrap: wrap;
|
|
559
|
-
|
|
560
|
-
|
|
372
|
+
align-items: center;
|
|
373
|
+
gap: var(--cg-s3) var(--cg-s8);
|
|
374
|
+
margin-block-start: var(--cg-s8);
|
|
561
375
|
padding: 0;
|
|
562
376
|
list-style: none;
|
|
563
377
|
}
|
|
564
378
|
|
|
565
|
-
|
|
379
|
+
/* `emphasis` stays a data attribute: it is the editor's intent, and the
|
|
380
|
+
stylesheet decides what it looks like. */
|
|
381
|
+
.cg-action[data-emphasis="primary"] {
|
|
566
382
|
display: inline-flex;
|
|
567
383
|
align-items: center;
|
|
568
384
|
justify-content: center;
|
|
569
|
-
|
|
570
|
-
padding: var(--cg-
|
|
571
|
-
border:
|
|
572
|
-
border-radius: var(--cg-radius-
|
|
573
|
-
|
|
385
|
+
min-block-size: 2.75rem;
|
|
386
|
+
padding: var(--cg-s2) var(--cg-s6);
|
|
387
|
+
border: var(--cg-rule) solid var(--cg-action);
|
|
388
|
+
border-radius: var(--cg-radius-control);
|
|
389
|
+
background: var(--cg-action);
|
|
390
|
+
color: var(--cg-action-fg);
|
|
391
|
+
font-size: var(--cg-text-md);
|
|
574
392
|
font-weight: var(--cg-weight-semibold);
|
|
575
|
-
|
|
576
|
-
line-height: var(--cg-leading-snug);
|
|
393
|
+
line-height: var(--cg-leading-heading);
|
|
577
394
|
text-decoration: none;
|
|
578
|
-
white-space: nowrap;
|
|
579
395
|
transition:
|
|
580
396
|
background-color var(--cg-duration) var(--cg-ease),
|
|
581
|
-
color var(--cg-duration) var(--cg-ease)
|
|
582
|
-
box-shadow var(--cg-duration) var(--cg-ease),
|
|
583
|
-
transform var(--cg-duration-fast) var(--cg-ease);
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
/* `emphasis` stays a data attribute, never a class: it is the editor's
|
|
587
|
-
semantic intent, and the skin — not the block — decides what it looks like. */
|
|
588
|
-
.cg-action[data-emphasis="primary"] {
|
|
589
|
-
background: var(--cg-accent);
|
|
590
|
-
color: var(--cg-accent-fg);
|
|
591
|
-
box-shadow: var(--cg-elevation-1);
|
|
397
|
+
border-color var(--cg-duration) var(--cg-ease);
|
|
592
398
|
}
|
|
593
399
|
|
|
594
400
|
.cg-action[data-emphasis="primary"]:hover {
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
color: var(--cg-accent-soft-fg);
|
|
609
|
-
box-shadow: var(--cg-ring-accent);
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
/* The press. Without it a hover lift reads as a bug on touch, where there is
|
|
613
|
-
no hover to come back from. */
|
|
614
|
-
.cg-action:active {
|
|
615
|
-
transform: translateY(0);
|
|
616
|
-
box-shadow: var(--cg-elevation-1);
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
/* --------------------------------------------------------------------------
|
|
620
|
-
Shared block furniture
|
|
621
|
-
-------------------------------------------------------------------------- */
|
|
622
|
-
|
|
623
|
-
/* Every block that carries a heading uses the same one, so eleven blocks do
|
|
624
|
-
not drift into eleven title sizes. */
|
|
625
|
-
.cg-features__title,
|
|
626
|
-
.cg-cta__title,
|
|
627
|
-
.cg-faq__title,
|
|
628
|
-
.cg-stats__title,
|
|
629
|
-
.cg-logos__title,
|
|
630
|
-
.cg-collection__title {
|
|
631
|
-
margin: 0 0 var(--cg-s8);
|
|
632
|
-
font-size: var(--cg-text-xl);
|
|
633
|
-
line-height: var(--cg-leading-snug);
|
|
634
|
-
letter-spacing: var(--cg-tracking-tight);
|
|
635
|
-
font-weight: var(--cg-weight-bold);
|
|
636
|
-
text-wrap: balance;
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
.cg-features__items,
|
|
640
|
-
.cg-logos__items,
|
|
641
|
-
.cg-gallery__items,
|
|
642
|
-
.cg-collection__items,
|
|
643
|
-
.cg-faq__items {
|
|
644
|
-
margin: 0;
|
|
645
|
-
padding: 0;
|
|
646
|
-
list-style: none;
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
/* A scroll-snapping row, used by both `gallery` and `collectionList`. The
|
|
650
|
-
container is focusable and labelled, so it is operable from the keyboard —
|
|
651
|
-
at zero bytes of JavaScript. */
|
|
652
|
-
.cg-gallery__viewport,
|
|
653
|
-
.cg-collection__viewport {
|
|
654
|
-
overflow-x: auto;
|
|
655
|
-
scroll-snap-type: x mandatory;
|
|
656
|
-
scroll-behavior: smooth;
|
|
657
|
-
overscroll-behavior-inline: contain;
|
|
658
|
-
scrollbar-width: thin;
|
|
659
|
-
scrollbar-color: var(--cg-line-strong) transparent;
|
|
660
|
-
/* Room for the focus ring and the hover lift, which would otherwise be
|
|
661
|
-
clipped by the scroll container. */
|
|
662
|
-
padding-block: var(--cg-s2);
|
|
663
|
-
margin-block: calc(var(--cg-s2) * -1);
|
|
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 {
|
|
401
|
+
border-color: var(--cg-action-hover);
|
|
402
|
+
background: var(--cg-action-hover);
|
|
403
|
+
color: var(--cg-action-fg);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/* A secondary action and every arrow link: words in ink under one continuous
|
|
407
|
+
underline, the arrow drawn after them as an atomic inline so the line does
|
|
408
|
+
not run under it, and the label kept on one line so the arrow never wraps
|
|
409
|
+
alone. */
|
|
410
|
+
.cg-action[data-emphasis="secondary"],
|
|
411
|
+
.cg-arrow-link {
|
|
412
|
+
display: inline-block;
|
|
413
|
+
padding-block: var(--cg-s3);
|
|
730
414
|
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
415
|
font-weight: var(--cg-weight-semibold);
|
|
788
|
-
|
|
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);
|
|
416
|
+
text-decoration-line: underline;
|
|
417
|
+
text-decoration-color: var(--cg-underline);
|
|
823
418
|
}
|
|
824
419
|
|
|
825
|
-
.cg-
|
|
826
|
-
|
|
827
|
-
margin: 0;
|
|
828
|
-
padding: 0;
|
|
829
|
-
list-style: none;
|
|
420
|
+
.cg-action[data-emphasis="secondary"] {
|
|
421
|
+
white-space: nowrap;
|
|
830
422
|
}
|
|
831
423
|
|
|
832
|
-
.cg-
|
|
833
|
-
|
|
834
|
-
border-block-end: 1px solid var(--cg-line-soft);
|
|
424
|
+
.cg-arrow-link__end {
|
|
425
|
+
white-space: nowrap;
|
|
835
426
|
}
|
|
836
427
|
|
|
837
|
-
.cg-
|
|
838
|
-
|
|
428
|
+
.cg-action[data-emphasis="secondary"]::after,
|
|
429
|
+
.cg-arrow-link__end::after {
|
|
430
|
+
content: "\2192" / "";
|
|
431
|
+
display: inline-block;
|
|
432
|
+
margin-inline-start: 0.35em;
|
|
839
433
|
}
|
|
840
434
|
|
|
841
|
-
.cg-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
435
|
+
.cg-arrow-link__start::before {
|
|
436
|
+
content: "\2190" / "";
|
|
437
|
+
display: inline-block;
|
|
438
|
+
margin-inline-end: 0.35em;
|
|
845
439
|
}
|
|
846
440
|
|
|
847
|
-
.cg-
|
|
848
|
-
|
|
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);
|
|
441
|
+
.cg-arrow-link__start {
|
|
442
|
+
white-space: nowrap;
|
|
859
443
|
}
|
|
860
444
|
|
|
861
|
-
.cg-
|
|
862
|
-
|
|
445
|
+
.cg-action[data-emphasis="secondary"]:hover,
|
|
446
|
+
.cg-arrow-link:hover {
|
|
447
|
+
color: var(--cg-accent);
|
|
448
|
+
text-decoration-color: currentColor;
|
|
863
449
|
}
|