@obvi/blueprint 1.1.1 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -176,14 +176,45 @@
176
176
  /* Diagonal hatch — drafting "section lining" for fenced / held /
177
177
  out-of-bounds regions. Faint ink lines over whatever fill the host
178
178
  element already has, so it reads as texture, not a second color.
179
- Theme-aware for free: it composes --bp-ink-faint, which flips in
180
- dark. --bp-hatch-gap controls the line pitch. */
179
+ Dark mode overrides --bp-hatch in [data-obvious-theme="dark"].
180
+ --bp-hatch-gap controls the line pitch. */
181
181
  --bp-hatch-gap: 7px;
182
182
  --bp-hatch: repeating-linear-gradient(
183
183
  -45deg,
184
184
  var(--bp-ink-faint) 0 var(--bp-stroke),
185
185
  oklch(0 0 0 / 0) var(--bp-stroke) var(--bp-hatch-gap)
186
186
  );
187
+ /* Drafting board — a faint dot-grid backdrop that marks INTERACTIVE
188
+ component surfaces (choice, preflight, choice-record, source, mock,
189
+ gallery): a second axis distinct from the diagonal --bp-hatch (which
190
+ means fenced / held / rejected). Dots read as an open working surface,
191
+ so the two textures never compete. --bp-board-gap is the grid pitch;
192
+ --bp-board the reusable image. The dot color rides on --bp-ink-faint;
193
+ light uses a stronger mix (55%) than dark (35%) — see the dark block. */
194
+ --bp-board-gap: 18px;
195
+ --bp-board-dot: color-mix(in oklch, var(--bp-ink-faint) 55%, oklch(0 0 0 / 0));
196
+ --bp-board: radial-gradient(
197
+ circle at center,
198
+ var(--bp-board-dot) 0 0.85px,
199
+ oklch(0 0 0 / 0) 0.85px
200
+ );
201
+ /* The board rides on a faintly tinted surface — one elevation step between
202
+ the desk (--bp-bg) and the sheet (--bp-paper) — so a dotted interactive
203
+ section reads as its own panel and the paper cards inside it lift off the
204
+ mat. Derived from the two surface tokens, so it tracks either theme (and
205
+ any host override of paper / bg) from this single definition. */
206
+ --bp-board-bg: color-mix(in oklch, var(--bp-paper) 60%, var(--bp-bg));
207
+ /* Footer strips on the mat (hint + reset): vertical breathing room and a
208
+ horizontal inset that lines up with the component content above.
209
+ --bp-board-footer-pad-x defaults to preflight question padding; choice
210
+ layouts reassign it to match .bp-choice__card inset. */
211
+ --bp-board-footer-pad-y: var(--bp-space-2);
212
+ --bp-board-footer-pad-x: var(--bp-space-4);
213
+ /* Single-surface interactive roots on the mat (tabs choice, preflight):
214
+ uniform inset + Obvious container radius so the paper card reads as a
215
+ decision surface on the dotted board. */
216
+ --bp-board-card-pad: var(--bp-space-4);
217
+ --bp-board-card-radius: var(--bp-radius-8);
187
218
  /* Modal scrim wash — darker than --bp-ink-soft so floated panels (search
188
219
  palette, lightbox, expanded mock) read clearly over the page. Always
189
220
  pair with --bp-hatch:
@@ -224,6 +255,7 @@
224
255
  --bp-text-body: 14px; --bp-lh-body: 20px; /* body copy */
225
256
  --bp-text-small: 13px; --bp-lh-small: 18px; /* small / captions */
226
257
  --bp-text-code: 12.5px; --bp-lh-code: 1.6; /* mono, harmonized to body */
258
+ --bp-lh-control: 1.3; /* tighter than reading text — sans control labels */
227
259
 
228
260
  /* 3-step monospace-label scale, ONE letter-spacing each */
229
261
  --bp-label-sm: 9px; --bp-label-sm-ls: 0.08em;
@@ -266,6 +298,32 @@
266
298
  --bp-radius-pill: 9999px;
267
299
  --bp-radius-round: 50%;
268
300
 
301
+ /* Obvious button palette — the interactive-control vocabulary. Buttons are
302
+ the one chrome surface that carries fill: primary (committed / CTA),
303
+ secondary (resting control), tertiary (quiet track / ghost fill), ghost
304
+ (text-only). Fills stay on the neutral scale (no hue) so figures keep the
305
+ blue monopoly. Each value consumes the live Obvious app variable
306
+ (--button-*) when a document is embedded in the dashboard, and otherwise
307
+ falls back to the OKLCH value from the app's colors.css. */
308
+ --bp-button-primary-bg: var(--button-primary-bg, oklch(0.1344 0 0));
309
+ --bp-button-primary-bg-hover: var(--button-primary-bg-hover, oklch(0.3012 0 0));
310
+ --bp-button-primary-bg-press: var(--button-primary-bg-press, oklch(0.36 0 0));
311
+ --bp-button-primary-fg: var(--button-primary-fg, oklch(1 0 0));
312
+ --bp-button-secondary-bg: var(--button-secondary-bg, oklch(1 0 0));
313
+ --bp-button-secondary-bg-hover: var(--button-secondary-bg-hover, oklch(0.9702 0 0));
314
+ --bp-button-secondary-bg-press: var(--button-secondary-bg-press, oklch(0.9461 0 0));
315
+ --bp-button-secondary-fg: var(--button-secondary-fg, oklch(0 0 0 / 0.8));
316
+ --bp-button-secondary-bd: var(--button-secondary-bd, oklch(0 0 0 / 0.08));
317
+ --bp-button-tertiary-bg: var(--button-tertiary-bg, oklch(0 0 0 / 0.04));
318
+ --bp-button-tertiary-bg-hover: var(--button-tertiary-bg-hover, oklch(0 0 0 / 0.08));
319
+ --bp-button-tertiary-fg: var(--button-tertiary-fg, oklch(0 0 0 / 0.64));
320
+ --bp-button-ghost-fg: var(--button-ghost-fg, oklch(0 0 0 / 0.4));
321
+ --bp-button-ghost-fg-hover: var(--button-ghost-fg-hover, oklch(0 0 0 / 0.64));
322
+ --bp-button-ghost-bg-hover: var(--button-ghost-bg-hover, oklch(0 0 0 / 0.04));
323
+ /* Lifted-border ring carried by a raised (selected) secondary control. */
324
+ --bp-button-lift: 0 0 2px 0 oklch(0 0 0 / 0.05),
325
+ 0 0 1px 0 oklch(0 0 0 / 0.05), 0 0 0 1px oklch(0 0 0 / 0.08);
326
+
269
327
  /* Section-eyebrow marker — the square that leads the "01 / 02" counter.
270
328
  Size is the block edge; gap is the space between it and the number. */
