@bongos/core 1.24.82 → 1.24.84

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 (59) hide show
  1. package/.bongos-core.json +63 -63
  2. package/docs/adr/0402-helm-is-the-halls-look-and-the-hall-is-dark-only.md +4 -0
  3. package/docs/copy-inventory.md +4 -4
  4. package/docs/copy-registry.json +6 -6
  5. package/docs/module-api-changelog.md +4 -0
  6. package/docs/page-readings.json +42 -42
  7. package/modules/hall-ui/public/ai-studio.html +1 -1
  8. package/modules/hall-ui/public/atlas.html +1 -1
  9. package/modules/hall-ui/public/blockers.html +1 -1
  10. package/modules/hall-ui/public/board-room.html +1 -1
  11. package/modules/hall-ui/public/city.css +3 -2
  12. package/modules/hall-ui/public/city.html +4 -4
  13. package/modules/hall-ui/public/collab.html +1 -1
  14. package/modules/hall-ui/public/commands.html +1 -1
  15. package/modules/hall-ui/public/controls.css +10 -2
  16. package/modules/hall-ui/public/copy-desk.html +1 -1
  17. package/modules/hall-ui/public/deploy.html +1 -1
  18. package/modules/hall-ui/public/goal-map.html +3 -3
  19. package/modules/hall-ui/public/goals.html +1 -1
  20. package/modules/hall-ui/public/government.html +1 -1
  21. package/modules/hall-ui/public/home-city.css +0 -4
  22. package/modules/hall-ui/public/idea.html +1 -1
  23. package/modules/hall-ui/public/ideas.html +1 -1
  24. package/modules/hall-ui/public/index.html +4 -4
  25. package/modules/hall-ui/public/market-watch-item.html +1 -1
  26. package/modules/hall-ui/public/market-watch-rules.html +1 -1
  27. package/modules/hall-ui/public/market-watch.html +1 -1
  28. package/modules/hall-ui/public/modules.html +1 -1
  29. package/modules/hall-ui/public/money.html +1 -1
  30. package/modules/hall-ui/public/my-agents.html +1 -1
  31. package/modules/hall-ui/public/options-menu.js +20 -0
  32. package/modules/hall-ui/public/primer.html +1 -1
  33. package/modules/hall-ui/public/profile.html +1 -1
  34. package/modules/hall-ui/public/project-settings.html +1 -1
  35. package/modules/hall-ui/public/roster.html +1 -1
  36. package/modules/hall-ui/public/settings.css +113 -46
  37. package/modules/hall-ui/public/settings.html +3 -3
  38. package/modules/hall-ui/public/street.html +1 -1
  39. package/modules/hall-ui/public/studio.html +1 -1
  40. package/modules/hall-ui/public/style.css +167 -71
  41. package/modules/hall-ui/public/task.html +1 -1
  42. package/modules/hall-ui/public/thinking.html +3 -3
  43. package/modules/hall-ui/public/tweak-editor.html +1 -1
  44. package/modules/hall-ui/public/visor.css +109 -48
  45. package/modules/hall-ui/public/visor.js +50 -33
  46. package/modules/hall-ui/public/watch.html +1 -1
  47. package/modules/hall-ui/public/work.html +1 -1
  48. package/modules/hall-ui/records/craft-mode.md +9 -0
  49. package/modules/hall-ui/records/options-menu.md +11 -0
  50. package/modules/hall-ui/records/visor.md +14 -2
  51. package/package-lock.json +2 -2
  52. package/package.json +1 -1
  53. package/release-notes.json +12 -0
  54. package/src/module-api.js +1 -1
  55. package/tests/design_tokens_shared.mjs +5 -1
  56. package/tests/hall_controls.mjs +1 -1
  57. package/tests/hall_helm.mjs +103 -1
  58. package/tests/hall_topbar_320.mjs +7 -4
  59. package/tests/hall_visor.mjs +128 -10
@@ -182,7 +182,12 @@
182
182
  --line: var(--ds-line);
183
183
  --radius: var(--ds-radius-panel);
184
184
  --radius-sm: var(--ds-radius-tile);
185
- --radius-pill: var(--ds-radius-pill);
185
+ /* HELM DRAWS NO PILL (task 1005194, ADR 0402). The name stays, because some
186
+ seventy rules across the page sheets spell it, but in the hall it is a
187
+ square corner: a field, a tag, a chip, a toggle and a toast are square
188
+ inside one hairline, and only what you press is cut (--cut-path). A thing
189
+ that must be round says --ds-radius-pill. */
190
+ --radius-pill: 0px;
186
191
 
