pandorga 2.0.4 → 2.1.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2dc703ecd304ea907703cb189abd6ef09f0747c42e36766b365b6cab275f50f5
4
- data.tar.gz: 1ae4bbec818b879199980c53e8c00e46d91c611b984f56f4d31fb5046b0fb1b0
3
+ metadata.gz: 41e9aae873bb7fe7ca6c4f16291342d17df63b1e67c4c9f21ee0a84a144241fa
4
+ data.tar.gz: 5c3d5f17a85c83dce67ad2e63561b7db672dee2539dfd116895f8a3c62735ead
5
5
  SHA512:
6
- metadata.gz: 4a87bd7621049333217620dcb59f44abda1d072edec0ea4aa06c362a60fee39d9c2b2ff4d75530c2b346caac34b715dd06bee92f0c4b880ce7308921a5cd2eed
7
- data.tar.gz: f033221a651aae72e83efefb0839c2eafc4ce5ddfb2405ef13c4359c326fea85c7489224ef8e5d2e31f8a934cb7b7efd5c598481e51a6423de61d281f6f44b3d
6
+ metadata.gz: 2c50582c8abb7a871df968d8dfe687803375e37d63381e91e058c24aa80f257e12e8aed779213c742893e5b5eaa904e067fa3494316416290cbb94e0aee46b43
7
+ data.tar.gz: 7b22b9148844a77f8d89a8957d5b65840899e1a29c6a947a5c7cbc2873b91e8873888dc9a6fc29f284631c3c1be48be47da4e3b6261b95c38af9341f98ac6e7a
data/CHANGELOG.md CHANGED
@@ -2,6 +2,27 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [2.1.1] — 2026-10-28
6
+
7
+ ### Fixed
8
+
9
+ - Mobile body weight (`body_weight_mobile` / `--weight-body-mobile`) now wins on viewports under 768px. The rebind lives in `theme-vars.html` after the theme token block so it is not overridden by the desktop `--weight-body` declaration (PLT-AC-57).
10
+
11
+ ## [2.1.0] — 2026-10-28
12
+
13
+ ### Added
14
+
15
+ - Site-configurable body weights under `pandorga.fonts.body_weight` (desktop default 300) and `pandorga.fonts.body_weight_mobile` (mobile default 350) wired into CSS custom properties (`--weight-body` and `--weight-body-mobile`) (PLT-AC-57).
16
+ - Static Marcellus SC label **“Explore projects”** above the Home Projects inventory (PLT-AC-61).
17
+
18
+ ### Changed
19
+
20
+ - Default resolved typography stack switches to four families: Ancizar Serif for titles and top-bar wordmark, Ancizar Sans for body and taglines, Marcellus SC for labels, and Courier Prime for code. Cinzel Decorative and Newsreader defaults are removed from the default stylesheet request (PLT-AC-56).
21
+ - `--font-content-title` uses `--font-title` (Ancizar Serif) instead of body face (PLT-AC-56).
22
+ - On the home hero, `.home-hero-family` renders in italic, primary color, with a highlighter mark wash scaled to ~40% intensity of detail action buttons, while `.home-hero-given` stays upright in default ink (PLT-AC-58).
23
+ - Heading and title selectors in ledger CSS no longer apply `text-transform: uppercase`, and title italics are restricted to `.home-hero-family` and `.section-title em` / `.page-header-title em` (PLT-AC-59, PLT-AC-60).
24
+ - On viewports at or above 900px, the Home Projects bench places the inventory column to the left of the specimen. Inventory buttons become logo-only with enlarged icon marks, keeping accessible labels (`aria-label`) and tooltips on hover/focus (`title`) (PLT-AC-61).
25
+
5
26
  ## [2.0.4] — 2026-10-28
6
27
 
7
28
  ### Fixed
@@ -5,27 +5,27 @@
5
5
  # Consumed by theme-context.liquid → theme-vars-block.liquid / font-loader.
6
6
 
7
7
  fonts:
8
- title: "Cinzel Decorative"
9
- subtitle: "Newsreader"
8
+ title: "Ancizar Serif"
9
+ subtitle: "Ancizar Sans"
10
10
  label: "Marcellus SC"
11
- body: "Newsreader"
11
+ body: "Ancizar Sans"
12
12
  mono: "Courier Prime"
13
13
  code: "Courier Prime"
14
- cv_body: "Newsreader"
14
+ cv_body: "Ancizar Sans"
15
15
  cv_body_weight: 400
