@cogenta/theme-portfolio 1.1.3 → 1.3.4

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 (128) hide show
  1. package/dist/src/index.d.ts +9 -0
  2. package/dist/src/index.d.ts.map +1 -1
  3. package/dist/src/index.js +10 -1
  4. package/dist/src/index.js.map +1 -1
  5. package/dist/src/render/blocks/accordion.d.ts.map +1 -1
  6. package/dist/src/render/blocks/accordion.js +10 -18
  7. package/dist/src/render/blocks/accordion.js.map +1 -1
  8. package/dist/src/render/blocks/collection-list.d.ts +0 -20
  9. package/dist/src/render/blocks/collection-list.d.ts.map +1 -1
  10. package/dist/src/render/blocks/collection-list.js +59 -66
  11. package/dist/src/render/blocks/collection-list.js.map +1 -1
  12. package/dist/src/render/blocks/cta.d.ts +4 -4
  13. package/dist/src/render/blocks/cta.d.ts.map +1 -1
  14. package/dist/src/render/blocks/cta.js +15 -10
  15. package/dist/src/render/blocks/cta.js.map +1 -1
  16. package/dist/src/render/blocks/embed.d.ts.map +1 -1
  17. package/dist/src/render/blocks/embed.js +16 -31
  18. package/dist/src/render/blocks/embed.js.map +1 -1
  19. package/dist/src/render/blocks/faq.d.ts.map +1 -1
  20. package/dist/src/render/blocks/faq.js +12 -17
  21. package/dist/src/render/blocks/faq.js.map +1 -1
  22. package/dist/src/render/blocks/feature-grid.d.ts.map +1 -1
  23. package/dist/src/render/blocks/feature-grid.js +26 -23
  24. package/dist/src/render/blocks/feature-grid.js.map +1 -1
  25. package/dist/src/render/blocks/gallery.d.ts +0 -14
  26. package/dist/src/render/blocks/gallery.d.ts.map +1 -1
  27. package/dist/src/render/blocks/gallery.js +29 -21
  28. package/dist/src/render/blocks/gallery.js.map +1 -1
  29. package/dist/src/render/blocks/hero.d.ts +8 -8
  30. package/dist/src/render/blocks/hero.d.ts.map +1 -1
  31. package/dist/src/render/blocks/hero.js +17 -18
  32. package/dist/src/render/blocks/hero.js.map +1 -1
  33. package/dist/src/render/blocks/logo-strip.d.ts.map +1 -1
  34. package/dist/src/render/blocks/logo-strip.js +9 -14
  35. package/dist/src/render/blocks/logo-strip.js.map +1 -1
  36. package/dist/src/render/blocks/logos.d.ts.map +1 -1
  37. package/dist/src/render/blocks/logos.js +14 -19
  38. package/dist/src/render/blocks/logos.js.map +1 -1
  39. package/dist/src/render/blocks/media-figure.d.ts +8 -12
  40. package/dist/src/render/blocks/media-figure.d.ts.map +1 -1
  41. package/dist/src/render/blocks/media-figure.js +20 -20
  42. package/dist/src/render/blocks/media-figure.js.map +1 -1
  43. package/dist/src/render/blocks/pricing-table.d.ts.map +1 -1
  44. package/dist/src/render/blocks/pricing-table.js +17 -20
  45. package/dist/src/render/blocks/pricing-table.js.map +1 -1
  46. package/dist/src/render/blocks/prose.d.ts +10 -9
  47. package/dist/src/render/blocks/prose.d.ts.map +1 -1
  48. package/dist/src/render/blocks/prose.js +29 -10
  49. package/dist/src/render/blocks/prose.js.map +1 -1
  50. package/dist/src/render/blocks/quote.d.ts +5 -12
  51. package/dist/src/render/blocks/quote.d.ts.map +1 -1
  52. package/dist/src/render/blocks/quote.js +9 -15
  53. package/dist/src/render/blocks/quote.js.map +1 -1
  54. package/dist/src/render/blocks/stat-counter.d.ts.map +1 -1
  55. package/dist/src/render/blocks/stat-counter.js +10 -12
  56. package/dist/src/render/blocks/stat-counter.js.map +1 -1
  57. package/dist/src/render/blocks/stats.d.ts.map +1 -1
  58. package/dist/src/render/blocks/stats.js +7 -15
  59. package/dist/src/render/blocks/stats.js.map +1 -1
  60. package/dist/src/render/blocks/testimonial.d.ts +4 -14
  61. package/dist/src/render/blocks/testimonial.d.ts.map +1 -1
  62. package/dist/src/render/blocks/testimonial.js +9 -18
  63. package/dist/src/render/blocks/testimonial.js.map +1 -1
  64. package/dist/src/render/chrome.d.ts.map +1 -1
  65. package/dist/src/render/chrome.js +93 -90
  66. package/dist/src/render/chrome.js.map +1 -1
  67. package/dist/src/render/layout.d.ts +61 -0
  68. package/dist/src/render/layout.d.ts.map +1 -0
  69. package/dist/src/render/layout.js +134 -0
  70. package/dist/src/render/layout.js.map +1 -0
  71. package/dist/src/render/project.d.ts +27 -0
  72. package/dist/src/render/project.d.ts.map +1 -0
  73. package/dist/src/render/project.js +82 -0
  74. package/dist/src/render/project.js.map +1 -0
  75. package/dist/src/render/render-block.d.ts +17 -7
  76. package/dist/src/render/render-block.d.ts.map +1 -1
  77. package/dist/src/render/render-block.js +47 -34
  78. package/dist/src/render/render-block.js.map +1 -1
  79. package/dist/src/render/term-archive.d.ts +0 -11
  80. package/dist/src/render/term-archive.d.ts.map +1 -1
  81. package/dist/src/render/term-archive.js +36 -24
  82. package/dist/src/render/term-archive.js.map +1 -1
  83. package/dist/src/render/widget-areas.d.ts +14 -0
  84. package/dist/src/render/widget-areas.d.ts.map +1 -0
  85. package/dist/src/render/widget-areas.js +21 -0
  86. package/dist/src/render/widget-areas.js.map +1 -0
  87. package/dist/src/render/work.d.ts +37 -0
  88. package/dist/src/render/work.d.ts.map +1 -0
  89. package/dist/src/render/work.js +49 -0
  90. package/dist/src/render/work.js.map +1 -0
  91. package/dist/theme.config.d.ts +4 -7
  92. package/dist/theme.config.d.ts.map +1 -1
  93. package/dist/theme.config.js +6 -9
  94. package/dist/theme.config.js.map +1 -1
  95. package/package.json +4 -4
  96. package/src/index.ts +10 -1
  97. package/src/render/blocks/accordion.ts +22 -42
  98. package/src/render/blocks/collection-list.ts +83 -137
  99. package/src/render/blocks/cta.ts +24 -12
  100. package/src/render/blocks/embed.ts +39 -47
  101. package/src/render/blocks/faq.ts +24 -33
  102. package/src/render/blocks/feature-grid.ts +38 -41
  103. package/src/render/blocks/gallery.ts +34 -28
  104. package/src/render/blocks/hero.ts +31 -28
  105. package/src/render/blocks/logo-strip.ts +18 -20
  106. package/src/render/blocks/logos.ts +22 -43
  107. package/src/render/blocks/media-figure.ts +28 -20
  108. package/src/render/blocks/pricing-table.ts +31 -32
  109. package/src/render/blocks/prose.ts +38 -13
  110. package/src/render/blocks/quote.ts +18 -18
  111. package/src/render/blocks/stat-counter.ts +19 -37
  112. package/src/render/blocks/stats.ts +18 -33
  113. package/src/render/blocks/testimonial.ts +16 -22
  114. package/src/render/chrome.ts +99 -97
  115. package/src/render/layout.ts +177 -0
  116. package/src/render/project.ts +140 -0
  117. package/src/render/render-block.ts +49 -45
  118. package/src/render/term-archive.ts +92 -70
  119. package/src/render/widget-areas.ts +25 -0
  120. package/src/render/work.ts +124 -0
  121. package/src/styles/archive.css +61 -21
  122. package/src/styles/base.css +763 -648
  123. package/src/styles/blocks.css +697 -1093
  124. package/src/styles/theme.css +22 -10
  125. package/src/styles/tokens.css +174 -252
  126. package/src/styles/widgets.css +948 -0
  127. package/src/styles/work.css +405 -0
  128. package/tokens.json +19 -19
@@ -1,7 +1,7 @@
1
1
  /*
2
- * Document, accessibility floor, page frame, chrome and the theme's one
3
- * control (an action link). Everything here reads the design system from
4
- * `tokens.css`; nothing here reads a `--cogenta-*` token directly.
2
+ * Document, accessibility floor, the grid, section labels, actions, the
3
+ * header and footer, and the utility pages the host renders (search, forms,
4
+ * comments). Everything reads `tokens.css`.
5
5
  */
6
6
 