187
192
  /* ---- the shell's metrics. --topbar-h stays under the kit's 80px top-bar
188
193
  floor; --sidebar-w IS the rail, because v3 pins the rail at every
@@ -785,16 +790,26 @@ html[data-theme="dark"] .brand-mark__mark { --mark-ink: #e2e1e4; }
785
790
  .founding-band { flex-wrap: wrap; row-gap: 2px; padding: 8px 16px; }
786
791
  .founding-band__desc { display: none; }
787
792
  .founding-band__stage { margin-left: 0; white-space: normal; }
788
- /* task 1005148, the visor (visor.css): the top of a phone belongs to the scene and the shell’s
789
- corner buttons, so the compass and the place line step aside and all three pills share the
790
- bottom row: the main action, Actions (its dots and key only), the sprite with the credits. */
791
- html[data-game="on"] .visor:not([hidden]) { --visor-inset-right: var(--ds-space-gutter-narrow); --visor-inset-left: var(--ds-space-gutter-narrow); --visor-inset-bottom: 40px; }
792
- html[data-game="on"] .visor__place, html[data-game="on"] .visor__cell, html[data-game="on"] .visor__mark { display: none; }
793
- html[data-game="on"] .visor__pill--actions { top: auto; right: auto; left: 50%; bottom: var(--visor-inset-bottom); transform: translateX(-50%); padding: 0 var(--ds-space-xs); }
794
- html[data-game="on"] .visor__pill--actions > span:not(.visor__dots) { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
795
- html[data-game="on"] .visor__sheet { top: auto; bottom: calc(var(--visor-inset-bottom) + 56px); right: var(--visor-inset-right); max-height: 70vh; }
796
- html[data-game="on"] .visor__me .visor__name { display: none; }
797
- html[data-game="on"] .visor__me { padding: 4px var(--ds-space-xs) 4px 4px; }
793
+ /* tasks 1005148 and 1005195, the visor (visor.css): the top of a phone belongs to the scene
794
+ and the shell’s corner buttons, so the top arc, its notch and the place all step aside. The foot row keeps its three parts in one line and nothing leans: the sprite
795
+ with the count over its word, the one accent button (its name may take two lines; its key is in the sheet), and of
796
+ the key hints only Actions, as its dots (every other hint is a row in its sheet). */
797
+ html[data-game="on"] #visor { --visor-inset-bottom: 52px; }
798
+ html[data-game="on"] .visor__place, html[data-game="on"] .visor__notch, html[data-game="on"] .visor__frame--top, html[data-game="on"] .visor__name { display: none; }
799
+ html[data-game="on"] .visor__foot { grid-template-columns: auto minmax(0, 1fr) auto; column-gap: var(--ds-space-hair); }
800
+ html[data-game="on"] .visor__me, html[data-game="on"] .visor__hints { transform: none; }
801
+ html[data-game="on"] .visor__me { gap: var(--ds-space-hair); }
802
+ html[data-game="on"] .visor__sprite { width: 36px; height: 36px; }
803
+ html[data-game="on"] .visor__num { font-size: var(--ds-text-4xl); }
804
+ html[data-game="on"] .visor__credits { flex-direction: column; align-items: flex-start; gap: 2px; }
805
+ html[data-game="on"] .visor__unit { font-size: var(--ds-text-2xs); line-height: 1; }
806
+ html[data-game="on"] .visor__main { min-width: 0; overflow-wrap: anywhere; min-height: 48px; padding: var(--ds-space-hair) var(--ds-space-xs); gap: var(--ds-space-hair); font-size: var(--ds-text-xl); clip-path: var(--cut-path-sm); }
807
+ html[data-game="on"] .visor__hint:not([data-visor-sheet]) { display: none; }
808
+ html[data-game="on"] .visor__hint--sheet { min-width: 44px; justify-content: center; }
809
+ html[data-game="on"] .visor__hint--sheet .visor__dots { display: block; }
810
+ html[data-game="on"] .visor__hint--sheet > :not(.visor__dots) { position: absolute; width: 1px; height: 1px; padding: 0; border: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
811
+ html[data-game="on"] .visor__main .visor__key { display: none; }
812
+ html[data-game="on"] .visor__sheet { bottom: calc(var(--visor-inset-bottom) + 80px); max-height: 70vh; }
798
813
  }
799
814
  /* task 1004424 (BV2.PS10): THE FOUNDING MARK. A pill in .rank-badge's grammar (same
800
815
  height, type and radius) so it sits beside a rank without competing with it; the
@@ -1126,19 +1141,26 @@ html[data-theme="dark"] .gplate__light { display: none; }
1126
1141
  min-width: 28px;
1127
1142
  padding: 0 11px 0 9px;
1128
1143
  border: 1px solid var(--rule);
1129
- border-radius: var(--radius-pill);
1130
- background: var(--bg-card);
1144
+ border-radius: var(--press-radius);
1145
+ /* Helm (task 1005194): it is pressed, so it is cut, in the name voice; the cut
1146
+ clips an outline, so its focus is the inset ring */
1147
+ clip-path: var(--cut-path-sm);
1148
+ --focus-ring: var(--press-focus);
1149
+ background: var(--press-fill);
1131
1150
  color: var(--ink);
1132
1151
  font: inherit;
1133
- font-size: 12px;
1134
- font-weight: 500;
1152
+ font-family: var(--name-face);
1153
+ font-size: var(--ds-text-xs);
1154
+ font-weight: var(--name-weight);
1155
+ letter-spacing: var(--name-space-tight);
1156
+ text-transform: var(--name-case);
1135
1157
  line-height: 1;
1136
1158
  white-space: nowrap;
1137
1159
  flex-shrink: 0;
1138
1160
  cursor: pointer;
1139
1161
  }
1140
1162
  .upd-pill:hover { border-color: var(--ink-faint); }
1141
- .upd-pill:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
1163
+ .upd-pill:focus-visible { outline: 0; border-radius: var(--press-radius); }
1142
1164
  .upd-pill__dot { width: 7px; height: 7px; border-radius: 50%; background: var(--accent); flex-shrink: 0; }
1143
1165
  .upd-pill[data-face="held"] .upd-pill__dot { background: var(--ink-faint); }
1144
1166
  .upd-pill[data-face="done"] { background: var(--accent); border-color: var(--accent); color: var(--accent-on); }
@@ -1331,7 +1353,6 @@ html[data-fullscreen="on"] .upd-pill {
1331
1353
  pointer-events: auto;
1332
1354
  min-height: 36px;
1333
1355
  margin-right: 8px;
1334
- box-shadow: var(--shadow-pop);
1335
1356
  }
1336
1357
  /* task 1004430: the way back must read on ANY ground. The hall's glass is
1337
1358
  near-clear, so over the black sky in the light theme it was a dark glyph on
@@ -1343,13 +1364,22 @@ html[data-fullscreen="on"] .fullscreen-toggle {
1343
1364
  gap: 6px;
1344
1365
  padding: 0 14px 0 10px;
1345
1366
  color: var(--ink);
1346
- background: var(--bg-card);
1347
- box-shadow: 0 0 0 1px var(--rule), 0 4px 16px rgba(0, 0, 0, .35);
1348
- font-size: 13px;
1349
- font-weight: 500;
1367
+ /* Helm (task 1005194): the cut corner on the press fill inside one hairline, in
1368
+ the name voice. The fill is opaque, so it still reads on any ground. */
1369
+ background: var(--press-fill);
1370
+ border: var(--line) solid var(--rule);
1371
+ border-radius: var(--press-radius);
1372
+ clip-path: var(--cut-path-sm);
1373
+ --focus-ring: var(--press-focus);
1374
+ font-family: var(--name-face);
1375
+ font-size: var(--ds-text-xs);
1376
+ font-weight: var(--name-weight);
1377
+ letter-spacing: var(--name-space-tight);
1378
+ text-transform: var(--name-case);
1350
1379
  white-space: nowrap;
1351
1380
  }