271
329
  --bp-marker-size: 10px;
@@ -354,6 +412,7 @@
354
412
  --bp-ink: var(--obvious-text-primary, oklch(1 0 0 / 0.92));
355
413
  --bp-ink-soft: oklch(1 0 0 / 0.4);
356
414
  --bp-ink-faint: oklch(1 0 0 / 0.16);
415
+ --bp-board-dot: color-mix(in oklch, var(--bp-ink-faint) 35%, oklch(0 0 0 / 0));
357
416
  --bp-highlight: oklch(1 0 0 / 0.14);
358
417
 
359
418
  /* Illustration accent (dark) — brighter blue holds on dark paper. */
@@ -365,7 +424,17 @@
365
424
  /* Neutral white-alpha panel fills over the dark paper. */
366
425
  --bp-fill-amb: oklch(1 0 0 / 0.04);
367
426
  --bp-fill-hi: oklch(1 0 0 / 0.08);
368
- --bp-scrim: oklch(1 0 0 / 0.58);
427
+ /* Scrim stays a black wash in dark mode too: a modal scrim must dim the
428
+ page behind a floated panel, not brighten it. White-alpha here washed
429
+ the whole overlay out. */
430
+ --bp-scrim: oklch(0 0 0 / 0.58);
431
+ /* Diagonal hatch (dark) — softer than --bp-ink-faint so scrims and
432
+ rejected-choice fills keep texture without brightening the wash. */
433
+ --bp-hatch: repeating-linear-gradient(
434
+ -45deg,
435
+ var(--bp-edge) 0 var(--bp-stroke),
436
+ oklch(0 0 0 / 0) var(--bp-stroke) var(--bp-hatch-gap)
437
+ );
369
438
  --bp-paper: var(--bp-gray-950);
370
439
  --bp-bg: oklch(0.15 0 0); /* the desk sits darker than the sheet, so the page lifts */
371
440
  --bp-edge: oklch(1 0 0 / 0.08);
@@ -374,6 +443,25 @@
374
443
  --bp-text-secondary: oklch(1 0 0 / 0.64);
375
444
  --bp-positive: oklch(0.74 0.15 150);
376
445
  --bp-positive-faint: oklch(0.34 0.07 150);
446
+
447
+ /* Obvious button palette (dark) — see the light block for the contract. */
448
+ --bp-button-primary-bg: var(--button-primary-bg, oklch(0.4091 0 0));
449
+ --bp-button-primary-bg-hover: var(--button-primary-bg-hover, oklch(0.4819 0 0));
450
+ --bp-button-primary-bg-press: var(--button-primary-bg-press, oklch(0.5795 0 0));
451
+ --bp-button-primary-fg: var(--button-primary-fg, oklch(1 0 0 / 0.92));
452
+ --bp-button-secondary-bg: var(--button-secondary-bg, oklch(0.3012 0 0));
453
+ --bp-button-secondary-bg-hover: var(--button-secondary-bg-hover, oklch(0.3407 0 0));
454
+ --bp-button-secondary-bg-press: var(--button-secondary-bg-press, oklch(0.4091 0 0));
455
+ --bp-button-secondary-fg: var(--button-secondary-fg, oklch(1 0 0 / 0.8));
456
+ --bp-button-secondary-bd: var(--button-secondary-bd, oklch(1 0 0 / 0.04));
457
+ --bp-button-tertiary-bg: var(--button-tertiary-bg, oklch(1 0 0 / 0.04));
458
+ --bp-button-tertiary-bg-hover: var(--button-tertiary-bg-hover, oklch(1 0 0 / 0.08));
459
+ --bp-button-tertiary-fg: var(--button-tertiary-fg, oklch(1 0 0 / 0.64));
460
+ --bp-button-ghost-fg: var(--button-ghost-fg, oklch(1 0 0 / 0.4));
461
+ --bp-button-ghost-fg-hover: var(--button-ghost-fg-hover, oklch(1 0 0 / 0.64));
462
+ --bp-button-ghost-bg-hover: var(--button-ghost-bg-hover, oklch(1 0 0 / 0.04));
463
+ --bp-button-lift: 0 0 2px 0 oklch(1 0 0 / 0.05),
464
+ 0 0 1px 0 oklch(1 0 0 / 0.05), 0 0 0 1px oklch(1 0 0 / 0.08);
377
465
  }
378
466
  }
379
467
 
@@ -1468,7 +1556,7 @@
1468
1556
  padding: var(--bp-space-2) var(--bp-space-3);
1469
1557
  background: var(--bp-ink);
1470
1558
  color: var(--bp-paper);
1471
- border-radius: var(--bp-radius-0);
1559
+ border-radius: var(--bp-radius-6);
1472
1560
  margin-bottom: var(--bp-space-3);
1473
1561
  }
1474
1562
  :where(.bp-choice:has(.bp-choice__commit:checked)) .bp-choice__verdict,
@@ -1528,10 +1616,9 @@
1528
1616
  border: 0;
1529
1617
  padding: 0;
1530
1618
  cursor: pointer;
1531
- font-family: var(--bp-mono);
1532
- font-size: var(--bp-label-md);
1533
- letter-spacing: var(--bp-label-md-ls);
1534
- text-transform: uppercase;
1619
+ font-family: var(--bp-sans);
1620
+ font-size: var(--bp-text-small);
1621
+ line-height: var(--bp-lh-control);
1535
1622
  color: var(--bp-text-secondary);
1536
1623
  text-decoration: underline dotted;
1537
1624
  text-underline-offset: 3px;
@@ -1554,37 +1641,50 @@
1554
1641
  color: var(--bp-paper);
1555
1642
  background: var(--bp-ink);
1556
1643
  padding: 2px 8px;
1644
+ border-radius: var(--bp-radius-pill);
1557
1645
  }
1558
1646
  :where(.bp-choice__tag--out) {
1559
1647
  color: var(--bp-ink);
1560
1648
  border: 1px solid var(--bp-ink-faint);
1561
1649
  padding: 1px 7px;
1650
+ border-radius: var(--bp-radius-pill);
1562
1651
  }
1563
1652
 
1564
1653
  /* ---- layout: tabs (preview drafts, then adopt) ------------------- */