16
- # Fallback after the named face. Body is Newsreader, a serif. A sans
17
- # fallback reflows the hero summary when the webfont swaps in.
18
- body_fallback: "Georgia, serif"
19
- subtitle_fallback: "serif"
16
+ body_weight: 300
17
+ body_weight_mobile: 350
18
+ body_fallback: "sans-serif"
19
+ subtitle_fallback: "sans-serif"
20
20
  title_fallback: "serif"
21
21
  label_fallback: "serif"
22
- google_title_spec: "wght@400;700;900"
23
- google_subtitle_spec: "ital,opsz,wght@0,6..72,300;0,6..72,400;0,6..72,500;0,6..72,600;0,6..72,700;1,6..72,300;1,6..72,400;1,6..72,500"
22
+ google_title_spec: "ital,wght@0,400;0,600;1,400"
23
+ google_subtitle_spec: "wght@300;350;400;600"
24
24
  google_label_spec: "wght@400;700"
25
- google_body_spec: "wght@300;400;500;600;700"
25
+ google_body_spec: "wght@300;350;400;600"
26
26
  google_mono_spec: "ital,wght@0,400;0,700;1,400;1,700"
27
27
  google_code_spec: "ital,wght@0,300;0,400;0,700;1,400;1,700"
28
- google_cv_body_spec: "wght@300;400;500;600;700"
28
+ google_cv_body_spec: "wght@300;350;400;600"
29
29
 
30
30
  motion:
31
31
  duration_fast: "0.15s"
@@ -375,6 +375,7 @@
375
375
  if (selectable) {
376
376
  row.setAttribute('aria-pressed', selected ? 'true' : 'false');
377
377
  row.setAttribute('aria-label', name);
378
+ row.setAttribute('title', name);
378
379
  }
379
380
 
380
381
  var initial = String(name || '?').charAt(0).toUpperCase();
@@ -55,8 +55,11 @@
55
55
  data-home-list
56
56
  data-tag-base="{{ _path }}"
57
57
  >
58
+ <div class="home-projects-inventory-wrap">
59
+ <span class="home-projects-inventory-label font-label">Explore projects</span>
60
+ <div class="home-project-inventory" data-home-inventory role="region" aria-label="Project inventory"></div>
61
+ </div>
58
62
  <div class="home-project-specimen-slot" data-home-specimen></div>
59
- <div class="home-project-inventory" data-home-inventory role="region" aria-label="Project inventory"></div>
60
63
  </div>
61
64
  {%- else -%}
62
65
  <div
@@ -19,6 +19,9 @@
19
19
  {% assign color_secondary = tc.secondary | default: "#287445" %}
20
20
  {% assign color_tertiary = tc.tertiary | default: "#746f30" %}
21
21
  {% assign font_cv_body_weight = sf.cv_body_weight | default: 400 %}
22
+ {% assign site_fonts = site.pandorga.fonts %}
23
+ {% assign font_body_weight = site_fonts.body_weight | default: sf.body_weight | default: 300 %}
24
+ {% assign font_body_weight_mobile = site_fonts.body_weight_mobile | default: sf.body_weight_mobile | default: 350 %}
22
25
  {% assign bg_secondary = tn.background_secondary | default: tn.surface_container_low | default: "#f5f5f5" %}
23
26
  {% assign surface_value = tn.surface | default: "#ffffff" %}
24
27
  {% assign surface_variant_value = tn.surface_variant | default: "#e2e2e2" %}
@@ -30,10 +33,11 @@
30
33
  --font-body: {{ site | pandorga_font_stack: "body" }};
31
34
  --font-cv-body: {{ site | pandorga_font_stack: "cv_body" }};
32
35
  --font-cv-body-weight: {{ font_cv_body_weight }};
36
+ --weight-body: {{ font_body_weight }};
37
+ --weight-body-mobile: {{ font_body_weight_mobile }};
33
38
  --font-serif: {{ site | pandorga_font_stack: "title" }};
34
- /* Content titles share the body face at 600 — Cinzel Decorative is
35
- reserved for page/display titles. */
36
- --font-content-title: var(--font-body);
39
+ /* Content titles use the title face (Ancizar Serif). */
40
+ --font-content-title: var(--font-title);
37
41
  --font-sans: var(--font-body);
38
42
  --font-mono: {{ site | pandorga_font_stack: "mono" }};
39
43
  --font-code: {{ site | pandorga_font_stack: "code" }};
@@ -13,4 +13,13 @@
13
13
  --motion-duration-slow: 0s;
14
14
  }
15
15
  }
16
+
17
+ /* After theme-vars-block sets --weight-body (desktop), rebind on small
18
+ viewports. Must live in this style tag: an earlier base.css media
19
+ query loses to the block's later --weight-body declaration (PLT-AC-57). */
20
+ @media (max-width: 767px) {
21
+ :root, [data-theme] {
22
+ --weight-body: var(--weight-body-mobile, 350);
23
+ }
24
+ }
16
25
  </style>