1352
- /* A phone has no room for the words; the round button keeps its card tone. */
1381
+ html[data-fullscreen="on"] .fullscreen-toggle:focus-visible { outline: 0; border-radius: var(--press-radius); }
1382
+ /* A phone has no room for the words; the button keeps its fill. */
1353
1383
  @media (max-width: 640px) {
1354
1384
  html[data-fullscreen="on"] .fullscreen-toggle { width: 36px; padding: 0; }
1355
1385
  .fullscreen-toggle__label { display: none; }
@@ -1376,7 +1406,7 @@ html[data-embed="on"] .app-content { padding-top: 0; }
1376
1406
  z-index: var(--z-topbar);
1377
1407
  max-width: min(320px, calc(100vw - 24px));
1378
1408
  padding: 8px 12px;
1379
- border-radius: 10px;
1409
+ border-radius: var(--press-radius);
1380
1410
  background: var(--bg-card);
1381
1411
  color: var(--ink);
1382
1412
  font-size: 13px;
@@ -1443,12 +1473,12 @@ html[data-embed="on"] .app-content { padding-top: 0; }
1443
1473
  (signing out). The sprites are pixel art, so they scale by whole pixels. */
1444
1474
  .craft-sprite { display: block; image-rendering: pixelated; object-fit: contain; }
1445
1475
  .craft-switch__me { padding: 0 10px 0 4px; color: var(--ink); }
1446
- /* The chip is the figure's head: the portrait cropped round its top third. */
1476
+ /* The chip is the figure's head: the portrait cropped to its top third. */
1447
1477
  .craft-sprite--chip { width: 26px; height: 26px; border-radius: var(--radius-pill); object-fit: cover; object-position: 50% 22%; }
1448
1478
  /* Character creation: each door is the owner's portrait — the figure on its plinth
1449
1479
  in the torch-lit hall — filling the top of the door, the words beneath it. */
1450
1480
  .craft-plinth { display: block; overflow: hidden; }
1451
- .craft-sprite--door { width: 100%; height: auto; aspect-ratio: 250 / 290; transition: transform 200ms cubic-bezier(.2, .7, .3, 1); }
1481
+ .craft-sprite--door { width: 100%; height: auto; aspect-ratio: 250 / 290; transition: transform var(--ds-dur-base) var(--ds-ease); }
1452
1482
  .craft-door--character:hover .craft-sprite--door,
1453
1483
  .craft-door--character:focus-visible .craft-sprite--door { transform: scale(1.03); }
1454
1484
 
@@ -1538,6 +1568,12 @@ html.setup-gate-open { overflow: hidden; }
1538
1568
  .setup-gate__foot { margin: 24px 0 0; font-size: 14px; }
1539
1569
  .setup-gate__foot a { color: var(--ink-soft); }
1540
1570
  @media (max-width: 640px) { .setup-gate__panel { padding: 28px 20px 20px; border-radius: 18px; } }
1571
+ /* THE PICKER IN HELM (task 1005194, ADR 0402). Two screens share these rules. The session
1572
+ picker ("What are you doing now?") is a square night panel over the scrim. Character
1573
+ creation (.craft-picker--create) is a whole screen, not a box: the night itself, the
1574
+ title centred in the name voice, three tall doors, the one line at the foot. A door is
1575
+ pressable, so it is cut; the door the hall suggests is the one thing lit. A cut clips an
1576
+ outline, so a door's focus is the inset ring (--press-focus). */
1541
1577
  .craft-picker {
1542
1578
  position: fixed;
1543
1579
  inset: 0;
@@ -1545,27 +1581,36 @@ html.setup-gate-open { overflow: hidden; }
1545
1581
  display: flex;
1546
1582
  align-items: flex-start;
1547
1583
  justify-content: center;
1548
- padding: max(24px, 8vh) 16px 24px;
1584
+ padding: max(var(--ds-space-md), 8vh) var(--ds-space-sm) var(--ds-space-md);
1549
1585
  overflow-y: auto;
1550
1586
  background: var(--scrim);
1551
1587
  }
1588
+ .craft-picker--create { background: var(--bg); }
1552
1589
  .craft-picker__panel {
1553
1590
  position: relative;
1554
1591
  width: min(1120px, 100%);
1555
1592
  box-sizing: border-box;
1556
1593
  display: flex;
1557
1594
  flex-direction: column;
1558
- gap: 12px;
1559
- padding: 40px 44px 30px;
1560
- border-radius: 22px;
1595
+ gap: var(--ds-space-xs);
1596
+ padding: var(--ds-space-lg) var(--ds-space-lg) var(--ds-space-md);
1561
1597
  background: var(--bg-card);
1562
1598
  color: var(--ink);
1563
- box-shadow: 0 0 0 1px var(--glass-edge), 0 24px 64px rgba(0, 0, 0, .35);
1599
+ border: var(--line-strong) solid var(--rule);
1600
+ box-shadow: var(--ds-shadow-pop);
1601
+ }
1602
+ .craft-picker__panel--create {
1603
+ padding: 0;
1604
+ gap: var(--ds-space-sm);
1605
+ background: none;
1606
+ border: 0;
1607
+ box-shadow: none;
1608
+ text-align: center;
1564
1609
  }
1565
1610
  .craft-picker__close {
1566
1611
  position: absolute;
1567
- top: 14px;
1568
- right: 14px;
1612
+ top: var(--ds-space-sm);
1613
+ right: var(--ds-space-sm);
1569
1614
  display: inline-flex;
1570
1615
  align-items: center;
1571
1616
  justify-content: center;
@@ -1587,44 +1632,88 @@ html.setup-gate-open { overflow: hidden; }
1587
1632
  text-transform: var(--label-case);
1588
1633
  color: var(--ink-faint);
1589
1634
  }
1635
+ .craft-picker__panel--create .craft-picker__eyebrow { color: var(--ink-soft); }
1590
1636
  .craft-picker__title {
1591
1637
  margin: 0;
1592
- font-family: var(--font-display);
1593
- font-size: clamp(28px, 4vw, 40px);
1594
- font-weight: 300;
1595
- letter-spacing: -0.03em;
1638
+ font-family: var(--name-face);
1639
+ font-size: var(--ds-text-headline);
1640
+ font-weight: var(--name-weight);
1641
+ letter-spacing: var(--name-space-tight);
1642
+ text-transform: var(--name-case);
1596
1643
  line-height: 1.15;
1644
+ text-wrap: balance;
1645
+ color: var(--ink);
1597
1646
  }
1598
- .craft-picker__lede { margin: 0 0 16px; font-size: 16px; line-height: 1.5; color: var(--ink-soft); }
1647
+ .craft-picker__panel--create .craft-picker__title { letter-spacing: var(--name-space-wide); text-shadow: var(--name-glow); }
1648
+ .craft-picker__lede { margin: 0 0 var(--ds-space-sm); font-size: var(--ds-text-xl); line-height: 1.5; color: var(--ink-soft); }
1649
+ /* character creation says its one line at the foot, under the doors; the words and the
1650
+ dialog's aria-describedby are where they were */
1651
+ .craft-picker__panel--create .craft-picker__lede { order: 3; margin: var(--ds-space-sm) 0 0; }
1652
+ .craft-picker__panel--create .craft-picker__error { order: 4; }
1599
1653
  .craft-picker__doors {
1600
1654
  display: grid;
1601
1655
  grid-template-columns: repeat(4, minmax(0, 1fr));
1602
- gap: 16px;
1656
+ gap: var(--ds-space-sm);
1603
1657
  }
1658
+ .craft-picker__panel--create .craft-picker__doors { gap: var(--ds-space-md); margin-top: var(--ds-space-md); }
1604
1659
  .craft-door {
1605
1660
  display: flex;
1606
1661
  flex-direction: column;
1607
1662
  align-items: stretch;
1608
- gap: 8px;
1609
- padding: 0 0 20px;
1663
+ gap: var(--ds-space-hair);
1664
+ padding: 0 0 var(--ds-space-md);
1610
1665
  overflow: hidden;
1611
1666
  border: 0;
1612
- border-radius: 14px;
1613
- background: var(--bg);
1614
- color: var(--ink);
1667
+ border-radius: var(--press-radius);
1668
+ clip-path: var(--cut-path);
1669
+ position: relative;
1670
+ background: var(--night-glass);
1671
+ color: var(--ink-soft);
1615
1672
  font: inherit;
1616
1673
  text-align: left;
1617
1674
  cursor: pointer;
1618
- box-shadow: inset 0 0 0 1px var(--glass-edge);
1619
- transition: transform 200ms cubic-bezier(.2, .7, .3, 1), box-shadow 200ms;
1620
- }
1621
- .craft-door:hover { transform: translateY(-3px); box-shadow: inset 0 0 0 1px var(--rule); }
1622
- .craft-door:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }
1623
- .craft-door--pre { box-shadow: inset 0 0 0 2px var(--accent); }
1624
- .craft-door__head { display: flex; align-items: center; gap: 10px; padding: 10px 20px 0; }
1625
- .craft-door__icon { width: 20px; height: 20px; flex-shrink: 0; }
1626
- .craft-door__name { font-size: 20px; font-weight: 500; letter-spacing: -0.02em; }
1627
- .craft-door__line { padding: 0 20px; font-size: 14px; line-height: 1.45; color: var(--ink-soft); }
1675
+ box-shadow: inset 0 0 0 var(--line-strong) var(--rule);
1676
+ transition: background-color var(--ds-dur-fast) var(--ds-ease), box-shadow var(--ds-dur-fast) var(--ds-ease);
1677
+ }
1678
+ /* the door's edge again, over what it holds: an inset shadow sits under a portrait
1679
+ that fills the door, so the hairline, the suggested door's edge and the focus ring
1680
+ would all stop at the picture */
1681
+ .craft-door::after { content: ""; position: absolute; inset: 0; pointer-events: none; box-shadow: inherit; }
1682
+ .craft-door:hover { background: var(--glass); box-shadow: inset 0 0 0 var(--line-strong) var(--ink-faint); }
1683
+ /* the door the hall suggests: the accent's wash inside the accent's edge */
1684
+ .craft-door--pre, .craft-door--pre:hover { background: var(--accent-tint); box-shadow: inset 0 0 0 2px var(--accent); }
1685
+ .craft-door:focus-visible { outline: 0; border-radius: var(--press-radius); box-shadow: var(--press-focus); }
1686
+ .craft-door__head { display: flex; align-items: center; gap: var(--ds-space-xs); padding: var(--ds-space-xs) var(--ds-space-md) 0; }
1687
+ .craft-door__icon { width: 20px; height: 20px; flex-shrink: 0; color: var(--ink); }
1688
+ .craft-door__name {
1689
+ font-family: var(--name-face);
1690
+ font-size: var(--ds-text-4xl);
1691
+ font-weight: var(--name-weight);
1692
+ letter-spacing: var(--name-space-tight);
1693
+ text-transform: var(--name-case);
1694
+ line-height: 1;
1695
+ color: var(--ink);
1696
+ }
1697
+ .craft-door--pre .craft-door__name { font-weight: var(--name-weight-lit); }
1698
+ .craft-door__line { padding: 0 var(--ds-space-md); font-size: var(--ds-text-lg); line-height: 1.45; color: var(--ink-soft); }
1699
+ /* a character's door: the portrait fills the top under the cut, the name is the largest
1700
+ thing on it, and the door under the keyboard names the key that takes it */
1701
+ .craft-door--character { gap: var(--ds-space-xs); }
1702
+ .craft-door--character .craft-door__head { flex-wrap: wrap; padding-top: var(--ds-space-sm); }
1703
+ .craft-door--character .craft-door__name { font-size: var(--ds-text-headline); letter-spacing: var(--name-space); }
1704
+ .craft-door--character .craft-door__line { font-size: var(--ds-text-2xl); }
1705
+ .craft-door--character:focus-visible .craft-door__head::after {
1706
+ content: "Enter";
1707
+ padding: 2px var(--ds-space-hair);
1708
+ background: var(--accent);
1709
+ color: var(--accent-on);
1710
+ font-family: var(--name-face);
1711
+ font-size: var(--ds-text-md);
1712
+ font-weight: var(--name-weight-lit);
1713
+ letter-spacing: var(--label-space);
1714
+ text-transform: var(--name-case);
1715
+ line-height: 1.2;
1716
+ }
1628
1717
  .craft-art {
1629
1718
  position: relative;
1630
1719
  display: block;
@@ -1664,22 +1753,22 @@ html.setup-gate-open { overflow: hidden; }
1664
1753
  flex-wrap: wrap;
1665
1754
  align-items: center;
1666
1755
  justify-content: space-between;
1667
- gap: 12px 24px;
1668
- margin-top: 14px;
1669
- padding-top: 18px;
1670
- border-top: 1px solid var(--rule-soft);
1756
+ gap: var(--ds-space-xs) var(--ds-space-md);
1757
+ margin-top: var(--ds-space-sm);
1758
+ padding-top: var(--ds-space-sm);
1759
+ border-top: var(--line) solid var(--rule-soft);
1671
1760
  }