1654
+ :where(.bp-choice--tabs) {
1655
+ padding: var(--bp-board-card-pad);
1656
+ border: 1px solid var(--bp-ink-line);
1657
+ border-radius: var(--bp-board-card-radius);
1658
+ overflow: hidden;
1659
+ }
1565
1660
  :where(.bp-choice--tabs) :where(.bp-choice__seg) {
1566
1661
  display: flex;
1567
1662
  flex-wrap: wrap;
1568
- gap: 0;
1569
- border: 1px solid var(--bp-ink-line);
1570
- border-radius: var(--bp-radius-0);
1571
- overflow: hidden;
1663
+ gap: 2px;
1664
+ padding: 2px;
1665
+ border: 0;
1666
+ border-radius: var(--bp-radius-pill);
1667
+ background: var(--bp-button-tertiary-bg);
1668
+ overflow: visible;
1572
1669
  margin: 0 0 var(--bp-space-3);
1573
1670
  width: fit-content;
1574
1671
  }
1575
1672
  :where(.bp-choice__seg-opt) {
1576
1673
  position: relative;
1577
1674
  cursor: pointer;
1578
- font-family: var(--bp-mono);
1579
- font-size: var(--bp-label-md);
1580
- letter-spacing: var(--bp-label-md-ls);
1581
- text-transform: uppercase;
1582
- color: var(--bp-text-secondary);
1675
+ font-family: var(--bp-sans);
1676
+ font-size: var(--bp-text-small);
1677
+ line-height: var(--bp-lh-control);
1678
+ color: var(--bp-button-ghost-fg);
1583
1679
  padding: 6px 14px;
1584
- border-right: 1px solid var(--bp-ink-line);
1680
+ border-radius: var(--bp-radius-pill);
1681
+ transition: background var(--bp-duration-fast) var(--bp-ease-out),
1682
+ color var(--bp-duration-fast) var(--bp-ease-out),
1683
+ box-shadow var(--bp-duration-fast) var(--bp-ease-out);
1585
1684
  }
1586
- :where(.bp-choice__seg-opt:last-child) {
1587
- border-right: 0;
1685
+ :where(.bp-choice__seg-opt:hover) {
1686
+ color: var(--bp-button-ghost-fg-hover);
1687
+ background: var(--bp-button-ghost-bg-hover);
1588
1688
  }
1589
1689
  :where(.bp-choice__seg-opt) :where(input) {
1590
1690
  position: absolute;
@@ -1592,8 +1692,9 @@
1592
1692
  pointer-events: none;
1593
1693
  }
1594
1694
  :where(.bp-choice__seg-opt:has(input:checked)) {
1595
- background: var(--bp-ink);
1596
- color: var(--bp-paper);
1695
+ background: var(--bp-button-secondary-bg);
1696
+ color: var(--bp-button-secondary-fg);
1697
+ box-shadow: var(--bp-button-lift);
1597
1698
  }
1598
1699
  :where(.bp-choice--tabs) :where(.bp-choice__panel) {
1599
1700
  display: none;
@@ -1606,18 +1707,19 @@
1606
1707
  align-items: center;
1607
1708
  gap: 8px;
1608
1709
  cursor: pointer;
1609
- border: 1px solid var(--bp-ink);
1610
- border-radius: var(--bp-radius-0);
1710
+ border: 1px solid var(--bp-button-secondary-bd);
1711
+ border-radius: var(--bp-radius-pill);
1611
1712
  padding: 6px 14px;
1612
- font-family: var(--bp-mono);
1613
- font-size: var(--bp-label-md);
1614
- letter-spacing: var(--bp-label-md-ls);
1615
- text-transform: uppercase;
1616
- color: var(--bp-ink);
1617
- background: var(--bp-paper);
1713
+ font-family: var(--bp-sans);
1714
+ font-size: var(--bp-text-small);
1715
+ line-height: var(--bp-lh-control);
1716
+ color: var(--bp-button-secondary-fg);
1717
+ background: var(--bp-button-secondary-bg);
1718
+ transition: background var(--bp-duration-fast) var(--bp-ease-out),
1719
+ color var(--bp-duration-fast) var(--bp-ease-out);
1618
1720
  }
1619
1721
  :where(.bp-choice__adopt:hover) {
1620
- background: var(--bp-fill-hi);
1722
+ background: var(--bp-button-secondary-bg-hover);
1621
1723
  }
1622
1724
  :where(.bp-choice__adopt) :where(input) {
1623
1725
  position: absolute;
@@ -1628,13 +1730,14 @@
1628
1730
  border: 1px solid var(--bp-ink);
1629
1731
  background: var(--bp-fill-amb);
1630
1732
  padding: var(--bp-space-3);
1631
- margin-left: calc(-1 * var(--bp-space-3));
1632
- margin-right: calc(-1 * var(--bp-space-3));
1633
- border-radius: var(--bp-radius-0);
1733
+ margin-left: calc(-1 * var(--bp-board-card-pad));
1734
+ margin-right: calc(-1 * var(--bp-board-card-pad));
1735
+ border-radius: var(--bp-radius-6);
1634
1736
  }
1635
1737
  :where(.bp-choice__panel:has(.bp-choice__commit:checked)) :where(.bp-choice__adopt) {
1636
- background: var(--bp-ink);
1637
- color: var(--bp-paper);
1738
+ border-color: var(--bp-button-primary-bg);
1739
+ background: var(--bp-button-primary-bg);
1740
+ color: var(--bp-button-primary-fg);
1638
1741
  }
1639
1742
 
1640
1743
  /* ---- layout: stack (all cards visible) --------------------------- */
@@ -1646,7 +1749,7 @@
1646
1749
  display: block;
1647
1750
  position: relative;
1648
1751
  border: 1px solid var(--bp-edge);
1649
- border-radius: var(--bp-radius-0);
1752
+ border-radius: var(--bp-radius-6);
1650
1753
  padding: var(--bp-space-3);
1651
1754
  cursor: pointer;
1652
1755
  background: var(--bp-paper);
@@ -1734,7 +1837,7 @@
1734
1837
  position: relative;
1735
1838
  cursor: pointer;
1736
1839
  border: 1px solid var(--bp-edge);
1737
- border-radius: var(--bp-radius-0);
1840
+ border-radius: var(--bp-radius-6);
1738
1841
  overflow: hidden;
1739
1842
  background: var(--bp-paper);
1740
1843
  }
@@ -1789,18 +1892,32 @@
1789
1892
 