7
7
  /* --------------------------------------------------------------------------
@@ -14,121 +14,135 @@
14
14
  box-sizing: border-box;
15
15
  }
16
16
 
17
+ html {
18
+ -webkit-text-size-adjust: 100%;
19
+ text-size-adjust: 100%;
20
+ scroll-padding-block-start: var(--cg-s6);
21
+ hanging-punctuation: first allow-end last;
22
+ }
23
+
17
24
  body {
18
25
  margin: 0;
19
26
  background: var(--cg-canvas);
20
27
  color: var(--cg-ink);
21
- font-family: var(--cogenta-font-sans);
28
+ font-family: var(--cg-font);
22
29
  font-size: var(--cg-text-md);
23
- line-height: var(--cg-leading-normal);
30
+ font-stretch: var(--cg-width-text);
31
+ font-weight: var(--cg-weight-regular);
32
+ line-height: var(--cg-leading-text);
24
33
  font-kerning: normal;
25
34
  font-variant-ligatures: common-ligatures;
26
- text-underline-offset: 0.16em;
27
- text-decoration-thickness: from-font;
28
- -webkit-text-size-adjust: 100%;
35
+ font-synthesis: none;
36
+ text-rendering: optimizeLegibility;
37
+ -webkit-font-smoothing: antialiased;
29
38
  }
30
39
 
31
40
  ::selection {
32
- background: var(--cg-accent);
33
- color: var(--cg-accent-fg);
41
+ background: var(--cg-signal);
42
+ color: var(--cg-signal-fg);
34
43
  }
35
44
 
36
45
  img,
37
46
  video,
38
47
  iframe {
39
- max-width: 100%;
40
- height: auto;
48
+ display: block;
49
+ max-inline-size: 100%;
50
+ block-size: auto;
41
51
  }
42
52
 
43
53
  img {
44
- display: block;
45
54
  object-fit: cover;
46
55
  }
47
56
 
57
+ :where(img, video) {
58
+ filter: brightness(var(--cg-image-brightness));
59
+ }
60
+
61
+ :where(h1, h2, h3, h4, h5, h6) {
62
+ margin: 0;
63
+ font-family: var(--cg-font);
64
+ font-weight: var(--cg-weight-medium);
65
+ line-height: var(--cg-leading-heading);
66
+ letter-spacing: var(--cg-tracking-heading);
67
+ text-wrap: balance;
68
+ }
69
+
70
+ :where(p, li, dd, figcaption, blockquote) {
71
+ text-wrap: pretty;
72
+ }
73
+
48
74
  :where(a) {
49
- color: currentColor;
50
- text-decoration-color: color-mix(in oklab, var(--cg-accent) 55%, transparent);
51
- text-underline-offset: 0.2em;
75
+ color: var(--cg-ink);
76
+ text-decoration-line: underline;
77
+ text-decoration-thickness: var(--cg-rule);
78
+ text-decoration-color: var(--cg-line-strong);
79
+ text-underline-offset: 0.22em;
52
80
  transition:
53
- color var(--cg-duration-fast) var(--cg-ease),
54
- text-decoration-color var(--cg-duration-fast) var(--cg-ease);
81
+ color var(--cg-duration) var(--cg-ease),
82
+ text-decoration-color var(--cg-duration) var(--cg-ease);
55
83
  }
56
84
 
57
85
  :where(a:hover) {
58
- color: var(--cg-accent);
59
86
  text-decoration-color: currentColor;
60
87
  }
61
88
 
62
89
  :where(hr) {
63
- block-size: 1px;
90
+ block-size: var(--cg-rule);
64
91
  border: 0;
65
92
  margin-block: var(--cg-s10);
66
93
  background: var(--cg-line);
67
94
  }
68
95
 
96
+ :where(code, kbd, samp, pre) {
97
+ font-family: var(--cg-font-code);
98
+ font-size: 0.86em;
99
+ }
100
+
101
+ .cg-visually-hidden {
102
+ position: absolute;
103
+ inline-size: 1px;
104
+ block-size: 1px;
105
+ margin: -1px;
106
+ padding: 0;
107
+ overflow: hidden;
108
+ clip-path: inset(50%);
109
+ white-space: nowrap;
110
+ border: 0;
111
+ }
112
+
69
113
  /* --------------------------------------------------------------------------
70
- Focus, targets, motion — the three that decide whether AA holds
114
+ Focus, targets, motion. Motion is a colour or an underline changing, in
115
+ under 150 ms; nothing moves in space, nothing fades in on scroll.
71
116
  -------------------------------------------------------------------------- */
72
117
 