1672
1761
  .craft-picker__again {
1673
1762
  display: inline-flex;
1674
1763
  align-items: center;
1675
- gap: 10px;
1764
+ gap: var(--ds-space-xs);
1676
1765
  min-height: 24px;
1677
- font-size: 14px;
1766
+ font-size: var(--ds-text-md);
1678
1767
  color: var(--ink-soft);
1679
1768
  cursor: pointer;
1680
1769
  }
1681
1770
  .craft-picker__again input { width: 18px; height: 18px; margin: 0; accent-color: var(--accent); }
1682
- .craft-picker__hint { font-size: 13px; color: var(--ink-faint); }
1771
+ .craft-picker__hint { font-size: var(--ds-text-sm); color: var(--ink-faint); }
1683
1772
  .craft-picker__close:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
1684
1773
  /* task 1004685 (prototype): Governing is a held seat, so a builder with none sees
1685
1774
  three doors, not four (craft-mode.js stamps the count). */
@@ -1690,20 +1779,22 @@ html.setup-gate-open { overflow: hidden; }
1690
1779
  .craft-picker__doors { grid-template-columns: repeat(2, minmax(0, 1fr)); }
1691
1780
  }
1692
1781
  @media (max-width: 640px) {
1693
- .craft-picker { padding: 12px; }
1694
- .craft-picker__panel { padding: 28px 18px 20px; gap: 8px; border-radius: 18px; }
1695
- .craft-picker__doors { grid-template-columns: minmax(0, 1fr); gap: 10px; }
1696
- .craft-door { flex-direction: row; flex-wrap: wrap; align-items: center; gap: 4px 0; padding: 0 0 14px; }
1782
+ .craft-picker { padding: var(--ds-space-xs); }
1783
+ .craft-picker--create { padding: var(--ds-space-md) var(--ds-space-xs); }
1784
+ .craft-picker__panel { padding: var(--ds-space-md) var(--ds-space-sm) var(--ds-space-sm); gap: var(--ds-space-hair); }
1785
+ .craft-picker__panel--create { padding: 0; }
1786
+ .craft-picker__doors, .craft-picker__panel--create .craft-picker__doors { grid-template-columns: minmax(0, 1fr); gap: var(--ds-space-xs); }
1787
+ .craft-door { flex-direction: row; flex-wrap: wrap; align-items: center; gap: 4px 0; padding: 0 0 var(--ds-space-sm); clip-path: var(--cut-path-sm); }
1697
1788
  .craft-art { flex: 0 0 100%; height: 96px; }
1698
1789
  .craft-art__city { top: -8px; }
1699
- .craft-door__head { padding: 10px 16px 0; }
1700
- .craft-door__name { font-size: 18px; }
1701
- .craft-door__line { flex: 0 0 100%; padding: 0 16px; box-sizing: border-box; }
1790
+ .craft-door__head { padding: var(--ds-space-xs) var(--ds-space-sm) 0; }
1791
+ .craft-door__line { flex: 0 0 100%; padding: 0 var(--ds-space-sm); box-sizing: border-box; }
1702
1792
  /* A phone stacks the three as rows: the portrait on the left, the words beside it. */
1703
- .craft-door.craft-door--character { display: grid; grid-template-columns: 86px minmax(0, 1fr); grid-template-rows: auto 1fr; align-content: start; gap: 4px 14px; padding: 0; }
1793
+ .craft-door.craft-door--character { display: grid; grid-template-columns: 86px minmax(0, 1fr); grid-template-rows: auto 1fr; align-content: start; gap: 4px var(--ds-space-sm); padding: 0; }
1704
1794
  .craft-plinth { grid-row: 1 / span 2; width: 86px; }
1705
- .craft-door.craft-door--character > .craft-door__head { padding: 12px 14px 0 0; }
1706
- .craft-door.craft-door--character > .craft-door__line { padding: 0 14px 12px 0; }
1795
+ .craft-door.craft-door--character > .craft-door__head { padding: var(--ds-space-xs) var(--ds-space-sm) 0 0; }
1796
+ .craft-door.craft-door--character > .craft-door__line { padding: 0 var(--ds-space-sm) var(--ds-space-xs) 0; font-size: var(--ds-text-lg); }
1797
+ .craft-door--character .craft-door__name { font-size: var(--ds-text-5xl); letter-spacing: var(--name-space-tight); }
1707
1798
  }