1790
1893
  :where(.bp-choice__compare) {
1791
1894
  margin-top: var(--bp-space-3);
1895
+ /* Override the base <details> inset (0 var(--bp-space-3) padding + a 2px
1896
+ left border) so the summary bar and disclosed body span the full card
1897
+ width — the summary and body carry their own padding. */
1898
+ padding: 0;
1792
1899
  border: 1px solid var(--bp-edge);
1793
- border-radius: var(--bp-radius-0);
1900
+ border-radius: var(--bp-radius-6);
1901
+ overflow: hidden;
1902
+ }
1903
+ :where(.bp-choice__compare[open]) {
1904
+ padding-bottom: 0;
1794
1905
  }
1795
1906
  :where(.bp-choice__compare > summary) {
1796
1907
  cursor: pointer;
1797
1908
  list-style: none;
1798
- padding: var(--bp-space-2) var(--bp-space-3);
1799
- font-family: var(--bp-mono);
1800
- font-size: var(--bp-label-md);
1801
- letter-spacing: var(--bp-label-md-ls);
1802
- text-transform: uppercase;
1803
- color: var(--bp-text-secondary);
1909
+ padding: var(--bp-space-3);
1910
+ font-family: var(--bp-sans);
1911
+ font-size: var(--bp-text-small);
1912
+ line-height: var(--bp-lh-control);
1913
+ color: var(--bp-button-ghost-fg);
1914
+ background: var(--bp-button-tertiary-bg);
1915
+ transition: background var(--bp-duration-fast) var(--bp-ease-out),
1916
+ color var(--bp-duration-fast) var(--bp-ease-out);
1917
+ }
1918
+ :where(.bp-choice__compare > summary:hover) {
1919
+ background: var(--bp-button-tertiary-bg-hover);
1920
+ color: var(--bp-button-ghost-fg-hover);
1804
1921
  }
1805
1922
  :where(.bp-choice__compare > summary)::-webkit-details-marker {
1806
1923
  display: none;
@@ -1809,11 +1926,17 @@
1809
1926
  padding: var(--bp-space-3);
1810
1927
  border-top: 1px solid var(--bp-edge);
1811
1928
  }
1929
+ /* The slot content is usually a <dl>; drop its document margins so the
1930
+ disclosed body keeps one uniform inset (vertical matches horizontal). */
1931
+ :where(.bp-choice__compare-body) :where(dl) {
1932
+ margin: 0;
1933
+ gap: var(--bp-space-2) var(--bp-space-3);
1934
+ }
1812
1935
 
1813
1936
  /* ---- Pre-flight (decisions before drafting) ---------------------- */
1814
1937
  :where(.bp-preflight) {
1815
1938
  border: 1px solid var(--bp-ink-line);
1816
- border-radius: var(--bp-radius-0);
1939
+ border-radius: var(--bp-board-card-radius);
1817
1940
  overflow: hidden;
1818
1941
  margin: var(--bp-space-4) 0;
1819
1942
  }
@@ -1842,23 +1965,9 @@
1842
1965
  }
1843
1966
  :where(.bp-preflight__q) {
1844
1967
  counter-increment: bp-preflight-q;
1845
- padding: var(--bp-space-3) var(--bp-space-3) var(--bp-space-3) calc(var(--bp-space-6) + 4px);
1846
- position: relative;
1968
+ padding: var(--bp-space-4);
1847
1969
  border-bottom: 1px solid var(--bp-edge);
1848
1970
  }
1849
- :where(.bp-preflight__q::before) {
1850
- content: counter(bp-preflight-q, decimal-leading-zero);
1851
- position: absolute;
1852
- left: var(--bp-space-3);
1853
- top: var(--bp-space-3);
1854
- font-family: var(--bp-mono);
1855
- font-size: var(--bp-label-lg);
1856
- letter-spacing: 0.08em;
1857
- color: var(--bp-ink-soft);
1858
- }
1859
- :where(.bp-preflight__q:has(input:checked)::before) {
1860
- color: var(--bp-ink);
1861
- }
1862
1971
  :where(.bp-preflight__prompt) {
1863
1972
  font-family: var(--bp-sans);
1864
1973
  font-weight: var(--bp-weight-strong);
@@ -1868,6 +1977,16 @@
1868
1977
  align-items: baseline;
1869
1978
  gap: var(--bp-space-2);
1870
1979
  }
1980
+ :where(.bp-preflight__prompt::before) {
1981
+ content: counter(bp-preflight-q, decimal-leading-zero);
1982
+ font-family: var(--bp-mono);
1983
+ font-size: var(--bp-label-lg);
1984
+ letter-spacing: 0.08em;
1985
+ color: var(--bp-ink-soft);
1986
+ }
1987
+ :where(.bp-preflight__q:has(input:checked)) :where(.bp-preflight__prompt::before) {
1988
+ color: var(--bp-ink);
1989
+ }
1871
1990
  :where(.bp-preflight__kind) {
1872
1991
  font-family: var(--bp-mono);
1873
1992
  font-size: var(--bp-label-sm);
@@ -1877,11 +1996,11 @@
1877
1996
  font-weight: var(--bp-weight-body);
1878
1997
  }
1879
1998
  :where(.bp-preflight__resolved) {
1880
- display: none;
1999
+ visibility: hidden;
1881
2000
  margin-left: auto;
1882
2001
  }
1883
2002
  :where(.bp-preflight__q:has(input:checked)) :where(.bp-preflight__resolved) {
1884
- display: inline-flex;
2003
+ visibility: visible;
1885
2004
  }
1886
2005
  :where(.bp-preflight__chips) {
1887
2006
  display: flex;
@@ -1894,23 +2013,31 @@
1894
2013
  align-items: center;
1895
2014
  gap: 7px;
1896
2015
  cursor: pointer;
1897
- border: 1px solid var(--bp-ink-faint);
1898
- border-radius: var(--bp-radius-0);
2016
+ border: 1px solid var(--bp-button-secondary-bd);
2017
+ border-radius: var(--bp-radius-pill);
1899
2018
  padding: 5px 12px;
1900
2019
  font-size: var(--bp-text-small);
1901
- background: var(--bp-paper);
2020
+ color: var(--bp-button-secondary-fg);
2021
+ background: oklch(0 0 0 / 0);
2022
+ transition: background var(--bp-duration-fast) var(--bp-ease-out),
2023
+ color var(--bp-duration-fast) var(--bp-ease-out),
2024
+ border-color var(--bp-duration-fast) var(--bp-ease-out);
1902
2025
  }