73
- :where(a, button, summary, [tabindex]):focus-visible {
74
- outline: 2px solid var(--cg-accent);
118
+ :where(a, button, summary, input, select, textarea, [tabindex]):focus-visible {
119
+ outline: var(--cg-rule-strong) solid var(--cg-signal);
75
120
  outline-offset: 3px;
76
- border-radius: var(--cg-radius-xs);
77
121
  }
78
122
 
79
- :where(.cg-action, .cg-faq__question, .cg-logo__link) {
123
+ :where(.cg-action, .cg-nav-toggle-label, .cg-theme-toggle, summary) {
80
124
  min-block-size: 44px;
81
- min-inline-size: 44px;
82
- }
83
-
84
- /* The entrance sweep every block opts into. Scroll-driven, so a section
85
- arrives as it is scrolled to rather than firing eleven times on load, and
86
- wrapped in a feature query because the starting state is `opacity: 0`. */
87
- @supports (animation-timeline: view()) {
88
- @media (prefers-reduced-motion: no-preference) {
89
- @keyframes cg-rise {
90
- from {
91
- opacity: 0;
92
- transform: translateY(var(--cg-s5));
93
- }
94
-
95
- to {
96
- opacity: 1;
97
- transform: none;
98
- }
99
- }
100
-
101
- .cg-block {
102
- animation: cg-rise linear both;
103
- animation-timeline: view();
104
- animation-range: entry 0% cover 20%;
105
- }
106
- }
107
125
  }
108
126
 
127
+ /* Every transition in this theme reads `--cg-duration`, so reduced motion is
128
+ one declaration rather than an `!important` sweep over every element. */
109
129
  @media (prefers-reduced-motion: reduce) {
110
- *,
111
- *::before,
112
- *::after {
113
- animation-duration: 1ms !important;
114
- animation-iteration-count: 1 !important;
115
- transition-duration: 1ms !important;
116
- scroll-behavior: auto !important;
130
+ :root {
131
+ --cg-duration: 0ms;
117
132
  }
118
133
  }
119
134
 
120
135
  .cg-skip-link {
121
136
  position: absolute;
122
137
  inset-inline-start: var(--cg-s3);
123
- inset-block-start: calc(var(--cg-s3) * -8);
124
- z-index: 20;
138
+ inset-block-start: calc(var(--cg-s16) * -1);
139
+ z-index: 30;
125
140
  padding: var(--cg-s2) var(--cg-s4);
126
- background: var(--cg-surface-inverted);
127
- color: var(--cg-surface-inverted-fg);
128
- border-radius: var(--cg-radius-xs);
129
- font-weight: var(--cg-weight-bold);
141
+ background: var(--cg-action);
142
+ color: var(--cg-action-fg);
143
+ font-size: var(--cg-text-caption);
144
+ font-weight: var(--cg-weight-medium);
130
145
  text-decoration: none;
131
- transition: inset-block-start var(--cg-duration) var(--cg-ease);
132
146
  }
133
147
 
134
148
  .cg-skip-link:focus-visible {
@@ -136,89 +150,108 @@ img {
136
150
  }
137
151
 
138
152
  /* --------------------------------------------------------------------------
139
- Page frame
153
+ The grid. Every block is a section around a twelve-column container; the
154
+ section rhythm is one variable, applied to all of them.
140
155
  -------------------------------------------------------------------------- */
141
156
 
142
157
  .cg-main {
143
158
  display: flow-root;
144
- /* Drives the "Fig. 01" plate number in `mediaFigure` — a page-wide count,
145
- since a plate numbers *the page's* figures, not one block's own. Every
146
- other numbered list (`featureGrid`, `gallery`) resets its own counter
147
- locally in `blocks.css`, since those numbers restart per list. */
148
- counter-reset: cg-figure;
149
- /* The hero's negative-margin media overlap (`.cg-hero__media`) and a
150
- full-bleed grid card's own offset-on-hover both read past the page's
151
- own edge by design; `clip` — not `hidden` — cuts them at the viewport
152
- without turning `<main>` into a scroll container of its own. */
153
159
  overflow-x: clip;
160
+ padding-block-end: calc(var(--cg-section) / 2);
154
161
  }
155
162
 
156
- /* The standard clip-to-1px technique — visible to assistive tech, invisible
157
- on screen, unlike `display:none` (which removes it from both). Every
158
- social icon link's own text label (`renderSocialLinks`, `@cogenta/
159
- theme-kit`) depends on this class existing here: theme-kit ships no CSS
160
- of its own (contract D, R5 — a theme owns its own stylesheet). */
161
- .cg-visually-hidden {
162
- position: absolute;
163
- inline-size: 1px;
164
- block-size: 1px;
165
- padding: 0;
166
- margin: -1px;
167
- overflow: hidden;
168
- clip: rect(0, 0, 0, 0);
169
- white-space: nowrap;
170
- }
171
-
172
- .cg-block {
173
- max-inline-size: var(--cg-page);
163
+ .cg-container {
164
+ display: grid;
165
+ grid-template-columns: repeat(var(--cg-columns), minmax(0, 1fr));
166
+ column-gap: var(--cg-col-gap);
167
+ align-items: start;
168
+ inline-size: 100%;
169
+ max-inline-size: calc(var(--cg-page) + var(--cg-gutter) * 2);
174
170
  margin-inline: auto;
175
- margin-block: var(--cg-section-y);
176
171
  padding-inline: var(--cg-gutter);
177
172
  }
178
173
 
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.
174
+ /* Below the wide breakpoint twelve columns only make slivers: every child
175
+ takes the full row, and each block redistributes from there. */
176
+ .cg-container > * {
177
+ grid-column: 1 / -1;
178
+ min-inline-size: 0;
179
+ }
185
180
 
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
- ------------------------------------------------------------------------- */
181
+ .cg-section {
182
+ padding-block: calc(var(--cg-section) / 2);
183
+ }
192
184
 
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);
185
+ :is(.cg-main, .cg-sidebar-layout__content) > .cg-section:first-child {
186
+ padding-block-start: calc(var(--cg-section) * 0.4);
197
187
  }
198
188
 
199
- [data-block][data-variant-background="muted"] {
200
- background: var(--cg-surface-sunken);
189
+ /* --- section labels ---------------------------------------------------------
190
+ One label for every titled block: a hairline across the container and the
191
+ title under it, small, in the text face. Above a grid it runs full width;
192
+ in a split block it takes the first three columns. */
193
+
194
+ .cg-head {
195
+ padding-block-start: var(--cg-s4);
196
+ border-block-start: var(--cg-rule) solid var(--cg-line-ink);
197
+ margin-block-end: var(--cg-s10);
201
198
  }
202
199
 
203
- [data-block][data-variant-background="image"] {
204
- background: var(--cg-surface-tinted);
200
+ .cg-head__title {
201
+ font-size: var(--cg-text-caption);
202
+ font-weight: var(--cg-weight-medium);
203
+ line-height: var(--cg-leading-ui);
204
+ letter-spacing: var(--cg-tracking-caption);
205
205
  }
206
206
 
207
- [data-block][data-variant-spacing="compact"] {
208
- margin-block: calc(var(--cg-section-y) / 2);
207
+ /* In a split block the label keeps its hairline over the first three
208
+ columns and the content takes its own over the rest: one rule broken at the
209
+ gutter, the way a studio's printed matter sets a label beside its text. */
210
+ @media (min-width: 64rem) {
211
+ .cg-split .cg-head {
212
+ grid-column: 1 / span 3;
213
+ margin: 0;
214
+ }
215
+
216
+ .cg-split .cg-head ~ * {
217
+ grid-column: 4 / -1;
218
+ padding-block-start: var(--cg-s4);
219
+ border-block-start: var(--cg-rule) solid var(--cg-line-ink);
220
+ }
221
+
222
+ .cg-split[data-titled="false"] .cg-container > * {
223
+ grid-column: 4 / -1;
224
+ }
209
225
  }
210
226
 
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. */
227
+ .cg-empty {
228
+ margin: 0;
229
+ padding-block: var(--cg-s6);
230
+ border-block-start: var(--cg-rule) solid var(--cg-line);
231
+ color: var(--cg-ink-muted);
232
+ font-size: var(--cg-text-caption);
233
+ }
215
234
 
216
- [data-block][data-variant-spacing="spacious"] {
217
- margin-block: calc(var(--cg-section-y) * 1.6);
235
+ /* Under a label the label's own rule is enough. */
236
+ .cg-head + .cg-empty {
237
+ padding-block-start: 0;
238
+ border-block-start: 0;
239
+ }
240
+
241
+ /* --- per-block variants (blocks@2.0, RFC 0002) --------------------------- */
242
+
243
+ [data-block][data-variant-background="muted"],
244
+ [data-block][data-variant-background="image"] {
245
+ background: var(--cg-surface-sunken);
246
+ padding-block: calc(var(--cg-section) * 0.75);
218
247
  }
219
248
 
220
- [data-block][data-variant-align="start"] {
221
- text-align: start;
249
+ [data-block][data-variant-spacing="compact"] {
250
+ padding-block: calc(var(--cg-section) / 4);
251
+ }
252
+
253
+ [data-block][data-variant-spacing="spacious"] {
254
+ padding-block: calc(var(--cg-section) * 0.85);
222
255
  }
223
256
 
224
257
  [data-block][data-variant-align="center"] {
@@ -229,320 +262,241 @@ img {
229
262
  text-align: end;
230
263
  }
231
264
 
232
- [data-block][data-variant-width="full"] {
265
+ [data-block][data-variant-width="full"] > .cg-container {
233
266
  max-inline-size: none;
234
- padding-inline: 0;
235
267
  }
236
268
 
237
- .cg-page__title {
238
- max-inline-size: var(--cg-page);
239
- margin-inline: auto;
240
- margin-block: var(--cg-section-y) var(--cg-s6);
241
- padding-inline: var(--cg-gutter);
242
- font-family: var(--cogenta-font-sans);
243
- font-size: var(--cg-text-hero);
244
- line-height: var(--cg-leading-tight);
245
- letter-spacing: var(--cg-tracking-tighter);
246
- font-weight: var(--cg-weight-black);
247
- text-wrap: balance;
269
+ /* --- the title of a page that is not a project ------------------------------ */
270
+
271
+ .cg-page-head {
272
+ padding-block: calc(var(--cg-section) * 0.45) calc(var(--cg-section) * 0.15);
248
273
  }
249
274
 
250
- /* --------------------------------------------------------------------------
251
- Entry header (`renderEntryHeader`, `@cogenta/theme-kit`, `theme@1.4`) — a
252
- project page's own furniture: the display title at the same scale as
253
- `.cg-page__title`, the excerpt (`summary`) in the reading measure, and a
254
- full-bleed cover with a hard, flat frame — no scrim, this theme never
255
- overlays text on an image.
256
- -------------------------------------------------------------------------- */
275
+ .cg-page-head__title {
276
+ font-size: var(--cg-size-title);
277
+ font-stretch: var(--cg-width-display);
278
+ font-weight: var(--cg-weight-medium);
279
+ line-height: var(--cg-leading-title);
280
+ letter-spacing: var(--cg-tracking-display);
281
+ }
257
282
 
258
- .cg-entry-header {
259
- max-inline-size: var(--cg-page);
260
- margin-inline: auto;
261
- margin-block: var(--cg-section-y) var(--cg-s10);
262
- padding-inline: var(--cg-gutter);
283
+ @media (min-width: 64rem) {
284
+ .cg-page-head__title {
285
+ grid-column: 1 / span 10;
286
+ }
263
287
  }
264
288
 
265
- .cg-entry-header__terms {
289
+ /* --------------------------------------------------------------------------
290
+ Actions: a filled rectangle in ink for the primary intent, and for the rest
291
+ the words underlined with an arrow after them. Square corners, no lift, no
292
+ shadow.
293
+ -------------------------------------------------------------------------- */
294
+
295
+ .cg-actions {
266
296
  display: flex;
267
297
  flex-wrap: wrap;
268
- gap: var(--cg-s4);
269
- margin: 0 0 var(--cg-s5);
298
+ align-items: center;
299
+ gap: var(--cg-s3) var(--cg-s8);
300
+ margin: 0;
270
301
  padding: 0;
271
302
  list-style: none;
272
- color: var(--cg-ink-muted);
273
- font-family: var(--cogenta-font-mono);
274
- font-size: var(--cg-text-xs);
275
- letter-spacing: var(--cg-tracking-wide);
276
- text-transform: uppercase;
277
303
  }
278
304
 
279
- .cg-entry-header__terms a {
280
- color: var(--cg-accent);
305
+ .cg-action {
306
+ font-size: var(--cg-text-md);
307
+ font-weight: var(--cg-weight-medium);
308
+ line-height: 1.2;
281
309
  text-decoration: none;
310
+ transition:
311
+ background-color var(--cg-duration) var(--cg-ease),
312
+ color var(--cg-duration) var(--cg-ease),
313
+ border-color var(--cg-duration) var(--cg-ease),
314
+ text-decoration-color var(--cg-duration) var(--cg-ease);
282
315
  }
283
316
 
284
- .cg-entry-header__terms a:hover {
285
- text-decoration: underline;
286
- }
287
-
288
- .cg-entry-header__title {
289
- margin: 0;
290
- font-family: var(--cogenta-font-sans);
291
- font-size: var(--cg-text-hero);
292
- line-height: var(--cg-leading-tight);
293
- letter-spacing: var(--cg-tracking-tighter);
294
- font-weight: var(--cg-weight-black);
295
- text-wrap: balance;
317
+ .cg-action[data-emphasis="primary"] {
318
+ display: inline-flex;
319
+ align-items: center;
320
+ justify-content: center;
321
+ padding: var(--cg-s3) var(--cg-s6);
322
+ border: var(--cg-rule) solid var(--cg-action);
323
+ border-radius: var(--cg-radius-control);
324
+ background: var(--cg-action);
325
+ color: var(--cg-action-fg);
326
+ white-space: nowrap;
296
327
  }
297
328
 
298
- .cg-entry-header__excerpt {
299
- margin: var(--cg-s6) 0 0;
300
- max-inline-size: var(--cg-measure-narrow);
301
- font-size: var(--cg-text-lg);
302
- line-height: var(--cg-leading-relaxed);
303
- color: var(--cg-ink-muted);
304
- text-wrap: pretty;
329
+ .cg-action[data-emphasis="primary"]:hover {
330
+ background: var(--cg-action-hover);
331
+ border-color: var(--cg-action-hover);
332
+ color: var(--cg-action-hover-fg);
333
+ }
334
+
335
+ /* A text link with an arrow after it. Not a flex container: in one, the
336
+ words and the arrow are two flex items and each gets its own underline.
337
+ As inline content the words carry one continuous underline, and the
338
+ arrow, an inline-block, inherits none (CSS Text Decoration: decorations do
339
+ not propagate to atomic inlines). The same rule draws every arrow link of
340
+ the theme, so a lone arrow cannot exist anywhere. */
341
+ .cg-action[data-emphasis="secondary"],
342
+ .cg-arrow-link {
343
+ display: inline-block;
344
+ color: var(--cg-ink);
345
+ text-decoration-line: underline;
346
+ text-decoration-thickness: var(--cg-rule);
347
+ text-decoration-color: var(--cg-line-strong);
348
+ text-decoration-skip-ink: none;
349
+ text-underline-offset: 0.3em;
305
350
  }
306
351
 
307
- .cg-entry-header__meta {
308
- display: flex;
309
- flex-wrap: wrap;
310
- align-items: center;
311
- gap: var(--cg-s4);
312
- margin: var(--cg-s6) 0 0;
313
- padding-block-start: var(--cg-s4);
314
- border-block-start: 1px solid var(--cg-line);
315
- color: var(--cg-ink-subtle);
316
- font-family: var(--cogenta-font-mono);
317
- font-size: var(--cg-text-xs);
318
- letter-spacing: var(--cg-tracking-wide);
319
- text-transform: uppercase;
352
+ .cg-action[data-emphasis="secondary"] {
353
+ padding-block: var(--cg-s3);
320
354
  }
321
355
 
322
- .cg-entry-header__author {
323
- color: var(--cg-ink);
324
- font-weight: var(--cg-weight-medium);
356
+ .cg-action[data-emphasis="secondary"]::after,
357
+ .cg-arrow-link::after {
358
+ content: "\2192" / "";
359
+ display: inline-block;
360
+ margin-inline-start: 0.4em;
325
361
  }
326
362
 
327
- .cg-entry-header__reading-time::before {
328
- content: "·";
329
- margin-inline-end: var(--cg-s4);
330
- color: var(--cg-line-strong);
363
+ .cg-arrow-link[data-direction="back"]::after {
364
+ content: none;
331
365
  }
332
366
 
333
- .cg-entry-header__cover {
334
- margin: var(--cg-s10) 0 0;
335
- border: 1px solid var(--cg-line);
367
+ .cg-arrow-link[data-direction="back"]::before {
368
+ content: "\2190" / "";
369
+ display: inline-block;
370
+ margin-inline-end: 0.4em;
336
371
  }
337
372
 
338
- .cg-entry-header__cover img,
339
- .cg-entry-header__cover video {
340
- display: block;
341
- inline-size: 100%;
342
- aspect-ratio: 16 / 9;
343
- object-fit: cover;
373
+ .cg-action[data-emphasis="secondary"]:hover,
374
+ .cg-arrow-link:hover {
375
+ color: var(--cg-ink);
376
+ text-decoration-color: currentColor;
344
377
  }
345
378
 
346
379
  /* --------------------------------------------------------------------------
347
- Chrome — a thin index bar and a footer that becomes a second headline.
380
+ Header: one row on the grid. The name, the tagline, the navigation.
348
381
  -------------------------------------------------------------------------- */
349
382
 
350
- .cg-site-header {
351
- position: sticky;
352
- inset-block-start: 0;
353
- z-index: 10;
354
- padding: var(--cg-s4) var(--cg-gutter);
355
- /* Flat and fully opaque, not a frosted-glass blur: a plane above the
356
- page, marked off by a hairline rather than a haze. */
383
+ .cg-masthead {
384
+ position: relative;
385
+ z-index: 20;
357
386
  background: var(--cg-canvas);
358
- border-block-end: 1px solid var(--cg-line);
359
387
  }
360
388
 
361
- .cg-site-header__inner {
362
- display: flex;
363
- flex-wrap: wrap;
389
+ .cg-masthead__inner {
390
+ display: grid;
391
+ grid-template-columns: repeat(var(--cg-columns), minmax(0, 1fr));
392
+ column-gap: var(--cg-col-gap);
364
393
  align-items: center;
365
- gap: var(--cg-gap);
366
- max-inline-size: var(--cg-page);
394
+ min-block-size: var(--cg-header-height);
395
+ max-inline-size: calc(var(--cg-page) + var(--cg-gutter) * 2);
367
396
  margin-inline: auto;
397
+ padding-inline: var(--cg-gutter);
368
398
  }
369
399
 
370
- .cg-site-header__mark {
400
+ .cg-masthead__home {
401
+ grid-column: 1 / span 4;
402
+ grid-row: 1;
403
+ justify-self: start;
371
404
  display: inline-flex;
372
405
  align-items: center;
373
- gap: var(--cg-s2);
406
+ min-block-size: 44px;
374
407
  color: var(--cg-ink);
375
- font-family: var(--cogenta-font-sans);
376
- font-weight: var(--cg-weight-black);
377
- font-size: var(--cg-text-lg);
378
- letter-spacing: var(--cg-tracking-snug);
379
408
  text-decoration: none;
380
- margin-inline-end: auto;
381
409
  }
382
410
 
383
- /* The uploaded site logo. Height-constrained, so a wordmark and a square
384
- mark both leave the index bar exactly as tall as it was. */
385
- .cg-site-header__logo {
411
+ .cg-masthead__wordmark {
412
+ font-size: var(--cg-text-lg);
413
+ font-stretch: var(--cg-width-display);
414
+ font-weight: var(--cg-weight-semibold);
415
+ line-height: 1;
416
+ letter-spacing: -0.01em;
417
+ white-space: nowrap;
418
+ }
419
+
420
+ .cg-masthead__logo {
386
421
  display: block;
387
- block-size: 1.75rem;
422
+ block-size: 2rem;
388
423
  inline-size: auto;
389
- max-inline-size: 14rem;
424
+ max-inline-size: min(14rem, 50vw);
390
425
  object-fit: contain;
426
+ filter: none;
391
427
  }
392
428
 
393
- .cg-site-header__glyph {
394
- color: var(--cg-accent);
395
- font-size: 1.2em;
396
- transition: transform var(--cg-duration-slow) var(--cg-ease);
397
- }
398
-
399
- .cg-site-header__mark:hover .cg-site-header__glyph {
400
- transform: rotate(90deg);
401
- }
402
-
403
- /* The mobile-menu checkbox: visually hidden the accessible way (still in
404
- the tab order, still Space-operable) rather than `display: none` (which
405
- would remove it from the tab order entirely). */
406
- .cg-nav-toggle-input {
407
- position: absolute;
408
- inline-size: 1px;
409
- block-size: 1px;
410
- overflow: hidden;
411
- clip-path: inset(50%);
412
- white-space: nowrap;
413
- }
414
-
415
- .cg-nav-toggle-label {
429
+ .cg-masthead__tagline {
416
430
  display: none;
417
- flex-direction: column;
418
- justify-content: center;
419
- gap: 0.3rem;
420
- inline-size: 2.5rem;
421
- block-size: 2.5rem;
422
- padding: 0.5rem;
423
- margin-inline-start: auto;
424
- cursor: pointer;
425
- }
426
-
427
- .cg-nav-toggle-input:focus-visible ~ .cg-nav-toggle-label {
428
- outline: 2px solid var(--cg-accent);
429
- outline-offset: 2px;
430
- border-radius: var(--cg-radius-xs);
431
- }
432
-
433
- .cg-nav-toggle-bar {
434
- display: block;
435
- inline-size: 100%;
436
- block-size: 2px;
437
- background: var(--cg-ink);
438
- transition: transform var(--cg-duration) var(--cg-ease);
431
+ margin: 0;
432
+ color: var(--cg-ink-muted);
433
+ font-size: var(--cg-text-caption);
434
+ line-height: var(--cg-leading-ui);
439
435
  }
440
436
 
441
- /* Shared by the header's nav list and the footer's own (`.cg-site-footer__row
442
- .cg-nav`) — declared here, ahead of the chrome media query below, so a
443
- later, more specific override (`.cg-site-header__nav .cg-nav` inside it)
444
- never has to fight a same-or-lower-specificity rule declared after it. */
445
- .cg-nav {
437
+ .cg-masthead__links {
446
438
  display: flex;
447
439
  flex-wrap: wrap;
448
- gap: var(--cg-s6);
440
+ gap: 0 var(--cg-s8);
449
441
  margin: 0;
450
442
  padding: 0;
451
443
  list-style: none;
452
- font-family: var(--cogenta-font-mono);
453
- font-size: var(--cg-text-xs);
454
- letter-spacing: var(--cg-tracking-wide);
455
- text-transform: uppercase;
456
444
  }
457
445
 
458
- .cg-nav li {
446
+ .cg-masthead__item a,
447
+ .cg-masthead__item span,
448
+ .cg-masthead__action {
459
449
  display: inline-flex;
460
- align-items: baseline;
461
- gap: var(--cg-s1);
462
- }
463
-
464
- .cg-nav a,
465
- .cg-nav span:not(.cg-nav__index) {
466
- color: inherit;
467
- text-decoration: none;
468
- }
469
-
470
- .cg-nav a {
471
- padding-block: var(--cg-s1);
472
- border-block-end: 1px solid transparent;
473
- transition:
474
- border-color var(--cg-duration) var(--cg-ease),
475
- color var(--cg-duration) var(--cg-ease);
476
- }
477
-
478
- .cg-nav a:hover {
479
- color: var(--cg-accent);
480
- border-block-end-color: currentColor;
481
- }
482
-
483
- .cg-nav__index {
484
- color: var(--cg-accent);
485
- opacity: 0.85;
450
+ align-items: center;
451
+ min-block-size: 44px;
452
+ color: var(--cg-ink);
453
+ font-size: var(--cg-text-md);
454
+ font-weight: var(--cg-weight-medium);
455
+ text-decoration-line: underline;
456
+ text-decoration-thickness: var(--cg-rule);
457
+ text-decoration-color: transparent;
458
+ text-underline-offset: 0.35em;
486
459
  }
487
460
 
488
- /* The desktop shape — a real, always-visible `<nav>` — declared *before* the
489
- media query below, on purpose: both rules below share this selector's
490
- exact specificity (0,1,0), so with equal specificity the later one in the
491
- file wins regardless of which media query is active. Declaring the
492
- override after the default is what makes "hidden below the breakpoint"
493
- actually win at narrow widths, rather than this unconditional rule
494
- silently overriding the media query's own `display: none` at every width
495
- because it happened to be declared later in the file. */
496
- .cg-site-header__nav {
497
- display: flex;
498
- align-items: center;
499
- gap: var(--cg-s6);
461
+ .cg-masthead__item a:hover,
462
+ .cg-masthead__action:hover {
463
+ text-decoration-color: currentColor;
500
464
  }
501
465
 
502
- .cg-site-header__action {
503
- flex: none;
466
+ .cg-masthead__action {
467
+ text-decoration-color: var(--cg-line-strong);
504
468
  }
505
469
 
506
- /* The manual light/dark/system control (`renderThemeToggle`, `@cogenta/
507
- theme-kit`, L26) — a plain icon button in this theme's own hairline-bordered,
508
- sharp-cornered register (`--cg-radius-xs`, not the pill canonical uses),
509
- sized to match the mobile-menu toggle beside it (`.cg-nav-toggle-label`)
510
- rather than a second, unrelated control size. */
511
470
  .cg-theme-toggle {
471
+ grid-column: 12;
472
+ grid-row: 1;
473
+ justify-self: end;
512
474
  display: inline-flex;
513
475
  align-items: center;
514
476
  justify-content: center;
515
- block-size: 2.5rem;
516
- inline-size: 2.5rem;
517
- flex-shrink: 0;
518
- margin-inline-start: var(--cg-s2);
519
- border: 1px solid var(--cg-line);
520
- border-radius: var(--cg-radius-xs);
477
+ inline-size: 2.75rem;
478
+ margin-inline-end: calc(var(--cg-s3) * -1);
479
+ padding: 0;
480
+ border: 0;
521
481
  background: transparent;
522
482
  color: var(--cg-ink);
523
483
  cursor: pointer;
524
- transition:
525
- color var(--cg-duration) var(--cg-ease),
526
- border-color var(--cg-duration) var(--cg-ease);
484
+ transition: color var(--cg-duration) var(--cg-ease);
527
485
  }
528
486
 
529
487
  .cg-theme-toggle:hover {
530
- color: var(--cg-accent);
531
- border-color: var(--cg-accent);
488
+ color: var(--cg-ink-muted);
532
489
  }
533
490
 
534
491
  .cg-theme-toggle__icon {
535
- block-size: 1.1rem;
536
- inline-size: 1.1rem;
492
+ inline-size: 1.05rem;
493
+ block-size: 1.05rem;
537
494
  }
538
495
 
539
496
  .cg-theme-toggle__icon--moon {
540
497
  display: none;
541
498
  }
542
499
 
543
- /* Icon reflects the *current* effective appearance — sun while light, moon
544
- while dark — from the same `[data-theme]`/`prefers-color-scheme` signals
545
- `tokens.css` already keys this theme's whole (dark-by-default) palette on. */
546
500
  @media (prefers-color-scheme: dark) {
547
501
  :where(:root:not([data-theme="light"])) .cg-theme-toggle__icon--sun {
548
502
  display: none;
@@ -561,371 +515,452 @@ img {
561
515
  display: block;
562
516
  }
563
517
 
564
- /* Below the breakpoint: the toggle button appears, and the real nav becomes
565
- a full-width panel anchored under the header, shown only while the
566
- checkbox is checked — one selector, no JavaScript, and the same `<nav>`
567
- desktop uses, never a second copy of the links. */
568
- @media (max-width: 56rem) {
569
- .cg-nav-toggle-label {
570
- display: flex;
518
+ .cg-nav-toggle-input {
519
+ position: absolute;
520
+ inline-size: 1px;
521
+ block-size: 1px;
522
+ overflow: hidden;
523
+ clip-path: inset(50%);
524
+ white-space: nowrap;
525
+ }
526
+
527
+ .cg-nav-toggle-label {
528
+ grid-column: 11;
529
+ grid-row: 1;
530
+ justify-self: end;
531
+ display: flex;
532
+ flex-direction: column;
533
+ justify-content: center;
534
+ gap: 0.4rem;
535
+ inline-size: 2.75rem;
536
+ padding: 0.7rem 0.55rem;
537
+ cursor: pointer;
538
+ }
539
+
540
+ .cg-nav-toggle-input:focus-visible ~ .cg-nav-toggle-label {
541
+ outline: var(--cg-rule-strong) solid var(--cg-signal);
542
+ outline-offset: 2px;
543
+ }
544
+
545
+ .cg-nav-toggle-bar {
546
+ display: block;
547
+ inline-size: 100%;
548
+ block-size: 2px;
549
+ background: var(--cg-ink);
550
+ }
551
+
552
+ /* Open: the two bars cross. A state, drawn at once; nothing is animated. */
553
+ .cg-nav-toggle-input:checked ~ .cg-nav-toggle-label {
554
+ gap: 0;
555
+ }
556
+
557
+ .cg-nav-toggle-input:checked ~ .cg-nav-toggle-label .cg-nav-toggle-bar:first-child {
558
+ transform: translateY(1px) rotate(45deg);
559
+ }
560
+
561
+ .cg-nav-toggle-input:checked ~ .cg-nav-toggle-label .cg-nav-toggle-bar:last-child {
562
+ transform: translateY(-1px) rotate(-45deg);
563
+ }
564
+
565
+ /* Below the wide breakpoint the navigation is a panel of large links under
566
+ the header, the full height of the screen. */
567
+ @media (max-width: 63.99rem) {
568
+ .cg-masthead__home {
569
+ grid-column: 1 / span 9;
571
570
  }
572
571
 
573
- .cg-site-header__nav {
572
+ .cg-masthead__nav {
574
573
  display: none;
575
- position: absolute;
576
- inset-inline: 0;
577
- inset-block-start: 100%;
578
- flex-direction: column;
579
- align-items: stretch;
580
- gap: var(--cg-s6);
581
- padding: var(--cg-s6) var(--cg-gutter);
574
+ position: fixed;
575
+ inset: var(--cg-header-height) 0 0;
576
+ z-index: 19;
577
+ overflow-y: auto;
578
+ padding: var(--cg-s6) var(--cg-gutter) var(--cg-s12);
579
+ border-block-start: var(--cg-rule) solid var(--cg-line);
582
580
  background: var(--cg-canvas);
583
- border-block-end: 1px solid var(--cg-line);
584
581
  }
585
582
 
586
- .cg-nav-toggle-input:checked ~ .cg-site-header__nav {
587
- display: flex;
583
+ .cg-nav-toggle-input:checked ~ .cg-masthead__nav {
584
+ display: block;
585
+ }
586
+
587
+ .cg-masthead__links {
588
+ display: block;
588
589
  }
589
590
 
590
- .cg-nav-toggle-input:checked ~ .cg-nav-toggle-label .cg-nav-toggle-bar:nth-child(1) {
591
- transform: translateY(0.45rem) rotate(45deg);
591
+ .cg-masthead__item {
592
+ border-block-end: var(--cg-rule) solid var(--cg-line);
592
593
  }
593
594
 
594
- .cg-nav-toggle-input:checked ~ .cg-nav-toggle-label .cg-nav-toggle-bar:nth-child(2) {
595
- opacity: 0;
595
+ .cg-masthead__item a,
596
+ .cg-masthead__item span,
597
+ .cg-masthead__action {
598
+ min-block-size: 0;
599
+ padding-block: var(--cg-s3);
600
+ font-size: var(--cg-size-nav);
601
+ font-stretch: var(--cg-width-display);
602
+ line-height: var(--cg-leading-title);
603
+ letter-spacing: var(--cg-tracking-display);
596
604
  }
597
605
 
598
- .cg-nav-toggle-input:checked ~ .cg-nav-toggle-label .cg-nav-toggle-bar:nth-child(3) {
599
- transform: translateY(-0.45rem) rotate(-45deg);
606
+ .cg-masthead__action {
607
+ margin-block-start: var(--cg-s6);
608
+ font-size: var(--cg-text-xl);
609
+ letter-spacing: var(--cg-tracking-heading);
600
610
  }
611
+ }
601
612
 
602
- .cg-site-header__nav .cg-nav {
603
- flex-direction: column;
604
- align-items: flex-start;
605
- gap: var(--cg-s5);
613
+ @media (min-width: 64rem) {
614
+ .cg-nav-toggle-label {
615
+ display: none;
616
+ }
617
+
618
+ .cg-masthead__tagline {
619
+ display: block;
620
+ grid-column: 5 / span 4;
621
+ grid-row: 1;
622
+ }
623
+
624
+ .cg-masthead__nav {
625
+ grid-column: 9 / span 3;
626
+ grid-row: 1;
627
+ justify-self: end;
628
+ display: flex;
629
+ align-items: center;
630
+ gap: var(--cg-s8);
606
631
  }
607
632
 
608
- .cg-site-header__action {
609
- align-self: flex-start;
633
+ .cg-masthead[data-nav="none"] .cg-masthead__tagline {
634
+ grid-column: 5 / span 7;
610
635
  }
611
636
  }
612
637
 
613
- .cg-site-footer {
614
- padding: var(--cg-s24) var(--cg-gutter) var(--cg-s10);
615
- background: var(--cg-surface-inverted);
616
- color: var(--cg-surface-inverted-fg);
617
- border-block-start: 1px solid var(--cg-line-strong);
638
+ /* --------------------------------------------------------------------------
639
+ Footer: a hairline, three columns, the legal line.
640
+ -------------------------------------------------------------------------- */
641
+
642
+ .cg-colophon {
643
+ margin-block-start: calc(var(--cg-section) / 2);
644
+ color: var(--cg-ink);
645
+ font-size: var(--cg-text-caption);
646
+ line-height: var(--cg-leading-ui);
618
647
  }
619
648
 
620
- .cg-site-footer__inner {
621
- max-inline-size: var(--cg-page);
649
+ .cg-colophon__inner {
650
+ display: grid;
651
+ grid-template-columns: repeat(var(--cg-columns), minmax(0, 1fr));
652
+ column-gap: var(--cg-col-gap);
653
+ row-gap: var(--cg-s8);
654
+ max-inline-size: calc(var(--cg-page) + var(--cg-gutter) * 2);
622
655
  margin-inline: auto;
656
+ padding: 0 var(--cg-gutter) var(--cg-s8);
623
657
  }
624
658
 
625
- .cg-site-footer__statement {
626
- display: block;
627
- color: inherit;
628
- font-family: var(--cogenta-font-sans);
629
- font-weight: var(--cg-weight-black);
630
- font-size: var(--cg-text-jumbo);
631
- line-height: 0.92;
632
- letter-spacing: var(--cg-tracking-tighter);
633
- text-decoration: none;
634
- text-wrap: balance;
635
- word-break: break-word;
659
+ .cg-colophon__inner > * {
660
+ grid-column: 1 / -1;
661
+ min-inline-size: 0;
636
662
  }
637
663
 
638
- .cg-site-footer__statement:hover {
639
- color: var(--cg-accent);
664
+ /* The hairline over the footer, on the grid rather than across the gutters. */
665
+ .cg-colophon__inner::before {
666
+ content: "";
667
+ grid-column: 1 / -1;
668
+ block-size: var(--cg-rule);
669
+ margin-block-end: calc(var(--cg-s5) - var(--cg-s8));
670
+ background: var(--cg-line-ink);
640
671
  }
641
672
 
642
- .cg-site-footer__row {
643
- display: flex;
644
- flex-wrap: wrap;
645
- align-items: flex-end;
646
- justify-content: space-between;
647
- gap: var(--cg-s6);
648
- margin-block-start: var(--cg-s16);
649
- padding-block-start: var(--cg-s8);
650
- border-block-start: 1px solid color-mix(in oklab, var(--cg-surface-inverted-fg) 25%, transparent);
673
+ .cg-colophon__name {
674
+ display: inline-block;
675
+ margin-block-end: var(--cg-s2);
676
+ color: var(--cg-ink);
677
+ font-size: var(--cg-text-md);
678
+ font-stretch: var(--cg-width-display);
679
+ font-weight: var(--cg-weight-semibold);
680
+ text-decoration: none;
651
681
  }
652
682
 
653
- .cg-site-footer__row .cg-nav {
654
- color: inherit;
683
+ .cg-colophon__tagline,
684
+ .cg-colophon__note p {
685
+ margin: 0;
686
+ max-inline-size: 36ch;
687
+ color: var(--cg-ink-muted);
655
688
  }
656
689
 
657
- .cg-site-footer__row .cg-nav__index {
658
- color: var(--cg-accent);
690
+ .cg-colophon__note {
691
+ margin-block-start: var(--cg-s3);
659
692
  }
660
693
 
661
- /* `general.tagline` (`theme@1.4`) — the second line of the closing
662
- statement, in the same reading measure the hero's own subtitle uses. */
663
- .cg-site-footer__tagline {
664
- margin: var(--cg-s4) 0 0;
665
- max-inline-size: var(--cg-measure-narrow);
666
- color: color-mix(in oklab, var(--cg-surface-inverted-fg) 70%, transparent);
667
- font-size: var(--cg-text-lg);
668
- line-height: var(--cg-leading-relaxed);
669
- text-wrap: pretty;
694
+ .cg-colophon__note p + p {
695
+ margin-block-start: var(--cg-s2);
670
696
  }
671
697
 
672
- /* `general.socialLinks` (`theme@1.4`), rendered by `renderSocialLinks` as a
673
- row of flat, hairline-ringed icon buttons — never a filled chip, so the
674
- row reads as a set of quiet exits rather than a second set of actions. */
675
- .cg-site-footer__social {
676
- display: flex;
677
- gap: var(--cg-s3);
698
+ .cg-colophon__links,
699
+ .cg-colophon__social {
700
+ display: grid;
701
+ gap: var(--cg-s1);
678
702
  margin: 0;
679
703
  padding: 0;
680
704
  list-style: none;
681
705
  }
682
706
 
683
- .cg-site-footer__social-item a {
707
+ .cg-colophon__item a,
708
+ .cg-colophon__item span,
709
+ .cg-colophon__social-item a {
684
710
  display: inline-flex;
685
711
  align-items: center;
686
- justify-content: center;
687
- inline-size: 2.5rem;
688
- block-size: 2.5rem;
689
- border: 1px solid color-mix(in oklab, var(--cg-surface-inverted-fg) 30%, transparent);
690
- border-radius: var(--cg-radius-xs);
691
- color: inherit;
692
- transition:
693
- color var(--cg-duration) var(--cg-ease),
694
- border-color var(--cg-duration) var(--cg-ease),
695
- transform var(--cg-duration-fast) var(--cg-ease);
696
- }
697
-
698
- .cg-site-footer__social-item a:hover {
699
- color: var(--cg-accent);
700
- border-color: var(--cg-accent);
701
- transform: translate(-2px, -2px);
702
- }
703
-
704
- .cg-social__icon {
705
- inline-size: 1.1rem;
706
- block-size: 1.1rem;
712
+ gap: var(--cg-s2);
713
+ min-block-size: 2rem;
714
+ color: var(--cg-ink);
715
+ text-decoration-line: underline;
716
+ text-decoration-color: transparent;
717
+ text-underline-offset: 0.3em;
707
718
  }
708
719
 
709
- .cg-site-footer__meta {
710
- display: flex;
711
- flex-direction: column;
712
- align-items: flex-start;
713
- gap: var(--cg-s3);
720
+ .cg-colophon__item a:hover,
721
+ .cg-colophon__social-item a:hover {
722
+ text-decoration-color: currentColor;
714
723
  }
715
724
 
716
- @media (min-width: 48rem) {
717
- .cg-site-footer__meta {
718
- align-items: flex-end;
719
- text-align: end;
720
- }
725
+ /* The social profiles keep their names: a list of icons alone asks a reader
726
+ to recognise every logo, and a studio's footer has room for the words. */
727
+ .cg-colophon__social .cg-visually-hidden {
728
+ position: static;
729
+ inline-size: auto;
730
+ block-size: auto;
731
+ margin: 0;
732
+ overflow: visible;
733
+ clip-path: none;
734
+ white-space: normal;
721
735
  }
722
736
 
723
- /* `general.footerNote` (`theme@1.4`) — a short site-wide line, set quietly
724
- above the branding credit rather than as a fourth headline. */
725
- .cg-site-footer__note {
726
- margin: 0;
727
- max-inline-size: 32ch;
728
- color: color-mix(in oklab, var(--cg-surface-inverted-fg) 70%, transparent);
729
- font-family: var(--cogenta-font-mono);
730
- font-size: var(--cg-text-xs);
731
- letter-spacing: var(--cg-tracking-wide);
737
+ .cg-social__icon {
738
+ inline-size: 0.95rem;
739
+ block-size: 0.95rem;
740
+ flex: none;
732
741
  }
733
742
 
734
- .cg-site-footer__branding {
743
+ .cg-colophon__legal {
735
744
  display: flex;
745
+ flex-wrap: wrap;
736
746
  align-items: center;
747
+ justify-content: space-between;
748
+ gap: var(--cg-s3) var(--cg-s8);
749
+ padding-block-start: var(--cg-s5);
750
+ border-block-start: var(--cg-rule) solid var(--cg-line);
751
+ color: var(--cg-ink-muted);
752
+ font-size: var(--cg-text-sm);
737
753
  }
738
754
 
739
- .cg-site-footer__branding a {
740
- display: flex;
741
- align-items: center;
742
- gap: 0.4em;
743
- color: inherit;
744
- opacity: 0.75;
745
- font-family: var(--cogenta-font-mono);
746
- font-size: var(--cg-text-xs);
747
- transition: opacity var(--cg-duration) var(--cg-ease);
755
+ .cg-colophon__copyright {
756
+ margin: 0;
757
+ font-variant-numeric: lining-nums tabular-nums;
748
758
  }
749
759
 
750
- .cg-site-footer__version {
751
- font-variant-numeric: tabular-nums;
752
- font-size: 0.9em;
760
+ .cg-colophon__branding a {
761
+ display: inline-flex;
762
+ align-items: center;
763
+ gap: 0.5em;
764
+ color: var(--cg-ink-muted);
765
+ text-decoration: none;
753
766
  }
754
767
 
755
- .cg-site-footer__branding a:hover,
756
- .cg-site-footer__branding a:focus-visible {
757
- opacity: 1;
768
+ .cg-colophon__branding a:hover {
769
+ color: var(--cg-ink);
758
770
  }
759
771
 
760
772
  .cg-site-footer__brand-logo {
761
773
  display: block;
762
- /* Explicit pixels, not `em`: relative sizing cascaded from the footer's
763
- own small font-size and made the credit mark unreadably tiny. */
764
- block-size: 25px;
774
+ block-size: 18px;
765
775
  inline-size: auto;
766
776
  }
767
777
 
768
- /* --------------------------------------------------------------------------
769
- Actions — the theme's only control
770
- -------------------------------------------------------------------------- */
771
-
772
- .cg-actions {
773
- display: flex;
774
- flex-wrap: wrap;
775
- gap: var(--cg-s3);
776
- margin: var(--cg-s8) 0 0;
777
- padding: 0;
778
- list-style: none;
778
+ .cg-site-footer__version {
779
+ font-variant-numeric: tabular-nums;
779
780
  }
780
781
 
781
- .cg-action {
782
- display: inline-flex;
783
- align-items: center;
784
- justify-content: center;
785
- gap: var(--cg-s2);
786
- padding: var(--cg-s3) var(--cg-s6);
787
- border: 1px solid transparent;
788
- border-radius: var(--cg-radius-xs);
789
- font-family: var(--cogenta-font-mono);
790
- font-size: var(--cg-text-sm);
791
- font-weight: var(--cg-weight-medium);
792
- letter-spacing: var(--cg-tracking-normal);
793
- line-height: var(--cg-leading-snug);
794
- text-decoration: none;
795
- white-space: nowrap;
796
- transition:
797
- background-color var(--cg-duration) var(--cg-ease),
798
- color var(--cg-duration) var(--cg-ease),
799
- border-color var(--cg-duration) var(--cg-ease),
800
- box-shadow var(--cg-duration) var(--cg-ease),
801
- transform var(--cg-duration-fast) var(--cg-ease);
802
- }
782
+ @media (min-width: 40rem) {
783
+ .cg-colophon__about {
784
+ grid-column: 1 / span 6;
785
+ }
803
786
 
804
- .cg-action[data-emphasis="primary"] {
805
- background: var(--cg-accent);
806
- color: var(--cg-accent-fg);
807
- box-shadow: var(--cg-elevation-1);
808
- }
787
+ .cg-colophon__nav {
788
+ grid-column: 7 / span 3;
789
+ }
809
790
 
810
- .cg-action[data-emphasis="primary"]:hover {
811
- box-shadow: var(--cg-elevation-2);
812
- transform: translate(-2px, -2px);
813
- }
791
+ .cg-colophon__follow {
792
+ grid-column: 10 / span 3;
793
+ }
814
794
 
815
- .cg-action[data-emphasis="secondary"] {
816
- background: transparent;
817
- color: currentColor;
818
- border-color: currentColor;
795
+ .cg-colophon__legal {
796
+ grid-column: 1 / -1;
797
+ }
819
798
  }
820
799
 
821
- .cg-action[data-emphasis="secondary"]:hover {
822
- background: var(--cg-accent);
823
- color: var(--cg-accent-fg);
824
- border-color: var(--cg-accent);
825
- transform: translate(-2px, -2px);
826
- }
800
+ @media (min-width: 64rem) {
801
+ .cg-colophon__about {
802
+ grid-column: 1 / span 4;
803
+ }
827
804
 
828
- .cg-action:active {
829
- transform: translate(0, 0);
830
- box-shadow: none;
805
+ .cg-colophon__nav {
806
+ grid-column: 7 / span 3;
807
+ }
831
808
  }
832
809
 
833
810
  /* --------------------------------------------------------------------------
834
- Shared block furniture
811
+ Search, forms and comments: the utility pages, in the same register.
835
812
  -------------------------------------------------------------------------- */
836
813
 
837
- .cg-features__title,
838
- .cg-faq__title,
839
- .cg-stats__title,
840
- .cg-logos__title,
841
- .cg-collection__title {
842
- margin: 0 0 var(--cg-s10);
843
- font-family: var(--cogenta-font-sans);
844
- font-size: var(--cg-text-2xl);
845
- line-height: var(--cg-leading-snug);
846
- letter-spacing: var(--cg-tracking-tight);
847
- font-weight: var(--cg-weight-black);
848
- text-wrap: balance;
849
- }
850
-
851
- .cg-features__items,
852
- .cg-logos__items,
853
- .cg-gallery__items,
854
- .cg-faq__items {
855
- margin: 0;
856
- padding: 0;
857
- list-style: none;
814
+ .cg-form,
815
+ .cg-form__confirmation {
816
+ max-inline-size: calc(var(--cg-measure) + var(--cg-gutter) * 2);
817
+ margin-inline: auto;
818
+ padding-inline: var(--cg-gutter);
858
819
  }
859
820
 
860
- .cg-collection__items {
861
- margin: 0;
862
- padding: 0;
821
+ /* The search page is set on the page's edges, like an archive: its title
822
+ large on the grid, the form under it, the results as the index of work.
823
+ The host draws it in a bare `<main class="cg-main">`; the list keeps the
824
+ gutters as its padding, so every rule of a row stays inside them. */
825
+ :is(.cg-main, .cg-sidebar-layout__content)
826
+ > :is(
827
+ .cg-page__title,
828
+ .cg-search__form,
829
+ .cg-search__results,
830
+ .cg-search__empty,
831
+ .cg-search__error
832
+ ) {
833
+ box-sizing: border-box;
834
+ inline-size: 100%;
835
+ max-inline-size: calc(var(--cg-page) + var(--cg-gutter) * 2);
836
+ margin-inline: auto;
837
+ padding-inline: var(--cg-gutter);
863
838
  }
864
839
 
865
- .cg-gallery__viewport,
866
- .cg-collection__viewport {
867
- overflow-x: auto;
868
- scroll-snap-type: x mandatory;
869
- scroll-behavior: smooth;
870
- overscroll-behavior-inline: contain;
871
- scrollbar-width: thin;
872
- scrollbar-color: var(--cg-line-strong) transparent;
873
- padding-block: var(--cg-s2);
874
- margin-block: calc(var(--cg-s2) * -1);
840
+ :is(.cg-main, .cg-sidebar-layout__content) > .cg-page__title {
841
+ margin-block: 0;
842
+ padding-block: calc(var(--cg-section) * 0.45) calc(var(--cg-section) * 0.15);
843
+ font-size: var(--cg-size-title);
844
+ font-stretch: var(--cg-width-display);
845
+ font-weight: var(--cg-weight-medium);
846
+ line-height: var(--cg-leading-title);
847
+ letter-spacing: var(--cg-tracking-display);
875
848
  }
876
849
 
877
- /* --------------------------------------------------------------------------
878
- Search, forms, comments — public utility pages and post-content furniture,
879
- dressed in the same mono-labelled, hairline-ruled register as the blocks.
880
- -------------------------------------------------------------------------- */
881
-
882
- .cg-search__form,
883
- .cg-search__results,
884
- .cg-search__empty,
885
- .cg-search__error,
886
- .cg-form,
887
- .cg-form__confirmation,
888
- .cg-comments {
889
- max-inline-size: var(--cg-page);
890
- margin-inline: auto;
891
- padding-inline: var(--cg-gutter);
850
+ /* The count sits under the title in the caption size, like the archive's
851
+ kicker sits above it. */
852
+ .cg-page__title .cg-search__count {
853
+ display: block;
854
+ margin-block-start: var(--cg-s4);
855
+ color: var(--cg-ink-muted);
856
+ font-size: var(--cg-text-caption);
857
+ font-stretch: var(--cg-width-text);
858
+ font-weight: var(--cg-weight-medium);
859
+ line-height: var(--cg-leading-ui);
860
+ letter-spacing: var(--cg-tracking-caption);
892
861
  }
893
862
 
894
863
  .cg-search__form {
895
864
  display: flex;
896
865
  flex-wrap: wrap;
897
866
  align-items: end;
898
- gap: var(--cg-s3);
899
- margin-block-end: var(--cg-s10);
867
+ gap: var(--cg-s3) var(--cg-s4);
868
+ margin-block: var(--cg-s6) var(--cg-s12);
869
+ }
870
+
871
+ .cg-search__form label {
872
+ flex-basis: 100%;
900
873
  }
901
874
 
902
875
  .cg-search__form label,
903
876
  .cg-form__field label,
904
877
  .cg-comment__form label {
905
878
  display: block;
906
- font-family: var(--cogenta-font-mono);
907
- font-size: var(--cg-text-xs);
908
- letter-spacing: var(--cg-tracking-wide);
909
- text-transform: uppercase;
910
- font-weight: var(--cg-weight-medium);
911
879
  margin-block-end: var(--cg-s2);
880
+ color: var(--cg-ink-muted);
881
+ font-size: var(--cg-text-caption);
882
+ font-weight: var(--cg-weight-medium);
912
883
  }
913
884
 
914
885
  .cg-search__form input[type="search"] {
915
- flex: 1 1 16rem;
886
+ flex: 1 1 18rem;
887
+ max-inline-size: 40rem;
916
888
  }
917
889
 
918
890
  .cg-search__results {
919
- margin: 0 auto;
920
- padding-inline-start: var(--cg-gutter);
921
891
  display: grid;
922
- gap: var(--cg-s5);
923
- font-size: var(--cg-text-lg);
892
+ gap: 0;
893
+ margin-block: 0 calc(var(--cg-section) / 2);
894
+ list-style: none;
895
+ font-size: var(--cg-size-work);
896
+ line-height: var(--cg-leading-ui);
897
+ }
898
+
899
+ /* One ruled row per result, the title, the statement and the date in the
900
+ columns the index of work gives them. */
901
+ .cg-search__hit {
902
+ display: grid;
903
+ grid-template-columns: minmax(0, 1fr);
904
+ column-gap: var(--cg-col-gap);
905
+ row-gap: var(--cg-s1);
906
+ align-items: baseline;
907
+ padding-block: var(--cg-s4);
908
+ border-block-end: var(--cg-rule) solid var(--cg-line);
909
+ }
910
+
911
+ .cg-search__hit:first-child {
912
+ border-block-start: var(--cg-rule) solid var(--cg-line-ink);
913
+ }
914
+
915
+ .cg-search__title {
916
+ color: var(--cg-ink);
917
+ font-weight: var(--cg-weight-medium);
918
+ text-decoration-color: transparent;
919
+ text-underline-offset: 0.25em;
920
+ }
921
+
922
+ .cg-search__hit:hover a.cg-search__title,
923
+ a.cg-search__title:focus-visible {
924
+ text-decoration-color: currentColor;
925
+ }
926
+
927
+ .cg-search__excerpt,
928
+ .cg-search__meta {
929
+ margin: 0;
930
+ color: var(--cg-ink-muted);
931
+ font-size: var(--cg-text-caption);
932
+ line-height: var(--cg-leading-ui);
933
+ font-variant-numeric: lining-nums tabular-nums;
934
+ }
935
+
936
+ .cg-search__excerpt {
937
+ max-inline-size: var(--cg-measure-short);
938
+ }
939
+
940
+ @media (min-width: 48rem) {
941
+ .cg-search__hit {
942
+ grid-template-columns: repeat(var(--cg-columns), minmax(0, 1fr));
943
+ grid-template-rows: auto 1fr;
944
+ align-items: start;
945
+ }
946
+
947
+ /* The date under the title, as a caption; the statement beside them. */
948
+ .cg-search__title,
949
+ .cg-search__meta {
950
+ grid-column: 1 / span 5;
951
+ }
952
+
953
+ .cg-search__excerpt {
954
+ grid-column: 6 / -1;
955
+ grid-row: 1 / span 2;
956
+ font-size: inherit;
957
+ }
924
958
  }
925
959
 
926
960
  .cg-search__empty,
927
961
  .cg-comments__empty,
928
- .cg-comments__closed {
962
+ .cg-comments__closed,
963
+ .cg-form__help {
929
964
  color: var(--cg-ink-muted);
930
965
  }
931
966
 
@@ -933,61 +968,102 @@ img {
933
968
  .cg-form__error,
934
969
  .cg-form__field-error {
935
970
  color: var(--cg-ink);
936
- font-weight: var(--cg-weight-bold);
971
+ font-weight: var(--cg-weight-semibold);
937
972
  }
938
973
 
974
+ /* Fields are a baseline, not a box: a rule under the words, darkening to ink
975
+ on focus. */
939
976
  .cg-search__form input,
940
977
  .cg-form__field input,
941
978
  .cg-form__field select,
942
979
  .cg-form__field textarea,
943
980
  .cg-comment__form input,
944
- .cg-comment__form textarea {
981
+ .cg-comment__form textarea,
982
+ .cg-widget__search-input,
983
+ .cg-widget__jump select,
984
+ .cg-widget__form :is(input:not([type="checkbox"]), select, textarea) {
945
985
  inline-size: 100%;
946
- padding: var(--cg-s3) var(--cg-s4);
947
- border: 1px solid var(--cg-line);
948
- border-radius: var(--cg-radius-xs);
949
- background: var(--cg-surface);
986
+ min-block-size: 44px;
987
+ padding: var(--cg-s2) 0;
988
+ border: 0;
989
+ border-block-end: var(--cg-rule) solid var(--cg-line-strong);
990
+ border-radius: 0;
991
+ background: transparent;
950
992
  color: var(--cg-ink);
951
- font: inherit;
993
+ font-family: var(--cg-font);
994
+ font-size: var(--cg-text-md);
995
+ line-height: var(--cg-leading-ui);
996
+ transition: border-color var(--cg-duration) var(--cg-ease);
997
+ }
998
+
999
+ .cg-form__field textarea,
1000
+ .cg-comment__form textarea,
1001
+ .cg-widget__form textarea {
1002
+ padding: var(--cg-s3);
1003
+ border: var(--cg-rule) solid var(--cg-line-strong);
1004
+ border-radius: var(--cg-radius);
1005
+ resize: vertical;
1006
+ }
1007
+
1008
+ .cg-search__form input:focus-visible,
1009
+ .cg-form__field :is(input, select, textarea):focus-visible,
1010
+ .cg-comment__form :is(input, textarea):focus-visible,
1011
+ .cg-widget__search-input:focus-visible,
1012
+ .cg-widget__jump select:focus-visible,
1013
+ .cg-widget__form :is(input, select, textarea):focus-visible {
1014
+ outline: none;
1015
+ border-color: var(--cg-ink);
1016
+ box-shadow: inset 0 calc(var(--cg-rule) * -1) 0 var(--cg-ink);
952
1017
  }
953
1018
 
954
1019
  .cg-form__field input[aria-invalid="true"],
955
1020
  .cg-form__field select[aria-invalid="true"],
956
1021
  .cg-form__field textarea[aria-invalid="true"] {
957
- border-width: 2px;
958
- border-color: var(--cg-line-strong);
1022
+ border-color: var(--cg-ink);
1023
+ border-block-end-width: var(--cg-rule-strong);
959
1024
  }
960
1025
 
961
1026
  .cg-search__form button,
962
1027
  .cg-form button[type="submit"],
963
- .cg-comment__form button[type="submit"] {
1028
+ .cg-comment__form button[type="submit"],
1029
+ .cg-widget__search-button,
1030
+ .cg-widget__jump-button,
1031
+ .cg-widget__form-submit {
1032
+ min-block-size: 44px;
964
1033
  padding: var(--cg-s3) var(--cg-s6);
965
- border: 1px solid var(--cg-accent);
966
- border-radius: var(--cg-radius-xs);
967
- background: var(--cg-accent);
968
- color: var(--cg-accent-fg);
969
- font-family: var(--cogenta-font-mono);
1034
+ border: var(--cg-rule) solid var(--cg-action);
1035
+ border-radius: var(--cg-radius-control);
1036
+ background: var(--cg-action);
1037
+ color: var(--cg-action-fg);
1038
+ font-family: var(--cg-font);
1039
+ font-size: var(--cg-text-md);
970
1040
  font-weight: var(--cg-weight-medium);
971
1041
  cursor: pointer;
972
- transition: background-color var(--cg-duration) var(--cg-ease);
1042
+ transition:
1043
+ background-color var(--cg-duration) var(--cg-ease),
1044
+ border-color var(--cg-duration) var(--cg-ease),
1045
+ color var(--cg-duration) var(--cg-ease);
973
1046
  }
974
1047
 
975
1048
  .cg-search__form button:hover,
976
1049
  .cg-form button[type="submit"]:hover,
977
- .cg-comment__form button[type="submit"]:hover {
978
- background: var(--cg-accent-hover);
1050
+ .cg-comment__form button[type="submit"]:hover,
1051
+ .cg-widget__search-button:hover,
1052
+ .cg-widget__jump-button:hover,
1053
+ .cg-widget__form-submit:hover {
1054
+ background: var(--cg-action-hover);
1055
+ border-color: var(--cg-action-hover);
1056
+ color: var(--cg-action-hover-fg);
979
1057
  }
980
1058
 
981
- .cg-form__field,
982
- .cg-comment__form p {
1059
+ .cg-form__field {
983
1060
  display: block;
984
- margin-block-end: var(--cg-s5);
1061
+ margin-block-end: var(--cg-s6);
985
1062
  }
986
1063
 
987
1064
  .cg-form__help {
988
1065
  margin: var(--cg-s2) 0 0;
989
1066
  font-size: var(--cg-text-sm);
990
- color: var(--cg-ink-muted);
991
1067
  }
992
1068
 
993
1069
  .cg-form__choice {
@@ -995,7 +1071,7 @@ img {
995
1071
  align-items: center;
996
1072
  gap: var(--cg-s2);
997
1073
  margin-inline-end: var(--cg-s4);
998
- font-weight: normal;
1074
+ font-weight: var(--cg-weight-regular);
999
1075
  }
1000
1076
 
1001
1077
  .cg-form__honeypot,
@@ -1007,11 +1083,33 @@ img {
1007
1083
  inset-inline-start: -9999px;
1008
1084
  }
1009
1085
 
1086
+ /* Comments sit on the same twelve columns as the text above them. */
1010
1087
  .cg-comments {
1011
- margin-block-start: var(--cg-section-y);
1012
- padding-block-start: var(--cg-s8);
1013
- padding-block-end: var(--cg-section-y);
1014
- border-block-start: 1px solid var(--cg-line);
1088
+ display: grid;
1089
+ grid-template-columns: repeat(var(--cg-columns), minmax(0, 1fr));
1090
+ column-gap: var(--cg-col-gap);
1091
+ max-inline-size: calc(var(--cg-page) + var(--cg-gutter) * 2);
1092
+ margin: 0 auto var(--cg-section);
1093
+ padding: var(--cg-s5) var(--cg-gutter) 0;
1094
+ }
1095
+
1096
+ .cg-comments > * {
1097
+ grid-column: 1 / -1;
1098
+ min-inline-size: 0;
1099
+ }
1100
+
1101
+ @media (min-width: 64rem) {
1102
+ .cg-comments > * {
1103
+ grid-column: 4 / span 7;
1104
+ }
1105
+ }
1106
+
1107
+ .cg-comments > h2 {
1108
+ padding-block-start: var(--cg-s4);
1109
+ border-block-start: var(--cg-rule) solid var(--cg-line-ink);
1110
+ margin-block-end: var(--cg-s5);
1111
+ font-size: var(--cg-text-caption);
1112
+ font-weight: var(--cg-weight-medium);
1015
1113
  }
1016
1114
 
1017
1115
  .cg-comments__list,
@@ -1023,34 +1121,51 @@ img {
1023
1121
 
1024
1122
  .cg-comment {
1025
1123
  padding-block: var(--cg-s5);
1026
- border-block-end: 1px solid var(--cg-line-soft);
1124
+ border-block-start: var(--cg-rule) solid var(--cg-line);
1027
1125
  }
1028
1126
 
1029
1127
  .cg-comment__replies {
1030
- padding-block-start: var(--cg-s5);
1031
- }
1032
-
1033
- .cg-comment__replies .cg-comment {
1128
+ margin-block-start: var(--cg-s4);
1034
1129
  padding-inline-start: var(--cg-s6);
1035
- border-inline-start: 2px solid var(--cg-line);
1036
- border-block-end: 0;
1130
+ border-inline-start: var(--cg-rule) solid var(--cg-line);
1037
1131
  }
1038
1132
 
1039
1133
  .cg-comment__meta {
1040
1134
  display: flex;
1041
- gap: var(--cg-s3);
1042
- align-items: baseline;
1043
- font-family: var(--cogenta-font-mono);
1044
- font-size: var(--cg-text-xs);
1045
- color: var(--cg-ink-muted);
1046
- margin-block-end: var(--cg-s2);
1135
+ flex-wrap: wrap;
1136
+ gap: var(--cg-s1) var(--cg-s3);
1137
+ margin: 0 0 var(--cg-s2);
1138
+ font-size: var(--cg-text-sm);
1047
1139
  }
1048
1140
 
1049
1141
  .cg-comment__author {
1050
- font-weight: var(--cg-weight-semibold);
1051
1142
  color: var(--cg-ink);
1143
+ font-weight: var(--cg-weight-semibold);
1052
1144
  }
1053
1145
 
1054
- .cg-comment__body {
1146
+ .cg-comment__date {
1147
+ color: var(--cg-ink-muted);
1148
+ font-variant-numeric: lining-nums tabular-nums;
1149
+ }
1150
+
1151
+ .cg-comment__body p {
1152
+ margin: 0;
1153
+ }
1154
+
1155
+ .cg-comment__body p + p {
1156
+ margin-block-start: var(--cg-s3);
1157
+ }
1158
+
1159
+ .cg-comment__form {
1160
+ display: grid;
1161
+ gap: var(--cg-s3);
1162
+ margin-block-start: var(--cg-s6);
1163
+ }
1164
+
1165
+ .cg-comment__form > * {
1055
1166
  margin: 0;
1056
1167
  }
1168
+
1169
+ .cg-comment__form button[type="submit"] {
1170
+ justify-self: start;
1171
+ }