1708
1799
 
1709
1800
  /* THE CRAFT MODE LOOKS (task 1004495; direction docs/design/craft-mode-direction.md).
@@ -4220,10 +4311,15 @@ html[data-door="out"] #hall-main { width: 100%; }
4220
4311
  color: var(--accent-ink);
4221
4312
  background: var(--accent-tint);
4222
4313
  border: 0;
4223
- border-radius: var(--radius-pill);
4314
+ border-radius: var(--press-radius);
4315
+ /* Helm (task 1005194): a chip is pressed, so it takes the small cut and the
4316
+ inset focus ring */
4317
+ clip-path: var(--cut-path-sm);
4318
+ --focus-ring: var(--press-focus);
4224
4319
  cursor: pointer;
4225
4320
  }
4226
4321
  .chip:hover { color: var(--ink); }
4322
+ .chip:focus-visible { outline: 0; border-radius: var(--press-radius); }
4227
4323
 
4228
4324
  /* tab strip — the .setup__tab idiom in the .setup__toggle frame, promoted */
4229
4325
  /* A tab strip is hairlines, not a segmented box: one rule under the row and a
@@ -8,7 +8,7 @@
8
8
  <link rel="icon" href="/modules/ui-design/public/brand/favicon.svg" type="image/svg+xml">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link rel="stylesheet" href="/builders/style.css?v=2026-11-11-view2">
11
+ <link rel="stylesheet" href="/builders/style.css?v=2026-11-11-helm3">
12
12
  <!-- The record archetype (shared with idea.html) and this page's own two
13
13
  shapes. Promoted out of an inline <style> by task 1003305 — the block was
14
14
  the hall's last substantive one and sat at its hall_audit ratchet. -->
@@ -12,8 +12,8 @@
12
12
  links, injected into this head by the server like every hall page's
13
13
  (tests/hall_tokens.mjs: no hall page hardcodes a web-font stylesheet).
14
14
  The template carried its own Google Fonts link for the same two faces. -->
15
- <link rel="stylesheet" href="/builders/style.css?v=2026-11-11-view2">
16
- <link rel="stylesheet" href="/builders/visor.css?v=2026-11-10-visor">
15
+ <link rel="stylesheet" href="/builders/style.css?v=2026-11-11-helm3">
16
+ <link rel="stylesheet" href="/builders/visor.css?v=2026-11-11-helm3">
17
17
  <link rel="stylesheet" href="/builders/thinking.css?v=2026-11-10-visor">
18
18
  </head>
19
19
  <!-- THE SKY (task 1004231 / sky part 3 of 5, goal 1000095; ADR 0331, ADR 0227
@@ -146,7 +146,7 @@
146
146
  <script src="/builders/shell.js?v=2026-11-11-view2"></script>
147
147
  <script src="/builders/hall-dialog.js"></script>
148
148
  <!-- task 1005148: the visor (glass over the scene, game mode only; ADR 0399), after the shell and hall-dialog.js -->
149
- <script src="/builders/visor.js?v=2026-11-11-view2"></script>
149
+ <script src="/builders/visor.js?v=2026-11-11-helm3"></script>
150
150
  <script src="/builders/palette.js" defer></script>
151
151
 
152
152
  <script src="/builders/idea-objects.js?v=2026-09-27-split"></script>
@@ -10,7 +10,7 @@
10
10
  <link rel="icon" href="/modules/ui-design/public/brand/favicon.svg" type="image/svg+xml">
11
11
  <link rel="preconnect" href="https://fonts.googleapis.com">
12
12
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
13
- <link rel="stylesheet" href="/builders/style.css?v=2026-11-11-view2">
13
+ <link rel="stylesheet" href="/builders/style.css?v=2026-11-11-helm3">
14
14
  <link rel="stylesheet" href="/builders/tweak-editor.css?v=2026-09-29-tw27-aqfix">
15
15
  </head>
16
16
  <!-- THE TWEAK EDITOR (task 1004321 / BV2.TW10, goal 1000095; ADR 0341 D4 and
@@ -1,80 +1,141 @@
1
- /* visor.css — the first-person visor (task 1005148, visor.js; ADR 0399). Glass over the scene:
2
- the frame lines, the place, three pills and the actions sheet. It shows in game mode only, and
3
- it is an overlay, never layout, so the stage under it never changes size (ADR 0399 §2.1).
4
- Colours are the hall's tokens; the frame is hairline ink, never a glow (DESIGN.md: no
5
- near-black-plus-neon HUD). Record: modules/hall-ui/records/visor.md. */
1
+ /* visor.css — the first-person visor (task 1005148, visor.js; ADR 0399), in the Helm look: the
2
+ minimal visor (task 1005195, ADR 0402). Glass over the scene: two thin arcs, the place in the
3
+ name voice, and one foot row (your credits, the one accent button, a quiet row of key hints).
4
+ Hairlines, not cards: nothing on the glass is a box but the button you press and the key in
5
+ a hint. It shows in game mode only, and it is an overlay, never layout, so the stage under it
6
+ never changes size (ADR 0399 §2.1).
7
+ IT READS OVER ANY SKY, with no per-hour style: the glass darkens toward its top and bottom
8
+ edge (--night-glass), every word wears the type halo (--type-halo), every line is drawn over a
9
+ wider stroke of the night and so is every letter, and a key sits on a chip of the night. Colours, sizes and corners
10
+ are the hall tier's tokens; nothing here is typed in. Record: modules/hall-ui/records/visor.md. */
6
11
  .visor { display: none; }