1903
2026
  :where(.bp-preflight__chip:hover) {
1904
- border-color: var(--bp-ink-line);
2027
+ border-color: var(--bp-button-secondary-bd);
2028
+ background: var(--bp-button-tertiary-bg-hover);
1905
2029
  }
1906
2030
  :where(.bp-preflight__chip) :where(input) {
1907
2031
  accent-color: var(--bp-ink);
1908
2032
  margin: 0;
1909
2033
  }
1910
2034
  :where(.bp-preflight__chip:has(input:checked)) {
1911
- background: var(--bp-ink);
1912
- color: var(--bp-paper);
1913
- border-color: var(--bp-ink);
2035
+ background: var(--bp-button-primary-bg);
2036
+ color: var(--bp-button-primary-fg);
2037
+ border-color: var(--bp-button-primary-bg);
2038
+ }
2039
+ :where(.bp-preflight__chip:has(input:checked)) :where(input) {
2040
+ accent-color: var(--bp-button-primary-fg);
1914
2041
  }
1915
2042
  :where(.bp-preflight__gate) {
1916
2043
  margin: var(--bp-space-3);
@@ -1939,17 +2066,22 @@
1939
2066
  display: inline-flex;
1940
2067
  align-items: center;
1941
2068
  gap: 8px;
1942
- border: 1px solid var(--bp-ink);
1943
- border-radius: var(--bp-radius-0);
2069
+ border: 1px solid var(--bp-button-primary-bg);
2070
+ border-radius: var(--bp-radius-pill);
1944
2071
  padding: 8px 16px;
1945
- font-family: var(--bp-mono);
1946
- font-size: var(--bp-label-md);
1947
- letter-spacing: var(--bp-label-md-ls);
1948
- text-transform: uppercase;
1949
- background: var(--bp-ink);
1950
- color: var(--bp-paper);
2072
+ font-family: var(--bp-sans);
2073
+ font-size: var(--bp-text-small);
2074
+ line-height: var(--bp-lh-control);
2075
+ background: var(--bp-button-primary-bg);
2076
+ color: var(--bp-button-primary-fg);
1951
2077
  cursor: pointer;
1952
2078
  margin-top: var(--bp-space-2);
2079
+ transition: background var(--bp-duration-fast) var(--bp-ease-out),
2080
+ border-color var(--bp-duration-fast) var(--bp-ease-out);
2081
+ }
2082
+ :where(.bp-preflight__draft:hover) {
2083
+ background: var(--bp-button-primary-bg-hover);
2084
+ border-color: var(--bp-button-primary-bg-hover);
1953
2085
  }