data/assets/css/base.css CHANGED
@@ -39,6 +39,15 @@
39
39
  line-gap-override: 0%;
40
40
  }
41
41
 
42
+ @font-face {
43
+ font-family: "Pandorga Ancizar Sans Fallback";
44
+ src: local("Arial"), local("Helvetica"), local("Liberation Sans"), local("sans-serif");
45
+ size-adjust: 100%;
46
+ ascent-override: 90%;
47
+ descent-override: 25%;
48
+ line-gap-override: 0%;
49
+ }
50
+
42
51
  @font-face {
43
52
  font-family: "Pandorga Label Fallback";
44
53
  src: local("Times New Roman"), local("Times"), local("Liberation Serif");
@@ -163,7 +172,7 @@
163
172
  html {
164
173
  font-size: 110%;
165
174
 
166
- /* Display — Cinzel Decorative 400 */
175
+ /* Display — Ancizar Serif */
167
176
  --type-display: 2.9015rem;
168
177
  --type-display-lg: 3.6515rem;
169
178
  --type-page: 2.4015rem;
@@ -173,7 +182,7 @@ html {
173
182
  /* Phone steps for home band titles and card titles (PLT-AC-49). */
174
183
  --type-section-sm: 1.375rem;
175
184
 
176
- /* Content titles — Newsreader Regular 400 */
185
+ /* Content titles — Ancizar Serif */
177
186
  --type-title: 2.20165rem;
178
187
  --type-title-lg: 2.64165rem;
179
188
  --type-card: 1.4015rem;
@@ -226,6 +235,12 @@ html {
226
235
  }
227
236
  }
228
237
 
238
+ @media (max-width: 767px) {
239
+ :root, [data-theme] {
240
+ --weight-body: var(--weight-body-mobile, 350);
241
+ }
242
+ }
243
+
229
244
  /* `html body`, not `body`: Tailwind's Preflight ships `body { line-height:
230
245
  inherit }` from the CDN <style> that loads after this file, so a bare `body`
231
246
  selector here loses the tie on source order and the leading silently becomes
@@ -1233,11 +1233,11 @@ nav.text-page-nav:not(:has(a)) {
1233
1233
  padding-bottom: var(--space-md);
1234
1234
  }
1235
1235
 
1236
- /* On mobile, date row and action buttons share one compact horizontal band. */
1236
+ /* On mobile, date row and action buttons share one compact horizontal band on one non-wrapping row. */
1237
1237
  .text-detail-sidebar .article-meta {
1238
1238
  display: flex;
1239
1239
  flex-direction: row;
1240
- flex-wrap: wrap;
1240
+ flex-wrap: nowrap;
1241
1241
  align-items: center;
1242
1242
  justify-content: space-between;
1243
1243
  gap: var(--space-xs) var(--space-sm);
@@ -1305,7 +1305,6 @@ nav.text-page-nav:not(:has(a)) {
1305
1305
  font-family: var(--font-label);
1306
1306
  font-size: var(--type-label-lg);
1307
1307
  letter-spacing: 0.08em;
1308
- text-transform: uppercase;
1309
1308
  color: var(--color-on-surface);
1310
1309
  font-weight: 600;
1311
1310
  margin: 0 0 var(--space-md);
@@ -169,13 +169,22 @@
169
169
  max-width: 100%;
170
170
  }
171
171
 
172
- .home-hero-given,
173
- .home-hero-family {
172
+ .home-hero-given {
174
173
  display: inline;
175
174
  }
176
175
 
177
176
  .home-hero-family {
177
+ display: inline;
178
+ font-style: italic;
178
179
  color: var(--color-primary);
180
+ --mark-ink: var(--color-primary);
181
+ --mark-1: calc(var(--mark-quiet-a) * 0.4);
182
+ --mark-2: calc(var(--mark-quiet-b) * 0.4);
183
+ --mark-3: calc(var(--mark-quiet-c) * 0.4);
184
+ background: linear-gradient(var(--mk-angle, 104deg), transparent var(--mk-s0, 0.9%), color-mix(in srgb, var(--mark-ink) var(--mark-1), transparent) var(--mk-s1, 2.6%), color-mix(in srgb, var(--mark-ink) var(--mark-2), transparent) var(--mk-mid, 58%), color-mix(in srgb, var(--mark-ink) var(--mark-3), transparent) var(--mk-end, 98%), transparent 100%) 0 var(--mk-y, 50%) / 100% var(--mk-h, 100%) no-repeat;
185
+ -webkit-box-decoration-break: clone;
186
+ box-decoration-break: clone;
187
+ padding: 0 0.1em;
179
188
  }
180
189
 
181
190
  @media (min-width: 640px) {
@@ -646,7 +655,7 @@ html[data-theme="light"] .home-hero-plate {
646
655
 
647
656
  [data-home-kind="articles"] .home-card-grid .card-title,
648
657
  [data-home-kind="articles"] .home-card-grid .ledger-card-title {
649
- font-size: calc(var(--type-card) + 2pt);
658
+ font-size: var(--type-card);
650
659
  }
651
660
 
652
661
  /* Phone only: the featured card's text sat against the top rule. One
@@ -664,6 +673,7 @@ html[data-theme="light"] .home-hero-plate {
664
673
  .home-project-specimen .ledger-card-title,
665
674
  .home-project-inventory-title {
666
675
  font-family: var(--font-content-title);
676
+ font-size: var(--type-card);
667
677
  font-weight: var(--weight-title);
668
678
  font-synthesis: none;
669
679
  }
@@ -989,6 +999,16 @@ html[data-theme="light"] .home-hero-plate {
989
999
  gap: var(--space-md);
990
1000
  }
991
1001
 
1002
+ .home-projects-inventory-label {
1003
+ display: block;
1004
+ font-family: var(--font-label);
1005
+ font-size: var(--type-label);
1006
+ font-weight: var(--weight-label);
1007
+ letter-spacing: 0.04em;
1008
+ color: var(--color-on-surface-variant);
1009
+ margin-bottom: var(--space-xs);
1010
+ }
1011
+
992
1012
  .home-project-inventory {
993
1013
  order: -1;
994
1014
  }
@@ -1313,10 +1333,7 @@ button.home-project-inventory-row {
1313
1333
 
1314
1334
  @media (min-width: 900px) {
1315
1335
 
1316
- /* The specimen column is 35% of the band (at least 20rem), which keeps the
1317
- 16:9 plate at 60% of the 7:5 split's height; the rack is 45% (at least
1318
- 21rem); the pair starts at the band's left edge and leaves the rest of
1319
- the row blank. The specimen sets the bench height; rack rows share it. */
1336
+ /* The inventory rack sits on the left (45%, min 21rem), and the specimen on the right (35%, min 20rem). */
1320
1337
  .home-projects-bench {
1321
1338
  --home-inventory-mark-size: 3rem;
1322
1339
  --home-inventory-row-min: calc(
@@ -1326,12 +1343,19 @@ button.home-project-inventory-row {
1326
1343
  single row to the full plate. */
1327
1344
  --home-inventory-row-max: calc(1.6 * var(--home-inventory-row-min));
1328
1345
  display: grid;
1329
- grid-template-columns: max(35%, 20rem) max(45%, 21rem);
1346
+ grid-template-columns: max(45%, 21rem) max(35%, 20rem);
1330
1347
  column-gap: var(--space-xl);
1331
1348
  justify-content: start;
1332
1349
  align-items: stretch;
1333
1350
  }
1334
1351
 
1352
+ .home-projects-inventory-wrap {
1353
+ display: flex;
1354
+ flex-direction: column;
1355
+ gap: var(--space-xs);
1356
+ width: 100%;
1357
+ }
1358
+
1335
1359
  .home-project-inventory {
1336
1360
  order: 0;
1337
1361
  display: flex;
@@ -1341,7 +1365,6 @@ button.home-project-inventory-row {
1341
1365
  width: 100%;
1342
1366
  min-height: var(--home-specimen-height);
1343
1367
  min-width: 0;
1344
- min-height: 0;
1345
1368
  overflow: hidden;
1346
1369
  padding: var(--space-md);
1347
1370
  background: var(--color-panel-contrast);
@@ -1354,7 +1377,7 @@ button.home-project-inventory-row {
1354
1377
  .home-project-inventory-row {
1355
1378
  flex: 1 1 0;
1356
1379
  align-items: center;
1357
- justify-content: flex-start;
1380
+ justify-content: center;
1358
1381
  gap: var(--space-md);
1359
1382
  height: auto;
1360
1383
  min-height: var(--home-inventory-row-min);
@@ -1373,7 +1396,12 @@ button.home-project-inventory-row {
1373
1396
  box-shadow: inset 3px 0 0 var(--color-primary);
1374
1397
  }
1375
1398
 
1376
- /* Square icon mark beside the two-line code + title body. */
1399
+ /* Logo-only buttons on desktop: hide text body visually. */
1400
+ .home-project-inventory-body {
1401
+ display: none;
1402
+ }
1403
+
1404
+ /* Square icon mark enlarged. */
1377
1405
  .home-project-inventory-media {
1378
1406
  display: block;
1379
1407
  flex: 0 0 auto;
@@ -1402,50 +1430,17 @@ button.home-project-inventory-row {
1402
1430
  }
1403
1431
 
1404
1432
  .home-project-inventory-mark .material-symbols-outlined {
1405
- font-size: 1.5rem;
1433
+ font-size: 1.75rem;
1406
1434
  }
1407
1435
 
1408
1436
  .home-project-inventory-mark--initial {
1409
1437
  font-family: var(--font-content-title);
1410
- font-size: var(--type-card);
1438
+ font-size: var(--type-card-lg);
1411
1439
  font-weight: var(--weight-title);
1412
1440
  line-height: 1;
1413
1441
  color: var(--color-on-surface);
1414
1442
  }
1415
1443
 
1416
- .home-project-inventory-body {
1417
- display: flex;
1418
- flex-direction: column;
1419
- justify-content: center;
1420
- align-self: center;
1421
- gap: 0.15rem;
1422
- flex: 1 1 0;
1423
- min-width: 0;
1424
- padding-top: 0;
1425
- }
1426
-
1427
- .home-project-inventory-code .ledger-meta {
1428
- font-size: var(--type-label-lg);
1429
- }
1430
-
1431
- .home-project-inventory-title {
1432
- margin: 0;
1433
- font-family: var(--font-content-title);
1434
- font-size: var(--type-card);
1435
- font-weight: var(--weight-title);
1436
- line-height: 1.2;
1437
- color: var(--color-on-surface);
1438
- overflow: hidden;
1439
- text-overflow: ellipsis;
1440
- white-space: nowrap;
1441
- }
1442
-
1443
- .home-project-inventory-row:hover .home-project-inventory-title,
1444
- .home-project-inventory-row:focus-visible .home-project-inventory-title,
1445
- .home-project-inventory-row.is-selected .home-project-inventory-title {
1446
- color: var(--color-primary);
1447
- }
1448
-
1449
1444
  /* Two classes: the glyph also carries .material-symbols-outlined, whose
1450
1445
  font stylesheet loads after this one and sets display. */
1451
1446
  .home-project-inventory-row .home-project-inventory-glyph {
@@ -1738,7 +1733,7 @@ button.home-project-inventory-row {
1738
1733
  that names the person, says what he does and offers the full record, rather
1739
1734
  than a name band followed by a summary band saying the same thing twice. */
1740
1735
 
1741
- .home-hero-summary {
1736
+ .home-hero .home-hero-summary {
1742
1737
  max-width: var(--reading-measure);
1743
1738
  margin-top: 0;
1744
1739
  font-size: var(--type-body);
@@ -1746,6 +1741,12 @@ button.home-project-inventory-row {
1746
1741
  color: var(--color-legend);
1747
1742
  }
1748
1743
 
1744
+ @media (min-width: 768px) {
1745
+ .home-hero .home-hero-summary {
1746
+ max-width: 65ch;
1747
+ }
1748
+ }
1749
+
1749
1750
  .home-hero-summary p {
1750
1751
  margin-bottom: var(--space-md);
1751
1752
  }
@@ -601,7 +601,6 @@
601
601
  font-family: var(--font-label);
602
602
  font-size: var(--type-label-lg);
603
603
  letter-spacing: 0.1em;
604
- text-transform: uppercase;
605
604
  font-weight: 600;
606
605
  color: var(--color-on-surface);
607
606
  }
@@ -19,10 +19,10 @@ pandorga:
19
19
  home:
20
20
  hero_art: page/hero-default.html
21
21
  fonts:
22
- title: "Cinzel Decorative"
22
+ title: "Ancizar Serif"
23
23
  body:
24
- family: "Newsreader"
25
- weights: [300, 400, 500, 600, 700]
24
+ family: "Ancizar Sans"
25
+ weights: [300, 350, 400, 600]
26
26
  mono:
27
27
  family: "Courier Prime"
28
28
  weights: [400, 700]
@@ -24,7 +24,7 @@ module Pandorga
24
24
 
25
25
  gem "pandorga", "~> 2.0"
26
26
  # Local checkout: gem "pandorga", path: "../pandorga"
27
- # GitHub tag: gem "pandorga", github: "alexandrelheinen/pandorga", tag: "v2.0.4"
27
+ # GitHub tag: gem "pandorga", github: "alexandrelheinen/pandorga", tag: "v2.1.1"
28
28
  gem "csv"
29
29
  gem "base64"
30
30
  RUBY
@@ -22,21 +22,18 @@ module Pandorga
22
22
  "Cinzel" => "Pandorga Cinzel Fallback",
23
23
  "Newsreader" => "Pandorga Body Fallback",
24
24
  "Ancizar Serif" => "Pandorga Ancizar Fallback",
25
+ "Ancizar Sans" => "Pandorga Ancizar Sans Fallback",
25
26
  "Marcellus SC" => "Pandorga Label Fallback"
26
27
  }.freeze
27
28
 
28
29
  DEFAULTS = {
29
- title: { family: "Cinzel Decorative", spec: "wght@400;700;900", fallback: "serif" },
30
- subtitle: {
31
- family: "Newsreader",
32
- spec: "ital,opsz,wght@0,6..72,300;0,6..72,400;0,6..72,500;0,6..72,600;0,6..72,700;1,6..72,300;1,6..72,400;1,6..72,500",
33
- fallback: "serif"
34
- },
30
+ title: { family: "Ancizar Serif", spec: "ital,wght@0,400;0,600;1,400", fallback: "serif" },
31
+ subtitle: { family: "Ancizar Sans", spec: "wght@300;350;400;600", fallback: "sans-serif" },
35
32
  label: { family: "Marcellus SC", spec: "wght@400;700", fallback: "serif" },
36
- body: { family: "Newsreader", spec: "wght@300;400;500;600;700", fallback: "Georgia, serif" },
33
+ body: { family: "Ancizar Sans", spec: "wght@300;350;400;600", fallback: "sans-serif" },
37
34
  mono: { family: "Courier Prime", spec: "ital,wght@0,400;0,700;1,400;1,700", fallback: MONO_FALLBACK },
38
35
  code: { family: "Courier Prime", spec: "ital,wght@0,300;0,400;0,700;1,400;1,700", fallback: MONO_FALLBACK },
39
- cv_body: { family: "Newsreader", spec: "wght@300;400;500;600;700", fallback: "Georgia, serif" }
36
+ cv_body: { family: "Ancizar Sans", spec: "wght@300;350;400;600", fallback: "sans-serif" }
40
37
  }.freeze
41
38
 
42
39
  def resolve(site_fonts, theme_fonts = nil)
@@ -57,10 +57,10 @@ fonts:
57
57
  keys:
58
58
  title:
59
59
  type: string or map
60
- notes: Display face. Default family `Cinzel Decorative`, weights 400, 700, and 900
60
+ notes: Display face. Default family `Ancizar Serif`, weights 400, 600, italic 400
61
61
  body:
62
62
  type: string or map
63
- notes: Reading face. Default family `Newsreader`, weights 300, 400, 500, 600, and 700
63
+ notes: Reading face. Default family `Ancizar Sans`, weights 300, 350, 400, and 600
64
64
  mono:
65
65
  type: string or map
66
66
  notes: Monospace face. Default family `Courier Prime`, roman and italic at 400 and 700
@@ -70,6 +70,12 @@ fonts:
70
70
  subtitle:
71
71
  type: string or map
72
72
  notes: Optional tagline face. Omitted, it follows `body` when the theme used the same family
73
+ body_weight:
74
+ type: integer
75
+ notes: Desktop body weight (default 300)
76
+ body_weight_mobile:
77
+ type: integer
78
+ notes: Mobile body weight (default 350)
73
79
 
74
80
  taxonomies:
75
81
  title: "`pandorga.taxonomies`"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Pandorga
4
- VERSION = "2.0.4"
4
+ VERSION = "2.1.1"
5
5
  end
@@ -45,6 +45,7 @@
45
45
  ">ARCO<",
46
46
  ">route<",
47
47
  "aria-pressed=\"false\"",
48
+ "title=\"ARCO\"",
48
49
  "data-slug=\"arco\""
49
50
  ]
50
51
  }
@@ -247,7 +247,7 @@ require_declarations(
247
247
  )
248
248
  require_declarations(
249
249
  errors, "assets/css/ledger/home.css", home_sheet,
250
- ".home-projects-bench", ["grid-template-columns: max(35%, 20rem) max(45%, 21rem)", "column-gap: var(--space-xl)", "justify-content: start", "--home-inventory-row-max: calc(1.6 * var(--home-inventory-row-min))"]
250
+ ".home-projects-bench", ["grid-template-columns: max(45%, 21rem) max(35%, 20rem)", "column-gap: var(--space-xl)", "justify-content: start", "--home-inventory-row-max: calc(1.6 * var(--home-inventory-row-min))"]
251
251
  )
252
252
  require_declarations(
253
253
  errors, "assets/css/ledger/home.css", home_sheet,
@@ -272,6 +272,24 @@ require_declarations(
272
272
  end
273
273
  end
274
274
 
275
+ # PLT-AC-60. Heading and title selectors in ledger CSS do not use text-transform: uppercase.
276
+ title_selector_pattern = /^\.(?:page-header-title|section-title|home-hero-title|card-title|ledger-card-title|text-title|home-featured-title|ledger-row-title|source-card-title|bib-card-title|home-project-inventory-title|home-index-title|article-title|article-related-title|projects-dossier-title)\b/
277
+
278
+ sheets.each do |path|
279
+ relative = Pathname.new(path).relative_path_from(REPO_ROOT)
280
+ cleaned = strip_noise(File.read(path))
281
+ cleaned.scan(/([^{}]+)\{([^{}]*)\}/m) do |sel, body|
282
+ next unless body.match?(/text-transform\s*:\s*uppercase/i)
283
+
284
+ sel.split(",").each do |part|
285
+ name = part.gsub(/\s+/, " ").strip
286
+ next unless name.match?(title_selector_pattern)
287
+
288
+ errors << "#{relative}: title selector #{name} applies text-transform: uppercase (PLT-AC-60)"
289
+ end
290
+ end
291
+ end
292
+
275
293
  # PLT-AC-23. The home hero summary uses --color-legend, the ink of the other
276
294
  # description texts.
277
295
  require_declarations(
@@ -147,12 +147,12 @@ end
147
147
  warn "FAIL test-examples-build: #{name} home is missing JSON-LD"
148
148
  exit 1
149
149
  end
150
- ledger_faces = "family=Cinzel+Decorative:wght@400;700;900"
150
+ ledger_faces = "family=Ancizar+Serif:ital,wght@0,400;0,600;1,400"
151
151
  unless html.include?(ledger_faces) && html.include?("&display=swap") && html.include?("__pandorgaFontsHref")
152
152
  warn "FAIL test-examples-build: #{name} home dropped the ledger font request"
153
153
  exit 1
154
154
  end
155
- unless html.include?("--font-title: 'Cinzel Decorative', 'Pandorga Title Fallback', serif")
155
+ unless html.include?("--font-title: 'Ancizar Serif', 'Pandorga Ancizar Fallback', serif")
156
156
  warn "FAIL test-examples-build: #{name} home dropped the title face"
157
157
  exit 1
158
158
  end
@@ -16,9 +16,9 @@ end
16
16
 
17
17
  require_relative "../../lib/pandorga/fonts"
18
18
 
19
- DEFAULT_HREF = "https://fonts.googleapis.com/css2?family=Cinzel+Decorative:wght@400;700;900" \
19
+ DEFAULT_HREF = "https://fonts.googleapis.com/css2?family=Ancizar+Serif:ital,wght@0,400;0,600;1,400" \
20
20
  "&family=Marcellus+SC:wght@400;700" \
21
- "&family=Newsreader:wght@300;400;500;600;700" \
21
+ "&family=Ancizar+Sans:wght@300;350;400;600" \
22
22
  "&family=Courier+Prime:ital,wght@0,400;0,700;1,400;1,700" \
23
23
  "&display=swap"
24
24
 
@@ -27,11 +27,12 @@ bare = Pandorga::Fonts.resolve(nil, nil)
27
27
  from_theme = Pandorga::Fonts.resolve(nil, theme)
28
28
  fail!("unset config dropped the ledger faces") unless Pandorga::Fonts.stylesheet_href(bare) == DEFAULT_HREF
29
29
  fail!("theme tokens drifted from the ledger faces") unless Pandorga::Fonts.stylesheet_href(from_theme) == DEFAULT_HREF
30
+ fail!("default stylesheet href contained Cinzel") if DEFAULT_HREF.include?("Cinzel")
30
31
 
31
- fail!("title stack dropped Cinzel") unless Pandorga::Fonts.css_stack(from_theme, "title") ==
32
- "'Cinzel Decorative', 'Pandorga Title Fallback', serif"
33
- fail!("body stack dropped the serif fallback") unless Pandorga::Fonts.css_stack(from_theme, "body") ==
34
- "'Newsreader', 'Pandorga Body Fallback', Georgia, serif"
32
+ fail!("title stack dropped Ancizar Serif") unless Pandorga::Fonts.css_stack(from_theme, "title") ==
33
+ "'Ancizar Serif', 'Pandorga Ancizar Fallback', serif"
34
+ fail!("body stack dropped Ancizar Sans") unless Pandorga::Fonts.css_stack(from_theme, "body") ==
35
+ "'Ancizar Sans', 'Pandorga Ancizar Sans Fallback', sans-serif"
35
36
  fail!("label stack dropped the metric fallback") unless Pandorga::Fonts.css_stack(from_theme, "label") ==
36
37
  "'Marcellus SC', 'Pandorga Label Fallback', serif"
37
38
  fail!("mono stack dropped Courier Prime") unless Pandorga::Fonts.css_stack(from_theme, "mono").start_with?("'Courier Prime', ui-monospace")
@@ -43,7 +44,7 @@ site_faces = Pandorga::Fonts.resolve(
43
44
  fail!("Cinzel stack missed its metric fallback") unless Pandorga::Fonts.css_stack(site_faces, "title") ==
44
45
  "'Cinzel', 'Pandorga Cinzel Fallback', serif"
45
46
  fail!("Ancizar stack missed its metric fallback") unless Pandorga::Fonts.css_stack(site_faces, "body") ==
46
- "'Ancizar Serif', 'Pandorga Ancizar Fallback', Georgia, serif"
47
+ "'Ancizar Serif', 'Pandorga Ancizar Fallback', sans-serif"
47
48
 
48
49
  custom = Pandorga::Fonts.resolve(
49
50
  {
@@ -77,7 +78,7 @@ end
77
78
  fail!("corrupted 'behind' left by a font rename (#{broken.size} files): #{broken.join(', ')}") unless broken.empty?
78
79
  fail!("code face did not follow mono") unless Pandorga::Fonts.css_stack(custom, "code").start_with?("'IBM Plex Mono'")
79
80
 
80
- kept = Pandorga::Fonts.resolve({ "title" => "Cinzel Decorative" }, theme)
81
+ kept = Pandorga::Fonts.resolve({ "title" => "Ancizar Serif" }, theme)
81
82
  fail!("naming the default title changed the stylesheet") unless Pandorga::Fonts.stylesheet_href(kept) == DEFAULT_HREF
82
83
 
83
84
  ignored = Pandorga::Fonts.resolve({ "title" => "Fraunces</style>" }, theme)
@@ -103,3 +104,7 @@ fail!("spec is missing PLT-AC-30") unless spec.include?("PLT-AC-30")
103
104
  fail!("configuration reference omits pandorga.fonts") unless ROOT.join("docs/configuration.md").read.include?("pandorga.fonts")
104
105
 
105
106
  puts "PASS test-fonts"
107
+
108
+ theme_vars = File.read(File.expand_path("../../_includes/theme/theme-vars.html", __dir__))
109
+ fail!("theme-vars.html missing mobile --weight-body rebind (PLT-AC-57 cascade)") unless theme_vars.match?(/@media\s*\(max-width:\s*767px\)[\s\S]*--weight-body:\s*var\(--weight-body-mobile/)
110
+
@@ -104,6 +104,6 @@ fail!("font loader missing") unless font_at && script_at && base_at
104
104
  fail!("font stylesheet precedes the preload script") unless script_at < font_at
105
105
  fail!("font stylesheet precedes local CSS") unless base_at < font_at
106
106
  fail!("font host is not preconnected before the preload script") unless preconnect_at && preconnect_at < script_at
107
- fail!("body fallback is still a sans") unless shared.include?('body_fallback: "Georgia, serif"')
107
+ fail!("body fallback is not sans-serif") unless shared.include?('body_fallback: "sans-serif"')
108
108
 
109
109
  puts "PASS test-hero-summary"
@@ -19,8 +19,8 @@ fail!("featured article title is not 2pt larger") unless home.include?(
19
19
  '[data-home-kind="articles"] .home-featured-title'
20
20
  ) && home.include?("calc(var(--home-featured-title-size) + 2pt)")
21
21
 
22
- fail!("listed article titles are not 2pt larger") unless home.include?(
23
- "calc(var(--type-card) + 2pt)"
22
+ fail!("listed article titles are not on --type-card step") unless home.include?(
23
+ "font-size: var(--type-card);"
24
24
  ) && home.include?('[data-home-kind="articles"] .home-card-grid .card-title')
25
25
 
26
26
  phone = home[/^@media \(max-width: 767px\) \{\n \[data-home-kind="articles"\] \.home-featured \{.*?\n \}/m]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pandorga
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.4
4
+ version: 2.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - The Pandorga contributors
@@ -571,7 +571,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
571
571
  requirements:
572
572
  - - ">="
573
573
  - !ruby/object:Gem::Version
574
- version: 3.3.0
574
+ version: 3.2.0
575
575
  required_rubygems_version: !ruby/object:Gem::Requirement
576
576
  requirements:
577
577
  - - ">="