7
12
  html[data-game="on"] .visor:not([hidden]) {
8
13
  display: block; position: fixed; inset: 0; z-index: 4; pointer-events: none;
9
14
  /* where the glass sits, so a scene's pop-up can keep clear of it (ADR 0399 §2.3) */
10
- --visor-inset-top: 64px; --visor-inset-right: 40px; --visor-inset-bottom: 76px; --visor-inset-left: 40px;
15
+ --visor-inset-top: 64px; --visor-inset-bottom: 76px;
16
+ --visor-inset-right: max(var(--ds-space-gutter-narrow), var(--helm-inset)); --visor-inset-left: var(--visor-inset-right);
17
+ background: linear-gradient(to bottom, var(--night-glass), transparent 128px, transparent calc(100% - 260px), var(--night-glass));
11
18
  color: var(--ink); font-family: var(--font-body);
12
19
  }
13
20
 
14
- /* the frame: stretched over the stage, every stroke one hairline at any size */
15
- .visor__frame { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
21
+ /* the frame: each arc is stretched across the stage, every stroke one hairline at any size. The
22
+ top arc, its notch and the place all sit inside the top inset, above where a scene starts its
23
+ own top row; the foot arc runs under the foot row. */
24
+ .visor__frame { position: absolute; left: 0; width: 100%; overflow: visible; }
25
+ .visor__frame--top { top: calc(var(--visor-inset-top) - 50px); height: 42px; }
26
+ .visor__frame--foot { bottom: calc(var(--visor-inset-bottom) - 44px); height: 18px; }
16
27
  .visor__frame path { vector-effect: non-scaling-stroke; }
17
- .visor__line { fill: none; stroke: var(--rule); stroke-width: var(--ds-line); }
18
- .visor__line--side { stroke: var(--rule-soft); }
19
- .visor__cell { fill: color-mix(in srgb, var(--ink) 12%, transparent); stroke: var(--rule); stroke-width: var(--ds-line); }
20
- .visor__mark { fill: var(--accent); stroke: none; }
28
+ .visor__line { fill: none; stroke: var(--ink-soft); stroke-opacity: .6; stroke-width: var(--line-strong); }
29
+ .visor__line--under { stroke: var(--night-glass); stroke-opacity: 1; stroke-width: 5px; }
30
+ .visor__dot { fill: var(--ink-soft); stroke: var(--night-glass); stroke-width: var(--line-strong); }
31
+ .visor__notch, .visor__sight { position: absolute; left: 50%; transform: translate(-50%, -50%); overflow: visible; }
32
+ .visor__notch { top: calc(var(--visor-inset-top) - 36px); width: 12px; height: 9px; }
33
+ .visor__sight { top: 50%; width: 24px; height: 24px; }
21
34
 
22
- /* the place, under the compass */
35
+ /* type over the scene: the halo, and a stroke of the night painted under each letter, the same
36
+ move as the lines' */
37
+ .visor__place, .visor__who, .visor__hint {
38
+ text-shadow: var(--type-halo); -webkit-text-stroke: 4px var(--night-glass); paint-order: stroke fill;
39
+ }
40
+ /* the name voice, for every name on the glass */
41
+ .visor__place, .visor__name, .visor__unit, .visor__main, .visor__hint, .visor__key, .visor__sheet-title, .visor__cap {
42
+ font-family: var(--name-face); font-weight: var(--name-weight); text-transform: var(--name-case);
43
+ }
44
+
45
+ /* the place, under the top arc */
23
46
  .visor__place {
24
- position: absolute; left: 50%; top: max(9.5%, 84px); transform: translateX(-50%); margin: 0;
25
- font-family: var(--font-mono); font-size: var(--ds-text-2xs); letter-spacing: .14em; text-transform: uppercase;
47
+ position: absolute; left: 50%; top: calc(var(--visor-inset-top) - 26px); transform: translateX(-50%); margin: 0;
48
+ font-size: var(--ds-text-2xl); letter-spacing: var(--name-space-wide); line-height: 1.2;
26
49
  color: var(--ink-soft); white-space: nowrap;
27
50
  }
28
51
 
29
- /* the pills: the only parts of the glass that take a pointer */
30
- .visor__pill, .visor__me {
31
- position: absolute; pointer-events: auto; box-sizing: border-box;
32
- display: inline-flex; align-items: center; gap: var(--ds-space-xs);
33
- min-height: 46px; padding: 0 var(--ds-space-sm);
34
- background: var(--bg-card); color: var(--ink); border: var(--ds-line) solid var(--rule);
35
- border-radius: var(--ds-radius-pill); font: inherit; font-size: var(--ds-text-sm); text-decoration: none;
52
+ /* the foot row: you on the left, the one thing to press in the middle, the key hints on the
53
+ right. The two side groups lean in a little, as the glass curves. */
54
+ .visor__foot {
55
+ position: absolute; left: var(--visor-inset-left); right: var(--visor-inset-right); bottom: var(--visor-inset-bottom);
56
+ display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; column-gap: var(--ds-space-sm);
57
+ }
58
+ .visor__me {
59
+ justify-self: start; display: flex; align-items: center; gap: var(--ds-space-sm);
60
+ transform: perspective(900px) rotateY(16deg); transform-origin: left center;
61
+ }
62
+ .visor__sprite {
63
+ flex: none; width: 56px; height: 56px; object-fit: cover; object-position: 50% 12%;
64
+ background: var(--glass-strong); clip-path: var(--cut-path-sm);
65
+ }
66
+ .visor__who { display: flex; flex-direction: column; gap: 2px; }
67
+ .visor__name { font-size: var(--ds-text-xs); letter-spacing: var(--name-space); line-height: 1; color: var(--ink-soft); }
68
+ .visor__credits { display: flex; align-items: baseline; gap: var(--ds-space-xs); white-space: nowrap; }
69
+ .visor__num { font-family: var(--name-face); font-size: var(--ds-text-headline); font-weight: 400; line-height: 1; color: var(--ink); font-variant-numeric: tabular-nums; }
70
+ .visor__unit { font-size: var(--ds-text-md); letter-spacing: var(--name-space); color: var(--ink-soft); }
71
+
72
+ /* the one accent button: the cut corner, the dark ink, the key that takes it */
73
+ .visor__main {
74
+ pointer-events: auto; box-sizing: border-box; justify-self: center;
75
+ display: inline-flex; align-items: center; justify-content: space-between; gap: var(--ds-space-sm);
76
+ min-height: 56px; padding: var(--ds-space-hair) var(--ds-space-sm) var(--ds-space-hair) var(--ds-space-md);
77
+ background: var(--accent); color: var(--accent-on); border: 0; border-radius: var(--press-radius); clip-path: var(--cut-path);
78
+ font-size: var(--ds-text-3xl); font-weight: var(--name-weight-lit); letter-spacing: var(--name-space-tight); line-height: 1.1;
79
+ text-decoration: none; cursor: pointer; transition: background-color var(--ds-dur-fast) var(--ds-ease);
80
+ }
81
+ .visor__main:hover { background: var(--accent-lift); color: var(--accent-on); text-decoration: none; }
82
+
83
+ /* the key hints: a key and a name, no box round the pair. The only other parts of the glass
84
+ that take a pointer. */
85
+ .visor__hints {
86
+ justify-self: end; display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 0 var(--ds-space-md);
87
+ transform: perspective(900px) rotateY(-16deg); transform-origin: right center;
88
+ }
89
+ .visor__hint {
90
+ pointer-events: auto; box-sizing: border-box; display: inline-flex; align-items: center; gap: var(--ds-space-hair);
91
+ min-height: 44px; padding: 0; background: none; border: 0; border-radius: var(--press-radius);
92
+ color: var(--ink-soft); font-size: var(--ds-text-lg); letter-spacing: var(--name-space-tight); white-space: nowrap;
93
+ text-decoration: none; cursor: pointer;
94
+ transition: color var(--ds-dur-fast) var(--ds-ease);
95
+ }
96
+ .visor__hint:hover { color: var(--ink); text-decoration: none; }
97
+ .visor__hint[hidden] { display: none; }
98
+ /* Actions on a phone: three dots on the same chip of the night a key sits on (style.css shows it) */
99
+ .visor__dots {
100
+ display: none; box-sizing: content-box; width: 14px; height: 4px; padding: 10px 5px; border: var(--line-strong) solid currentColor;
101
+ background: radial-gradient(circle, currentColor 1.5px, transparent 2px) 0 0 / 5px 4px repeat-x content-box, var(--bg);
36
102
  }
37
- .visor__pill { cursor: pointer; }
38
- .visor__pill:hover { border-color: var(--ink-faint); }
39
- .visor__pill:focus-visible, .visor__row:focus-visible, .visor__close:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
40
- .visor__pill--main { left: var(--visor-inset-left); bottom: var(--visor-inset-bottom); background: var(--accent); color: var(--accent-on); border-color: var(--accent); font-weight: 500; }
41
- .visor__pill--main:hover { border-color: var(--accent-deep); }
42
- .visor__pill--actions { right: var(--visor-inset-right); top: var(--visor-inset-top); }
43
- .visor__pill[hidden] { display: none; }
44
- .visor__dots { width: 14px; height: 4px; background: radial-gradient(circle, currentColor 1.5px, transparent 2px) 0 0 / 5px 4px repeat-x; }
45
- .visor__me { right: var(--visor-inset-right); bottom: var(--visor-inset-bottom); padding: 4px var(--ds-space-sm) 4px 4px; pointer-events: none; }
46
- .visor__sprite { width: 38px; height: 38px; border-radius: var(--ds-radius-pill); object-fit: cover; object-position: 50% 12%; background: var(--bg-deep); }
47
- .visor__who { display: flex; flex-direction: column; line-height: 1.2; }
48
- .visor__name { font-weight: 500; }
49
- .visor__credits { font-size: var(--ds-text-2xs); color: var(--ink-soft); font-variant-numeric: tabular-nums; }
50
103
  .visor__key {
51
- font-family: var(--font-mono); font-size: var(--ds-text-2xs); line-height: 1; padding: 3px 5px;
52
- border: var(--ds-line) solid currentColor; border-radius: var(--ds-radius-pill); opacity: .75;
104
+ box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; flex: none;
105
+ min-width: 24px; height: 24px; padding: 0 5px;
106
+ border: var(--line-strong) solid currentColor; background: var(--bg);
107
+ font-size: var(--ds-text-sm); letter-spacing: 0; line-height: 1; text-shadow: none; -webkit-text-stroke: 0;
53
108
  }
109
+ .visor__main .visor__key { background: none; }
110
+ /* a cut corner clips an outline, so every control here takes the inset two-tone ring */
111
+ .visor__main:focus-visible, .visor__hint:focus-visible, .visor__row:focus-visible, .visor__close:focus-visible { outline: 0; border-radius: var(--press-radius); box-shadow: var(--press-focus); }
54
112
 
55
- /* the sheet: above the scene's pop-ups, under the modals (ADR 0399 §2.3 layer 4) */
113
+ /* the sheet: above the scene's pop-ups, under the modals (ADR 0399 §2.3 layer 4). The night
114
+ panel between two strong hairlines, standing over the hints that opened it, clear of the foot
115
+ row even when the hints have wrapped onto a second line. */
56
116
  .visor__sheet {
57
- position: absolute; right: var(--visor-inset-right); top: var(--visor-inset-top); z-index: 1;
117
+ position: absolute; right: var(--visor-inset-right); bottom: calc(var(--visor-inset-bottom) + 100px); z-index: 1;
58
118
  pointer-events: auto; box-sizing: border-box; width: min(18rem, calc(100vw - 2 * var(--ds-space-gutter-narrow)));
59
- max-height: calc(100% - var(--visor-inset-top) - var(--visor-inset-bottom)); overflow-y: auto;
60
- padding: var(--ds-space-sm); background: var(--bg-card); border: var(--ds-line) solid var(--rule);
61
- border-radius: var(--ds-radius-panel); box-shadow: var(--ds-shadow-pop);
119
+ max-height: calc(100% - var(--visor-inset-top) - var(--visor-inset-bottom) - 100px); overflow-y: auto;
120
+ padding: var(--ds-space-sm); background: var(--bg-card);
121
+ border: 0 solid var(--rule); border-left-width: var(--line-strong); border-right-width: var(--line-strong);
62
122
  }
63
123
  .visor__sheet-head { display: flex; align-items: center; justify-content: space-between; }
64
- .visor__sheet-title { margin: 0; font-size: var(--ds-text-md); font-weight: 500; }
65
- .visor__close { min-width: 32px; min-height: 32px; background: none; border: 0; color: var(--ink-soft); cursor: pointer; }
66
- .visor__cap { margin: var(--ds-space-xs) 0 2px; font-family: var(--font-mono); font-size: var(--ds-text-2xs); letter-spacing: .12em; text-transform: uppercase; color: var(--ink-soft); }
124
+ .visor__sheet-title { margin: 0; font-size: var(--ds-text-xl); letter-spacing: var(--name-space); color: var(--ink); }
125
+ .visor__close { min-width: 32px; min-height: 32px; padding: 0; background: none; border: 0; color: var(--ink-soft); cursor: pointer; }
126
+ .visor__cap { margin: var(--ds-space-xs) 0 2px; font-size: var(--ds-text-xs); letter-spacing: var(--name-space); color: var(--ink-soft); }
67
127
  .visor__rows { list-style: none; margin: 0; padding: 0; }
68
128
  .visor__rows + .visor__rows { margin-top: var(--ds-space-xs); }
69
129
  .visor__row {
70
130
  display: flex; align-items: center; justify-content: space-between; gap: var(--ds-space-xs);
71
- box-sizing: border-box; width: 100%; min-height: 36px; padding: 0 2px;
131
+ box-sizing: border-box; width: 100%; min-height: 40px; padding: 0 2px;
72
132
  background: none; border: 0; border-top: var(--ds-line) solid var(--rule-soft);
73
- color: var(--ink); font: inherit; font-size: var(--ds-text-sm); text-align: left; text-decoration: none; cursor: pointer;
133
+ color: var(--ink); font: inherit; font-size: var(--ds-text-md); text-align: left; text-decoration: none; cursor: pointer;
74
134
  }
75
- .visor__row:hover { color: var(--accent-deep); }
135
+ .visor__row:hover { color: var(--accent-ink); }
76
136
  .visor__row--hint { cursor: default; color: var(--ink-soft); }
77
137
  .visor__row--hint:hover { color: var(--ink-soft); }
138
+ .visor__sheet .visor__key { color: var(--ink-soft); background: none; }
78
139
 
79
140
  /* a phone (640px and narrower): the rules live in style.css’s shared phone block, so the
80
141
  visor adds no breakpoint of its own (the design-count ratchet). */