1954
2086
  :where(.bp-preflight__footer) {
1955
2087
  display: flex;
@@ -1962,17 +2094,45 @@
1962
2094
  :where(.bp-choice-record) {
1963
2095
  margin: var(--bp-space-4) 0;
1964
2096
  }
1965
- :where(.bp-choice-record__row) {
2097
+ /* One Obvious container card per row: the host carries border and paper
2098
+ fill; radius + overflow come from the [data-bp-rendered] mat rule above. */
2099
+ :where(bp-choice-record-row) {
2100
+ display: block;
1966
2101
  border: 1px solid var(--bp-edge);
1967
- border-radius: var(--bp-radius-0);
2102
+ background-color: var(--bp-paper);
2103
+ }
2104
+ :where(bp-choice-record-row + bp-choice-record-row) {
2105
+ margin-top: var(--bp-space-2);
2106
+ }
2107
+ :where(.bp-choice-record__row) {
2108
+ margin: 0;
2109
+ border: 0;
2110
+ border-radius: 0;
2111
+ background-color: oklch(0 0 0 / 0);
1968
2112
  padding: var(--bp-space-2) var(--bp-space-3);
1969
2113
  display: grid;
1970
2114
  grid-template-columns: minmax(8rem, 14rem) 1fr auto;
1971
2115
  gap: var(--bp-space-2) var(--bp-space-3);
1972
2116
  align-items: baseline;
1973
2117
  }
1974
- :where(.bp-choice-record__row + .bp-choice-record__row) {
1975
- margin-top: var(--bp-space-2);
2118
+ :where(bp-choice-record-row:has(.bp-choice__compare)) :where(.bp-choice-record__row) {
2119
+ border-bottom: 1px solid var(--bp-edge);
2120
+ }
2121
+ /* Compare sits flush in the card: drop the base compare top-margin and the
2122
+ standalone compare card chrome (border / radius) used in gallery layout.
2123
+ Wins over the base :where(.bp-choice__compare) rule by source order — no
2124
+ !important, since the record row no longer carries a JS inline margin. */
2125
+ :where(bp-choice-record-row) :where(.bp-choice__compare) {
2126
+ margin: 0;
2127
+ border: 0;
2128
+ border-radius: 0;
2129
+ padding: 0;
2130
+ }
2131
+ :where(bp-choice-record-row) :where(.bp-choice__compare > summary) {
2132
+ background-color: var(--bp-fill-amb);
2133
+ }
2134
+ :where(bp-choice-record-row) :where(.bp-choice__compare > summary:hover) {
2135
+ background-color: var(--bp-fill-hi);
1976
2136
  }
1977
2137
  :where(.bp-choice-record__row) :where(dt) {
1978
2138
  font-family: var(--bp-mono);
@@ -2364,6 +2524,46 @@
2364
2524
  text-transform: uppercase;
2365
2525
  color: var(--bp-text-secondary);
2366
2526
  }
2527
+ :where(.bp-cite-actions) {
2528
+ display: flex;
2529
+ align-items: center;
2530
+ gap: var(--bp-space-2);
2531
+ flex: 0 0 auto;
2532
+ }
2533
+ /* Open-in-pane action. Hidden unless a host advertises a side pane, so the
2534
+ standalone popover (no pane host) never shows a dead control. */
2535
+ :where(.bp-cite-expand) {
2536
+ display: none;
2537
+ align-items: center;
2538
+ justify-content: center;
2539
+ width: 22px;
2540
+ height: 22px;
2541
+ margin: 0;
2542
+ padding: 0;
2543
+ border: var(--bp-stroke) solid var(--bp-edge);
2544
+ border-radius: var(--bp-radius-2);
2545
+ background: var(--bp-fill-amb);
2546
+ color: var(--bp-text-secondary);
2547
+ cursor: pointer;
2548
+ transition:
2549
+ color var(--bp-duration-fast) var(--bp-ease-out),
2550
+ border-color var(--bp-duration-fast) var(--bp-ease-out),
2551
+ background-color var(--bp-duration-fast) var(--bp-ease-out);
2552
+ }
2553
+ :where(html[data-bp-cite-pane] .bp-cite-expand) {
2554
+ display: inline-flex;
2555
+ }
2556
+ :where(.bp-cite-expand:hover),
2557
+ :where(.bp-cite-expand:focus-visible) {
2558
+ color: var(--bp-ink);
2559
+ border-color: var(--bp-ink-line);
2560
+ background: var(--bp-paper);
2561
+ }
2562
+ :where(.bp-cite-expand svg) {
2563
+ display: block;
2564
+ width: 13px;
2565
+ height: 13px;
2566
+ }
2367
2567
  /* Code block inside the card — base treatment; blueprint-code.css makes
2368
2568
  the highlighted variant sit flush and rounds the lower corners. */
2369
2569
  :where(.bp-cite-pop pre) {
@@ -4008,6 +4208,119 @@
4008
4208
  }
4009
4209
  }
4010
4210
 
4211
+ /* =====================================================================
4212
+ @layer components — drafting board: interactive surfaces sit on a dot
4213
+ mat. Last in the layer so its surface overrides win by source order.
4214
+ ===================================================================== */
4215
+ @layer components {
4216
+ /* The interactive component family (choice, preflight, choice-record,
4217
+ source, mock, gallery) gets a dot-grid backdrop + a padding "mat", so a
4218
+ live/interactive block reads as a working surface distinct from settled
4219
+ prose — a second axis beside the Obvious pill vocabulary, one that marks
4220
+ even the non-decision interactive surfaces. The host is the mat (board
4221
+ shows in its padding and any internal gaps); the rendered root inside is
4222
+ the solid card. */
4223
+ :where(bp-choice, bp-preflight, bp-choice-record, bp-source, bp-mock, bp-gallery) {
4224
+ display: block;
4225
+ margin: var(--bp-space-4) 0;
4226
+ padding: var(--bp-space-5);
4227
+ background-color: var(--bp-board-bg);
4228
+ background-image: var(--bp-board);
4229
+ background-size: var(--bp-board-gap) var(--bp-board-gap);
4230
+ }
4231
+ /* Once upgraded, every dotted-mat host rounds to the Obvious container
4232
+ radius. data-bp-rendered is the uniform runtime hook — all interactive
4233
+ hosts set it on connect. bp-rationale also carries the flag but is not
4234
+ a mat host and is excluded from this selector list. */
4235
+ :where(
4236
+ bp-choice,
4237
+ bp-preflight,
4238
+ bp-choice-record,
4239
+ bp-choice-record-row,
4240
+ bp-source,
4241
+ bp-mock,
4242
+ bp-gallery
4243
+ )[data-bp-rendered="1"] {
4244
+ border-radius: var(--bp-radius-8);
4245
+ overflow: hidden;
4246
+ }
4247
+ /* The rendered root owns no outer margin now — the host carries document
4248
+ rhythm — so the mat reads even on all four sides. */
4249
+ :where(.bp-choice, .bp-choice-record, .bp-source, .bp-mock, .bp-gallery),
4250
+ :where(bp-preflight) :where(.bp-preflight) {
4251
+ margin: 0;
4252
+ }
4253
+ /* Expanded mock floats fullscreen (position: fixed): collapse the host so
4254
+ no empty dotted mat is left behind in the document flow. */
4255
+ :where(bp-mock:has(.bp-mock.is-expanded)) {
4256
+ margin: 0;
4257
+ padding: 0;
4258
+ }
4259
+
4260
+ /* Single-surface specimens read as ONE continuous paper card on the mat;
4261
+ give each an opaque paper fill (source inherits a translucent
4262
+ --bp-fill-amb from <details>, which would let the dots bleed through). */
4263
+ :where(.bp-choice--tabs, .bp-preflight, .bp-source, .bp-gallery) {
4264
+ background-color: var(--bp-paper);
4265
+ }
4266
+
4267
+ /* Multi-card layouts (stack / gallery / resolved / record) stay transparent
4268
+ so the host board shows in their gaps; each card carries its own paper.
4269
+ Chosen / resolved cards swap paper for a translucent fill — restore an
4270
+ opaque paper base so the board can't bleed through the card. */
4271
+ :where(.bp-choice__card:has(.bp-choice__pick:checked)),
4272
+ :where(.bp-choice__card[data-resolved]) {
4273
+ background-color: var(--bp-paper);
4274
+ background-image: linear-gradient(var(--bp-fill-amb), var(--bp-fill-amb));
4275
+ }
4276
+ /* Rejected / set-aside cards use opacity, so the whole card (incl. its
4277
+ hatch) goes translucent and the board bleeds through. Keep the set-aside
4278
+ read via hatch + tag, not element opacity. */
4279
+ :where(
4280
+ .bp-choice--stack:has(.bp-choice__pick:checked)
4281
+ .bp-choice__card:not(:has(.bp-choice__pick:checked)),
4282
+ .bp-choice--resolved .bp-choice__card:not([data-resolved])
4283
+ ) {
4284
+ opacity: 1;
4285
+ background-color: var(--bp-paper);
4286
+ background-image: var(--bp-hatch);
4287
+ }
4288
+ :where(
4289
+ .bp-choice--gallery:has(.bp-choice__pick:checked)
4290
+ .bp-choice__mock:not(:has(.bp-choice__pick:checked))
4291
+ ) {
4292
+ opacity: 1;
4293
+ }
4294
+ :where(
4295
+ .bp-choice--gallery:has(.bp-choice__pick:checked)
4296
+ .bp-choice__mock:not(:has(.bp-choice__pick:checked))
4297
+ .bp-choice__mock-frame
4298
+ ) {
4299
+ background-color: var(--bp-paper);
4300
+ background-image: var(--bp-hatch);
4301
+ }
4302
+
4303
+ /* The compare disclosure sits between transparent siblings (gallery /
4304
+ record); make it an opaque paper card so the dots stop at its edge. */
4305
+ :where(.bp-choice__compare) {
4306
+ background-color: var(--bp-paper);
4307
+ }
4308
+
4309
+ /* Action footers (hint + reset): machine-voice mono directly on the dots is
4310
+ hard to read. A paper strip with a top hairline keeps the gap above as
4311
+ board; horizontal padding matches the content inset above. Tabs already
4312
+ sit on their own paper panel, so skip them. */
4313
+ :where(.bp-choice--stack, .bp-choice--gallery, .bp-choice--resolved) :where(.bp-choice__actions),
4314
+ :where(.bp-preflight__footer) {
4315
+ background-color: var(--bp-paper);
4316
+ padding: var(--bp-board-footer-pad-y) var(--bp-board-footer-pad-x);
4317
+ border-top: var(--bp-stroke) solid var(--bp-edge);
4318
+ }
4319
+ :where(.bp-choice--stack, .bp-choice--gallery, .bp-choice--resolved) :where(.bp-choice__actions) {
4320
+ --bp-board-footer-pad-x: var(--bp-space-3);
4321
+ }
4322
+ }
4323
+
4011
4324
  /* =====================================================================
4012
4325
  @layer utilities — last-resort single-purpose helpers + responsive
4013
4326
  ===================================================================== */
@@ -4379,7 +4692,7 @@ body > .site-nav .site-nav__theme:hover {
4379
4692
  read as one control family (border, radius, surface + hover/focus states). */
4380
4693
  .sidebar-field {
4381
4694
  border: 1px solid var(--bp-edge);
4382
- border-radius: var(--bp-radius-6, 6px);
4695
+ border-radius: var(--bp-radius-pill);
4383
4696
  background: var(--bp-paper);
4384
4697
  /* Hover-only color motion — idle fields snap on theme flip so the root
4385
4698
  view-transition crossfade isn't fighting per-field token tweens. */
@@ -4968,7 +5281,7 @@ body > .site-nav .site-nav__theme:hover {
4968
5281
  height: var(--bp-theme-toggle-height);
4969
5282
  padding: 2px;
4970
5283
  border: 1px solid var(--bp-edge);
4971
- border-radius: var(--bp-radius-6, 6px);
5284
+ border-radius: var(--bp-radius-pill);
4972
5285
  background: var(--bp-fill-amb);
4973
5286
  color: var(--bp-text-secondary);
4974
5287
  cursor: pointer;
@@ -4994,7 +5307,7 @@ body > .site-nav .site-nav__theme:hover {
4994
5307
  width: calc(var(--bp-theme-toggle-height) - 6px);
4995
5308
  height: calc(var(--bp-theme-toggle-height) - 6px);
4996
5309
  border: 1px solid var(--bp-ink-line);
4997
- border-radius: var(--bp-radius-4, 4px);
5310
+ border-radius: var(--bp-radius-round);
4998
5311
  background: var(--bp-paper);
4999
5312
  box-shadow: 0 1px 2px oklch(0 0 0 / 0.06);
5000
5313
  pointer-events: none;
@@ -5042,7 +5355,7 @@ body > .site-nav .site-nav__theme:hover {
5042
5355
  height: var(--bp-sidebar-toggle-size);
5043
5356
  padding: 0;
5044
5357
  border: 1px solid var(--bp-edge);
5045
- border-radius: var(--bp-radius-6, 6px);
5358
+ border-radius: var(--bp-radius-pill);
5046
5359
  background: var(--bp-fill-amb);
5047
5360
  color: var(--bp-text-secondary);
5048
5361
  cursor: pointer;
@@ -5177,7 +5490,7 @@ body > .site-nav .site-nav__theme:hover {
5177
5490
 
5178
5491
  /* Fade scrim above the footer: the TOC scrolls out beneath it (z below the
5179
5492
  footer controls), with a solid bottom band backing the footer. */
5180
- .bp-sidebar::after {
5493
+ #bp-contents-rail::after {
5181
5494
  content: "";
5182
5495
  position: fixed;
5183
5496
  left: 0;
@@ -5192,7 +5505,7 @@ body > .site-nav .site-nav__theme:hover {
5192
5505
  /* Radial scrim around the corner toggle: the TOC dissolves in a circle that
5193
5506
  radiates from the icon as entries scroll up beneath it. The box is large
5194
5507
  enough to hold the gradient's outer radius; transparent beyond it. */
5195
- .bp-sidebar::before {
5508
+ #bp-contents-rail::before {
5196
5509
  content: "";
5197
5510
  position: fixed;
5198
5511
  top: 0;
@@ -5230,3 +5543,198 @@ body > .site-nav .site-nav__theme:hover {
5230
5543
  display: none;
5231
5544
  }
5232
5545
  }
5546
+
5547
+ /* ---------------------------------------------------------------------------
5548
+ Cited-source side pane
5549
+ ---------------------------------------------------------------------------
5550
+ The host surface a <bp-cite> popover promotes its source into (the "open in
5551
+ side pane" action). It is a right COLUMN, not an overlay: opening reflows the
5552
+ sheet left to reclaim a column inside the desk frame, and the pane's
5553
+ full-height left border is the crosshair divider — the same --bp-edge
5554
+ hairline as the frame rules. No scrim; the document stays interactive beside
5555
+ it. Built and toggled by blueprint.js (wireCitePane); reuses the merged
5556
+ detail-pane shell. */
5557
+ :root {
5558
+ --bp-cite-pane-w: min(480px, 78vw);
5559
+ --bp-cite-pane-swap-shift: var(--bp-space-3);
5560
+ }
5561
+
5562
+ /* Reflow the sheet to open the column. The margin transition is supplied by
5563
+ the bp-sidebar-animate rule above (added one frame after paint), so opening
5564
+ animates while first paint never does — the pane is always closed on load. */
5565
+ html[data-bp-document]:has(.bp-cite-pane.is-open) main {
5566
+ margin-right: calc(var(--bp-shell-inset-right) + var(--bp-cite-pane-w));
5567
+ }
5568
+
5569
+ /* Clip port stops at the right frame rule so the parked pane adds no page
5570
+ scroll. Sits above the desk masks but below the frame rules. */
5571
+ .bp-cite-pane-port {
5572
+ position: fixed;
5573
+ top: 0;
5574
+ left: 0;
5575
+ bottom: 0;
5576
+ right: var(--bp-shell-inset-right, var(--bp-space-4));
5577
+ z-index: calc(var(--bp-shell-mask-z, 150) + 10);
5578
+ overflow: hidden;
5579
+ pointer-events: none;
5580
+ }
5581
+
5582
+ .bp-cite-pane {
5583
+ position: absolute;
5584
+ top: var(--bp-shell-inset-top, var(--bp-space-4));
5585
+ bottom: var(--bp-shell-inset-block, var(--bp-space-4));
5586
+ right: 0;
5587
+ width: var(--bp-cite-pane-w);
5588
+ display: flex;
5589
+ flex-direction: column;
5590
+ background: var(--bp-paper);
5591
+ border-left: var(--bp-stroke) solid var(--bp-edge);
5592
+ /* parked just past the clip so it travels exactly its own width to open */
5593
+ transform: translateX(100%);
5594
+ /* ease-in-out matches the shell push so the divider moves as one boundary */
5595
+ transition: transform var(--bp-duration-slow) var(--bp-ease-in-out);
5596
+ pointer-events: auto;
5597
+ }
5598
+ .bp-cite-pane.is-open {
5599
+ transform: translateX(0);
5600
+ }
5601
+ .bp-cite-pane:focus-visible {
5602
+ outline: none;
5603
+ }
5604
+
5605
+ .bp-cite-pane__head {
5606
+ position: relative;
5607
+ padding:
5608
+ var(--bp-sidebar-chrome-gap)
5609
+ var(--bp-sidebar-chrome-gap)
5610
+ var(--bp-sidebar-chrome-gap)
5611
+ var(--bp-space-4);
5612
+ border-bottom: var(--bp-stroke) solid var(--bp-edge);
5613
+ }
5614
+ .bp-cite-pane__heading {
5615
+ display: flex;
5616
+ flex-direction: column;
5617
+ gap: var(--bp-space-1);
5618
+ min-width: 0;
5619
+ padding-right: calc(
5620
+ var(--bp-sidebar-toggle-size) + var(--bp-sidebar-chrome-gap)
5621
+ );
5622
+ }
5623
+ .bp-cite-pane__eyebrow {
5624
+ font-family: var(--bp-mono);
5625
+ font-size: var(--bp-label-md);
5626
+ letter-spacing: var(--bp-label-md-ls);
5627
+ text-transform: uppercase;
5628
+ color: var(--bp-text-secondary);
5629
+ }
5630
+ /* The locator the source was opened from — scrolls back to the citation. */
5631
+ .bp-cite-pane__loc {
5632
+ display: block;
5633
+ width: 100%;
5634
+ margin: 0;
5635
+ padding: 0;
5636
+ border: 0;
5637
+ background: none;
5638
+ text-align: left;
5639
+ font-family: var(--bp-mono);
5640
+ font-size: var(--bp-text-small);
5641
+ line-height: var(--bp-lh-body);
5642
+ color: var(--bp-text);
5643
+ white-space: nowrap;
5644
+ overflow: hidden;
5645
+ text-overflow: ellipsis;
5646
+ cursor: pointer;
5647
+ text-decoration: underline;
5648
+ text-decoration-color: var(--bp-ink-line);
5649
+ text-underline-offset: 0.18em;
5650
+ transition:
5651
+ color var(--bp-duration-fast) var(--bp-ease-out),
5652
+ text-decoration-color var(--bp-duration-fast) var(--bp-ease-out);
5653
+ }
5654
+ .bp-cite-pane__loc:hover,
5655
+ .bp-cite-pane__loc:focus-visible {
5656
+ color: var(--bp-text);
5657
+ text-decoration-color: var(--bp-text);
5658
+ }
5659
+ .bp-cite-pane__loc[hidden] {
5660
+ display: none;
5661
+ }
5662
+ .bp-cite-pane__close {
5663
+ position: absolute;
5664
+ top: var(--bp-sidebar-chrome-gap);
5665
+ right: var(--bp-sidebar-chrome-gap);
5666
+ display: inline-flex;
5667
+ align-items: center;
5668
+ justify-content: center;
5669
+ width: var(--bp-sidebar-toggle-size);
5670
+ height: var(--bp-sidebar-toggle-size);
5671
+ padding: 0;
5672
+ border: var(--bp-stroke) solid var(--bp-edge);
5673
+ border-radius: var(--bp-radius-pill);
5674
+ background: var(--bp-fill-amb);
5675
+ color: var(--bp-text-secondary);
5676
+ cursor: pointer;
5677
+ transition:
5678
+ border-color var(--bp-duration-fast) var(--bp-ease-out),
5679
+ background-color var(--bp-duration-fast) var(--bp-ease-out),
5680
+ color var(--bp-duration-fast) var(--bp-ease-out);
5681
+ }
5682
+ .bp-cite-pane__close:hover {
5683
+ border-color: var(--bp-ink-line);
5684
+ background: var(--bp-paper);
5685
+ color: var(--bp-ink);
5686
+ }
5687
+ .bp-cite-pane__close svg {
5688
+ display: block;
5689
+ width: 16px;
5690
+ height: 16px;
5691
+ }
5692
+
5693
+ /* The body owns vertical scroll; its content sizes to itself so a short
5694
+ snippet keeps a short card instead of a column-tall empty box. */
5695
+ .bp-cite-pane__body {
5696
+ flex: 1;
5697
+ min-height: 0;
5698
+ overflow-y: auto;
5699
+ overscroll-behavior: contain;
5700
+ padding: var(--bp-space-4);
5701
+ }
5702
+ /* Content swap when promoting another citation while the pane is open: the
5703
+ pane holds, only the source crossfades to the right. */
5704
+ .bp-cite-pane__swap {
5705
+ transition:
5706
+ opacity var(--bp-duration-normal) var(--bp-ease-out),
5707
+ transform var(--bp-duration-normal) var(--bp-ease-out);
5708
+ }
5709
+ .bp-cite-pane__swap.is-leaving {
5710
+ opacity: 0;
5711
+ transform: translateX(var(--bp-cite-pane-swap-shift));
5712
+ }
5713
+ /* JS mount point for the cloned <pre>. Visual treatment lives in
5714
+ blueprint-code.css (full highlighted-block + accent bar). Margin is cleared
5715
+ here (not :where) so it beats the base-layer :where(pre) rhythm margin and
5716
+ the theme's margin-block — document specimens outside the pane are untouched. */
5717
+ .bp-cite-pane__source {
5718
+ min-width: 0;
5719
+ }
5720
+ .bp-cite-pane__source pre {
5721
+ margin: 0;
5722
+ margin-block: 0;
5723
+ }
5724
+
5725
+ /* Below the rail's fixed breakpoint the desk frame flattens; let the pane fill
5726
+ the viewport edge-to-edge and drop the reflow (the sheet goes static). */
5727
+ @media (max-width: 700px) {
5728
+ html[data-bp-document]:has(.bp-cite-pane.is-open) main {
5729
+ margin-right: 0;
5730
+ }
5731
+ :root {
5732
+ --bp-cite-pane-w: min(420px, 92vw);
5733
+ }
5734
+ }
5735
+
5736
+ @media print {
5737
+ .bp-cite-pane-port {
5738
+ display: none;
5739
+ }
5740
+ }