@obvi/blueprint 1.0.10 → 1.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.
- package/README.md +14 -436
- package/THIRD_PARTY_NOTICES.md +27 -0
- package/dist/blueprint-choices.js +64 -4
- package/dist/blueprint.css +2636 -611
- package/dist/blueprint.js +2473 -35
- package/dist/code-highlighting/blueprint-code.css +12 -7
- package/package.json +7 -4
package/dist/blueprint.css
CHANGED
|
@@ -182,8 +182,14 @@
|
|
|
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
|
+
/* Modal scrim wash — darker than --bp-ink-soft so floated panels (search
|
|
188
|
+
palette, lightbox, expanded mock) read clearly over the page. Always
|
|
189
|
+
pair with --bp-hatch:
|
|
190
|
+
background-color: var(--bp-scrim);
|
|
191
|
+
background-image: var(--bp-hatch); */
|
|
192
|
+
--bp-scrim: oklch(0 0 0 / 0.58);
|
|
187
193
|
--bp-edge: var(--obvious-border-subtle, oklch(0 0 0 / 0.08));
|
|
188
194
|
--bp-ink-line: var(--obvious-border-default, oklch(0 0 0 / 0.16));
|
|
189
195
|
--bp-text: var(--obvious-text-primary, oklch(0 0 0 / 0.92));
|
|
@@ -322,6 +328,7 @@
|
|
|
322
328
|
--bp-duration-normal: 200ms;
|
|
323
329
|
--bp-duration-slow: 300ms;
|
|
324
330
|
--bp-duration-deliberate: 450ms;
|
|
331
|
+
--bp-duration-spin: 1.4s; /* constant rotation (marquees, loading glyphs) */
|
|
325
332
|
|
|
326
333
|
/* Easing — strong curves only; never ease-in for UI (its slow start delays
|
|
327
334
|
feedback and feels sluggish).
|
|
@@ -358,6 +365,7 @@
|
|
|
358
365
|
/* Neutral white-alpha panel fills over the dark paper. */
|
|
359
366
|
--bp-fill-amb: oklch(1 0 0 / 0.04);
|
|
360
367
|
--bp-fill-hi: oklch(1 0 0 / 0.08);
|
|
368
|
+
--bp-scrim: oklch(1 0 0 / 0.58);
|
|
361
369
|
--bp-paper: var(--bp-gray-950);
|
|
362
370
|
--bp-bg: oklch(0.15 0 0); /* the desk sits darker than the sheet, so the page lifts */
|
|
363
371
|
--bp-edge: oklch(1 0 0 / 0.08);
|
|
@@ -430,6 +438,19 @@
|
|
|
430
438
|
-moz-osx-font-smoothing: grayscale;
|
|
431
439
|
counter-reset: bp-sec bp-fig bp-fn;
|
|
432
440
|
}
|
|
441
|
+
|
|
442
|
+
/* Theme crossfade — View Transitions capture one old/new snapshot of the
|
|
443
|
+
document and the compositor crossfades them in a single pass. Per-element
|
|
444
|
+
color transitions on a token flip fight the cascade (thousands of
|
|
445
|
+
mismatched 150ms/200ms tweens, pseudo-elements snapping mid-fade, and
|
|
446
|
+
transitions cut off when an animate flag clears). blueprint.js wraps theme
|
|
447
|
+
flips in startViewTransition(); reduced motion is handled globally in
|
|
448
|
+
@layer reset. Pseudo-elements can't live in :where(); same rule here. */
|
|
449
|
+
::view-transition-old(root),
|
|
450
|
+
::view-transition-new(root) {
|
|
451
|
+
animation-duration: var(--bp-duration-normal);
|
|
452
|
+
animation-timing-function: var(--bp-ease-out);
|
|
453
|
+
}
|
|
433
454
|
/* Pseudo-elements can't live inside :where()/:is() — Chromium (incl. Dia)
|
|
434
455
|
and Firefox drop the whole rule. Keep these as plain selectors, and
|
|
435
456
|
split ::selection / ::-moz-selection so one invalid token doesn't
|
|
@@ -451,8 +472,8 @@
|
|
|
451
472
|
padding: var(--bp-space-6);
|
|
452
473
|
}
|
|
453
474
|
|
|
454
|
-
/* Section rhythm
|
|
455
|
-
|
|
475
|
+
/* Section rhythm — primary section eyebrows are injected by blueprint.js
|
|
476
|
+
on h2[data-sidebar]; nested sections without data-sidebar stay plain. */
|
|
456
477
|
:where(section) {
|
|
457
478
|
counter-increment: bp-sec;
|
|
458
479
|
}
|
|
@@ -470,6 +491,38 @@
|
|
|
470
491
|
margin-bottom: var(--bp-space-2);
|
|
471
492
|
text-wrap: var(--bp-wrap-heading);
|
|
472
493
|
}
|
|
494
|
+
/* Document masthead — the first <header> in <main>. No implicit, position-
|
|
495
|
+
based styling: author the eyebrow with <bp-eyebrow> and the lede with
|
|
496
|
+
<bp-subheader> explicitly. We only reset the title's top margin and tune
|
|
497
|
+
the gap before a following contents index. */
|
|
498
|
+
:where(main > header:first-child) {
|
|
499
|
+
margin-bottom: 0;
|
|
500
|
+
}
|
|
501
|
+
:where(main > header:first-child > h1) {
|
|
502
|
+
margin: 0 0 var(--bp-space-2);
|
|
503
|
+
}
|
|
504
|
+
:where(main > header:first-child:has(+ :is(.bp-contents, bp-toc))) {
|
|
505
|
+
margin-bottom: var(--bp-space-4);
|
|
506
|
+
}
|
|
507
|
+
:where(main > header:first-child + :is(.bp-contents, bp-toc)) {
|
|
508
|
+
margin-top: 0;
|
|
509
|
+
}
|
|
510
|
+
/* Navigation GROUP divider — every repeated <header> after the masthead.
|
|
511
|
+
It reuses the masthead structure (eyebrow + h1 + optional <bp-subheader>)
|
|
512
|
+
and reads as a calm "part" break: a hairline above and generous rhythm,
|
|
513
|
+
so the document splits into labelled groups that the runtime mirrors as
|
|
514
|
+
eyebrows in the contents rail. */
|
|
515
|
+
:where(main > header:not(:first-child)) {
|
|
516
|
+
margin: calc(var(--bp-space-7) + var(--bp-space-5)) 0 0;
|
|
517
|
+
padding-top: var(--bp-space-6);
|
|
518
|
+
border-top: 1px solid var(--bp-edge);
|
|
519
|
+
}
|
|
520
|
+
:where(main > header:not(:first-child) > h1) {
|
|
521
|
+
margin: 0 0 var(--bp-space-2);
|
|
522
|
+
}
|
|
523
|
+
:where(bp-toc) {
|
|
524
|
+
display: block;
|
|
525
|
+
}
|
|
473
526
|
:where(h2) {
|
|
474
527
|
font-family: var(--bp-sans);
|
|
475
528
|
font-size: var(--bp-text-h2);
|
|
@@ -480,12 +533,10 @@
|
|
|
480
533
|
scroll-margin-top: var(--bp-space-4);
|
|
481
534
|
text-wrap: var(--bp-wrap-heading);
|
|
482
535
|
}
|
|
483
|
-
/*
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
:where(section > h2:first-child)::before,
|
|
488
|
-
:where(section > hgroup:first-child > h2)::before {
|
|
536
|
+
/* Legacy section-scoped eyebrow for pages without blueprint.js. Authored
|
|
537
|
+
h2[data-sidebar] headings get .bp-heading-eyebrow from the runtime. */
|
|
538
|
+
:where(section > h2:first-child:not([data-sidebar]):not(:has(.bp-heading-eyebrow)))::before,
|
|
539
|
+
:where(section > hgroup:first-child > h2:not([data-sidebar]):not(:has(.bp-heading-eyebrow)))::before {
|
|
489
540
|
content: counter(bp-sec, decimal-leading-zero);
|
|
490
541
|
display: block;
|
|
491
542
|
width: max-content;
|
|
@@ -539,8 +590,8 @@
|
|
|
539
590
|
text-wrap: var(--bp-wrap-body);
|
|
540
591
|
}
|
|
541
592
|
/* Lede-by-position was removed — a paragraph following a heading should
|
|
542
|
-
render as ordinary body type. Use
|
|
543
|
-
the narrative lead-in treatment. */
|
|
593
|
+
render as ordinary body type. Use <bp-subheader> explicitly when you
|
|
594
|
+
want the narrative lead-in treatment. */
|
|
544
595
|
:where(ul, ol) {
|
|
545
596
|
margin: 0 0 1.2em;
|
|
546
597
|
padding-left: 1.3em;
|
|
@@ -785,7 +836,7 @@
|
|
|
785
836
|
background: var(--bp-fill-amb);
|
|
786
837
|
padding: 2px 5px;
|
|
787
838
|
color: var(--bp-ink);
|
|
788
|
-
border-radius: var(--bp-radius-
|
|
839
|
+
border-radius: var(--bp-radius-0);
|
|
789
840
|
}
|
|
790
841
|
:where(pre) {
|
|
791
842
|
font-family: var(--bp-mono);
|
|
@@ -810,7 +861,7 @@
|
|
|
810
861
|
background: var(--bp-paper);
|
|
811
862
|
border: 1px solid var(--bp-ink-line);
|
|
812
863
|
border-bottom-width: 2px;
|
|
813
|
-
border-radius: var(--bp-radius-
|
|
864
|
+
border-radius: var(--bp-radius-0);
|
|
814
865
|
padding: 1px 5px;
|
|
815
866
|
color: var(--bp-text);
|
|
816
867
|
}
|
|
@@ -944,13 +995,22 @@
|
|
|
944
995
|
:where(summary)::-webkit-details-marker {
|
|
945
996
|
display: none;
|
|
946
997
|
}
|
|
998
|
+
/* Disclosure caret — Iconoir nav-arrow-right, inlined as a mask so every
|
|
999
|
+
native <summary> stays JS-free and inherits ink via currentColor. */
|
|
947
1000
|
:where(summary)::before {
|
|
948
1001
|
content: "";
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
1002
|
+
flex-shrink: 0;
|
|
1003
|
+
width: 16px;
|
|
1004
|
+
height: 16px;
|
|
1005
|
+
background-color: var(--bp-ink);
|
|
1006
|
+
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 6L15 12L9 18'/%3E%3C/svg%3E");
|
|
1007
|
+
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 6L15 12L9 18'/%3E%3C/svg%3E");
|
|
1008
|
+
-webkit-mask-size: contain;
|
|
1009
|
+
mask-size: contain;
|
|
1010
|
+
-webkit-mask-repeat: no-repeat;
|
|
1011
|
+
mask-repeat: no-repeat;
|
|
1012
|
+
-webkit-mask-position: center;
|
|
1013
|
+
mask-position: center;
|
|
954
1014
|
/* Motion: .bp-transition-transform .bp-ease (disclosure caret rotate) */
|
|
955
1015
|
transition-property: transform;
|
|
956
1016
|
transition-duration: var(--bp-duration-fast);
|
|
@@ -967,7 +1027,65 @@
|
|
|
967
1027
|
:where(a, button, summary, [tabindex]):focus-visible {
|
|
968
1028
|
outline: 2px solid var(--bp-ink);
|
|
969
1029
|
outline-offset: 3px;
|
|
970
|
-
border-radius: var(--bp-radius-
|
|
1030
|
+
border-radius: var(--bp-radius-0);
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
/* Squared checkbox. Native checkboxes render with rounded corners that
|
|
1034
|
+
border-radius cannot override, so reset appearance and draw the box: a
|
|
1035
|
+
paper square with an Iconoir check tick (mask-inlined, same glyph as the
|
|
1036
|
+
heading permalink copied state). Paper fill + ink tick stay legible
|
|
1037
|
+
whether the control sits on paper or an inked chip. Radios keep their
|
|
1038
|
+
native round rendering — a square radio reads as a checkbox. */
|
|
1039
|
+
:where(input[type="checkbox"]) {
|
|
1040
|
+
appearance: none;
|
|
1041
|
+
-webkit-appearance: none;
|
|
1042
|
+
flex: none;
|
|
1043
|
+
display: inline-grid;
|
|
1044
|
+
place-items: center;
|
|
1045
|
+
inline-size: 1em;
|
|
1046
|
+
block-size: 1em;
|
|
1047
|
+
border: 1px solid var(--bp-ink-line);
|
|
1048
|
+
border-radius: var(--bp-radius-0);
|
|
1049
|
+
background: var(--bp-paper);
|
|
1050
|
+
cursor: pointer;
|
|
1051
|
+
/* Motion: .bp-transition-colors (border + fill settle on toggle) */
|
|
1052
|
+
transition-property: border-color, background;
|
|
1053
|
+
transition-duration: var(--bp-duration-fast);
|
|
1054
|
+
transition-timing-function: var(--bp-ease-out);
|
|
1055
|
+
}
|
|
1056
|
+
:where(input[type="checkbox"])::before {
|
|
1057
|
+
content: "";
|
|
1058
|
+
inline-size: 0.7em;
|
|
1059
|
+
block-size: 0.7em;
|
|
1060
|
+
background-color: var(--bp-ink);
|
|
1061
|
+
/* Iconoir check — same glyph as heading permalink copied state. */
|
|
1062
|
+
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 13L9 17L19 7'/%3E%3C/svg%3E");
|
|
1063
|
+
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 13L9 17L19 7'/%3E%3C/svg%3E");
|
|
1064
|
+
-webkit-mask-size: contain;
|
|
1065
|
+
mask-size: contain;
|
|
1066
|
+
-webkit-mask-repeat: no-repeat;
|
|
1067
|
+
mask-repeat: no-repeat;
|
|
1068
|
+
-webkit-mask-position: center;
|
|
1069
|
+
mask-position: center;
|
|
1070
|
+
transform: scale(0);
|
|
1071
|
+
transform-origin: center;
|
|
1072
|
+
/* Motion: tick draws in as the box is checked */
|
|
1073
|
+
transition: transform var(--bp-duration-fast) var(--bp-ease-out);
|
|
1074
|
+
}
|
|
1075
|
+
:where(input[type="checkbox"]:checked) {
|
|
1076
|
+
border-color: var(--bp-ink);
|
|
1077
|
+
}
|
|
1078
|
+
:where(input[type="checkbox"]:checked)::before {
|
|
1079
|
+
transform: scale(1);
|
|
1080
|
+
}
|
|
1081
|
+
:where(input[type="checkbox"]:disabled) {
|
|
1082
|
+
opacity: 0.4;
|
|
1083
|
+
cursor: not-allowed;
|
|
1084
|
+
pointer-events: none;
|
|
1085
|
+
}
|
|
1086
|
+
:where(input[type="checkbox"]:focus-visible) {
|
|
1087
|
+
outline: 2px solid var(--bp-ink);
|
|
1088
|
+
outline-offset: 3px;
|
|
971
1089
|
}
|
|
972
1090
|
}
|
|
973
1091
|
|
|
@@ -987,37 +1105,51 @@
|
|
|
987
1105
|
===================================================================== */
|
|
988
1106
|
@layer components {
|
|
989
1107
|
|
|
990
|
-
/* ---- Narrative lede
|
|
991
|
-
A lede must be asked for —
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
:where(
|
|
1108
|
+
/* ---- Narrative lede — <bp-subheader> ----------------------------
|
|
1109
|
+
A lede must be asked for — wrap a lead-in paragraph in <bp-subheader>
|
|
1110
|
+
so it reads as the narrative opener. Lede-by-position (the old
|
|
1111
|
+
automatic `section > h2 + p` rule) was removed; a paragraph following
|
|
1112
|
+
a heading is ordinary body type unless it is a <bp-subheader>. */
|
|
1113
|
+
:where(bp-subheader) {
|
|
1114
|
+
display: block;
|
|
1115
|
+
margin: 0 0 1.2em;
|
|
996
1116
|
font-size: var(--bp-text-lede);
|
|
997
1117
|
line-height: var(--bp-lh-lede);
|
|
998
1118
|
color: var(--bp-text);
|
|
999
1119
|
}
|
|
1000
1120
|
|
|
1001
|
-
/* ---- Section heading permalink
|
|
1002
|
-
Injected by blueprint.js
|
|
1003
|
-
|
|
1004
|
-
hover, check after a successful copy. */
|
|
1005
|
-
:where(
|
|
1121
|
+
/* ---- Section heading permalink + eyebrow --------------------------------
|
|
1122
|
+
Injected by blueprint.js on headings with data-sidebar: a numbered eyebrow
|
|
1123
|
+
on primary (h2) sections, plus a gutter permalink on every opted-in level.
|
|
1124
|
+
Link on heading hover, copy on icon hover, check after a successful copy. */
|
|
1125
|
+
:where(.bp-heading-eyebrow) {
|
|
1126
|
+
display: block;
|
|
1127
|
+
width: max-content;
|
|
1128
|
+
font-family: var(--bp-mono);
|
|
1129
|
+
font-size: var(--bp-label-lg);
|
|
1130
|
+
font-weight: var(--bp-weight-medium);
|
|
1131
|
+
letter-spacing: 0.18em;
|
|
1132
|
+
color: var(--bp-ink);
|
|
1133
|
+
padding-left: calc(var(--bp-marker-size) + var(--bp-marker-gap));
|
|
1134
|
+
background: linear-gradient(var(--bp-ink), var(--bp-ink)) left center / var(--bp-marker-size) var(--bp-marker-size) no-repeat;
|
|
1135
|
+
margin-bottom: var(--bp-space-2);
|
|
1136
|
+
}
|
|
1137
|
+
:where(:is(h2, h3, h4, h5, h6):has(.bp-heading-row)) {
|
|
1006
1138
|
position: relative;
|
|
1007
1139
|
}
|
|
1008
1140
|
/* Invisible bridge from the title into the gutter so the icon stays
|
|
1009
|
-
reachable while the pointer crosses the gap outside
|
|
1010
|
-
:where(h2:has(.bp-heading-row))::after {
|
|
1141
|
+
reachable while the pointer crosses the gap outside the heading box. */
|
|
1142
|
+
:where(:is(h2, h3, h4, h5, h6):has(.bp-heading-row))::after {
|
|
1011
1143
|
content: "";
|
|
1012
1144
|
position: absolute;
|
|
1013
1145
|
left: calc(-1 * (16px + var(--bp-space-2)));
|
|
1014
1146
|
bottom: 0;
|
|
1015
1147
|
z-index: 0;
|
|
1016
1148
|
width: calc(16px + var(--bp-space-2) + var(--bp-space-3));
|
|
1017
|
-
height:
|
|
1149
|
+
height: 1.2em;
|
|
1018
1150
|
pointer-events: none;
|
|
1019
1151
|
}
|
|
1020
|
-
:where(h2:is(:hover, :focus-within, [data-heading-link="visible"]):has(.bp-heading-row))::after {
|
|
1152
|
+
:where(:is(h2, h3, h4, h5, h6):is(:hover, :focus-within, [data-heading-link="visible"]):has(.bp-heading-row))::after {
|
|
1021
1153
|
pointer-events: auto;
|
|
1022
1154
|
}
|
|
1023
1155
|
:where(.bp-heading-row) {
|
|
@@ -1043,7 +1175,7 @@
|
|
|
1043
1175
|
margin: 0;
|
|
1044
1176
|
padding: 0;
|
|
1045
1177
|
border: 0;
|
|
1046
|
-
background:
|
|
1178
|
+
background: oklch(0 0 0 / 0);
|
|
1047
1179
|
color: var(--bp-ink-soft);
|
|
1048
1180
|
cursor: pointer;
|
|
1049
1181
|
opacity: 0;
|
|
@@ -1069,21 +1201,20 @@
|
|
|
1069
1201
|
inset: 0;
|
|
1070
1202
|
display: block;
|
|
1071
1203
|
opacity: 0;
|
|
1072
|
-
image-rendering: pixelated;
|
|
1073
1204
|
transition: opacity var(--bp-duration-fast) var(--bp-ease-out);
|
|
1074
1205
|
}
|
|
1075
|
-
:where(h2:hover .bp-heading-link),
|
|
1076
|
-
:where(h2:focus-within .bp-heading-link),
|
|
1077
|
-
:where(h2[data-heading-link="visible"] .bp-heading-link),
|
|
1206
|
+
:where(:is(h2, h3, h4, h5, h6):hover .bp-heading-link),
|
|
1207
|
+
:where(:is(h2, h3, h4, h5, h6):focus-within .bp-heading-link),
|
|
1208
|
+
:where(:is(h2, h3, h4, h5, h6)[data-heading-link="visible"] .bp-heading-link),
|
|
1078
1209
|
:where(button.bp-heading-link:focus-visible),
|
|
1079
1210
|
:where(button.bp-heading-link[data-bp-copy-state="copied"]),
|
|
1080
1211
|
:where(button.bp-heading-link[data-bp-copy-state="error"]) {
|
|
1081
1212
|
opacity: 1;
|
|
1082
1213
|
pointer-events: auto;
|
|
1083
1214
|
}
|
|
1084
|
-
:where(h2:hover .bp-heading-link__icon--link),
|
|
1085
|
-
:where(h2:focus-within .bp-heading-link__icon--link),
|
|
1086
|
-
:where(h2[data-heading-link="visible"] .bp-heading-link__icon--link),
|
|
1215
|
+
:where(:is(h2, h3, h4, h5, h6):hover .bp-heading-link__icon--link),
|
|
1216
|
+
:where(:is(h2, h3, h4, h5, h6):focus-within .bp-heading-link__icon--link),
|
|
1217
|
+
:where(:is(h2, h3, h4, h5, h6)[data-heading-link="visible"] .bp-heading-link__icon--link),
|
|
1087
1218
|
:where(button.bp-heading-link:focus-visible .bp-heading-link__icon--link) {
|
|
1088
1219
|
opacity: 1;
|
|
1089
1220
|
}
|
|
@@ -1110,14 +1241,19 @@
|
|
|
1110
1241
|
:where(button.bp-heading-link:focus-visible) {
|
|
1111
1242
|
outline: 2px solid var(--bp-ink);
|
|
1112
1243
|
outline-offset: 2px;
|
|
1113
|
-
border-radius: var(--bp-radius-
|
|
1244
|
+
border-radius: var(--bp-radius-0);
|
|
1114
1245
|
}
|
|
1115
1246
|
:where(button.bp-heading-link[data-bp-copy-state="error"]) {
|
|
1116
1247
|
color: var(--bp-ink-soft);
|
|
1117
1248
|
}
|
|
1118
1249
|
|
|
1119
|
-
/* ----
|
|
1120
|
-
|
|
1250
|
+
/* ---- Mono micro-label family — <bp-eyebrow> + internal aliases -----
|
|
1251
|
+
<bp-eyebrow> is a short uppercase kicker line that heads the block
|
|
1252
|
+
beneath it. Default is ink; add the [muted] attribute for quiet
|
|
1253
|
+
metadata or provenance. The legacy .bp-eyebrow / .bp-label classes
|
|
1254
|
+
are the same ink role, and .bp-meta the muted role — all kept only
|
|
1255
|
+
for runtime-injected chrome and choice internals, not authoring. */
|
|
1256
|
+
:where(bp-eyebrow, .bp-eyebrow, .bp-label) {
|
|
1121
1257
|
display: block;
|
|
1122
1258
|
font-family: var(--bp-mono);
|
|
1123
1259
|
font-size: var(--bp-label-md);
|
|
@@ -1126,212 +1262,28 @@
|
|
|
1126
1262
|
color: var(--bp-ink);
|
|
1127
1263
|
margin-bottom: var(--bp-space-2);
|
|
1128
1264
|
}
|
|
1129
|
-
:where(
|
|
1130
|
-
font-family: var(--bp-mono);
|
|
1131
|
-
font-size: var(--bp-label-md);
|
|
1132
|
-
letter-spacing: var(--bp-label-md-ls);
|
|
1133
|
-
text-transform: uppercase;
|
|
1134
|
-
color: var(--bp-text-secondary);
|
|
1135
|
-
}
|
|
1136
|
-
:where(.bp-note) {
|
|
1265
|
+
:where(bp-eyebrow[muted]) {
|
|
1137
1266
|
color: var(--bp-text-secondary);
|
|
1138
1267
|
}
|
|
1139
|
-
|
|
1140
|
-
/* ---- 1. Decision panel ------------------------------------------
|
|
1141
|
-
The single load-bearing decision, given more weight than a routine
|
|
1142
|
-
callout. An inverted masthead band carries the kicker, an optional
|
|
1143
|
-
status pill, and optional provenance (decider + <time>); the headline
|
|
1144
|
-
statement is the typographic hero; stacked tenets explain it; and a
|
|
1145
|
-
distinct hatched footer states the condition for revisiting it. Every
|
|
1146
|
-
part but the statement is optional. Markup:
|
|
1147
|
-
<section class="bp-decision">
|
|
1148
|
-
<header class="bp-decision__bar">
|
|
1149
|
-
<span class="bp-label">Decision</span>
|
|
1150
|
-
<span class="bp-decision__status">Locked</span>
|
|
1151
|
-
<p class="bp-decision__meta">Obvious · <time datetime="2026-06-16">16 Jun 2026</time></p>
|
|
1152
|
-
</header>
|
|
1153
|
-
<div class="bp-decision__body">
|
|
1154
|
-
<p class="bp-decision-stmt">…the headline…</p>
|
|
1155
|
-
<dl class="bp-decision__tenets"> <dt>Holds because</dt><dd>…</dd> … </dl>
|
|
1156
|
-
</div>
|
|
1157
|
-
<p class="bp-decision__revisit"><b>Revisit when</b> …</p>
|
|
1158
|
-
</section> */
|
|
1159
|
-
:where(.bp-decision) {
|
|
1160
|
-
border: 1px solid var(--bp-ink);
|
|
1161
|
-
border-radius: var(--bp-radius-6);
|
|
1162
|
-
background: var(--bp-paper);
|
|
1163
|
-
overflow: hidden;
|
|
1164
|
-
margin: var(--bp-space-4) 0;
|
|
1165
|
-
}
|
|
1166
|
-
/* Inverted masthead band: kicker left, status pill, provenance pushed
|
|
1167
|
-
right. Paper-on-ink, so it flips with the theme like the doc band. */
|
|
1168
|
-
:where(.bp-decision__bar) {
|
|
1169
|
-
display: flex;
|
|
1170
|
-
align-items: center;
|
|
1171
|
-
gap: var(--bp-space-2);
|
|
1172
|
-
padding: var(--bp-space-2) var(--bp-space-3);
|
|
1173
|
-
background: var(--bp-ink);
|
|
1174
|
-
color: var(--bp-paper);
|
|
1175
|
-
}
|
|
1176
|
-
:where(.bp-decision__bar) > :where(.bp-label) {
|
|
1177
|
-
margin: 0;
|
|
1178
|
-
color: var(--bp-paper);
|
|
1179
|
-
font-size: var(--bp-label-lg);
|
|
1180
|
-
letter-spacing: var(--bp-label-lg-ls);
|
|
1181
|
-
font-weight: var(--bp-weight-medium);
|
|
1182
|
-
}
|
|
1183
|
-
:where(.bp-decision__status) {
|
|
1184
|
-
font-family: var(--bp-mono);
|
|
1185
|
-
font-size: var(--bp-label-sm);
|
|
1186
|
-
letter-spacing: var(--bp-label-sm-ls);
|
|
1187
|
-
text-transform: uppercase;
|
|
1188
|
-
border: 1px solid color-mix(in oklch, var(--bp-paper) 45%, transparent);
|
|
1189
|
-
border-radius: var(--bp-radius-pill);
|
|
1190
|
-
padding: 1px 8px;
|
|
1191
|
-
}
|
|
1192
|
-
:where(.bp-decision__meta) {
|
|
1193
|
-
margin: 0 0 0 auto;
|
|
1194
|
-
font-family: var(--bp-mono);
|
|
1195
|
-
font-size: var(--bp-label-md);
|
|
1196
|
-
letter-spacing: var(--bp-label-md-ls);
|
|
1197
|
-
text-transform: uppercase;
|
|
1198
|
-
color: color-mix(in oklch, var(--bp-paper) 72%, transparent);
|
|
1199
|
-
text-align: right;
|
|
1200
|
-
}
|
|
1201
|
-
:where(.bp-decision__meta) :where(time) {
|
|
1202
|
-
color: color-mix(in oklch, var(--bp-paper) 90%, transparent);
|
|
1203
|
-
}
|
|
1204
|
-
:where(.bp-decision__body) {
|
|
1205
|
-
padding: var(--bp-space-4) var(--bp-space-4) var(--bp-space-4);
|
|
1206
|
-
}
|
|
1207
|
-
:where(.bp-decision-stmt) {
|
|
1208
|
-
font-family: var(--bp-sans);
|
|
1209
|
-
font-size: var(--bp-text-title);
|
|
1210
|
-
font-weight: var(--bp-weight-strong);
|
|
1211
|
-
letter-spacing: -0.48px;
|
|
1212
|
-
line-height: var(--bp-lh-title);
|
|
1213
|
-
color: var(--bp-text);
|
|
1214
|
-
margin: 0;
|
|
1215
|
-
text-wrap: balance;
|
|
1216
|
-
}
|
|
1217
|
-
/* Stacked tenets — mono label ABOVE its value (no stranded label column),
|
|
1218
|
-
so several points stay aligned to the left margin and read cleanly. */
|
|
1219
|
-
:where(.bp-decision__tenets) {
|
|
1220
|
-
display: block;
|
|
1221
|
-
margin: var(--bp-space-3) 0 0;
|
|
1222
|
-
padding: 0;
|
|
1223
|
-
}
|
|
1224
|
-
:where(.bp-decision__tenets) > :where(dt) {
|
|
1268
|
+
:where(.bp-meta) {
|
|
1225
1269
|
font-family: var(--bp-mono);
|
|
1226
1270
|
font-size: var(--bp-label-md);
|
|
1227
|
-
font-weight: var(--bp-weight-body);
|
|
1228
1271
|
letter-spacing: var(--bp-label-md-ls);
|
|
1229
1272
|
text-transform: uppercase;
|
|
1230
1273
|
color: var(--bp-text-secondary);
|
|
1231
|
-
padding: 0;
|
|
1232
|
-
margin: 0 0 var(--bp-space-1);
|
|
1233
|
-
}
|
|
1234
|
-
:where(.bp-decision__tenets) > :where(dt ~ dt) {
|
|
1235
|
-
margin-top: var(--bp-space-3);
|
|
1236
1274
|
}
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
margin: 0;
|
|
1275
|
+
/* Quiet subordinate paragraph — <bp-note> for authored asides/caveats.
|
|
1276
|
+
.bp-note is the same role kept for runtime-injected chrome. */
|
|
1277
|
+
:where(bp-note) {
|
|
1278
|
+
display: block;
|
|
1279
|
+
margin: 0 0 1.2em;
|
|
1242
1280
|
}
|
|
1243
|
-
|
|
1244
|
-
revision" texture). Tight, flush to the panel's bottom edge. */
|
|
1245
|
-
:where(.bp-decision__revisit) {
|
|
1246
|
-
display: flex;
|
|
1247
|
-
align-items: baseline;
|
|
1248
|
-
gap: var(--bp-space-2);
|
|
1249
|
-
margin: 0;
|
|
1250
|
-
padding: var(--bp-space-2) var(--bp-space-4);
|
|
1251
|
-
border-top: 1px solid var(--bp-edge);
|
|
1252
|
-
background-image: var(--bp-hatch);
|
|
1253
|
-
font-size: var(--bp-text-small);
|
|
1254
|
-
line-height: var(--bp-lh-small);
|
|
1281
|
+
:where(bp-note, .bp-note) {
|
|
1255
1282
|
color: var(--bp-text-secondary);
|
|
1256
1283
|
}
|
|
1257
|
-
:where(.bp-decision__revisit) > :where(b) {
|
|
1258
|
-
font-family: var(--bp-mono);
|
|
1259
|
-
font-size: var(--bp-label-md);
|
|
1260
|
-
font-weight: var(--bp-weight-body);
|
|
1261
|
-
letter-spacing: var(--bp-label-md-ls);
|
|
1262
|
-
text-transform: uppercase;
|
|
1263
|
-
color: var(--bp-ink);
|
|
1264
|
-
white-space: nowrap;
|
|
1265
|
-
}
|
|
1266
|
-
|
|
1267
|
-
/* ---- 1b. Collapsible decision -----------------------------------
|
|
1268
|
-
A <details> variant for pages that carry several decisions. Collapsed,
|
|
1269
|
-
the whole panel is just the inverted bar — the decision reads on the
|
|
1270
|
-
left (compact, not hero scale), provenance on the right. Expanding
|
|
1271
|
-
drops the tenets and the revisit footer below the same bar. No JS —
|
|
1272
|
-
native disclosure. Markup:
|
|
1273
|
-
<details class="bp-decision bp-decision--collapsible">
|
|
1274
|
-
<summary class="bp-decision__bar">
|
|
1275
|
-
<span class="bp-label">Decision</span>
|
|
1276
|
-
<span class="bp-decision__title">…the decision…</span>
|
|
1277
|
-
<span class="bp-decision__meta">Obvious · <time …>…</time></span>
|
|
1278
|
-
<span class="bp-decision__caret" aria-hidden="true"></span>
|
|
1279
|
-
</summary>
|
|
1280
|
-
<dl class="bp-decision__tenets"> … </dl>
|
|
1281
|
-
<p class="bp-decision__revisit"> … </p>
|
|
1282
|
-
</details> */
|
|
1283
|
-
:where(.bp-decision--collapsible) {
|
|
1284
|
-
padding: 0;
|
|
1285
|
-
}
|
|
1286
|
-
/* The summary IS the bar — clicking it toggles the disclosure. */
|
|
1287
|
-
:where(.bp-decision--collapsible) > :where(summary) {
|
|
1288
|
-
cursor: pointer;
|
|
1289
|
-
list-style: none;
|
|
1290
|
-
gap: var(--bp-space-3);
|
|
1291
|
-
}
|
|
1292
|
-
:where(.bp-decision--collapsible) > :where(summary)::-webkit-details-marker {
|
|
1293
|
-
display: none;
|
|
1294
|
-
}
|
|
1295
|
-
/* Suppress the global <summary> caret; this variant carries its own. */
|
|
1296
|
-
:where(.bp-decision--collapsible) > :where(summary)::before {
|
|
1297
|
-
content: none;
|
|
1298
|
-
}
|
|
1299
|
-
/* The decision itself, compact (not hero scale), sits left of the meta. */
|
|
1300
|
-
:where(.bp-decision__title) {
|
|
1301
|
-
min-width: 0;
|
|
1302
|
-
font-family: var(--bp-sans);
|
|
1303
|
-
font-size: var(--bp-text-h4);
|
|
1304
|
-
font-weight: var(--bp-weight-strong);
|
|
1305
|
-
letter-spacing: -0.2px;
|
|
1306
|
-
line-height: var(--bp-lh-h4);
|
|
1307
|
-
color: var(--bp-paper);
|
|
1308
|
-
}
|
|
1309
|
-
:where(.bp-decision--collapsible) :where(.bp-decision__meta) {
|
|
1310
|
-
margin-right: 0;
|
|
1311
|
-
}
|
|
1312
|
-
/* Caret rides at the far right and rotates open. */
|
|
1313
|
-
:where(.bp-decision__caret) {
|
|
1314
|
-
flex: 0 0 auto;
|
|
1315
|
-
width: 0;
|
|
1316
|
-
height: 0;
|
|
1317
|
-
border-left: 5px solid currentColor;
|
|
1318
|
-
border-top: 4px solid transparent;
|
|
1319
|
-
border-bottom: 4px solid transparent;
|
|
1320
|
-
transition: transform var(--bp-duration-fast) var(--bp-ease);
|
|
1321
|
-
}
|
|
1322
|
-
/* No meta? Caret takes the auto margin so it still parks on the right. */
|
|
1323
|
-
:where(.bp-decision--collapsible) :where(.bp-decision__bar):not(:has(.bp-decision__meta)) :where(.bp-decision__caret) {
|
|
1324
|
-
margin-left: auto;
|
|
1325
|
-
}
|
|
1326
|
-
:where(.bp-decision--collapsible[open]) :where(.bp-decision__caret) {
|
|
1327
|
-
transform: rotate(90deg);
|
|
1328
|
-
}
|
|
1329
|
-
:where(.bp-decision--collapsible) > :where(.bp-decision__tenets) {
|
|
1330
|
-
padding: var(--bp-space-4) var(--bp-space-4) var(--bp-space-3);
|
|
1331
|
-
}
|
|
1332
1284
|
|
|
1333
1285
|
/* ---- 2. Typed callout family ------------------------------------
|
|
1334
|
-
A coherent callout family with legible roles
|
|
1286
|
+
A coherent callout family with legible roles.
|
|
1335
1287
|
Drafting-style: instead of a box, four L-shaped registration ticks
|
|
1336
1288
|
bracket the corners (drawn as layered background gradients — no extra
|
|
1337
1289
|
DOM), with an icon + mono type label heading the body. The base is
|
|
@@ -1351,7 +1303,7 @@
|
|
|
1351
1303
|
padding: var(--bp-space-3) var(--bp-space-4);
|
|
1352
1304
|
margin: var(--bp-space-4) 0;
|
|
1353
1305
|
color: var(--bp-text);
|
|
1354
|
-
background-color:
|
|
1306
|
+
background-color: oklch(0 0 0 / 0);
|
|
1355
1307
|
background-repeat: no-repeat;
|
|
1356
1308
|
/* 8 solid slivers = 4 corner Ls, then an optional texture fill below. */
|
|
1357
1309
|
background-image:
|
|
@@ -1380,10 +1332,7 @@
|
|
|
1380
1332
|
/* Remove trailing margin from the last child of ANY boxed component so
|
|
1381
1333
|
padding, not stray paragraph space, controls the inner bottom gap. */
|
|
1382
1334
|
:where(
|
|
1383
|
-
.bp-decision,
|
|
1384
1335
|
.bp-callout,
|
|
1385
|
-
.bp-option-grid > *,
|
|
1386
|
-
.bp-state-grid > *,
|
|
1387
1336
|
.bp-sequence > li,
|
|
1388
1337
|
details
|
|
1389
1338
|
) > :last-child {
|
|
@@ -1451,41 +1400,10 @@
|
|
|
1451
1400
|
grid-template-columns: minmax(10rem, 16rem) 1fr;
|
|
1452
1401
|
}
|
|
1453
1402
|
|
|
1454
|
-
/*
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
:where(.bp-option-grid) {
|
|
1459
|
-
display: grid;
|
|
1460
|
-
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
|
1461
|
-
gap: 0;
|
|
1462
|
-
border: 1px solid var(--bp-edge);
|
|
1463
|
-
margin: var(--bp-space-4) 0;
|
|
1464
|
-
}
|
|
1465
|
-
:where(.bp-option-grid > *) {
|
|
1466
|
-
padding: var(--bp-space-3);
|
|
1467
|
-
border-right: 1px solid var(--bp-edge);
|
|
1468
|
-
background: var(--bp-paper);
|
|
1469
|
-
}
|
|
1470
|
-
:where(.bp-option-grid > :last-child) {
|
|
1471
|
-
border-right: 0;
|
|
1472
|
-
}
|
|
1473
|
-
:where(.bp-opt--rec) {
|
|
1474
|
-
background: var(--bp-fill-amb);
|
|
1475
|
-
outline: 2px solid var(--bp-ink);
|
|
1476
|
-
outline-offset: -2px;
|
|
1477
|
-
}
|
|
1478
|
-
:where(.bp-verdict) {
|
|
1479
|
-
display: inline-block;
|
|
1480
|
-
font-family: var(--bp-mono);
|
|
1481
|
-
font-size: var(--bp-label-sm);
|
|
1482
|
-
letter-spacing: var(--bp-label-sm-ls);
|
|
1483
|
-
text-transform: uppercase;
|
|
1484
|
-
color: var(--bp-paper);
|
|
1485
|
-
background: var(--bp-ink);
|
|
1486
|
-
padding: 2px 8px;
|
|
1487
|
-
margin-top: var(--bp-space-2);
|
|
1488
|
-
}
|
|
1403
|
+
/* Parallel comparisons and state models are author-composed: a small
|
|
1404
|
+
grid in the document's own <style>, colored from the core tokens (see
|
|
1405
|
+
SKILL "Visual grammar"). Recommendations live in <bp-choice resolved>,
|
|
1406
|
+
not a static grid modifier. */
|
|
1489
1407
|
|
|
1490
1408
|
/* ---- 5. Numbered linear sequence --------------------------------
|
|
1491
1409
|
A linear mechanism (pipeline, escalation). NOT a comparison grid.
|
|
@@ -1518,29 +1436,6 @@
|
|
|
1518
1436
|
color: var(--bp-ink);
|
|
1519
1437
|
}
|
|
1520
1438
|
|
|
1521
|
-
/* ---- State grid -------------------------------------------------
|
|
1522
|
-
Off-happy-path state model (empty / loading / ready / error …).
|
|
1523
|
-
Built from <article>s; each gets a mono state name via .bp-label. */
|
|
1524
|
-
:where(.bp-state-grid) {
|
|
1525
|
-
display: grid;
|
|
1526
|
-
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
1527
|
-
gap: 0;
|
|
1528
|
-
border: 1px solid var(--bp-edge);
|
|
1529
|
-
margin: var(--bp-space-4) 0;
|
|
1530
|
-
}
|
|
1531
|
-
:where(.bp-state-grid > *) {
|
|
1532
|
-
padding: var(--bp-space-3);
|
|
1533
|
-
border-right: 1px solid var(--bp-edge);
|
|
1534
|
-
border-bottom: 1px solid var(--bp-edge);
|
|
1535
|
-
background: var(--bp-paper);
|
|
1536
|
-
}
|
|
1537
|
-
/* Void / fenced-off state — a dead cell (orphaned, reclaimed away).
|
|
1538
|
-
The hatch layers over the paper set above; declared after so the
|
|
1539
|
-
zero-specificity rules resolve by source order. */
|
|
1540
|
-
:where(.bp-state--void) {
|
|
1541
|
-
background-image: var(--bp-hatch);
|
|
1542
|
-
}
|
|
1543
|
-
|
|
1544
1439
|
/* ---- Hatch utility ----------------------------------------------
|
|
1545
1440
|
Drop .bp-hatch on any block element to mark a fenced / held /
|
|
1546
1441
|
out-of-bounds region with drafting section-lining. Layers the hatch
|
|
@@ -1573,7 +1468,7 @@
|
|
|
1573
1468
|
padding: var(--bp-space-2) var(--bp-space-3);
|
|
1574
1469
|
background: var(--bp-ink);
|
|
1575
1470
|
color: var(--bp-paper);
|
|
1576
|
-
border-radius: var(--bp-radius-
|
|
1471
|
+
border-radius: var(--bp-radius-0);
|
|
1577
1472
|
margin-bottom: var(--bp-space-3);
|
|
1578
1473
|
}
|
|
1579
1474
|
:where(.bp-choice:has(.bp-choice__commit:checked)) .bp-choice__verdict,
|
|
@@ -1601,7 +1496,7 @@
|
|
|
1601
1496
|
font-size: var(--bp-label-md);
|
|
1602
1497
|
letter-spacing: var(--bp-label-md-ls);
|
|
1603
1498
|
text-transform: uppercase;
|
|
1604
|
-
color: color-mix(in oklch, var(--bp-paper) 72%,
|
|
1499
|
+
color: color-mix(in oklch, var(--bp-paper) 72%, oklch(0 0 0 / 0));
|
|
1605
1500
|
}
|
|
1606
1501
|
|
|
1607
1502
|
:where(.bp-choice-rationale) {
|
|
@@ -1672,7 +1567,7 @@
|
|
|
1672
1567
|
flex-wrap: wrap;
|
|
1673
1568
|
gap: 0;
|
|
1674
1569
|
border: 1px solid var(--bp-ink-line);
|
|
1675
|
-
border-radius: var(--bp-radius-
|
|
1570
|
+
border-radius: var(--bp-radius-0);
|
|
1676
1571
|
overflow: hidden;
|
|
1677
1572
|
margin: 0 0 var(--bp-space-3);
|
|
1678
1573
|
width: fit-content;
|
|
@@ -1712,7 +1607,7 @@
|
|
|
1712
1607
|
gap: 8px;
|
|
1713
1608
|
cursor: pointer;
|
|
1714
1609
|
border: 1px solid var(--bp-ink);
|
|
1715
|
-
border-radius: var(--bp-radius-
|
|
1610
|
+
border-radius: var(--bp-radius-0);
|
|
1716
1611
|
padding: 6px 14px;
|
|
1717
1612
|
font-family: var(--bp-mono);
|
|
1718
1613
|
font-size: var(--bp-label-md);
|
|
@@ -1735,7 +1630,7 @@
|
|
|
1735
1630
|
padding: var(--bp-space-3);
|
|
1736
1631
|
margin-left: calc(-1 * var(--bp-space-3));
|
|
1737
1632
|
margin-right: calc(-1 * var(--bp-space-3));
|
|
1738
|
-
border-radius: var(--bp-radius-
|
|
1633
|
+
border-radius: var(--bp-radius-0);
|
|
1739
1634
|
}
|
|
1740
1635
|
:where(.bp-choice__panel:has(.bp-choice__commit:checked)) :where(.bp-choice__adopt) {
|
|
1741
1636
|
background: var(--bp-ink);
|
|
@@ -1751,7 +1646,7 @@
|
|
|
1751
1646
|
display: block;
|
|
1752
1647
|
position: relative;
|
|
1753
1648
|
border: 1px solid var(--bp-edge);
|
|
1754
|
-
border-radius: var(--bp-radius-
|
|
1649
|
+
border-radius: var(--bp-radius-0);
|
|
1755
1650
|
padding: var(--bp-space-3);
|
|
1756
1651
|
cursor: pointer;
|
|
1757
1652
|
background: var(--bp-paper);
|
|
@@ -1796,6 +1691,38 @@
|
|
|
1796
1691
|
display: inline-flex;
|
|
1797
1692
|
}
|
|
1798
1693
|
|
|
1694
|
+
/* ---- mode: resolved (non-interactive — the decision is already made) -
|
|
1695
|
+
Same stack visuals, but driven by [data-resolved] instead of :checked:
|
|
1696
|
+
the verdict banner and chosen card are shown statically, the rest read
|
|
1697
|
+
as considered-and-set-aside. No inputs, no reset. */
|
|
1698
|
+
:where(.bp-choice--resolved) :where(.bp-choice__verdict) {
|
|
1699
|
+
display: flex;
|
|
1700
|
+
}
|
|
1701
|
+
:where(.bp-choice--resolved) :where(.bp-choice__verdict-pick[data-resolved]) {
|
|
1702
|
+
display: block;
|
|
1703
|
+
}
|
|
1704
|
+
:where(.bp-choice--resolved) :where(.bp-choice__stack) {
|
|
1705
|
+
display: grid;
|
|
1706
|
+
gap: var(--bp-space-3);
|
|
1707
|
+
}
|
|
1708
|
+
:where(.bp-choice--resolved) :where(.bp-choice__card) {
|
|
1709
|
+
cursor: default;
|
|
1710
|
+
}
|
|
1711
|
+
:where(.bp-choice__card[data-resolved]) {
|
|
1712
|
+
border: 2px solid var(--bp-ink);
|
|
1713
|
+
background: var(--bp-fill-amb);
|
|
1714
|
+
}
|
|
1715
|
+
:where(.bp-choice__card[data-resolved]) :where(.bp-choice__card-chosen) {
|
|
1716
|
+
display: inline-flex;
|
|
1717
|
+
}
|
|
1718
|
+
:where(.bp-choice--resolved) :where(.bp-choice__card:not([data-resolved])) {
|
|
1719
|
+
opacity: 0.62;
|
|
1720
|
+
background-image: var(--bp-hatch);
|
|
1721
|
+
}
|
|
1722
|
+
:where(.bp-choice--resolved) :where(.bp-choice__card:not([data-resolved])) :where(.bp-choice__card-rejected) {
|
|
1723
|
+
display: inline-flex;
|
|
1724
|
+
}
|
|
1725
|
+
|
|
1799
1726
|
/* ---- layout: gallery (mockup pick) ------------------------------- */
|
|
1800
1727
|
:where(.bp-choice--gallery) :where(.bp-choice__gallery) {
|
|
1801
1728
|
display: grid;
|
|
@@ -1807,7 +1734,7 @@
|
|
|
1807
1734
|
position: relative;
|
|
1808
1735
|
cursor: pointer;
|
|
1809
1736
|
border: 1px solid var(--bp-edge);
|
|
1810
|
-
border-radius: var(--bp-radius-
|
|
1737
|
+
border-radius: var(--bp-radius-0);
|
|
1811
1738
|
overflow: hidden;
|
|
1812
1739
|
background: var(--bp-paper);
|
|
1813
1740
|
}
|
|
@@ -1863,7 +1790,7 @@
|
|
|
1863
1790
|
:where(.bp-choice__compare) {
|
|
1864
1791
|
margin-top: var(--bp-space-3);
|
|
1865
1792
|
border: 1px solid var(--bp-edge);
|
|
1866
|
-
border-radius: var(--bp-radius-
|
|
1793
|
+
border-radius: var(--bp-radius-0);
|
|
1867
1794
|
}
|
|
1868
1795
|
:where(.bp-choice__compare > summary) {
|
|
1869
1796
|
cursor: pointer;
|
|
@@ -1886,7 +1813,7 @@
|
|
|
1886
1813
|
/* ---- Pre-flight (decisions before drafting) ---------------------- */
|
|
1887
1814
|
:where(.bp-preflight) {
|
|
1888
1815
|
border: 1px solid var(--bp-ink-line);
|
|
1889
|
-
border-radius: var(--bp-radius-
|
|
1816
|
+
border-radius: var(--bp-radius-0);
|
|
1890
1817
|
overflow: hidden;
|
|
1891
1818
|
margin: var(--bp-space-4) 0;
|
|
1892
1819
|
}
|
|
@@ -1908,7 +1835,7 @@
|
|
|
1908
1835
|
font-size: var(--bp-label-md);
|
|
1909
1836
|
letter-spacing: var(--bp-label-md-ls);
|
|
1910
1837
|
text-transform: uppercase;
|
|
1911
|
-
color: color-mix(in oklch, var(--bp-paper) 78%,
|
|
1838
|
+
color: color-mix(in oklch, var(--bp-paper) 78%, oklch(0 0 0 / 0));
|
|
1912
1839
|
}
|
|
1913
1840
|
:where(.bp-preflight__questions) {
|
|
1914
1841
|
counter-reset: bp-preflight-q;
|
|
@@ -1968,7 +1895,7 @@
|
|
|
1968
1895
|
gap: 7px;
|
|
1969
1896
|
cursor: pointer;
|
|
1970
1897
|
border: 1px solid var(--bp-ink-faint);
|
|
1971
|
-
border-radius: var(--bp-radius-
|
|
1898
|
+
border-radius: var(--bp-radius-0);
|
|
1972
1899
|
padding: 5px 12px;
|
|
1973
1900
|
font-size: var(--bp-text-small);
|
|
1974
1901
|
background: var(--bp-paper);
|
|
@@ -1988,7 +1915,7 @@
|
|
|
1988
1915
|
:where(.bp-preflight__gate) {
|
|
1989
1916
|
margin: var(--bp-space-3);
|
|
1990
1917
|
border: 1px dashed var(--bp-ink-line);
|
|
1991
|
-
border-radius: var(--bp-radius-
|
|
1918
|
+
border-radius: var(--bp-radius-0);
|
|
1992
1919
|
padding: var(--bp-space-4);
|
|
1993
1920
|
text-align: center;
|
|
1994
1921
|
background-image: var(--bp-hatch);
|
|
@@ -2013,7 +1940,7 @@
|
|
|
2013
1940
|
align-items: center;
|
|
2014
1941
|
gap: 8px;
|
|
2015
1942
|
border: 1px solid var(--bp-ink);
|
|
2016
|
-
border-radius: var(--bp-radius-
|
|
1943
|
+
border-radius: var(--bp-radius-0);
|
|
2017
1944
|
padding: 8px 16px;
|
|
2018
1945
|
font-family: var(--bp-mono);
|
|
2019
1946
|
font-size: var(--bp-label-md);
|
|
@@ -2037,7 +1964,7 @@
|
|
|
2037
1964
|
}
|
|
2038
1965
|
:where(.bp-choice-record__row) {
|
|
2039
1966
|
border: 1px solid var(--bp-edge);
|
|
2040
|
-
border-radius: var(--bp-radius-
|
|
1967
|
+
border-radius: var(--bp-radius-0);
|
|
2041
1968
|
padding: var(--bp-space-2) var(--bp-space-3);
|
|
2042
1969
|
display: grid;
|
|
2043
1970
|
grid-template-columns: minmax(8rem, 14rem) 1fr auto;
|
|
@@ -2080,30 +2007,161 @@
|
|
|
2080
2007
|
margin-inline: max(calc(50% - 50vw), calc((100% - var(--bp-wide)) / 2));
|
|
2081
2008
|
}
|
|
2082
2009
|
|
|
2083
|
-
/* ----
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2010
|
+
/* ---- <bp-table>: opt-in enhanced data table ----------------------
|
|
2011
|
+
The bare <table> stays the calm typographic primitive in @layer base.
|
|
2012
|
+
<bp-table> is the recommended wrapper when a table earns data-table
|
|
2013
|
+
behavior: the runtime wraps the author's <table> in a .bp-table-x scroll
|
|
2014
|
+
shell so horizontal overflow stays contained without making <bp-table> the
|
|
2015
|
+
sticky header's scroll ancestor. The host washes rows on hover, end-aligns
|
|
2016
|
+
numeric columns (runtime adds .bp-col-num), and opts into a sticky header /
|
|
2017
|
+
key column or a compact density. The inner <table> is author content and
|
|
2018
|
+
keeps its base styling untouched. All of it lives here in @layer components
|
|
2019
|
+
so a plain <table> is unchanged. */
|
|
2020
|
+
:where(bp-table) {
|
|
2088
2021
|
display: block;
|
|
2022
|
+
max-width: 100%;
|
|
2023
|
+
margin: var(--bp-space-3) 0 var(--bp-space-4);
|
|
2089
2024
|
}
|
|
2090
|
-
|
|
2091
|
-
|
|
2025
|
+
/* Horizontal scroll lives on the inner shell, not on <bp-table> itself, so a
|
|
2026
|
+
plain (non-sticky) table never makes the host an overflow ancestor. */
|
|
2027
|
+
:where(bp-table > .bp-table-x) {
|
|
2028
|
+
max-width: 100%;
|
|
2029
|
+
overflow-x: auto;
|
|
2092
2030
|
}
|
|
2093
|
-
|
|
2094
|
-
|
|
2031
|
+
/* [sticky] turns the shell into a self-contained scroll REGION: one element
|
|
2032
|
+
scrolls BOTH axes within an explicit block size, so the header sticks to
|
|
2033
|
+
the region's top edge and the header + body share a single horizontal
|
|
2034
|
+
scroll coordinate system (no desync), identically at every width and with
|
|
2035
|
+
`wide`. This is the only model that reconciles a sticky header with
|
|
2036
|
+
horizontal scroll — a pure-CSS page-scroll sticky header is impossible once
|
|
2037
|
+
an ancestor must scroll horizontally. Authors can retune the height with
|
|
2038
|
+
--bp-table-sticky-height. */
|
|
2039
|
+
:where(bp-table[sticky] > .bp-table-x) {
|
|
2040
|
+
max-height: var(--bp-table-sticky-height, min(70vh, 32rem));
|
|
2041
|
+
overflow: auto;
|
|
2042
|
+
}
|
|
2043
|
+
/* Sticky cells need border-collapse:separate — the base table rule uses
|
|
2044
|
+
collapse, which prevents position:sticky from engaging on th. */
|
|
2045
|
+
:where(bp-table[sticky] > .bp-table-x > table) {
|
|
2046
|
+
border-collapse: separate;
|
|
2047
|
+
border-spacing: 0;
|
|
2048
|
+
}
|
|
2049
|
+
/* The host owns the block rhythm; null the inner table's base margin so the
|
|
2050
|
+
scroll shell (a BFC) does not add a top/bottom gutter. The base
|
|
2051
|
+
`table { width: 100% }` makes the table shrink to exactly fill the shell,
|
|
2052
|
+
so it can never overflow and overflow-x:auto never scrolls - columns just
|
|
2053
|
+
crush. Size to content instead (min-width:100% still fills the band when
|
|
2054
|
+
the table is narrow), so a table wider than its band overflows and the
|
|
2055
|
+
shell scrolls horizontally. */
|
|
2056
|
+
:where(bp-table > .bp-table-x > table) {
|
|
2057
|
+
margin: 0;
|
|
2058
|
+
width: max-content;
|
|
2059
|
+
min-width: 100%;
|
|
2095
2060
|
}
|
|
2096
|
-
/*
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
gap: var(--bp-space-3);
|
|
2103
|
-
padding: var(--bp-space-2) var(--bp-space-3);
|
|
2061
|
+
/* Opt-in breakout: reuse the .bp-table-wrap--wide measure math. */
|
|
2062
|
+
:where(bp-table[wide]) {
|
|
2063
|
+
width: 100vw;
|
|
2064
|
+
max-width: var(--bp-wide);
|
|
2065
|
+
margin-inline: calc(50% - 50vw);
|
|
2066
|
+
margin-inline: max(calc(50% - 50vw), calc((100% - var(--bp-wide)) / 2));
|
|
2104
2067
|
}
|
|
2105
|
-
|
|
2106
|
-
|
|
2068
|
+
/* Inside the document shell, a wide table is an edge-aware scroll band. The
|
|
2069
|
+
wrapper breaks out to fill <main> from its left border to the right frame
|
|
2070
|
+
rule, but carries scroll padding equal to the prose offset on both ends.
|
|
2071
|
+
At rest the first column lines up with the body text while the band runs
|
|
2072
|
+
out to the frame rule on the right; scrolled to the end the last column
|
|
2073
|
+
stops on the text's right line while the earlier columns run out to
|
|
2074
|
+
<main>'s left border. The pad is the centered measure's offset from the
|
|
2075
|
+
sheet edge, and collapses to 0 once the measure fills the sheet (narrow
|
|
2076
|
+
widths), so the breakout simply disappears there. */
|
|
2077
|
+
:where(html[data-bp-document] bp-table[wide]) {
|
|
2078
|
+
--bp-wt-pad: max(
|
|
2079
|
+
0px,
|
|
2080
|
+
(
|
|
2081
|
+
100vw - var(--bp-shell-inset-left) - var(--bp-shell-inset-right) -
|
|
2082
|
+
(var(--bp-content) - 2 * var(--bp-space-6))
|
|
2083
|
+
) / 2
|
|
2084
|
+
);
|
|
2085
|
+
width: auto;
|
|
2086
|
+
max-width: none;
|
|
2087
|
+
margin-inline: calc(-1 * var(--bp-wt-pad));
|
|
2088
|
+
padding-inline: var(--bp-wt-pad);
|
|
2089
|
+
}
|
|
2090
|
+
/* Numeric columns — the runtime end-aligns a column's data cells AND its
|
|
2091
|
+
th[scope=col] by adding .bp-col-num (value-specific, so JS-driven). */
|
|
2092
|
+
:where(bp-table .bp-col-num) {
|
|
2093
|
+
text-align: end;
|
|
2094
|
+
}
|
|
2095
|
+
/* Row hover — wash the ambient fill across the row's cells. Transition on
|
|
2096
|
+
the resting cell so hover-in and hover-out both ease (tokens only). */
|
|
2097
|
+
:where(bp-table tbody tr :is(td, th)) {
|
|
2098
|
+
transition: background-color var(--bp-duration-fast) var(--bp-ease-out);
|
|
2099
|
+
}
|
|
2100
|
+
:where(bp-table tbody tr:hover :is(td, th)) {
|
|
2101
|
+
background: var(--bp-fill-amb);
|
|
2102
|
+
}
|
|
2103
|
+
/* Sticky header (opt-in [sticky]) — pins to the top of the scroll region as
|
|
2104
|
+
it scrolls vertically. Backgrounds are paper so scrolled rows never show
|
|
2105
|
+
through; the header out-stacks the sticky key column. */
|
|
2106
|
+
:where(bp-table[sticky] thead th) {
|
|
2107
|
+
position: sticky;
|
|
2108
|
+
top: 0;
|
|
2109
|
+
z-index: 3;
|
|
2110
|
+
background: var(--bp-paper);
|
|
2111
|
+
}
|
|
2112
|
+
/* Sticky key column — the row header pins to the left edge as the region
|
|
2113
|
+
scrolls horizontally, staying in sync with the header (one scroll box). */
|
|
2114
|
+
:where(bp-table[sticky] th[scope="row"]) {
|
|
2115
|
+
position: sticky;
|
|
2116
|
+
left: 0;
|
|
2117
|
+
z-index: 2;
|
|
2118
|
+
background: var(--bp-paper);
|
|
2119
|
+
}
|
|
2120
|
+
/* The pinned corner (column header above the key column) out-stacks both.
|
|
2121
|
+
Authors label the key column with scope="row" in tbody; the matching
|
|
2122
|
+
thead cell is scope="col", so pin the first header cell left. */
|
|
2123
|
+
:where(bp-table[sticky] thead th:first-child) {
|
|
2124
|
+
left: 0;
|
|
2125
|
+
z-index: 4;
|
|
2126
|
+
}
|
|
2127
|
+
/* Compact density — tighter cells; body cells drop to small, the mono
|
|
2128
|
+
column headers to the small label step. */
|
|
2129
|
+
:where(bp-table[density="compact"] :is(td, th)) {
|
|
2130
|
+
padding-top: var(--bp-space-1);
|
|
2131
|
+
padding-bottom: var(--bp-space-1);
|
|
2132
|
+
}
|
|
2133
|
+
:where(bp-table[density="compact"] :is(td, th[scope="row"])) {
|
|
2134
|
+
font-size: var(--bp-text-small);
|
|
2135
|
+
}
|
|
2136
|
+
:where(bp-table[density="compact"] :is(th[scope="col"], thead th)) {
|
|
2137
|
+
font-size: var(--bp-label-sm);
|
|
2138
|
+
letter-spacing: var(--bp-label-sm-ls);
|
|
2139
|
+
}
|
|
2140
|
+
|
|
2141
|
+
/* ---- Source disclosure -------------------------------------------
|
|
2142
|
+
A reusable source-code panel. The semantic shell is a native <details>;
|
|
2143
|
+
authors provide the explicit language/copy toolbar, blueprint-code.js
|
|
2144
|
+
enables the copy button, and blueprint-code.css adds Prism color. */
|
|
2145
|
+
:where(bp-source) {
|
|
2146
|
+
display: block;
|
|
2147
|
+
}
|
|
2148
|
+
:where(.bp-source) {
|
|
2149
|
+
padding: 0;
|
|
2150
|
+
}
|
|
2151
|
+
:where(.bp-source[open]) {
|
|
2152
|
+
padding-bottom: 0;
|
|
2153
|
+
}
|
|
2154
|
+
/* The summary IS the header bar: marker + intent label on the left, the
|
|
2155
|
+
language tag + copy action pushed to the right. One strip, then the code
|
|
2156
|
+
beneath it — no nested boxes. */
|
|
2157
|
+
:where(.bp-source > summary) {
|
|
2158
|
+
display: flex;
|
|
2159
|
+
align-items: center;
|
|
2160
|
+
gap: var(--bp-space-3);
|
|
2161
|
+
padding: var(--bp-space-2) var(--bp-space-3);
|
|
2162
|
+
}
|
|
2163
|
+
:where(.bp-source-name) {
|
|
2164
|
+
font-family: var(--bp-mono);
|
|
2107
2165
|
font-size: var(--bp-label-md);
|
|
2108
2166
|
letter-spacing: var(--bp-label-md-ls);
|
|
2109
2167
|
text-transform: uppercase;
|
|
@@ -2125,9 +2183,9 @@
|
|
|
2125
2183
|
:where(.bp-source-copy) {
|
|
2126
2184
|
appearance: none;
|
|
2127
2185
|
border: 1px solid var(--bp-ink-line);
|
|
2128
|
-
border-radius: var(--bp-radius-
|
|
2186
|
+
border-radius: var(--bp-radius-0);
|
|
2129
2187
|
padding: 4px var(--bp-space-2);
|
|
2130
|
-
background:
|
|
2188
|
+
background: oklch(0 0 0 / 0);
|
|
2131
2189
|
color: var(--bp-ink);
|
|
2132
2190
|
font-family: var(--bp-mono);
|
|
2133
2191
|
font-size: var(--bp-label-sm);
|
|
@@ -2222,7 +2280,7 @@
|
|
|
2222
2280
|
width: min(460px, calc(100vw - 20px));
|
|
2223
2281
|
padding: 0;
|
|
2224
2282
|
border: 1px solid var(--bp-ink-line);
|
|
2225
|
-
border-radius: var(--bp-radius-
|
|
2283
|
+
border-radius: var(--bp-radius-0);
|
|
2226
2284
|
background: var(--bp-paper);
|
|
2227
2285
|
color: var(--bp-text);
|
|
2228
2286
|
box-shadow: var(--bp-shadow-pop);
|
|
@@ -2261,7 +2319,7 @@
|
|
|
2261
2319
|
left: var(--bp-cite-caret, 50%);
|
|
2262
2320
|
width: 0;
|
|
2263
2321
|
height: 0;
|
|
2264
|
-
border: 7px solid
|
|
2322
|
+
border: 7px solid oklch(0 0 0 / 0);
|
|
2265
2323
|
transform: translateX(-50%);
|
|
2266
2324
|
}
|
|
2267
2325
|
:where(.bp-cite-pop[data-placement="top"])::before {
|
|
@@ -2312,88 +2370,63 @@
|
|
|
2312
2370
|
max-height: 320px;
|
|
2313
2371
|
margin: 0;
|
|
2314
2372
|
border: 0;
|
|
2315
|
-
border-radius: 0 0 var(--bp-radius-
|
|
2316
|
-
}
|
|
2317
|
-
|
|
2318
|
-
/* ---- SVG figure marks (1px hairline default via --bp-stroke) -------
|
|
2319
|
-
ILLUSTRATIONS are the one place blue lives. Node/edge line work draws
|
|
2320
|
-
in --bp-illustration; only the in-diagram TEXT labels stay neutral ink
|
|
2321
|
-
(text everywhere reads in the monochrome scale). */
|
|
2322
|
-
:where(.bp-node) {
|
|
2323
|
-
fill: var(--bp-paper);
|
|
2324
|
-
stroke: var(--bp-illustration);
|
|
2325
|
-
stroke-width: var(--bp-stroke);
|
|
2326
|
-
}
|
|
2327
|
-
:where(.bp-node--amb) {
|
|
2328
|
-
fill: var(--bp-illustration-fill);
|
|
2329
|
-
}
|
|
2330
|
-
/* Fenced node — a barrier / held step. Filled with the diagonal hatch
|
|
2331
|
-
paint server (define the <pattern> once in the figure's <defs>; see
|
|
2332
|
-
the .bp-hatch-fill / .bp-hatch-line tiles below). The .bp-node stroke
|
|
2333
|
-
keeps the illustration border. CSS gradients can't paint an SVG shape,
|
|
2334
|
-
so SVG uses a <pattern> while HTML uses the --bp-hatch gradient token. */
|
|
2335
|
-
:where(.bp-node--fenced) {
|
|
2336
|
-
fill: url(#bp-hatch);
|
|
2337
|
-
}
|
|
2338
|
-
/* Tiles for the SVG hatch <pattern> — token-driven so both themes track.
|
|
2339
|
-
The fill rect carries the illustration wash; the line is the drafting
|
|
2340
|
-
section-lining, both in the blue illustration family. */
|
|
2341
|
-
:where(.bp-hatch-fill) {
|
|
2342
|
-
fill: var(--bp-illustration-fill);
|
|
2343
|
-
}
|
|
2344
|
-
:where(.bp-hatch-line) {
|
|
2345
|
-
stroke: var(--bp-illustration-faint);
|
|
2346
|
-
stroke-width: var(--bp-stroke);
|
|
2347
|
-
}
|
|
2348
|
-
:where(.bp-edge) {
|
|
2349
|
-
fill: none;
|
|
2350
|
-
stroke: var(--bp-illustration);
|
|
2351
|
-
stroke-width: var(--bp-stroke);
|
|
2352
|
-
}
|
|
2353
|
-
:where(.bp-edge--skip) {
|
|
2354
|
-
stroke: var(--bp-illustration-soft);
|
|
2355
|
-
stroke-dasharray: 4 3;
|
|
2356
|
-
}
|
|
2357
|
-
:where(.bp-svg-label) {
|
|
2358
|
-
font-family: var(--bp-mono);
|
|
2359
|
-
font-size: 11px;
|
|
2360
|
-
fill: var(--bp-text);
|
|
2361
|
-
}
|
|
2362
|
-
:where(.bp-svg-meta) {
|
|
2363
|
-
font-family: var(--bp-mono);
|
|
2364
|
-
font-size: 9px;
|
|
2365
|
-
fill: var(--bp-text-secondary);
|
|
2366
|
-
}
|
|
2367
|
-
/* Callout terminator dot — illustration line work, so it draws in blue */
|
|
2368
|
-
:where(.bp-svg-dot) {
|
|
2369
|
-
fill: var(--bp-illustration);
|
|
2373
|
+
border-radius: 0 0 var(--bp-radius-0) var(--bp-radius-0);
|
|
2370
2374
|
}
|
|
2371
2375
|
|
|
2372
|
-
/* ----
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2376
|
+
/* ---- SVG paint utilities (diagrams live entirely in the blue ramp) -
|
|
2377
|
+
Color is the ONLY thing these set: line work AND labels are blue —
|
|
2378
|
+
there is no neutral/gray ink inside a figure. Everything else
|
|
2379
|
+
(stroke-width, stroke-dasharray, font-size, text-anchor, markers,
|
|
2380
|
+
geometry) is plain SVG the author writes as normal attributes; SVG's
|
|
2381
|
+
default stroke-width:1 already equals the hairline.
|
|
2382
|
+
svg-fill-{100..900} paints `fill` — interiors and label text
|
|
2383
|
+
svg-stroke-{100..900} paints `stroke` — outlines, edges, grids
|
|
2384
|
+
The number is ink STRENGTH, not absolute lightness: 900 is the
|
|
2385
|
+
strongest mark (label text, key strokes), 100 the faintest fill. So
|
|
2386
|
+
the ramp inverts under the dark theme (below) to stay legible while
|
|
2387
|
+
never leaving the blue family — authors only ever touch the classes.
|
|
2388
|
+
A class beats a fill=""/stroke="" presentation attribute; reach for
|
|
2389
|
+
style="" only to override a single element. */
|
|
2390
|
+
:where(:root) {
|
|
2391
|
+
--svg-blue-100: var(--bp-blue-100);
|
|
2392
|
+
--svg-blue-200: var(--bp-blue-200);
|
|
2393
|
+
--svg-blue-300: var(--bp-blue-300);
|
|
2394
|
+
--svg-blue-400: var(--bp-blue-400);
|
|
2395
|
+
--svg-blue-500: var(--bp-blue-500);
|
|
2396
|
+
--svg-blue-600: var(--bp-blue-600);
|
|
2397
|
+
--svg-blue-700: var(--bp-blue-700);
|
|
2398
|
+
--svg-blue-800: var(--bp-blue-800);
|
|
2399
|
+
--svg-blue-900: var(--bp-blue-900);
|
|
2396
2400
|
}
|
|
2401
|
+
:where([data-obvious-theme="dark"]) {
|
|
2402
|
+
--svg-blue-100: var(--bp-blue-900);
|
|
2403
|
+
--svg-blue-200: var(--bp-blue-800);
|
|
2404
|
+
--svg-blue-300: var(--bp-blue-700);
|
|
2405
|
+
--svg-blue-400: var(--bp-blue-600);
|
|
2406
|
+
--svg-blue-500: var(--bp-blue-500);
|
|
2407
|
+
--svg-blue-600: var(--bp-blue-400);
|
|
2408
|
+
--svg-blue-700: var(--bp-blue-300);
|
|
2409
|
+
--svg-blue-800: var(--bp-blue-200);
|
|
2410
|
+
--svg-blue-900: var(--bp-blue-100);
|
|
2411
|
+
}
|
|
2412
|
+
:where(.svg-fill-100) { fill: var(--svg-blue-100); }
|
|
2413
|
+
:where(.svg-fill-200) { fill: var(--svg-blue-200); }
|
|
2414
|
+
:where(.svg-fill-300) { fill: var(--svg-blue-300); }
|
|
2415
|
+
:where(.svg-fill-400) { fill: var(--svg-blue-400); }
|
|
2416
|
+
:where(.svg-fill-500) { fill: var(--svg-blue-500); }
|
|
2417
|
+
:where(.svg-fill-600) { fill: var(--svg-blue-600); }
|
|
2418
|
+
:where(.svg-fill-700) { fill: var(--svg-blue-700); }
|
|
2419
|
+
:where(.svg-fill-800) { fill: var(--svg-blue-800); }
|
|
2420
|
+
:where(.svg-fill-900) { fill: var(--svg-blue-900); }
|
|
2421
|
+
:where(.svg-stroke-100) { stroke: var(--svg-blue-100); }
|
|
2422
|
+
:where(.svg-stroke-200) { stroke: var(--svg-blue-200); }
|
|
2423
|
+
:where(.svg-stroke-300) { stroke: var(--svg-blue-300); }
|
|
2424
|
+
:where(.svg-stroke-400) { stroke: var(--svg-blue-400); }
|
|
2425
|
+
:where(.svg-stroke-500) { stroke: var(--svg-blue-500); }
|
|
2426
|
+
:where(.svg-stroke-600) { stroke: var(--svg-blue-600); }
|
|
2427
|
+
:where(.svg-stroke-700) { stroke: var(--svg-blue-700); }
|
|
2428
|
+
:where(.svg-stroke-800) { stroke: var(--svg-blue-800); }
|
|
2429
|
+
:where(.svg-stroke-900) { stroke: var(--svg-blue-900); }
|
|
2397
2430
|
|
|
2398
2431
|
/* ---- Masthead title-block: a metadata strip (author/date/status) - */
|
|
2399
2432
|
:where(.bp-title-block) {
|
|
@@ -2549,6 +2582,10 @@
|
|
|
2549
2582
|
margin: 0;
|
|
2550
2583
|
padding: 0;
|
|
2551
2584
|
list-style: none;
|
|
2585
|
+
/* Primary label text starts after pad + index tick + gap — sub-entries
|
|
2586
|
+
reuse this inset so their labels line up with the row above. */
|
|
2587
|
+
--bp-toc-index-w: 14px;
|
|
2588
|
+
--bp-toc-label-inset: calc(var(--bp-space-3) + var(--bp-toc-index-w) + var(--bp-space-2));
|
|
2552
2589
|
}
|
|
2553
2590
|
/* The gliding active pill, drawn behind the entries and travelling via
|
|
2554
2591
|
--bp-toc-y / --bp-toc-h (set by blueprint.js). */
|
|
@@ -2591,45 +2628,72 @@
|
|
|
2591
2628
|
text-decoration: none;
|
|
2592
2629
|
padding: 6px var(--bp-space-3);
|
|
2593
2630
|
border-radius: var(--bp-radius-6);
|
|
2594
|
-
/*
|
|
2595
|
-
|
|
2596
|
-
transition
|
|
2597
|
-
transition-timing-function: var(--bp-ease);
|
|
2631
|
+
/* Idle entries snap on theme flip so the root crossfade isn't fighting
|
|
2632
|
+
per-row token tweens (labels + index numbers alike). */
|
|
2633
|
+
transition: none;
|
|
2598
2634
|
}
|
|
2599
2635
|
/* Auto-numbered index (01, 02…), tabular so the digits line up. */
|
|
2600
2636
|
:where(.bp-sidebar > ul > li > a, .bp-sidebar__panel > ul > li > a, .bp-toc > ul > li > a)::before {
|
|
2601
2637
|
content: counter(bp-toc, decimal-leading-zero);
|
|
2602
|
-
flex: 0 0
|
|
2638
|
+
flex: 0 0 var(--bp-toc-index-w, 14px);
|
|
2639
|
+
min-width: var(--bp-toc-index-w, 14px);
|
|
2603
2640
|
font-size: var(--bp-label-lg);
|
|
2604
2641
|
font-variant-numeric: tabular-nums;
|
|
2605
2642
|
letter-spacing: 0.02em;
|
|
2606
2643
|
color: var(--bp-ink-soft);
|
|
2607
|
-
|
|
2608
|
-
transition-property: color;
|
|
2609
|
-
transition-duration: var(--bp-duration-fast);
|
|
2610
|
-
transition-timing-function: var(--bp-ease);
|
|
2644
|
+
transition: none;
|
|
2611
2645
|
}
|
|
2612
|
-
/* Nested sub-entries
|
|
2646
|
+
/* Nested sub-entries align with primary label text and read tighter. */
|
|
2613
2647
|
:where(.bp-sidebar ul ul, .bp-toc ul ul) {
|
|
2614
|
-
margin: 0;
|
|
2615
|
-
padding: 0
|
|
2648
|
+
margin: 0 0 var(--bp-space-1);
|
|
2649
|
+
padding: 0;
|
|
2616
2650
|
list-style: none;
|
|
2617
2651
|
}
|
|
2618
2652
|
:where(.bp-sidebar ul ul a, .bp-toc ul ul a) {
|
|
2653
|
+
display: block;
|
|
2619
2654
|
font-size: var(--bp-text-small);
|
|
2655
|
+
line-height: 1.25;
|
|
2656
|
+
padding: 1px var(--bp-space-3) 1px var(--bp-toc-label-inset);
|
|
2657
|
+
}
|
|
2658
|
+
/* Group eyebrow row — a quiet mono kicker that heads a run of entries. It is
|
|
2659
|
+
a flat sibling of the entry items (so the gliding pill + scroll-spy are
|
|
2660
|
+
untouched) and is skipped by the auto-numbering counter, keeping the
|
|
2661
|
+
section numbers continuous with the document's own section eyebrows. */
|
|
2662
|
+
:where(.bp-sidebar .bp-nav-group, .bp-toc .bp-nav-group) {
|
|
2663
|
+
counter-increment: none;
|
|
2664
|
+
margin: var(--bp-space-4) 0 var(--bp-space-1);
|
|
2665
|
+
}
|
|
2666
|
+
:where(.bp-sidebar .bp-nav-group:first-child, .bp-toc .bp-nav-group:first-child) {
|
|
2667
|
+
margin-top: var(--bp-space-1);
|
|
2668
|
+
}
|
|
2669
|
+
:where(.bp-nav-group__label) {
|
|
2670
|
+
display: block;
|
|
2671
|
+
padding: 0 var(--bp-space-3);
|
|
2672
|
+
font-family: var(--bp-mono);
|
|
2673
|
+
font-size: var(--bp-label-sm);
|
|
2674
|
+
letter-spacing: var(--bp-label-sm-ls);
|
|
2675
|
+
text-transform: uppercase;
|
|
2676
|
+
color: var(--bp-text-secondary);
|
|
2620
2677
|
}
|
|
2621
2678
|
/* Hover shows its own subtle pill; the active entry rides the gliding pill
|
|
2622
2679
|
above (so it keeps no own background) and reads in ink + medium weight. */
|
|
2623
2680
|
:where(.bp-sidebar a:hover, .bp-toc a:hover) {
|
|
2624
2681
|
color: var(--bp-ink);
|
|
2625
2682
|
background: var(--bp-fill-amb);
|
|
2683
|
+
transition:
|
|
2684
|
+
color var(--bp-duration-fast) var(--bp-ease),
|
|
2685
|
+
background-color var(--bp-duration-fast) var(--bp-ease);
|
|
2626
2686
|
}
|
|
2627
2687
|
:where(.bp-sidebar a[aria-current="location"], .bp-toc a[aria-current="location"], .bp-sidebar a.active, .bp-sidebar a.is-active, .bp-toc a.active, .bp-toc a.is-active) {
|
|
2628
2688
|
color: var(--bp-ink);
|
|
2629
2689
|
background: none;
|
|
2630
2690
|
font-weight: var(--bp-weight-medium);
|
|
2631
2691
|
}
|
|
2632
|
-
:where(.bp-sidebar a:hover::before, .bp-toc a:hover::before
|
|
2692
|
+
:where(.bp-sidebar a:hover::before, .bp-toc a:hover::before) {
|
|
2693
|
+
color: var(--bp-ink);
|
|
2694
|
+
transition: color var(--bp-duration-fast) var(--bp-ease);
|
|
2695
|
+
}
|
|
2696
|
+
:where(.bp-sidebar a[aria-current="location"]::before, .bp-toc a[aria-current="location"]::before, .bp-sidebar a.active::before, .bp-toc a.active::before) {
|
|
2633
2697
|
color: var(--bp-ink);
|
|
2634
2698
|
}
|
|
2635
2699
|
/* ---- Full-width contents block -----------------------------------
|
|
@@ -2656,6 +2720,25 @@
|
|
|
2656
2720
|
counter-increment: bp-contents;
|
|
2657
2721
|
margin: 0;
|
|
2658
2722
|
}
|
|
2723
|
+
/* Group eyebrow in the inline index: a full-width band that breaks the grid
|
|
2724
|
+
into labelled runs. Skipped by the numbering counter (it carries no link),
|
|
2725
|
+
so entry numbers stay continuous across groups. */
|
|
2726
|
+
:where(.bp-contents-group) {
|
|
2727
|
+
grid-column: 1 / -1;
|
|
2728
|
+
counter-increment: none;
|
|
2729
|
+
margin: var(--bp-space-4) 0 var(--bp-space-1);
|
|
2730
|
+
}
|
|
2731
|
+
:where(.bp-contents-group:first-child) {
|
|
2732
|
+
margin-top: 0;
|
|
2733
|
+
}
|
|
2734
|
+
:where(.bp-contents-group__label) {
|
|
2735
|
+
display: block;
|
|
2736
|
+
font-family: var(--bp-mono);
|
|
2737
|
+
font-size: var(--bp-label-sm);
|
|
2738
|
+
letter-spacing: var(--bp-label-sm-ls);
|
|
2739
|
+
text-transform: uppercase;
|
|
2740
|
+
color: var(--bp-text-secondary);
|
|
2741
|
+
}
|
|
2659
2742
|
:where(.bp-contents a) {
|
|
2660
2743
|
display: flex;
|
|
2661
2744
|
align-items: baseline;
|
|
@@ -2708,13 +2791,10 @@
|
|
|
2708
2791
|
transform: translateX(var(--bp-space-1));
|
|
2709
2792
|
}
|
|
2710
2793
|
|
|
2711
|
-
/* Column frame: the
|
|
2712
|
-
desk margin
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
solid top band masking scroll bleed into the margin. Shadows off while
|
|
2716
|
-
testing. */
|
|
2717
|
-
:where(html:has(.bp-shell)) {
|
|
2794
|
+
/* Column frame: the PAGE scrolls, while fixed top/bottom bands + fixed vertical
|
|
2795
|
+
edge rules hold the desk margin on all four sides. <main> sits in normal
|
|
2796
|
+
flow (paper sheet); the sidebar rail stays fixed. */
|
|
2797
|
+
:where(html[data-bp-document]) {
|
|
2718
2798
|
--bp-shell-inset-block: var(--bp-space-4);
|
|
2719
2799
|
--bp-shell-inset-top: var(--bp-shell-inset-block);
|
|
2720
2800
|
--bp-shell-inset-left: var(--bp-sidebar);
|
|
@@ -2727,29 +2807,43 @@
|
|
|
2727
2807
|
--bp-frame-line-z: 210;
|
|
2728
2808
|
--bp-scroll-margin: var(--bp-space-6);
|
|
2729
2809
|
}
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
-
|
|
2810
|
+
/* Top/bottom desk bands are body padding so the sheet clears the fixed
|
|
2811
|
+
frame rules and the page tail is not occluded by the bottom band. */
|
|
2812
|
+
:where(html[data-bp-document] body) {
|
|
2813
|
+
padding-top: var(--bp-shell-inset-top);
|
|
2814
|
+
padding-bottom: var(--bp-shell-inset-block);
|
|
2815
|
+
}
|
|
2816
|
+
/* <main> is the paper sheet spanning the full column between the vertical
|
|
2817
|
+
frame rules; direct children keep the prose measure from Tier 1b. Keep the
|
|
2818
|
+
shell out of the overflow/scroll chain so viewport-fixed navigation nested
|
|
2819
|
+
by stored Blueprints is not clipped by WebKit. The page owns scrolling. */
|
|
2820
|
+
:where(html[data-bp-document] main) {
|
|
2821
|
+
max-width: none;
|
|
2822
|
+
overflow: visible;
|
|
2823
|
+
margin: 0 var(--bp-shell-inset-right) 0 var(--bp-shell-inset-left);
|
|
2824
|
+
min-height: calc(
|
|
2825
|
+
100vh - var(--bp-shell-inset-top) - var(--bp-shell-inset-block)
|
|
2826
|
+
);
|
|
2742
2827
|
background: var(--bp-paper);
|
|
2743
2828
|
border: 0;
|
|
2744
2829
|
border-radius: var(--bp-radius-0);
|
|
2745
2830
|
box-shadow: none;
|
|
2746
2831
|
}
|
|
2747
|
-
/*
|
|
2748
|
-
|
|
2749
|
-
|
|
2832
|
+
/* Same inner measure as max-width: var(--bp-content) on a padded main, and
|
|
2833
|
+
auto margins center that measure within the sheet so the reading column
|
|
2834
|
+
sits balanced between the frame rules. The sheet's own box shrinks when the
|
|
2835
|
+
rail collapses (margin-inline transition above), so the centered measure
|
|
2836
|
+
re-centers in step with the slide rather than hugging the left rule. */
|
|
2837
|
+
:where(html[data-bp-document] main > *) {
|
|
2838
|
+
max-width: min(100%, calc(var(--bp-content) - 2 * var(--bp-space-6)));
|
|
2839
|
+
margin-inline: auto;
|
|
2840
|
+
}
|
|
2841
|
+
/* TOC / hash targets — reserve top air so a heading clears the fixed top
|
|
2842
|
+
band instead of landing flush beneath it. */
|
|
2843
|
+
:where(html[data-bp-document] main :is(section[id], [id][data-sidebar])) {
|
|
2750
2844
|
scroll-margin-top: var(--bp-scroll-margin);
|
|
2751
2845
|
}
|
|
2752
|
-
:where(html
|
|
2846
|
+
:where(html[data-bp-document])::before {
|
|
2753
2847
|
content: "";
|
|
2754
2848
|
position: fixed;
|
|
2755
2849
|
inset-inline: 0;
|
|
@@ -2759,7 +2853,7 @@
|
|
|
2759
2853
|
pointer-events: none;
|
|
2760
2854
|
z-index: var(--bp-frame-line-z);
|
|
2761
2855
|
}
|
|
2762
|
-
:where(html
|
|
2856
|
+
:where(html[data-bp-document])::after {
|
|
2763
2857
|
content: "";
|
|
2764
2858
|
position: fixed;
|
|
2765
2859
|
inset-block: 0;
|
|
@@ -2775,10 +2869,10 @@
|
|
|
2775
2869
|
var(--bp-shell-inset-left) 0,
|
|
2776
2870
|
calc(100% - var(--bp-shell-inset-right)) 0;
|
|
2777
2871
|
}
|
|
2778
|
-
/* Top
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
:where(
|
|
2872
|
+
/* Top/bottom desk bands (fixed) mask the page scrolling beneath them; the
|
|
2873
|
+
bottom band draws the lower horizontal at its top edge. Frame lines sit
|
|
2874
|
+
above rail scrims so the verticals run edge-to-edge through horizontals. */
|
|
2875
|
+
:where(html[data-bp-document] body)::before {
|
|
2782
2876
|
content: "";
|
|
2783
2877
|
position: fixed;
|
|
2784
2878
|
inset-inline: 0;
|
|
@@ -2788,15 +2882,16 @@
|
|
|
2788
2882
|
pointer-events: none;
|
|
2789
2883
|
z-index: var(--bp-shell-mask-z);
|
|
2790
2884
|
}
|
|
2791
|
-
:where(
|
|
2885
|
+
:where(html[data-bp-document] body)::after {
|
|
2792
2886
|
content: "";
|
|
2793
2887
|
position: fixed;
|
|
2794
2888
|
inset-inline: 0;
|
|
2795
|
-
|
|
2889
|
+
bottom: 0;
|
|
2890
|
+
height: var(--bp-shell-inset-block);
|
|
2796
2891
|
border-top: var(--bp-stroke) solid var(--bp-edge);
|
|
2892
|
+
background: var(--bp-bg);
|
|
2797
2893
|
pointer-events: none;
|
|
2798
2894
|
z-index: var(--bp-frame-line-z);
|
|
2799
|
-
bottom: var(--bp-shell-inset-block);
|
|
2800
2895
|
}
|
|
2801
2896
|
:where(.scroll-progress) {
|
|
2802
2897
|
position: fixed;
|
|
@@ -2815,124 +2910,475 @@
|
|
|
2815
2910
|
transition-duration: var(--bp-duration-instant);
|
|
2816
2911
|
transition-timing-function: var(--bp-ease-linear);
|
|
2817
2912
|
}
|
|
2818
|
-
}
|
|
2819
2913
|
|
|
2820
|
-
/*
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
z-index: 100;
|
|
2914
|
+
/* ---- <bp-mock> — drafting browser frame for UX mockups ------------
|
|
2915
|
+
The frame is CHROME, so it is drawn in the neutral ink scale; the
|
|
2916
|
+
sketch inside keeps the illustration-blue ramp. `viewport` draws the
|
|
2917
|
+
canvas at a fixed pixel width and scales it to fit (crisp 1:1 when the
|
|
2918
|
+
frame is wide enough or expanded); the expand control lifts the frame
|
|
2919
|
+
into a near-fullscreen overlay over a drafting scrim. */
|
|
2920
|
+
:where(.bp-mock) {
|
|
2921
|
+
display: block;
|
|
2922
|
+
margin: var(--bp-space-4) 0;
|
|
2830
2923
|
}
|
|
2831
|
-
:where(.
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2924
|
+
:where(.bp-mock__frame) {
|
|
2925
|
+
display: flex;
|
|
2926
|
+
flex-direction: column;
|
|
2927
|
+
border: var(--bp-stroke) solid var(--bp-ink-line);
|
|
2928
|
+
border-radius: var(--bp-radius-0);
|
|
2929
|
+
background: var(--bp-paper);
|
|
2930
|
+
overflow: hidden;
|
|
2835
2931
|
}
|
|
2836
|
-
:where(.
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2932
|
+
:where(.bp-mock__bar) {
|
|
2933
|
+
display: flex;
|
|
2934
|
+
align-items: center;
|
|
2935
|
+
gap: var(--bp-space-2);
|
|
2936
|
+
min-height: 34px;
|
|
2937
|
+
padding: var(--bp-space-2) var(--bp-space-3);
|
|
2938
|
+
border-bottom: var(--bp-stroke) solid var(--bp-edge);
|
|
2939
|
+
background: var(--bp-fill-amb);
|
|
2841
2940
|
}
|
|
2842
|
-
:where(.
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
color: var(--text-secondary);
|
|
2847
|
-
margin-top: 6px;
|
|
2941
|
+
:where(.bp-mock__ticks) {
|
|
2942
|
+
display: inline-flex;
|
|
2943
|
+
gap: 5px;
|
|
2944
|
+
flex: 0 0 auto;
|
|
2848
2945
|
}
|
|
2849
|
-
:where(.
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
display: flex;
|
|
2855
|
-
flex-direction: column;
|
|
2946
|
+
:where(.bp-mock__ticks i) {
|
|
2947
|
+
width: 8px;
|
|
2948
|
+
height: 8px;
|
|
2949
|
+
border-radius: var(--bp-radius-0);
|
|
2950
|
+
border: var(--bp-stroke) solid var(--bp-ink-faint);
|
|
2856
2951
|
}
|
|
2857
|
-
:where(.
|
|
2858
|
-
|
|
2952
|
+
:where(.bp-mock__label) {
|
|
2953
|
+
flex: 1 1 auto;
|
|
2954
|
+
min-width: 0;
|
|
2955
|
+
font-family: var(--bp-mono);
|
|
2956
|
+
font-size: var(--bp-label-md);
|
|
2957
|
+
letter-spacing: var(--bp-label-md-ls);
|
|
2958
|
+
color: var(--bp-text-secondary);
|
|
2959
|
+
white-space: nowrap;
|
|
2960
|
+
overflow: hidden;
|
|
2961
|
+
text-overflow: ellipsis;
|
|
2962
|
+
}
|
|
2963
|
+
:where(.bp-mock__btn) {
|
|
2964
|
+
display: inline-flex;
|
|
2965
|
+
align-items: center;
|
|
2966
|
+
justify-content: center;
|
|
2967
|
+
flex: 0 0 auto;
|
|
2968
|
+
width: 24px;
|
|
2969
|
+
height: 24px;
|
|
2859
2970
|
padding: 0;
|
|
2971
|
+
border: var(--bp-stroke) solid var(--bp-edge);
|
|
2972
|
+
border-radius: var(--bp-radius-0);
|
|
2973
|
+
background: var(--bp-paper);
|
|
2974
|
+
color: var(--bp-text-secondary);
|
|
2975
|
+
cursor: pointer;
|
|
2860
2976
|
}
|
|
2861
|
-
:where(.
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
font: 400 12px/1.35 var(--sans);
|
|
2865
|
-
color: var(--text-secondary);
|
|
2866
|
-
text-decoration: none;
|
|
2867
|
-
padding: 7px 10px 7px 36px;
|
|
2977
|
+
:where(.bp-mock__btn svg) {
|
|
2978
|
+
width: 14px;
|
|
2979
|
+
height: 14px;
|
|
2868
2980
|
}
|
|
2869
|
-
:where(.
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
position: absolute;
|
|
2873
|
-
left: 10px;
|
|
2874
|
-
top: 8px;
|
|
2875
|
-
font: 400 10px/1 var(--mono);
|
|
2876
|
-
letter-spacing: 0.06em;
|
|
2877
|
-
color: var(--ink-faint);
|
|
2981
|
+
:where(.bp-mock__btn:hover) {
|
|
2982
|
+
color: var(--bp-text);
|
|
2983
|
+
border-color: var(--bp-ink-line);
|
|
2878
2984
|
}
|
|
2879
|
-
:where(.
|
|
2880
|
-
|
|
2881
|
-
|
|
2985
|
+
:where(.bp-mock__btn:focus-visible) {
|
|
2986
|
+
outline: 2px solid var(--bp-ink);
|
|
2987
|
+
outline-offset: 2px;
|
|
2882
2988
|
}
|
|
2883
|
-
:where(.
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
width: 2px;
|
|
2888
|
-
background: var(--ink);
|
|
2989
|
+
:where(.bp-mock__stage) {
|
|
2990
|
+
position: relative;
|
|
2991
|
+
overflow: hidden;
|
|
2992
|
+
background: var(--bp-bg);
|
|
2889
2993
|
}
|
|
2890
|
-
:where(.
|
|
2891
|
-
|
|
2994
|
+
:where(.bp-mock__canvas) {
|
|
2995
|
+
transform-origin: top left;
|
|
2996
|
+
transform: scale(var(--bp-mock-scale, 1));
|
|
2892
2997
|
}
|
|
2893
|
-
|
|
2998
|
+
|
|
2999
|
+
/* Expanded → near-fullscreen overlay; the frame floats over a drafting
|
|
3000
|
+
scrim (ink wash + hatch). The frame itself stays the bordered window. */
|
|
3001
|
+
:where(.bp-mock.is-expanded) {
|
|
3002
|
+
position: fixed;
|
|
3003
|
+
inset: 0;
|
|
3004
|
+
/* Above the fixed rail (100), scroll-progress (200), and frame rules
|
|
3005
|
+
(210) so the overlay fully covers the document chrome. */
|
|
3006
|
+
z-index: 300;
|
|
2894
3007
|
margin: 0;
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
3008
|
+
display: grid;
|
|
3009
|
+
place-items: center;
|
|
3010
|
+
padding: clamp(var(--bp-space-4), 4vw, var(--bp-space-7));
|
|
3011
|
+
background-color: var(--bp-scrim);
|
|
3012
|
+
background-image: var(--bp-hatch);
|
|
2898
3013
|
}
|
|
2899
|
-
:where(.
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
3014
|
+
:where(.bp-mock.is-expanded) :where(.bp-mock__frame) {
|
|
3015
|
+
width: min(100%, 1120px);
|
|
3016
|
+
max-height: 100%;
|
|
3017
|
+
box-shadow: var(--bp-shadow-pop);
|
|
2903
3018
|
}
|
|
2904
|
-
:where(.
|
|
2905
|
-
|
|
2906
|
-
letter-spacing: 0.14em;
|
|
2907
|
-
text-transform: uppercase;
|
|
2908
|
-
color: var(--ink-soft);
|
|
2909
|
-
margin-bottom: 16px;
|
|
3019
|
+
:where(.bp-mock.is-expanded) :where(.bp-mock__stage) {
|
|
3020
|
+
overflow: auto;
|
|
2910
3021
|
}
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
3022
|
+
|
|
3023
|
+
/* ---- <bp-gallery> — image grid with a lightbox viewer -------------
|
|
3024
|
+
A tidy responsive grid of images (screenshots, mockups, uploads).
|
|
3025
|
+
Each thumbnail wears a BLUESCALE treatment by default — the raster
|
|
3026
|
+
is desaturated and a blue veil (.bp-gallery__wash) color-blends over
|
|
3027
|
+
it — and reveals its true color on hover/focus. Activating a tile
|
|
3028
|
+
opens .bp-lightbox, a near-fullscreen viewer over a drafting scrim. */
|
|
3029
|
+
:where(.bp-gallery) {
|
|
3030
|
+
display: block;
|
|
3031
|
+
margin: var(--bp-space-5) 0;
|
|
2915
3032
|
}
|
|
2916
|
-
:where(.
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
3033
|
+
:where(.bp-gallery__grid) {
|
|
3034
|
+
display: grid;
|
|
3035
|
+
grid-template-columns: repeat(auto-fill, minmax(min(100%, 200px), 1fr));
|
|
3036
|
+
gap: var(--bp-space-3);
|
|
2920
3037
|
}
|
|
2921
|
-
:where(.
|
|
2922
|
-
margin-top: 34px;
|
|
2923
|
-
border: 1px solid var(--ink-line);
|
|
3038
|
+
:where(.bp-gallery__item) {
|
|
2924
3039
|
display: flex;
|
|
2925
|
-
flex-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
padding:
|
|
2930
|
-
border
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
3040
|
+
flex-direction: column;
|
|
3041
|
+
gap: var(--bp-space-2);
|
|
3042
|
+
min-width: 0;
|
|
3043
|
+
margin: 0;
|
|
3044
|
+
padding: 0;
|
|
3045
|
+
border: 0;
|
|
3046
|
+
background: none;
|
|
3047
|
+
text-align: left;
|
|
3048
|
+
cursor: pointer;
|
|
3049
|
+
font: inherit;
|
|
3050
|
+
color: inherit;
|
|
3051
|
+
}
|
|
3052
|
+
:where(.bp-gallery__thumb) {
|
|
3053
|
+
position: relative;
|
|
3054
|
+
display: block;
|
|
3055
|
+
overflow: hidden;
|
|
3056
|
+
aspect-ratio: 4 / 3;
|
|
3057
|
+
border: var(--bp-stroke) solid var(--bp-ink-line);
|
|
3058
|
+
border-radius: var(--bp-radius-0);
|
|
3059
|
+
background: var(--bp-bg);
|
|
3060
|
+
}
|
|
3061
|
+
:where(.bp-gallery__img) {
|
|
3062
|
+
display: block;
|
|
3063
|
+
width: 100%;
|
|
3064
|
+
height: 100%;
|
|
3065
|
+
object-fit: cover;
|
|
3066
|
+
/* Bluescale: drop saturation; the wash supplies the blue cast. */
|
|
3067
|
+
filter: grayscale(1) contrast(1.02);
|
|
3068
|
+
transition:
|
|
3069
|
+
filter var(--bp-duration-slow) var(--bp-ease-out),
|
|
3070
|
+
transform var(--bp-duration-slow) var(--bp-ease-out);
|
|
3071
|
+
}
|
|
3072
|
+
:where(.bp-gallery__wash) {
|
|
3073
|
+
position: absolute;
|
|
3074
|
+
inset: 0;
|
|
3075
|
+
background: var(--bp-illustration);
|
|
3076
|
+
mix-blend-mode: color;
|
|
3077
|
+
opacity: 0.85;
|
|
3078
|
+
transition: opacity var(--bp-duration-slow) var(--bp-ease-out);
|
|
3079
|
+
pointer-events: none;
|
|
3080
|
+
}
|
|
3081
|
+
:where(.bp-gallery__zoom) {
|
|
3082
|
+
position: absolute;
|
|
3083
|
+
inset: auto var(--bp-space-2) var(--bp-space-2) auto;
|
|
3084
|
+
display: inline-flex;
|
|
3085
|
+
align-items: center;
|
|
3086
|
+
justify-content: center;
|
|
3087
|
+
width: 28px;
|
|
3088
|
+
height: 28px;
|
|
3089
|
+
border-radius: var(--bp-radius-0);
|
|
3090
|
+
background: var(--bp-paper);
|
|
3091
|
+
color: var(--bp-text-secondary);
|
|
3092
|
+
box-shadow: var(--bp-shadow-pop);
|
|
3093
|
+
opacity: 0;
|
|
3094
|
+
transform: translateY(4px);
|
|
3095
|
+
transition:
|
|
3096
|
+
opacity var(--bp-duration-fast) var(--bp-ease-out),
|
|
3097
|
+
transform var(--bp-duration-fast) var(--bp-ease-out);
|
|
3098
|
+
pointer-events: none;
|
|
3099
|
+
}
|
|
3100
|
+
:where(.bp-gallery__zoom svg) {
|
|
3101
|
+
width: 16px;
|
|
3102
|
+
height: 16px;
|
|
3103
|
+
}
|
|
3104
|
+
/* Reveal true color on hover or keyboard focus. */
|
|
3105
|
+
:where(.bp-gallery__item:hover, .bp-gallery__item:focus-visible)
|
|
3106
|
+
:where(.bp-gallery__img) {
|
|
3107
|
+
filter: none;
|
|
3108
|
+
transform: scale(1.03);
|
|
3109
|
+
}
|
|
3110
|
+
:where(.bp-gallery__item:hover, .bp-gallery__item:focus-visible)
|
|
3111
|
+
:where(.bp-gallery__wash) {
|
|
3112
|
+
opacity: 0;
|
|
3113
|
+
}
|
|
3114
|
+
:where(.bp-gallery__item:hover, .bp-gallery__item:focus-visible)
|
|
3115
|
+
:where(.bp-gallery__zoom) {
|
|
3116
|
+
opacity: 1;
|
|
3117
|
+
transform: translateY(0);
|
|
3118
|
+
}
|
|
3119
|
+
:where(.bp-gallery__item:focus-visible) :where(.bp-gallery__thumb) {
|
|
3120
|
+
outline: 2px solid var(--bp-ink);
|
|
3121
|
+
outline-offset: 2px;
|
|
3122
|
+
}
|
|
3123
|
+
:where(.bp-gallery__caption) {
|
|
3124
|
+
font-family: var(--bp-mono);
|
|
3125
|
+
font-size: var(--bp-label-md);
|
|
3126
|
+
letter-spacing: var(--bp-label-md-ls);
|
|
3127
|
+
color: var(--bp-text-secondary);
|
|
3128
|
+
overflow: hidden;
|
|
3129
|
+
text-overflow: ellipsis;
|
|
3130
|
+
white-space: nowrap;
|
|
3131
|
+
}
|
|
3132
|
+
|
|
3133
|
+
/* The lightbox is appended to <body> by the runtime; hidden until open. */
|
|
3134
|
+
:where(.bp-lightbox) {
|
|
3135
|
+
/* Scrim inset and the room reserved for the caption row below the
|
|
3136
|
+
image, so a portrait image taller than the viewport scales down
|
|
3137
|
+
instead of pushing its caption off-screen. */
|
|
3138
|
+
--bp-lightbox-pad: clamp(var(--bp-space-4), 4vw, var(--bp-space-7));
|
|
3139
|
+
--bp-lightbox-meta: calc(var(--bp-space-3) + var(--bp-space-5));
|
|
3140
|
+
position: fixed;
|
|
3141
|
+
inset: 0;
|
|
3142
|
+
z-index: 300;
|
|
3143
|
+
display: none;
|
|
3144
|
+
/* Side columns reserve the prev/next controls; the figure rides the
|
|
3145
|
+
centered middle column and the single 1fr row fills the height so
|
|
3146
|
+
the image is centered on both axes. */
|
|
3147
|
+
grid-template-columns: auto minmax(0, 1fr) auto;
|
|
3148
|
+
grid-template-rows: minmax(0, 1fr);
|
|
3149
|
+
align-items: center;
|
|
3150
|
+
justify-items: center;
|
|
3151
|
+
gap: var(--bp-space-3);
|
|
3152
|
+
padding: var(--bp-lightbox-pad);
|
|
3153
|
+
background-color: var(--bp-scrim);
|
|
3154
|
+
background-image: var(--bp-hatch);
|
|
3155
|
+
}
|
|
3156
|
+
:where(.bp-lightbox.is-open) {
|
|
3157
|
+
display: grid;
|
|
3158
|
+
}
|
|
3159
|
+
:where(.bp-lightbox__figure) {
|
|
3160
|
+
grid-column: 2;
|
|
3161
|
+
display: flex;
|
|
3162
|
+
flex-direction: column;
|
|
3163
|
+
align-items: center;
|
|
3164
|
+
justify-content: center;
|
|
3165
|
+
gap: var(--bp-space-3);
|
|
3166
|
+
margin: 0;
|
|
3167
|
+
min-width: 0;
|
|
3168
|
+
min-height: 0;
|
|
3169
|
+
max-width: 100%;
|
|
3170
|
+
max-height: 100%;
|
|
3171
|
+
}
|
|
3172
|
+
:where(.bp-lightbox__img) {
|
|
3173
|
+
display: block;
|
|
3174
|
+
/* Width is bounded by the centered column; height is bounded by the
|
|
3175
|
+
viewport minus the scrim inset and the reserved caption row. With
|
|
3176
|
+
both maxes set and intrinsic sizing left auto, the browser scales
|
|
3177
|
+
the image down while preserving its aspect ratio. */
|
|
3178
|
+
width: auto;
|
|
3179
|
+
height: auto;
|
|
3180
|
+
max-width: 100%;
|
|
3181
|
+
max-height: calc(100dvh - 2 * var(--bp-lightbox-pad) - var(--bp-lightbox-meta));
|
|
3182
|
+
object-fit: contain;
|
|
3183
|
+
border: var(--bp-stroke) solid var(--bp-ink-line);
|
|
3184
|
+
border-radius: var(--bp-radius-0);
|
|
3185
|
+
background: var(--bp-paper);
|
|
3186
|
+
box-shadow: var(--bp-shadow-pop);
|
|
3187
|
+
}
|
|
3188
|
+
:where(.bp-lightbox__meta) {
|
|
3189
|
+
display: flex;
|
|
3190
|
+
align-items: baseline;
|
|
3191
|
+
gap: var(--bp-space-3);
|
|
3192
|
+
max-width: 100%;
|
|
3193
|
+
font-family: var(--bp-mono);
|
|
3194
|
+
font-size: var(--bp-label-md);
|
|
3195
|
+
letter-spacing: var(--bp-label-md-ls);
|
|
3196
|
+
color: var(--bp-paper);
|
|
3197
|
+
}
|
|
3198
|
+
:where(.bp-lightbox__kicker) {
|
|
3199
|
+
text-transform: uppercase;
|
|
3200
|
+
opacity: 0.7;
|
|
3201
|
+
}
|
|
3202
|
+
:where(.bp-lightbox__counter) {
|
|
3203
|
+
opacity: 0.7;
|
|
3204
|
+
}
|
|
3205
|
+
:where(.bp-lightbox__caption) {
|
|
3206
|
+
min-width: 0;
|
|
3207
|
+
overflow: hidden;
|
|
3208
|
+
text-overflow: ellipsis;
|
|
3209
|
+
white-space: nowrap;
|
|
3210
|
+
}
|
|
3211
|
+
:where(.bp-lightbox__close) {
|
|
3212
|
+
position: absolute;
|
|
3213
|
+
inset: var(--bp-space-4) var(--bp-space-4) auto auto;
|
|
3214
|
+
display: inline-flex;
|
|
3215
|
+
align-items: center;
|
|
3216
|
+
justify-content: center;
|
|
3217
|
+
width: 40px;
|
|
3218
|
+
height: 40px;
|
|
3219
|
+
padding: 0;
|
|
3220
|
+
border: var(--bp-stroke) solid var(--bp-edge);
|
|
3221
|
+
border-radius: var(--bp-radius-0);
|
|
3222
|
+
background: var(--bp-paper);
|
|
3223
|
+
color: var(--bp-text-secondary);
|
|
3224
|
+
cursor: pointer;
|
|
3225
|
+
}
|
|
3226
|
+
:where(.bp-lightbox__nav) {
|
|
3227
|
+
display: inline-flex;
|
|
3228
|
+
align-items: center;
|
|
3229
|
+
justify-content: center;
|
|
3230
|
+
width: 44px;
|
|
3231
|
+
height: 44px;
|
|
3232
|
+
padding: 0;
|
|
3233
|
+
border: var(--bp-stroke) solid var(--bp-edge);
|
|
3234
|
+
border-radius: var(--bp-radius-0);
|
|
3235
|
+
background: var(--bp-paper);
|
|
3236
|
+
color: var(--bp-text-secondary);
|
|
3237
|
+
cursor: pointer;
|
|
3238
|
+
}
|
|
3239
|
+
:where(.bp-lightbox__nav--prev) {
|
|
3240
|
+
grid-column: 1;
|
|
3241
|
+
}
|
|
3242
|
+
:where(.bp-lightbox__nav--next) {
|
|
3243
|
+
grid-column: 3;
|
|
3244
|
+
}
|
|
3245
|
+
:where(.bp-lightbox.is-single) :where(.bp-lightbox__nav) {
|
|
3246
|
+
visibility: hidden;
|
|
3247
|
+
}
|
|
3248
|
+
:where(.bp-lightbox__close:hover, .bp-lightbox__nav:hover) {
|
|
3249
|
+
color: var(--bp-text);
|
|
3250
|
+
border-color: var(--bp-ink-line);
|
|
3251
|
+
}
|
|
3252
|
+
:where(.bp-lightbox__close:focus-visible, .bp-lightbox__nav:focus-visible) {
|
|
3253
|
+
outline: 2px solid var(--bp-paper);
|
|
3254
|
+
outline-offset: 2px;
|
|
3255
|
+
}
|
|
3256
|
+
:where(.bp-lightbox__close svg) {
|
|
3257
|
+
width: 18px;
|
|
3258
|
+
height: 18px;
|
|
3259
|
+
}
|
|
3260
|
+
:where(.bp-lightbox__nav svg) {
|
|
3261
|
+
width: 22px;
|
|
3262
|
+
height: 22px;
|
|
3263
|
+
}
|
|
3264
|
+
}
|
|
3265
|
+
|
|
3266
|
+
/* Stored Blueprint shell contracts. New documents use bp-* components. */
|
|
3267
|
+
@layer components {
|
|
3268
|
+
:where(.sidebar) {
|
|
3269
|
+
position: fixed;
|
|
3270
|
+
inset: 0 auto 0 0;
|
|
3271
|
+
width: var(--sidebar);
|
|
3272
|
+
height: 100vh;
|
|
3273
|
+
overflow-y: auto;
|
|
3274
|
+
padding: 34px 20px 34px 26px;
|
|
3275
|
+
z-index: 100;
|
|
3276
|
+
}
|
|
3277
|
+
:where(.sidebar-head) {
|
|
3278
|
+
padding-bottom: 16px;
|
|
3279
|
+
border-bottom: 1px solid var(--edge);
|
|
3280
|
+
margin-bottom: 16px;
|
|
3281
|
+
}
|
|
3282
|
+
:where(.sidebar-title) {
|
|
3283
|
+
font: 500 11px/1.4 var(--mono);
|
|
3284
|
+
letter-spacing: 0.12em;
|
|
3285
|
+
text-transform: uppercase;
|
|
3286
|
+
color: var(--ink);
|
|
3287
|
+
}
|
|
3288
|
+
:where(.sidebar-doc) {
|
|
3289
|
+
font: 400 10px/1.4 var(--mono);
|
|
3290
|
+
letter-spacing: 0.08em;
|
|
3291
|
+
text-transform: uppercase;
|
|
3292
|
+
color: var(--text-secondary);
|
|
3293
|
+
margin-top: 6px;
|
|
3294
|
+
}
|
|
3295
|
+
:where(.sidebar ul) {
|
|
3296
|
+
list-style: none;
|
|
3297
|
+
margin: 0;
|
|
3298
|
+
padding: 0;
|
|
3299
|
+
counter-reset: navsec;
|
|
3300
|
+
display: flex;
|
|
3301
|
+
flex-direction: column;
|
|
3302
|
+
}
|
|
3303
|
+
:where(.sidebar li) {
|
|
3304
|
+
margin: 0;
|
|
3305
|
+
padding: 0;
|
|
3306
|
+
}
|
|
3307
|
+
:where(.sidebar a) {
|
|
3308
|
+
position: relative;
|
|
3309
|
+
display: block;
|
|
3310
|
+
font: 400 12px/1.35 var(--sans);
|
|
3311
|
+
color: var(--text-secondary);
|
|
3312
|
+
text-decoration: none;
|
|
3313
|
+
padding: 7px 10px 7px 36px;
|
|
3314
|
+
}
|
|
3315
|
+
:where(.sidebar a)::before {
|
|
3316
|
+
counter-increment: navsec;
|
|
3317
|
+
content: counter(navsec, decimal-leading-zero);
|
|
3318
|
+
position: absolute;
|
|
3319
|
+
left: 10px;
|
|
3320
|
+
top: 8px;
|
|
3321
|
+
font: 400 10px/1 var(--mono);
|
|
3322
|
+
letter-spacing: 0.06em;
|
|
3323
|
+
color: var(--ink-faint);
|
|
3324
|
+
}
|
|
3325
|
+
:where(.sidebar a:hover, .sidebar a[aria-current="location"]) {
|
|
3326
|
+
color: var(--ink);
|
|
3327
|
+
background: var(--fill-amb);
|
|
3328
|
+
}
|
|
3329
|
+
:where(.sidebar a[aria-current="location"])::after {
|
|
3330
|
+
content: "";
|
|
3331
|
+
position: absolute;
|
|
3332
|
+
inset: 0 auto 0 0;
|
|
3333
|
+
width: 2px;
|
|
3334
|
+
background: var(--ink);
|
|
3335
|
+
}
|
|
3336
|
+
:where(.page-body) {
|
|
3337
|
+
margin-left: var(--sidebar);
|
|
3338
|
+
}
|
|
3339
|
+
:where(.sheet) {
|
|
3340
|
+
margin: 0;
|
|
3341
|
+
min-height: 100vh;
|
|
3342
|
+
background: var(--paper);
|
|
3343
|
+
border-left: 1px solid var(--edge);
|
|
3344
|
+
}
|
|
3345
|
+
:where(.hero) {
|
|
3346
|
+
padding: 48px 56px 36px;
|
|
3347
|
+
border-bottom: 1px solid var(--ink-line);
|
|
3348
|
+
font-family: var(--sans);
|
|
3349
|
+
}
|
|
3350
|
+
:where(.hero-meta) {
|
|
3351
|
+
font: 400 11px/1.4 var(--mono);
|
|
3352
|
+
letter-spacing: 0.14em;
|
|
3353
|
+
text-transform: uppercase;
|
|
3354
|
+
color: var(--ink-soft);
|
|
3355
|
+
margin-bottom: 16px;
|
|
3356
|
+
}
|
|
3357
|
+
:where(.hero h1) {
|
|
3358
|
+
font: 600 24px/32px var(--sans);
|
|
3359
|
+
letter-spacing: -0.48px;
|
|
3360
|
+
margin: 10px 0 14px;
|
|
3361
|
+
}
|
|
3362
|
+
:where(.hero-sub) {
|
|
3363
|
+
font: 400 14px/20px var(--serif);
|
|
3364
|
+
text-align: justify;
|
|
3365
|
+
hyphens: auto;
|
|
3366
|
+
}
|
|
3367
|
+
:where(.title-block) {
|
|
3368
|
+
margin-top: 34px;
|
|
3369
|
+
border: 1px solid var(--ink-line);
|
|
3370
|
+
display: flex;
|
|
3371
|
+
flex-wrap: wrap;
|
|
3372
|
+
}
|
|
3373
|
+
:where(.tb-cell) {
|
|
3374
|
+
flex: 0 0 auto;
|
|
3375
|
+
padding: 10px 20px 11px 14px;
|
|
3376
|
+
border-right: 1px solid var(--ink-line);
|
|
3377
|
+
}
|
|
3378
|
+
:where(.tb-cell--grow) {
|
|
3379
|
+
flex: 1 1 auto;
|
|
3380
|
+
}
|
|
3381
|
+
:where(.tb-cell:last-child) {
|
|
2936
3382
|
border-right: 0;
|
|
2937
3383
|
}
|
|
2938
3384
|
:where(.tb-label) {
|
|
@@ -3024,36 +3470,541 @@
|
|
|
3024
3470
|
max-width: 100%;
|
|
3025
3471
|
height: auto;
|
|
3026
3472
|
}
|
|
3027
|
-
:where(.fig-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3473
|
+
:where(.fig-cap) {
|
|
3474
|
+
font: 400 10px/1.4 var(--mono);
|
|
3475
|
+
letter-spacing: 0.06em;
|
|
3476
|
+
text-transform: uppercase;
|
|
3477
|
+
color: var(--text-secondary);
|
|
3478
|
+
text-align: center;
|
|
3479
|
+
margin-top: 14px;
|
|
3480
|
+
}
|
|
3481
|
+
}
|
|
3482
|
+
|
|
3483
|
+
/* =====================================================================
|
|
3484
|
+
@layer components — <bp-workplan>
|
|
3485
|
+
|
|
3486
|
+
A live "work plan": typed, dependent tasks that resolve into waves,
|
|
3487
|
+
rendered four ways (list · gantt · kanban · swimlanes). Light-DOM,
|
|
3488
|
+
token-only, theme-aware. Chrome is ink; the only non-ink token is
|
|
3489
|
+
--bp-positive for a passing/approved PR. The element renders only
|
|
3490
|
+
<div>/<span> for structure, so the base layer's semantic-element
|
|
3491
|
+
styling never applies — no resets needed.
|
|
3492
|
+
===================================================================== */
|
|
3493
|
+
@layer components {
|
|
3494
|
+
:where(.bp-workplan) {
|
|
3495
|
+
font-family: var(--bp-sans);
|
|
3496
|
+
color: var(--bp-text);
|
|
3497
|
+
container-type: inline-size;
|
|
3498
|
+
}
|
|
3499
|
+
|
|
3500
|
+
/* ---- plan header + summary stats ---------------------------- */
|
|
3501
|
+
:where(.wp-head) {
|
|
3502
|
+
display: flex;
|
|
3503
|
+
flex-wrap: wrap;
|
|
3504
|
+
gap: var(--bp-space-3);
|
|
3505
|
+
align-items: flex-end;
|
|
3506
|
+
justify-content: space-between;
|
|
3507
|
+
padding-bottom: var(--bp-space-3);
|
|
3508
|
+
margin-bottom: var(--bp-space-3);
|
|
3509
|
+
border-bottom: 1px solid var(--bp-ink-line);
|
|
3510
|
+
}
|
|
3511
|
+
:where(.wp-head__name) {
|
|
3512
|
+
font-size: var(--bp-text-h3);
|
|
3513
|
+
line-height: var(--bp-lh-h3);
|
|
3514
|
+
font-weight: var(--bp-weight-strong);
|
|
3515
|
+
margin: 0;
|
|
3516
|
+
}
|
|
3517
|
+
:where(.wp-head__sub) {
|
|
3518
|
+
font-size: var(--bp-text-small);
|
|
3519
|
+
color: var(--bp-text-secondary);
|
|
3520
|
+
margin: 2px 0 0;
|
|
3521
|
+
}
|
|
3522
|
+
:where(.wp-stats) {
|
|
3523
|
+
display: flex;
|
|
3524
|
+
gap: var(--bp-space-4);
|
|
3525
|
+
margin: 0;
|
|
3526
|
+
}
|
|
3527
|
+
:where(.wp-stat) { text-align: right; }
|
|
3528
|
+
:where(.wp-stat__k) {
|
|
3529
|
+
display: block;
|
|
3530
|
+
font-family: var(--bp-mono);
|
|
3531
|
+
font-size: var(--bp-label-sm);
|
|
3532
|
+
letter-spacing: var(--bp-label-sm-ls);
|
|
3533
|
+
text-transform: uppercase;
|
|
3534
|
+
color: var(--bp-text-secondary);
|
|
3535
|
+
}
|
|
3536
|
+
:where(.wp-stat__v) {
|
|
3537
|
+
display: block;
|
|
3538
|
+
margin-top: 2px;
|
|
3539
|
+
font-variant-numeric: tabular-nums;
|
|
3540
|
+
font-size: var(--bp-text-h4);
|
|
3541
|
+
font-weight: var(--bp-weight-medium);
|
|
3542
|
+
}
|
|
3543
|
+
|
|
3544
|
+
/* ---- toolbar: built-in view selector + gantt unit toggle ---- */
|
|
3545
|
+
:where(.wp-toolbar) {
|
|
3546
|
+
display: flex;
|
|
3547
|
+
flex-wrap: wrap;
|
|
3548
|
+
gap: var(--bp-space-3);
|
|
3549
|
+
align-items: center;
|
|
3550
|
+
justify-content: space-between;
|
|
3551
|
+
margin-bottom: var(--bp-space-3);
|
|
3552
|
+
}
|
|
3553
|
+
:where(.wp-modes) { display: flex; flex-wrap: wrap; gap: var(--bp-space-1); }
|
|
3554
|
+
:where(.wp-modes--unit) { margin-left: auto; }
|
|
3555
|
+
:where(.wp-modes__btn) {
|
|
3556
|
+
font: inherit;
|
|
3557
|
+
font-size: var(--bp-text-small);
|
|
3558
|
+
line-height: 1;
|
|
3559
|
+
padding: var(--bp-space-1) var(--bp-space-3);
|
|
3560
|
+
border: 1px solid var(--bp-edge);
|
|
3561
|
+
border-radius: var(--bp-radius-0);
|
|
3562
|
+
background: var(--bp-paper);
|
|
3563
|
+
color: var(--bp-text-secondary);
|
|
3564
|
+
cursor: pointer;
|
|
3565
|
+
}
|
|
3566
|
+
:where(.wp-modes__btn):hover { background: var(--bp-fill-amb); }
|
|
3567
|
+
:where(.wp-modes__btn[aria-selected="true"]) {
|
|
3568
|
+
border-color: var(--bp-ink);
|
|
3569
|
+
color: var(--bp-text);
|
|
3570
|
+
background: var(--bp-fill-amb);
|
|
3571
|
+
}
|
|
3572
|
+
|
|
3573
|
+
/* ---- type badge (inline mono, not a pill) ------------------- */
|
|
3574
|
+
:where(.wp-type) {
|
|
3575
|
+
display: inline-flex;
|
|
3576
|
+
align-items: center;
|
|
3577
|
+
gap: 5px;
|
|
3578
|
+
font-family: var(--bp-mono);
|
|
3579
|
+
font-size: var(--bp-label-md);
|
|
3580
|
+
letter-spacing: var(--bp-label-md-ls);
|
|
3581
|
+
text-transform: uppercase;
|
|
3582
|
+
color: var(--bp-text-secondary);
|
|
3583
|
+
white-space: nowrap;
|
|
3584
|
+
}
|
|
3585
|
+
:where(.wp-type__glyph) { color: var(--bp-ink-soft); flex: none; }
|
|
3586
|
+
:where(.wp-type__label) { line-height: 1; }
|
|
3587
|
+
|
|
3588
|
+
/* ---- phase dot (status without color) ----------------------- */
|
|
3589
|
+
:where(.wp-dot) {
|
|
3590
|
+
--d: 10px;
|
|
3591
|
+
width: var(--d);
|
|
3592
|
+
height: var(--d);
|
|
3593
|
+
border-radius: var(--bp-radius-0);
|
|
3594
|
+
flex: none;
|
|
3595
|
+
box-sizing: border-box;
|
|
3596
|
+
}
|
|
3597
|
+
:where(.wp-dot--done) { background: var(--bp-ink); }
|
|
3598
|
+
:where(.wp-dot--active) {
|
|
3599
|
+
background: var(--bp-ink);
|
|
3600
|
+
box-shadow: 0 0 0 2px var(--bp-paper), 0 0 0 3px var(--bp-ink);
|
|
3601
|
+
}
|
|
3602
|
+
:where(.wp-dot--ready) {
|
|
3603
|
+
background: oklch(0 0 0 / 0);
|
|
3604
|
+
border: 1.5px solid var(--bp-ink-soft);
|
|
3605
|
+
}
|
|
3606
|
+
:where(.wp-dot--blocked) {
|
|
3607
|
+
background: oklch(0 0 0 / 0);
|
|
3608
|
+
border: 1.5px dashed var(--bp-ink-faint);
|
|
3609
|
+
}
|
|
3610
|
+
|
|
3611
|
+
/* ---- PR status — inline mono text, NO pill ------------------ */
|
|
3612
|
+
:where(.wp-pr) {
|
|
3613
|
+
display: inline-flex;
|
|
3614
|
+
align-items: center;
|
|
3615
|
+
gap: 6px;
|
|
3616
|
+
font-family: var(--bp-mono);
|
|
3617
|
+
font-size: var(--bp-label-md);
|
|
3618
|
+
letter-spacing: 0.01em;
|
|
3619
|
+
color: var(--bp-text-secondary);
|
|
3620
|
+
white-space: nowrap;
|
|
3621
|
+
min-width: 0;
|
|
3622
|
+
}
|
|
3623
|
+
:where(.wp-pr__glyph) { flex: none; width: 13px; height: 13px; }
|
|
3624
|
+
:where(.wp-pr__num) { color: var(--bp-text); font-weight: var(--bp-weight-medium); }
|
|
3625
|
+
:where(.wp-pr__ci) { color: var(--bp-text-secondary); }
|
|
3626
|
+
:where(.wp-pr__diff) { color: var(--bp-text-secondary); }
|
|
3627
|
+
:where(.wp-pr__add) { color: var(--bp-positive); }
|
|
3628
|
+
|
|
3629
|
+
:where(.wp-pr--passed .wp-pr__ci),
|
|
3630
|
+
:where(.wp-pr--approved .wp-pr__ci) { color: var(--bp-positive); }
|
|
3631
|
+
:where(.wp-pr--failed .wp-pr__glyph) { color: var(--bp-text); stroke-width: 1.8; }
|
|
3632
|
+
:where(.wp-pr--running .wp-pr__glyph) {
|
|
3633
|
+
color: var(--bp-ink-soft);
|
|
3634
|
+
animation: wp-spin var(--bp-duration-spin) var(--bp-ease-linear) infinite;
|
|
3635
|
+
}
|
|
3636
|
+
@keyframes wp-spin { to { transform: rotate(360deg); } }
|
|
3637
|
+
@media (prefers-reduced-motion: reduce) {
|
|
3638
|
+
:where(.wp-pr--running .wp-pr__glyph) { animation: none; }
|
|
3639
|
+
}
|
|
3640
|
+
|
|
3641
|
+
/* ---- owner mark — agent (square + spark) vs human (circle) -- */
|
|
3642
|
+
:where(.wp-owner) {
|
|
3643
|
+
display: inline-grid;
|
|
3644
|
+
place-items: center;
|
|
3645
|
+
width: 22px;
|
|
3646
|
+
height: 22px;
|
|
3647
|
+
flex: none;
|
|
3648
|
+
font-family: var(--bp-mono);
|
|
3649
|
+
font-size: 9px;
|
|
3650
|
+
letter-spacing: 0.02em;
|
|
3651
|
+
}
|
|
3652
|
+
:where(.wp-owner--human) {
|
|
3653
|
+
border-radius: var(--bp-radius-0);
|
|
3654
|
+
background: var(--bp-fill-hi);
|
|
3655
|
+
border: 1px solid var(--bp-edge);
|
|
3656
|
+
color: var(--bp-text-secondary);
|
|
3657
|
+
}
|
|
3658
|
+
:where(.wp-owner--agent) {
|
|
3659
|
+
border-radius: var(--bp-radius-0);
|
|
3660
|
+
border: 1px solid var(--bp-ink-line);
|
|
3661
|
+
color: var(--bp-text-secondary);
|
|
3662
|
+
}
|
|
3663
|
+
:where(.wp-owner__glyph) { width: 12px; height: 12px; }
|
|
3664
|
+
|
|
3665
|
+
/* ---- waiting note — quiet inline text ----------------------- */
|
|
3666
|
+
:where(.wp-wait) {
|
|
3667
|
+
display: block;
|
|
3668
|
+
font-size: var(--bp-text-small);
|
|
3669
|
+
color: var(--bp-text-secondary);
|
|
3670
|
+
white-space: nowrap;
|
|
3671
|
+
overflow: hidden;
|
|
3672
|
+
text-overflow: ellipsis;
|
|
3673
|
+
}
|
|
3674
|
+
|
|
3675
|
+
/* greyed-out-until-ready treatment, shared across views */
|
|
3676
|
+
:where([data-locked="true"]) { opacity: 0.66; }
|
|
3677
|
+
|
|
3678
|
+
/* ---- LIST view ---------------------------------------------- */
|
|
3679
|
+
:where(.wp-view--list) { display: grid; gap: var(--bp-space-3); }
|
|
3680
|
+
:where(.wp-wave__head) {
|
|
3681
|
+
display: flex;
|
|
3682
|
+
align-items: baseline;
|
|
3683
|
+
justify-content: space-between;
|
|
3684
|
+
gap: var(--bp-space-2);
|
|
3685
|
+
margin-bottom: 6px;
|
|
3686
|
+
padding: 0 2px;
|
|
3687
|
+
}
|
|
3688
|
+
:where(.wp-wave__no),
|
|
3689
|
+
:where(.wp-wave__count) {
|
|
3690
|
+
font-family: var(--bp-mono);
|
|
3691
|
+
font-size: var(--bp-label-md);
|
|
3692
|
+
letter-spacing: var(--bp-label-md-ls);
|
|
3693
|
+
text-transform: uppercase;
|
|
3694
|
+
}
|
|
3695
|
+
:where(.wp-wave__no) { color: var(--bp-text); }
|
|
3696
|
+
:where(.wp-wave__count) { color: var(--bp-text-secondary); }
|
|
3697
|
+
:where(.wp-row) {
|
|
3698
|
+
display: grid;
|
|
3699
|
+
grid-template-columns: auto 84px minmax(0, 1fr) auto auto;
|
|
3700
|
+
align-items: center;
|
|
3701
|
+
gap: var(--bp-space-3);
|
|
3702
|
+
padding: 11px var(--bp-space-3);
|
|
3703
|
+
border: 1px solid var(--bp-edge);
|
|
3704
|
+
border-top: none;
|
|
3705
|
+
background: var(--bp-paper);
|
|
3706
|
+
}
|
|
3707
|
+
:where(.wp-row:first-child) {
|
|
3708
|
+
border-top: 1px solid var(--bp-edge);
|
|
3709
|
+
border-radius: var(--bp-radius-0) var(--bp-radius-0) 0 0;
|
|
3710
|
+
}
|
|
3711
|
+
:where(.wp-row:last-child) { border-radius: 0 0 var(--bp-radius-0) var(--bp-radius-0); }
|
|
3712
|
+
:where(.wp-row__main) { position: relative; min-width: 0; }
|
|
3713
|
+
:where(.wp-row__name) {
|
|
3714
|
+
display: block;
|
|
3715
|
+
font-size: var(--bp-text-body);
|
|
3716
|
+
font-weight: var(--bp-weight-medium);
|
|
3717
|
+
white-space: nowrap;
|
|
3718
|
+
overflow: hidden;
|
|
3719
|
+
text-overflow: ellipsis;
|
|
3720
|
+
}
|
|
3721
|
+
/* Waiting note overlays the name and is revealed on hover, so a locked
|
|
3722
|
+
row reads as its title at rest and its blockers on demand. */
|
|
3723
|
+
:where(.wp-row__main .wp-wait) {
|
|
3724
|
+
position: absolute;
|
|
3725
|
+
inset: 0;
|
|
3726
|
+
display: flex;
|
|
3727
|
+
align-items: center;
|
|
3728
|
+
margin: 0;
|
|
3729
|
+
background: var(--bp-paper);
|
|
3730
|
+
opacity: 0;
|
|
3731
|
+
pointer-events: none;
|
|
3732
|
+
transition: opacity var(--bp-duration-fast) var(--bp-ease-out);
|
|
3733
|
+
}
|
|
3734
|
+
:where(.wp-row[data-locked="true"]:hover .wp-row__name) { opacity: 0; }
|
|
3735
|
+
:where(.wp-row[data-locked="true"]:hover .wp-row__main .wp-wait) { opacity: 1; }
|
|
3736
|
+
:where(.wp-row--done .wp-row__name) {
|
|
3737
|
+
color: var(--bp-text-secondary);
|
|
3738
|
+
text-decoration: line-through;
|
|
3739
|
+
text-decoration-color: var(--bp-ink-faint);
|
|
3740
|
+
}
|
|
3741
|
+
:where(.wp-row__pr) { justify-self: end; }
|
|
3742
|
+
|
|
3743
|
+
/* ---- KANBAN view — min-width columns, horizontal scroll ----- */
|
|
3744
|
+
:where(.wp-view--kanban) {
|
|
3745
|
+
display: grid;
|
|
3746
|
+
grid-auto-flow: column;
|
|
3747
|
+
grid-auto-columns: minmax(216px, 1fr);
|
|
3748
|
+
gap: var(--bp-space-3);
|
|
3749
|
+
align-items: start;
|
|
3750
|
+
overflow-x: auto;
|
|
3751
|
+
padding-bottom: var(--bp-space-2);
|
|
3752
|
+
}
|
|
3753
|
+
:where(.wp-col) {
|
|
3754
|
+
background: var(--bp-bg);
|
|
3755
|
+
border: 1px solid var(--bp-edge);
|
|
3756
|
+
border-radius: var(--bp-radius-0);
|
|
3757
|
+
padding: var(--bp-space-2);
|
|
3758
|
+
display: flex;
|
|
3759
|
+
flex-direction: column;
|
|
3760
|
+
min-width: 0;
|
|
3761
|
+
}
|
|
3762
|
+
:where(.wp-col__head) {
|
|
3763
|
+
display: flex;
|
|
3764
|
+
align-items: center;
|
|
3765
|
+
justify-content: space-between;
|
|
3766
|
+
padding: 4px var(--bp-space-1) var(--bp-space-2);
|
|
3767
|
+
}
|
|
3768
|
+
:where(.wp-col__title) {
|
|
3769
|
+
font-family: var(--bp-mono);
|
|
3770
|
+
font-size: var(--bp-label-md);
|
|
3771
|
+
letter-spacing: var(--bp-label-md-ls);
|
|
3772
|
+
text-transform: uppercase;
|
|
3773
|
+
color: var(--bp-text);
|
|
3774
|
+
}
|
|
3775
|
+
:where(.wp-col__count) {
|
|
3776
|
+
font-family: var(--bp-mono);
|
|
3777
|
+
font-size: var(--bp-label-sm);
|
|
3778
|
+
color: var(--bp-text-secondary);
|
|
3779
|
+
font-variant-numeric: tabular-nums;
|
|
3780
|
+
}
|
|
3781
|
+
/* One full-width track — minmax(0,1fr) keeps cards at the column width
|
|
3782
|
+
so nowrap text truncates instead of stretching the card. */
|
|
3783
|
+
:where(.wp-col__body) {
|
|
3784
|
+
display: grid;
|
|
3785
|
+
grid-template-columns: minmax(0, 1fr);
|
|
3786
|
+
gap: var(--bp-space-2);
|
|
3787
|
+
align-content: start;
|
|
3788
|
+
min-width: 0;
|
|
3789
|
+
}
|
|
3790
|
+
:where(.wp-col__empty) {
|
|
3791
|
+
font-family: var(--bp-mono);
|
|
3792
|
+
font-size: var(--bp-label-sm);
|
|
3793
|
+
letter-spacing: var(--bp-label-sm-ls);
|
|
3794
|
+
text-transform: uppercase;
|
|
3795
|
+
color: var(--bp-ink-faint);
|
|
3796
|
+
margin: var(--bp-space-1) 0 var(--bp-space-2);
|
|
3797
|
+
padding-left: var(--bp-space-1);
|
|
3798
|
+
}
|
|
3799
|
+
:where(.wp-card) {
|
|
3800
|
+
background: var(--bp-paper);
|
|
3801
|
+
border: 1px solid var(--bp-edge);
|
|
3802
|
+
border-radius: var(--bp-radius-0);
|
|
3803
|
+
padding: 10px var(--bp-space-2);
|
|
3804
|
+
display: grid;
|
|
3805
|
+
grid-template-columns: minmax(0, 1fr);
|
|
3806
|
+
gap: 7px;
|
|
3807
|
+
min-width: 0;
|
|
3808
|
+
}
|
|
3809
|
+
:where(.wp-card__top) {
|
|
3810
|
+
display: flex;
|
|
3811
|
+
align-items: center;
|
|
3812
|
+
justify-content: space-between;
|
|
3813
|
+
}
|
|
3814
|
+
:where(.wp-card__name) {
|
|
3815
|
+
margin: 0;
|
|
3816
|
+
font-size: var(--bp-text-small);
|
|
3817
|
+
font-weight: var(--bp-weight-medium);
|
|
3818
|
+
line-height: 1.35;
|
|
3819
|
+
}
|
|
3820
|
+
:where(.wp-card--done .wp-card__name) { color: var(--bp-text-secondary); }
|
|
3821
|
+
:where(.wp-card__pr) { min-width: 0; overflow: hidden; }
|
|
3822
|
+
:where(.wp-card__pr .wp-pr) { font-size: var(--bp-label-sm); max-width: 100%; }
|
|
3823
|
+
:where(.wp-card__pr .wp-pr__ci) {
|
|
3824
|
+
overflow: hidden;
|
|
3825
|
+
text-overflow: ellipsis;
|
|
3826
|
+
}
|
|
3827
|
+
:where(.wp-card__foot) {
|
|
3828
|
+
display: flex;
|
|
3829
|
+
align-items: center;
|
|
3830
|
+
justify-content: space-between;
|
|
3831
|
+
gap: var(--bp-space-2);
|
|
3832
|
+
margin-top: 1px;
|
|
3833
|
+
}
|
|
3834
|
+
:where(.wp-card__wave) {
|
|
3835
|
+
font-family: var(--bp-mono);
|
|
3836
|
+
font-size: var(--bp-label-sm);
|
|
3837
|
+
letter-spacing: var(--bp-label-sm-ls);
|
|
3838
|
+
text-transform: uppercase;
|
|
3839
|
+
color: var(--bp-text-secondary);
|
|
3840
|
+
}
|
|
3841
|
+
|
|
3842
|
+
/* ---- SWIMLANES view (type × wave grid) — single-line chips -- */
|
|
3843
|
+
:where(.wp-view--swim) {
|
|
3844
|
+
display: grid;
|
|
3845
|
+
grid-template-columns: 120px repeat(var(--wp-waves), minmax(168px, 1fr));
|
|
3846
|
+
gap: 1px;
|
|
3847
|
+
background: var(--bp-edge);
|
|
3848
|
+
border: 1px solid var(--bp-edge);
|
|
3849
|
+
border-radius: var(--bp-radius-0);
|
|
3850
|
+
overflow: hidden;
|
|
3851
|
+
}
|
|
3852
|
+
:where(.wp-swim__corner),
|
|
3853
|
+
:where(.wp-swim__whead),
|
|
3854
|
+
:where(.wp-swim__lanehead),
|
|
3855
|
+
:where(.wp-swim__cell) { background: var(--bp-paper); padding: var(--bp-space-2); min-width: 0; }
|
|
3856
|
+
:where(.wp-swim__corner),
|
|
3857
|
+
:where(.wp-swim__whead) {
|
|
3858
|
+
font-family: var(--bp-mono);
|
|
3859
|
+
font-size: var(--bp-label-sm);
|
|
3860
|
+
letter-spacing: var(--bp-label-sm-ls);
|
|
3861
|
+
text-transform: uppercase;
|
|
3862
|
+
color: var(--bp-text-secondary);
|
|
3863
|
+
background: var(--bp-bg);
|
|
3864
|
+
}
|
|
3865
|
+
:where(.wp-swim__lanehead) { background: var(--bp-bg); display: flex; align-items: center; }
|
|
3866
|
+
:where(.wp-swim__cell) { display: grid; gap: 6px; align-content: start; }
|
|
3867
|
+
:where(.wp-chip) {
|
|
3868
|
+
display: grid;
|
|
3869
|
+
gap: 5px;
|
|
3870
|
+
padding: 7px 9px;
|
|
3871
|
+
border: 1px solid var(--bp-edge);
|
|
3872
|
+
border-radius: var(--bp-radius-0);
|
|
3873
|
+
background: var(--bp-paper);
|
|
3874
|
+
min-width: 0;
|
|
3875
|
+
}
|
|
3876
|
+
:where(.wp-chip__head) {
|
|
3877
|
+
display: grid;
|
|
3878
|
+
grid-template-columns: auto minmax(0, 1fr) auto;
|
|
3879
|
+
align-items: center;
|
|
3880
|
+
gap: 7px;
|
|
3881
|
+
}
|
|
3882
|
+
:where(.wp-chip__name) {
|
|
3883
|
+
font-size: var(--bp-text-small);
|
|
3884
|
+
font-weight: var(--bp-weight-medium);
|
|
3885
|
+
line-height: 1.2;
|
|
3886
|
+
white-space: nowrap;
|
|
3887
|
+
overflow: hidden;
|
|
3888
|
+
text-overflow: ellipsis;
|
|
3889
|
+
}
|
|
3890
|
+
:where(.wp-chip--done .wp-chip__name) { color: var(--bp-text-secondary); }
|
|
3891
|
+
:where(.wp-chip__pr) { min-width: 0; overflow: hidden; }
|
|
3892
|
+
:where(.wp-chip__pr .wp-pr) { font-size: var(--bp-label-sm); max-width: 100%; }
|
|
3893
|
+
:where(.wp-chip[data-locked="true"]) { border-style: dashed; }
|
|
3894
|
+
|
|
3895
|
+
/* ---- GANTT view (longest-path schedule) --------------------- */
|
|
3896
|
+
:where(.wp-view--gantt) { display: grid; gap: 4px; }
|
|
3897
|
+
:where(.wp-gantt__row) {
|
|
3898
|
+
display: grid;
|
|
3899
|
+
grid-template-columns: 264px 1fr;
|
|
3900
|
+
gap: var(--bp-space-3);
|
|
3901
|
+
align-items: center;
|
|
3902
|
+
}
|
|
3903
|
+
:where(.wp-gantt__label) {
|
|
3904
|
+
display: grid;
|
|
3905
|
+
grid-template-columns: 84px minmax(0, 1fr) auto;
|
|
3906
|
+
gap: var(--bp-space-2);
|
|
3907
|
+
align-items: center;
|
|
3908
|
+
min-width: 0;
|
|
3909
|
+
}
|
|
3910
|
+
:where(.wp-gantt__name) {
|
|
3911
|
+
font-size: var(--bp-text-small);
|
|
3912
|
+
font-weight: var(--bp-weight-medium);
|
|
3913
|
+
white-space: nowrap;
|
|
3914
|
+
overflow: hidden;
|
|
3915
|
+
text-overflow: ellipsis;
|
|
3916
|
+
}
|
|
3917
|
+
:where(.wp-gantt__row--done .wp-gantt__name) { color: var(--bp-text-secondary); }
|
|
3918
|
+
:where(.wp-gantt__track) {
|
|
3919
|
+
position: relative;
|
|
3920
|
+
height: 26px;
|
|
3921
|
+
background: var(--bp-fill-amb);
|
|
3922
|
+
border-radius: var(--bp-radius-0);
|
|
3923
|
+
background-image: repeating-linear-gradient(
|
|
3924
|
+
to right,
|
|
3925
|
+
oklch(0 0 0 / 0) 0 calc(100% / var(--span, 10) - 1px),
|
|
3926
|
+
var(--bp-edge) calc(100% / var(--span, 10) - 1px) calc(100% / var(--span, 10))
|
|
3927
|
+
);
|
|
3928
|
+
}
|
|
3929
|
+
:where(.wp-gantt__bar) {
|
|
3930
|
+
position: absolute;
|
|
3931
|
+
top: 3px;
|
|
3932
|
+
bottom: 3px;
|
|
3933
|
+
display: flex;
|
|
3934
|
+
align-items: center;
|
|
3935
|
+
gap: 6px;
|
|
3936
|
+
padding: 0 8px;
|
|
3937
|
+
border-radius: var(--bp-radius-0);
|
|
3938
|
+
border: 1px solid var(--bp-ink-line);
|
|
3939
|
+
background: var(--bp-paper);
|
|
3940
|
+
min-width: 28px;
|
|
3941
|
+
}
|
|
3942
|
+
:where(.wp-gantt__bar--done) { background: var(--bp-ink); border-color: var(--bp-ink); }
|
|
3943
|
+
:where(.wp-gantt__bar--done .wp-gantt__bar-label),
|
|
3944
|
+
:where(.wp-gantt__bar--done .wp-dot) { color: var(--bp-paper); }
|
|
3945
|
+
:where(.wp-gantt__bar--done .wp-dot--done) { background: var(--bp-paper); }
|
|
3946
|
+
:where(.wp-gantt__bar--active) { background: var(--bp-fill-hi); border-color: var(--bp-ink); }
|
|
3947
|
+
:where(.wp-gantt__bar--blocked) { border-style: dashed; }
|
|
3948
|
+
:where(.wp-gantt__bar-label) {
|
|
3949
|
+
font-family: var(--bp-mono);
|
|
3950
|
+
font-size: var(--bp-label-sm);
|
|
3951
|
+
letter-spacing: 0.02em;
|
|
3952
|
+
color: var(--bp-text-secondary);
|
|
3953
|
+
}
|
|
3954
|
+
:where(.wp-gantt__track--axis) {
|
|
3955
|
+
position: relative;
|
|
3956
|
+
height: 18px;
|
|
3957
|
+
background: none;
|
|
3958
|
+
background-image: none;
|
|
3959
|
+
}
|
|
3960
|
+
:where(.wp-gantt__tick) {
|
|
3961
|
+
position: absolute;
|
|
3962
|
+
left: calc(var(--at) / var(--span) * 100%);
|
|
3963
|
+
transform: translateX(-50%);
|
|
3964
|
+
font-family: var(--bp-mono);
|
|
3965
|
+
font-size: var(--bp-label-sm);
|
|
3966
|
+
color: var(--bp-text-secondary);
|
|
3967
|
+
font-variant-numeric: tabular-nums;
|
|
3968
|
+
}
|
|
3969
|
+
:where(.wp-gantt__label--axis) {
|
|
3970
|
+
display: block;
|
|
3971
|
+
font-family: var(--bp-mono);
|
|
3972
|
+
font-size: var(--bp-label-sm);
|
|
3973
|
+
letter-spacing: var(--bp-label-sm-ls);
|
|
3974
|
+
text-transform: uppercase;
|
|
3975
|
+
color: var(--bp-text-secondary);
|
|
3976
|
+
}
|
|
3977
|
+
:where(.wp-gantt__row--axis) { border-bottom: 1px solid var(--bp-edge); padding-bottom: 4px; }
|
|
3978
|
+
|
|
3979
|
+
/* ---- EMPTY / no-data state ---------------------------------- */
|
|
3980
|
+
:where(.wp-empty) {
|
|
3981
|
+
display: grid;
|
|
3982
|
+
place-items: center;
|
|
3983
|
+
gap: var(--bp-space-2);
|
|
3984
|
+
text-align: center;
|
|
3985
|
+
padding: var(--bp-space-6) var(--bp-space-4);
|
|
3986
|
+
border: 1px dashed var(--bp-ink-line);
|
|
3987
|
+
border-radius: var(--bp-radius-0);
|
|
3988
|
+
background-color: var(--bp-fill-amb);
|
|
3989
|
+
background-image: var(--bp-hatch);
|
|
3990
|
+
color: var(--bp-text-secondary);
|
|
3991
|
+
}
|
|
3992
|
+
:where(.wp-empty__art) { color: var(--bp-ink-soft); margin-bottom: var(--bp-space-1); }
|
|
3993
|
+
:where(.wp-empty__title) {
|
|
3994
|
+
margin: 0;
|
|
3995
|
+
font-size: var(--bp-text-h4);
|
|
3996
|
+
font-weight: var(--bp-weight-strong);
|
|
3997
|
+
color: var(--bp-text);
|
|
3049
3998
|
}
|
|
3050
|
-
:where(.
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3999
|
+
:where(.wp-empty__hint) { margin: 0; max-width: 42ch; font-size: var(--bp-text-small); }
|
|
4000
|
+
:where(.wp-mono) { font-family: var(--bp-mono); font-size: 0.92em; }
|
|
4001
|
+
|
|
4002
|
+
/* ---- responsive: collapse the dense grids on narrow containers */
|
|
4003
|
+
@container (max-width: 560px) {
|
|
4004
|
+
:where(.wp-row) { grid-template-columns: auto minmax(0, 1fr) auto; }
|
|
4005
|
+
:where(.wp-row .wp-type) { display: none; }
|
|
4006
|
+
:where(.wp-row__pr) { grid-column: 2 / -1; justify-self: start; }
|
|
4007
|
+
:where(.wp-gantt__row) { grid-template-columns: 1fr; gap: 4px; }
|
|
3057
4008
|
}
|
|
3058
4009
|
}
|
|
3059
4010
|
|
|
@@ -3107,6 +4058,29 @@
|
|
|
3107
4058
|
:where(.bp-ease-overshoot) { transition-timing-function: var(--bp-ease-overshoot); }
|
|
3108
4059
|
:where(.bp-ease-linear) { transition-timing-function: var(--bp-ease-linear); }
|
|
3109
4060
|
|
|
4061
|
+
/* Theme flip — mute per-element transitions while the root crossfade runs.
|
|
4062
|
+
TOC links, inputs, and other token-bound surfaces bake color motion into
|
|
4063
|
+
@layer components; that fights the view transition the same way
|
|
4064
|
+
.bp-transition-colors utilities do. blueprint.js sets
|
|
4065
|
+
data-bp-theme-switching for the duration of startViewTransition().
|
|
4066
|
+
Keep the data-attribute and typed selectors in separate rules — an
|
|
4067
|
+
unknown :active-view-transition-type() in a comma list invalidates the
|
|
4068
|
+
whole block in engines that lack typed View Transition selector support. */
|
|
4069
|
+
html[data-bp-theme-switching] :where(*) {
|
|
4070
|
+
transition-property: none;
|
|
4071
|
+
}
|
|
4072
|
+
html:active-view-transition-type(bp-theme) :where(*) {
|
|
4073
|
+
transition-property: none;
|
|
4074
|
+
}
|
|
4075
|
+
html[data-bp-theme-switching] *::before,
|
|
4076
|
+
html[data-bp-theme-switching] *::after {
|
|
4077
|
+
transition-property: none;
|
|
4078
|
+
}
|
|
4079
|
+
html:active-view-transition-type(bp-theme) *::before,
|
|
4080
|
+
html:active-view-transition-type(bp-theme) *::after {
|
|
4081
|
+
transition-property: none;
|
|
4082
|
+
}
|
|
4083
|
+
|
|
3110
4084
|
/* Responsive: keep section navigation reachable while collapsing the rail. */
|
|
3111
4085
|
@media (max-width: 860px) {
|
|
3112
4086
|
:where(.bp-sidebar, .bp-toc, .sidebar) {
|
|
@@ -3126,6 +4100,16 @@
|
|
|
3126
4100
|
padding-bottom: var(--bp-space-1);
|
|
3127
4101
|
}
|
|
3128
4102
|
:where(.bp-sidebar li, .bp-toc li, .sidebar li) { flex: 0 0 auto; }
|
|
4103
|
+
/* In the collapsed horizontal nav the group eyebrow rides inline as a
|
|
4104
|
+
quiet separator ahead of its entries rather than a stacked header. */
|
|
4105
|
+
:where(.bp-sidebar .bp-nav-group, .bp-toc .bp-nav-group) {
|
|
4106
|
+
display: flex;
|
|
4107
|
+
align-items: center;
|
|
4108
|
+
margin: 0;
|
|
4109
|
+
}
|
|
4110
|
+
:where(.bp-nav-group__label) {
|
|
4111
|
+
padding: var(--bp-space-1) var(--bp-space-2);
|
|
4112
|
+
}
|
|
3129
4113
|
/* The gliding pill only makes sense in the fixed column; in the collapsed
|
|
3130
4114
|
horizontal nav the active entry just shows its own static pill. */
|
|
3131
4115
|
:where(.bp-sidebar > ul, .bp-sidebar__panel > ul, .bp-toc > ul)::before { content: none; }
|
|
@@ -3133,7 +4117,7 @@
|
|
|
3133
4117
|
background: var(--bp-fill-hi);
|
|
3134
4118
|
}
|
|
3135
4119
|
/* Rail is now on top; the sheet floats with a uniform margin. */
|
|
3136
|
-
:where(html
|
|
4120
|
+
:where(html[data-bp-document]) {
|
|
3137
4121
|
--bp-shell-inset-block: var(--bp-space-3);
|
|
3138
4122
|
--bp-shell-inset-top: var(--bp-shell-inset-block);
|
|
3139
4123
|
--bp-shell-inset-left: var(--bp-space-3);
|
|
@@ -3145,26 +4129,29 @@
|
|
|
3145
4129
|
:where(main, article) {
|
|
3146
4130
|
padding: var(--bp-space-4) var(--bp-space-3);
|
|
3147
4131
|
}
|
|
3148
|
-
/* Edge-to-edge on phones — the float costs too much width here. */
|
|
3149
|
-
:where(
|
|
3150
|
-
|
|
4132
|
+
/* Edge-to-edge on phones — the desk float costs too much width here. */
|
|
4133
|
+
:where(html[data-bp-document] body) {
|
|
4134
|
+
padding-top: 0;
|
|
4135
|
+
padding-bottom: 0;
|
|
3151
4136
|
}
|
|
3152
|
-
:where(
|
|
3153
|
-
position: static;
|
|
3154
|
-
inset: auto;
|
|
4137
|
+
:where(html[data-bp-document] main) {
|
|
3155
4138
|
margin: 0;
|
|
3156
|
-
|
|
4139
|
+
max-width: var(--bp-content);
|
|
4140
|
+
min-height: 0;
|
|
3157
4141
|
border: 0;
|
|
3158
4142
|
border-radius: var(--bp-radius-0);
|
|
3159
4143
|
box-shadow: none;
|
|
3160
4144
|
}
|
|
3161
|
-
:where(html
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
:where(
|
|
4145
|
+
:where(html[data-bp-document] main > *) {
|
|
4146
|
+
max-width: none;
|
|
4147
|
+
}
|
|
4148
|
+
:where(html[data-bp-document])::before,
|
|
4149
|
+
:where(html[data-bp-document])::after,
|
|
4150
|
+
:where(html[data-bp-document] body)::before,
|
|
4151
|
+
:where(html[data-bp-document] body)::after {
|
|
3165
4152
|
content: none;
|
|
3166
4153
|
}
|
|
3167
|
-
:where(.bp-
|
|
4154
|
+
:where(.bp-card-grid, .bp-layout) {
|
|
3168
4155
|
grid-template-columns: 1fr;
|
|
3169
4156
|
}
|
|
3170
4157
|
:where(.bp-content) {
|
|
@@ -3185,23 +4172,1061 @@
|
|
|
3185
4172
|
:where(.bp-sidebar, .bp-toc, .sidebar, .scroll-progress, .bp-no-print) {
|
|
3186
4173
|
display: none !important;
|
|
3187
4174
|
}
|
|
3188
|
-
:where(
|
|
3189
|
-
:where(
|
|
3190
|
-
|
|
4175
|
+
:where(html[data-bp-document] main, .page-body, .sheet) { margin: 0; border: 0; border-radius: var(--bp-radius-0); box-shadow: none; }
|
|
4176
|
+
:where(html[data-bp-document] body) {
|
|
4177
|
+
padding-top: 0;
|
|
4178
|
+
padding-bottom: 0;
|
|
3191
4179
|
}
|
|
3192
|
-
:where(
|
|
3193
|
-
|
|
3194
|
-
inset: auto;
|
|
4180
|
+
:where(html[data-bp-document] main) {
|
|
4181
|
+
min-height: 0;
|
|
3195
4182
|
overflow: visible;
|
|
3196
4183
|
}
|
|
3197
|
-
:where(html
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
:where(
|
|
4184
|
+
:where(html[data-bp-document] main > *) {
|
|
4185
|
+
max-width: none;
|
|
4186
|
+
}
|
|
4187
|
+
:where(html[data-bp-document])::before,
|
|
4188
|
+
:where(html[data-bp-document])::after,
|
|
4189
|
+
:where(html[data-bp-document] body)::before,
|
|
4190
|
+
:where(html[data-bp-document] body)::after {
|
|
3201
4191
|
content: none;
|
|
3202
4192
|
}
|
|
3203
|
-
:where(.bp-
|
|
4193
|
+
:where(.bp-callout, .bp-card, .bp-section, .bp-figure, figure, details) {
|
|
3204
4194
|
break-inside: avoid;
|
|
3205
4195
|
}
|
|
3206
4196
|
}
|
|
3207
4197
|
}
|
|
4198
|
+
|
|
4199
|
+
/* Shared document chrome. This stays separate in source so the docs site can
|
|
4200
|
+
iterate on it independently, but the npm build appends it to the default
|
|
4201
|
+
blueprint.css export because blueprint.js injects these runtime elements. */
|
|
4202
|
+
|
|
4203
|
+
:root {
|
|
4204
|
+
--bp-site-nav-height: 44px;
|
|
4205
|
+
}
|
|
4206
|
+
|
|
4207
|
+
/* Only the pages that still use the top bar (e.g. the code demo) reserve
|
|
4208
|
+
space for it. The main docs page drops it in favor of the sidebar
|
|
4209
|
+
blueprint switcher + bottom-left theme toggle below. */
|
|
4210
|
+
body:has(.site-nav) {
|
|
4211
|
+
padding-top: var(--bp-site-nav-height);
|
|
4212
|
+
}
|
|
4213
|
+
|
|
4214
|
+
/* Frame and shell top inset align below the site nav. */
|
|
4215
|
+
html[data-bp-document]:has(.site-nav) {
|
|
4216
|
+
--bp-shell-inset-top: calc(var(--bp-site-nav-height) + var(--bp-shell-inset-block));
|
|
4217
|
+
}
|
|
4218
|
+
|
|
4219
|
+
.site-nav {
|
|
4220
|
+
position: fixed;
|
|
4221
|
+
inset: 0 0 auto;
|
|
4222
|
+
z-index: 400;
|
|
4223
|
+
display: flex;
|
|
4224
|
+
align-items: stretch;
|
|
4225
|
+
height: var(--bp-site-nav-height);
|
|
4226
|
+
padding: 0 16px;
|
|
4227
|
+
border-bottom: 1px solid var(--bp-edge);
|
|
4228
|
+
background: var(--bp-paper);
|
|
4229
|
+
color: var(--bp-text);
|
|
4230
|
+
font-family: var(--bp-mono, var(--mono, ui-monospace, monospace));
|
|
4231
|
+
font-size: 11px;
|
|
4232
|
+
letter-spacing: 0.08em;
|
|
4233
|
+
text-transform: uppercase;
|
|
4234
|
+
}
|
|
4235
|
+
|
|
4236
|
+
.site-nav__brand,
|
|
4237
|
+
.site-nav a {
|
|
4238
|
+
display: flex;
|
|
4239
|
+
align-items: center;
|
|
4240
|
+
min-height: 0;
|
|
4241
|
+
padding: 0 12px;
|
|
4242
|
+
color: var(--bp-text-secondary);
|
|
4243
|
+
text-decoration: none;
|
|
4244
|
+
}
|
|
4245
|
+
|
|
4246
|
+
.site-nav__brand {
|
|
4247
|
+
gap: 8px;
|
|
4248
|
+
padding-left: 0;
|
|
4249
|
+
color: var(--bp-ink);
|
|
4250
|
+
font-weight: 650;
|
|
4251
|
+
letter-spacing: 0.04em;
|
|
4252
|
+
text-transform: none;
|
|
4253
|
+
}
|
|
4254
|
+
|
|
4255
|
+
.site-nav__logo {
|
|
4256
|
+
width: 20px;
|
|
4257
|
+
height: 20px;
|
|
4258
|
+
flex: 0 0 20px;
|
|
4259
|
+
color: var(--bp-ink);
|
|
4260
|
+
}
|
|
4261
|
+
|
|
4262
|
+
.site-nav__links {
|
|
4263
|
+
display: flex;
|
|
4264
|
+
align-items: stretch;
|
|
4265
|
+
gap: 2px;
|
|
4266
|
+
margin: 0 0 0 12px;
|
|
4267
|
+
padding: 0;
|
|
4268
|
+
list-style: none;
|
|
4269
|
+
}
|
|
4270
|
+
|
|
4271
|
+
.site-nav__links > li {
|
|
4272
|
+
display: flex;
|
|
4273
|
+
margin: 0;
|
|
4274
|
+
line-height: 1;
|
|
4275
|
+
}
|
|
4276
|
+
|
|
4277
|
+
.site-nav a:hover,
|
|
4278
|
+
.site-nav a[aria-current="page"] {
|
|
4279
|
+
color: var(--bp-ink);
|
|
4280
|
+
background: var(--bp-fill-amb);
|
|
4281
|
+
}
|
|
4282
|
+
|
|
4283
|
+
.site-nav a:focus-visible,
|
|
4284
|
+
.site-nav button:focus-visible {
|
|
4285
|
+
outline: 2px solid var(--bp-ink);
|
|
4286
|
+
outline-offset: -2px;
|
|
4287
|
+
}
|
|
4288
|
+
|
|
4289
|
+
body > .site-nav .site-nav__theme {
|
|
4290
|
+
position: static;
|
|
4291
|
+
inset: auto;
|
|
4292
|
+
z-index: auto;
|
|
4293
|
+
align-self: center;
|
|
4294
|
+
margin: 0 0 0 auto;
|
|
4295
|
+
padding: 6px 10px;
|
|
4296
|
+
border: 1px solid var(--bp-ink);
|
|
4297
|
+
border-radius: var(--bp-radius-0, 0);
|
|
4298
|
+
background: oklch(0 0 0 / 0);
|
|
4299
|
+
color: var(--bp-ink);
|
|
4300
|
+
font-family: inherit;
|
|
4301
|
+
font-size: inherit;
|
|
4302
|
+
letter-spacing: inherit;
|
|
4303
|
+
line-height: 1;
|
|
4304
|
+
text-transform: uppercase;
|
|
4305
|
+
cursor: pointer;
|
|
4306
|
+
}
|
|
4307
|
+
|
|
4308
|
+
body > .site-nav .site-nav__theme:hover {
|
|
4309
|
+
background: var(--bp-fill-amb);
|
|
4310
|
+
}
|
|
4311
|
+
|
|
4312
|
+
/* The docs sidebar remains fixed, but begins below the global site nav. */
|
|
4313
|
+
.site-nav ~ .bp-sidebar {
|
|
4314
|
+
top: var(--bp-site-nav-height);
|
|
4315
|
+
height: calc(100vh - var(--bp-site-nav-height));
|
|
4316
|
+
}
|
|
4317
|
+
|
|
4318
|
+
.site-nav + .scroll-progress {
|
|
4319
|
+
position: fixed;
|
|
4320
|
+
top: calc(var(--bp-site-nav-height)+ 4px);
|
|
4321
|
+
right: 0;
|
|
4322
|
+
left: 0;
|
|
4323
|
+
height: 2px;
|
|
4324
|
+
background: var(--bp-ink);
|
|
4325
|
+
transform: scaleX(0);
|
|
4326
|
+
transform-origin: left;
|
|
4327
|
+
z-index: 500;
|
|
4328
|
+
pointer-events: none;
|
|
4329
|
+
transition: transform var(--bp-duration-instant) var(--bp-ease-linear);
|
|
4330
|
+
}
|
|
4331
|
+
|
|
4332
|
+
@media (max-width: 560px) {
|
|
4333
|
+
:root {
|
|
4334
|
+
--bp-site-nav-height: 40px;
|
|
4335
|
+
}
|
|
4336
|
+
|
|
4337
|
+
.site-nav {
|
|
4338
|
+
padding: 0 8px;
|
|
4339
|
+
}
|
|
4340
|
+
|
|
4341
|
+
.site-nav__brand {
|
|
4342
|
+
padding: 0 8px 0 0;
|
|
4343
|
+
}
|
|
4344
|
+
|
|
4345
|
+
.site-nav__wordmark {
|
|
4346
|
+
display: none;
|
|
4347
|
+
}
|
|
4348
|
+
|
|
4349
|
+
.site-nav__links {
|
|
4350
|
+
margin-left: 0;
|
|
4351
|
+
}
|
|
4352
|
+
|
|
4353
|
+
.site-nav a {
|
|
4354
|
+
padding: 0 8px;
|
|
4355
|
+
}
|
|
4356
|
+
|
|
4357
|
+
body > .site-nav .site-nav__theme {
|
|
4358
|
+
padding: 6px 8px;
|
|
4359
|
+
}
|
|
4360
|
+
}
|
|
4361
|
+
|
|
4362
|
+
/* =====================================================================
|
|
4363
|
+
Blueprint collection switcher (sidebar header) + bottom-left theme toggle
|
|
4364
|
+
---------------------------------------------------------------------
|
|
4365
|
+
Docs chrome that replaces the old top bar: the sidebar wordmark becomes
|
|
4366
|
+
a menu for jumping between blueprints, and the theme control becomes a
|
|
4367
|
+
line icon pinned to the bottom-left corner.
|
|
4368
|
+
===================================================================== */
|
|
4369
|
+
|
|
4370
|
+
/* Reset the library <details>/<summary> chrome for the switcher. */
|
|
4371
|
+
.doc-switcher {
|
|
4372
|
+
position: relative;
|
|
4373
|
+
margin: 0 0 var(--bp-space-3);
|
|
4374
|
+
padding: 0;
|
|
4375
|
+
border: 0;
|
|
4376
|
+
background: none;
|
|
4377
|
+
}
|
|
4378
|
+
/* Shared field chrome for the switcher trigger and the search input so they
|
|
4379
|
+
read as one control family (border, radius, surface + hover/focus states). */
|
|
4380
|
+
.sidebar-field {
|
|
4381
|
+
border: 1px solid var(--bp-edge);
|
|
4382
|
+
border-radius: var(--bp-radius-6, 6px);
|
|
4383
|
+
background: var(--bp-paper);
|
|
4384
|
+
/* Hover-only color motion — idle fields snap on theme flip so the root
|
|
4385
|
+
view-transition crossfade isn't fighting per-field token tweens. */
|
|
4386
|
+
transition: none;
|
|
4387
|
+
}
|
|
4388
|
+
.sidebar-field:hover,
|
|
4389
|
+
.sidebar-field:focus-within {
|
|
4390
|
+
border-color: var(--bp-ink-line);
|
|
4391
|
+
background: var(--bp-fill-amb);
|
|
4392
|
+
transition:
|
|
4393
|
+
border-color var(--bp-duration-fast) var(--bp-ease-out),
|
|
4394
|
+
background-color var(--bp-duration-fast) var(--bp-ease-out);
|
|
4395
|
+
}
|
|
4396
|
+
.doc-switcher__current {
|
|
4397
|
+
display: flex;
|
|
4398
|
+
align-items: center;
|
|
4399
|
+
justify-content: space-between;
|
|
4400
|
+
gap: var(--bp-space-3);
|
|
4401
|
+
margin: 0;
|
|
4402
|
+
/* Match the sidebar toggle box so the two controls align on one row. */
|
|
4403
|
+
height: var(--bp-sidebar-toggle-size);
|
|
4404
|
+
padding: 0 var(--bp-space-3);
|
|
4405
|
+
list-style: none;
|
|
4406
|
+
font-weight: 400;
|
|
4407
|
+
cursor: pointer;
|
|
4408
|
+
}
|
|
4409
|
+
.doc-switcher__current::-webkit-details-marker {
|
|
4410
|
+
display: none;
|
|
4411
|
+
}
|
|
4412
|
+
.doc-switcher__current::before {
|
|
4413
|
+
content: none !important;
|
|
4414
|
+
}
|
|
4415
|
+
.doc-switcher__label {
|
|
4416
|
+
display: flex;
|
|
4417
|
+
flex-direction: column;
|
|
4418
|
+
gap: var(--bp-space-1);
|
|
4419
|
+
min-width: 0;
|
|
4420
|
+
}
|
|
4421
|
+
.doc-switcher__title {
|
|
4422
|
+
font-size: var(--bp-text-small);
|
|
4423
|
+
line-height: 1.3;
|
|
4424
|
+
font-weight: var(--bp-weight-medium);
|
|
4425
|
+
color: var(--bp-text);
|
|
4426
|
+
}
|
|
4427
|
+
.doc-switcher__meta {
|
|
4428
|
+
display: none;
|
|
4429
|
+
}
|
|
4430
|
+
.doc-switcher__chevron {
|
|
4431
|
+
display: inline-flex;
|
|
4432
|
+
flex: 0 0 auto;
|
|
4433
|
+
color: var(--bp-text-secondary);
|
|
4434
|
+
}
|
|
4435
|
+
.doc-switcher[open] .doc-switcher__chevron {
|
|
4436
|
+
transform: rotate(180deg);
|
|
4437
|
+
}
|
|
4438
|
+
.doc-switcher__menu {
|
|
4439
|
+
position: absolute;
|
|
4440
|
+
left: 0;
|
|
4441
|
+
right: 0;
|
|
4442
|
+
top: calc(100% + var(--bp-space-1));
|
|
4443
|
+
z-index: 300;
|
|
4444
|
+
display: flex;
|
|
4445
|
+
flex-direction: column;
|
|
4446
|
+
gap: var(--bp-space-1);
|
|
4447
|
+
padding: var(--bp-space-1);
|
|
4448
|
+
border: 1px solid var(--bp-edge);
|
|
4449
|
+
/* Container radius − padding = item radius, so the rows nest perfectly. */
|
|
4450
|
+
border-radius: var(--bp-radius-8, 8px);
|
|
4451
|
+
background: var(--bp-paper);
|
|
4452
|
+
box-shadow: var(--bp-shadow-pop);
|
|
4453
|
+
transform-origin: top center;
|
|
4454
|
+
}
|
|
4455
|
+
/* Open animation: keyframes re-run every time [open] is set on the <details>,
|
|
4456
|
+
unlike @starting-style which only fires on first render. Close stays instant
|
|
4457
|
+
(native <details> hides content immediately). Timing uses motion tokens. */
|
|
4458
|
+
.doc-switcher[open] .doc-switcher__menu {
|
|
4459
|
+
animation: bp-doc-switcher-in var(--bp-duration-normal) var(--bp-ease-out);
|
|
4460
|
+
}
|
|
4461
|
+
@keyframes bp-doc-switcher-in {
|
|
4462
|
+
from {
|
|
4463
|
+
opacity: 0;
|
|
4464
|
+
transform: translateY(-4px) scale(0.98);
|
|
4465
|
+
}
|
|
4466
|
+
to {
|
|
4467
|
+
opacity: 1;
|
|
4468
|
+
transform: none;
|
|
4469
|
+
}
|
|
4470
|
+
}
|
|
4471
|
+
.doc-switcher__menu a {
|
|
4472
|
+
display: flex;
|
|
4473
|
+
align-items: center;
|
|
4474
|
+
justify-content: space-between;
|
|
4475
|
+
gap: var(--bp-space-2);
|
|
4476
|
+
padding: var(--bp-space-2) var(--bp-space-3);
|
|
4477
|
+
border-radius: var(--bp-radius-4, 4px);
|
|
4478
|
+
text-decoration: none;
|
|
4479
|
+
}
|
|
4480
|
+
.doc-switcher__menu a:hover {
|
|
4481
|
+
background: var(--bp-fill-amb);
|
|
4482
|
+
}
|
|
4483
|
+
.doc-switcher__menu a.is-current {
|
|
4484
|
+
background: var(--bp-fill-hi);
|
|
4485
|
+
}
|
|
4486
|
+
.doc-switcher__option {
|
|
4487
|
+
display: flex;
|
|
4488
|
+
flex-direction: column;
|
|
4489
|
+
min-width: 0;
|
|
4490
|
+
}
|
|
4491
|
+
.doc-switcher__name {
|
|
4492
|
+
font-size: var(--bp-text-small);
|
|
4493
|
+
line-height: 1.3;
|
|
4494
|
+
font-weight: var(--bp-weight-medium);
|
|
4495
|
+
color: var(--bp-text);
|
|
4496
|
+
}
|
|
4497
|
+
.doc-switcher__desc {
|
|
4498
|
+
overflow: hidden;
|
|
4499
|
+
font-size: var(--bp-label-md);
|
|
4500
|
+
line-height: 1.4;
|
|
4501
|
+
color: var(--bp-text-secondary);
|
|
4502
|
+
white-space: nowrap;
|
|
4503
|
+
text-overflow: ellipsis;
|
|
4504
|
+
}
|
|
4505
|
+
/* Reused chevron as a quiet "go to" affordance — only on the current and
|
|
4506
|
+
hovered rows so the resting menu stays clean and condensed. */
|
|
4507
|
+
.doc-switcher__go {
|
|
4508
|
+
flex: 0 0 auto;
|
|
4509
|
+
display: inline-flex;
|
|
4510
|
+
color: var(--bp-text-secondary);
|
|
4511
|
+
opacity: 0;
|
|
4512
|
+
transform: rotate(-90deg);
|
|
4513
|
+
}
|
|
4514
|
+
.doc-switcher__menu a:hover .doc-switcher__go,
|
|
4515
|
+
.doc-switcher__menu a.is-current .doc-switcher__go {
|
|
4516
|
+
opacity: 1;
|
|
4517
|
+
}
|
|
4518
|
+
|
|
4519
|
+
/* Sidebar search — header row beside the corner toggle, above the header scrim. */
|
|
4520
|
+
.sidebar-search {
|
|
4521
|
+
position: relative;
|
|
4522
|
+
/* Sit above the header scrim (z 200) so the field stays crisp while the TOC
|
|
4523
|
+
fades behind it. */
|
|
4524
|
+
z-index: 300;
|
|
4525
|
+
/* Left margin clears the fixed corner toggle so search sits on the same row,
|
|
4526
|
+
beside it. Right edge stops at the content edge so it lines up with the
|
|
4527
|
+
TOC entry pills below. */
|
|
4528
|
+
margin: calc(-1 * var(--bp-space-2)) 0 var(--bp-space-3)
|
|
4529
|
+
calc(var(--bp-sidebar-toggle-size) + var(--bp-space-3));
|
|
4530
|
+
}
|
|
4531
|
+
/* Trigger button: magnifier + label + ⌘K hint on one row. It is a <button>
|
|
4532
|
+
(it opens the search dialog, it is not a text field); the .sidebar-field
|
|
4533
|
+
chrome carries the border/radius/surface and children align inside it. */
|
|
4534
|
+
.sidebar-search__field {
|
|
4535
|
+
display: flex;
|
|
4536
|
+
align-items: center;
|
|
4537
|
+
gap: var(--bp-space-2);
|
|
4538
|
+
width: 100%;
|
|
4539
|
+
height: var(--bp-sidebar-toggle-size);
|
|
4540
|
+
padding: 0 var(--bp-space-3);
|
|
4541
|
+
font: inherit;
|
|
4542
|
+
text-align: left;
|
|
4543
|
+
color: inherit;
|
|
4544
|
+
cursor: pointer;
|
|
4545
|
+
-webkit-appearance: none;
|
|
4546
|
+
appearance: none;
|
|
4547
|
+
}
|
|
4548
|
+
.sidebar-search__field:focus-visible {
|
|
4549
|
+
outline: 2px solid var(--bp-ink);
|
|
4550
|
+
outline-offset: 2px;
|
|
4551
|
+
}
|
|
4552
|
+
.sidebar-search__icon {
|
|
4553
|
+
flex: 0 0 auto;
|
|
4554
|
+
display: inline-flex;
|
|
4555
|
+
color: var(--bp-text-secondary);
|
|
4556
|
+
}
|
|
4557
|
+
.sidebar-search__label {
|
|
4558
|
+
flex: 1 1 auto;
|
|
4559
|
+
min-width: 0;
|
|
4560
|
+
font-family: var(--bp-sans);
|
|
4561
|
+
font-size: var(--bp-text-small);
|
|
4562
|
+
line-height: 1.3;
|
|
4563
|
+
font-weight: 400;
|
|
4564
|
+
color: var(--bp-text-secondary);
|
|
4565
|
+
}
|
|
4566
|
+
/* ⌘K affordance — quiet keycaps, sized down from the base kbd for the rail. */
|
|
4567
|
+
.sidebar-search__hint {
|
|
4568
|
+
flex: 0 0 auto;
|
|
4569
|
+
display: inline-flex;
|
|
4570
|
+
gap: 2px;
|
|
4571
|
+
}
|
|
4572
|
+
.sidebar-search__hint kbd {
|
|
4573
|
+
padding: 0 4px;
|
|
4574
|
+
border-width: 1px;
|
|
4575
|
+
border-radius: var(--bp-radius-2, 2px);
|
|
4576
|
+
font-size: var(--bp-label-md);
|
|
4577
|
+
line-height: 1.5;
|
|
4578
|
+
color: var(--bp-text-secondary);
|
|
4579
|
+
}
|
|
4580
|
+
|
|
4581
|
+
/* =====================================================================
|
|
4582
|
+
Search command menu (docs chrome) — Mintlify-style palette
|
|
4583
|
+
---------------------------------------------------------------------
|
|
4584
|
+
Opened from the sidebar trigger or ⌘K / Ctrl+K (see wireSearchPalette).
|
|
4585
|
+
Reuses the rounded sidebar control family: paper surface, --bp-radius-8
|
|
4586
|
+
panel with --bp-shadow-pop, --bp-radius-4 rows, the --bp-fill-amb /
|
|
4587
|
+
--bp-fill-hi hover + selected surfaces, and the shared open animation.
|
|
4588
|
+
Chrome stays on the neutral ink scale. Query filtering is a plain
|
|
4589
|
+
substring match over the page's headings; richer search is deferred.
|
|
4590
|
+
===================================================================== */
|
|
4591
|
+
|
|
4592
|
+
/* Modal scrim. Hidden until .is-open; centers the panel near the top of the
|
|
4593
|
+
viewport, the way command palettes sit. Sits above all docs chrome. Uses
|
|
4594
|
+
the same drafting scrim as .bp-lightbox (--bp-scrim + --bp-hatch). */
|
|
4595
|
+
.docs-search-overlay {
|
|
4596
|
+
position: fixed;
|
|
4597
|
+
inset: 0;
|
|
4598
|
+
z-index: 600;
|
|
4599
|
+
display: none;
|
|
4600
|
+
justify-content: center;
|
|
4601
|
+
align-items: flex-start;
|
|
4602
|
+
padding: clamp(var(--bp-space-5), 12vh, var(--bp-space-7)) var(--bp-space-4)
|
|
4603
|
+
var(--bp-space-4);
|
|
4604
|
+
background-color: var(--bp-scrim);
|
|
4605
|
+
background-image: var(--bp-hatch);
|
|
4606
|
+
}
|
|
4607
|
+
.docs-search-overlay.is-open {
|
|
4608
|
+
display: flex;
|
|
4609
|
+
animation: bp-search-overlay-in var(--bp-duration-fast, 120ms)
|
|
4610
|
+
var(--bp-ease-out);
|
|
4611
|
+
}
|
|
4612
|
+
.docs-search-overlay.is-open .docs-search {
|
|
4613
|
+
animation: bp-doc-switcher-in var(--bp-duration-normal) var(--bp-ease-out);
|
|
4614
|
+
}
|
|
4615
|
+
@keyframes bp-search-overlay-in {
|
|
4616
|
+
from {
|
|
4617
|
+
opacity: 0;
|
|
4618
|
+
}
|
|
4619
|
+
to {
|
|
4620
|
+
opacity: 1;
|
|
4621
|
+
}
|
|
4622
|
+
}
|
|
4623
|
+
|
|
4624
|
+
/* The panel. Position-agnostic: the overlay wrapper centers it over a scrim. */
|
|
4625
|
+
.docs-search {
|
|
4626
|
+
display: flex;
|
|
4627
|
+
flex-direction: column;
|
|
4628
|
+
width: min(640px, 100%);
|
|
4629
|
+
max-height: min(560px, 80vh);
|
|
4630
|
+
overflow: hidden;
|
|
4631
|
+
border: 1px solid var(--bp-edge);
|
|
4632
|
+
border-radius: var(--bp-radius-8, 8px);
|
|
4633
|
+
background: var(--bp-paper);
|
|
4634
|
+
box-shadow: var(--bp-shadow-pop);
|
|
4635
|
+
}
|
|
4636
|
+
|
|
4637
|
+
/* Search row */
|
|
4638
|
+
.docs-search__field {
|
|
4639
|
+
display: flex;
|
|
4640
|
+
align-items: center;
|
|
4641
|
+
gap: var(--bp-space-3);
|
|
4642
|
+
padding: var(--bp-space-3) var(--bp-space-4);
|
|
4643
|
+
border-bottom: 1px solid var(--bp-edge);
|
|
4644
|
+
}
|
|
4645
|
+
.docs-search__icon {
|
|
4646
|
+
flex: 0 0 auto;
|
|
4647
|
+
display: inline-flex;
|
|
4648
|
+
color: var(--bp-text-secondary);
|
|
4649
|
+
}
|
|
4650
|
+
.docs-search__input {
|
|
4651
|
+
flex: 1 1 auto;
|
|
4652
|
+
min-width: 0;
|
|
4653
|
+
margin: 0;
|
|
4654
|
+
padding: 0;
|
|
4655
|
+
border: 0;
|
|
4656
|
+
background: none;
|
|
4657
|
+
font-family: var(--bp-sans);
|
|
4658
|
+
font-size: var(--bp-text-body);
|
|
4659
|
+
line-height: var(--bp-lh-body);
|
|
4660
|
+
color: var(--bp-text);
|
|
4661
|
+
-webkit-appearance: none;
|
|
4662
|
+
appearance: none;
|
|
4663
|
+
}
|
|
4664
|
+
.docs-search__input::placeholder {
|
|
4665
|
+
color: var(--bp-text-secondary);
|
|
4666
|
+
}
|
|
4667
|
+
.docs-search__input:focus {
|
|
4668
|
+
outline: none;
|
|
4669
|
+
}
|
|
4670
|
+
.docs-search__input::-webkit-search-decoration,
|
|
4671
|
+
.docs-search__input::-webkit-search-cancel-button {
|
|
4672
|
+
-webkit-appearance: none;
|
|
4673
|
+
}
|
|
4674
|
+
.docs-search__esc {
|
|
4675
|
+
flex: 0 0 auto;
|
|
4676
|
+
padding: 1px 6px;
|
|
4677
|
+
font-size: var(--bp-label-md);
|
|
4678
|
+
letter-spacing: var(--bp-label-md-ls);
|
|
4679
|
+
text-transform: uppercase;
|
|
4680
|
+
color: var(--bp-text-secondary);
|
|
4681
|
+
}
|
|
4682
|
+
|
|
4683
|
+
/* Results region */
|
|
4684
|
+
.docs-search__results {
|
|
4685
|
+
flex: 1 1 auto;
|
|
4686
|
+
overflow-y: auto;
|
|
4687
|
+
padding: var(--bp-space-2);
|
|
4688
|
+
}
|
|
4689
|
+
/* Group label — machine voice (mono + uppercase) with a trailing count. */
|
|
4690
|
+
.docs-search__group {
|
|
4691
|
+
display: flex;
|
|
4692
|
+
align-items: center;
|
|
4693
|
+
gap: var(--bp-space-2);
|
|
4694
|
+
padding: var(--bp-space-2) var(--bp-space-3) var(--bp-space-1);
|
|
4695
|
+
font-family: var(--bp-mono);
|
|
4696
|
+
font-size: var(--bp-label-md);
|
|
4697
|
+
letter-spacing: var(--bp-label-md-ls);
|
|
4698
|
+
text-transform: uppercase;
|
|
4699
|
+
color: var(--bp-text-secondary);
|
|
4700
|
+
}
|
|
4701
|
+
.docs-search__group-count {
|
|
4702
|
+
color: var(--bp-text-secondary);
|
|
4703
|
+
opacity: 0.7;
|
|
4704
|
+
}
|
|
4705
|
+
|
|
4706
|
+
/* A result row: breadcrumb · title · snippet, with a trailing return key.
|
|
4707
|
+
Rows are <a> for navigation; suppress the base prose link underline except
|
|
4708
|
+
on the selected/hovered surface (background carries the affordance). */
|
|
4709
|
+
.docs-search__row {
|
|
4710
|
+
display: grid;
|
|
4711
|
+
grid-template-columns: 1fr auto;
|
|
4712
|
+
align-items: center;
|
|
4713
|
+
gap: var(--bp-space-1) var(--bp-space-3);
|
|
4714
|
+
padding: var(--bp-space-2) var(--bp-space-3);
|
|
4715
|
+
border-radius: var(--bp-radius-4, 4px);
|
|
4716
|
+
cursor: pointer;
|
|
4717
|
+
text-decoration: none;
|
|
4718
|
+
color: inherit;
|
|
4719
|
+
}
|
|
4720
|
+
.docs-search__row:hover {
|
|
4721
|
+
background: var(--bp-fill-amb);
|
|
4722
|
+
text-decoration: none;
|
|
4723
|
+
}
|
|
4724
|
+
/* Keyboard-selected row — reuses the rail's "current" surface. */
|
|
4725
|
+
.docs-search__row[aria-selected="true"] {
|
|
4726
|
+
background: var(--bp-fill-hi);
|
|
4727
|
+
text-decoration: none;
|
|
4728
|
+
}
|
|
4729
|
+
.docs-search__row-main {
|
|
4730
|
+
display: flex;
|
|
4731
|
+
flex-direction: column;
|
|
4732
|
+
gap: var(--bp-space-1);
|
|
4733
|
+
min-width: 0;
|
|
4734
|
+
}
|
|
4735
|
+
.docs-search__crumb {
|
|
4736
|
+
display: block;
|
|
4737
|
+
font-family: var(--bp-mono);
|
|
4738
|
+
font-size: var(--bp-label-md);
|
|
4739
|
+
letter-spacing: var(--bp-label-md-ls);
|
|
4740
|
+
color: var(--bp-text-secondary);
|
|
4741
|
+
white-space: nowrap;
|
|
4742
|
+
overflow: hidden;
|
|
4743
|
+
text-overflow: ellipsis;
|
|
4744
|
+
}
|
|
4745
|
+
.docs-search__title {
|
|
4746
|
+
display: flex;
|
|
4747
|
+
align-items: baseline;
|
|
4748
|
+
gap: var(--bp-space-1);
|
|
4749
|
+
min-width: 0;
|
|
4750
|
+
font-family: var(--bp-sans);
|
|
4751
|
+
font-size: var(--bp-text-small);
|
|
4752
|
+
line-height: 1.3;
|
|
4753
|
+
font-weight: var(--bp-weight-medium);
|
|
4754
|
+
color: var(--bp-text);
|
|
4755
|
+
}
|
|
4756
|
+
/* The "#" anchor glyph borrows the machine voice so it reads as a heading
|
|
4757
|
+
link, not prose. */
|
|
4758
|
+
.docs-search__hash {
|
|
4759
|
+
flex: 0 0 auto;
|
|
4760
|
+
font-family: var(--bp-mono);
|
|
4761
|
+
color: var(--bp-text-secondary);
|
|
4762
|
+
}
|
|
4763
|
+
.docs-search__snippet {
|
|
4764
|
+
overflow: hidden;
|
|
4765
|
+
font-size: var(--bp-text-small);
|
|
4766
|
+
line-height: 1.4;
|
|
4767
|
+
color: var(--bp-text-secondary);
|
|
4768
|
+
white-space: nowrap;
|
|
4769
|
+
text-overflow: ellipsis;
|
|
4770
|
+
}
|
|
4771
|
+
.docs-search__snippet mark {
|
|
4772
|
+
padding: 0;
|
|
4773
|
+
background: var(--bp-highlight);
|
|
4774
|
+
color: var(--bp-text);
|
|
4775
|
+
}
|
|
4776
|
+
/* Return-key affordance — only on the selected/hovered row, like the
|
|
4777
|
+
switcher's quiet "go to" chevron. */
|
|
4778
|
+
.docs-search__enter {
|
|
4779
|
+
flex: 0 0 auto;
|
|
4780
|
+
align-self: center;
|
|
4781
|
+
padding: 1px 5px;
|
|
4782
|
+
font-size: var(--bp-label-md);
|
|
4783
|
+
color: var(--bp-text-secondary);
|
|
4784
|
+
opacity: 0;
|
|
4785
|
+
}
|
|
4786
|
+
.docs-search__row:hover .docs-search__enter,
|
|
4787
|
+
.docs-search__row[aria-selected="true"] .docs-search__enter {
|
|
4788
|
+
opacity: 1;
|
|
4789
|
+
}
|
|
4790
|
+
|
|
4791
|
+
/* Empty state */
|
|
4792
|
+
.docs-search__empty {
|
|
4793
|
+
display: flex;
|
|
4794
|
+
flex-direction: column;
|
|
4795
|
+
align-items: center;
|
|
4796
|
+
gap: var(--bp-space-2);
|
|
4797
|
+
padding: var(--bp-space-6) var(--bp-space-4);
|
|
4798
|
+
text-align: center;
|
|
4799
|
+
}
|
|
4800
|
+
.docs-search__empty-icon {
|
|
4801
|
+
display: inline-flex;
|
|
4802
|
+
color: var(--bp-text-secondary);
|
|
4803
|
+
opacity: 0.6;
|
|
4804
|
+
}
|
|
4805
|
+
.docs-search__empty-title {
|
|
4806
|
+
font-family: var(--bp-sans);
|
|
4807
|
+
font-size: var(--bp-text-small);
|
|
4808
|
+
font-weight: var(--bp-weight-medium);
|
|
4809
|
+
color: var(--bp-text);
|
|
4810
|
+
}
|
|
4811
|
+
.docs-search__empty-note {
|
|
4812
|
+
font-size: var(--bp-text-small);
|
|
4813
|
+
color: var(--bp-text-secondary);
|
|
4814
|
+
}
|
|
4815
|
+
|
|
4816
|
+
/* Footer keyboard legend */
|
|
4817
|
+
.docs-search__foot {
|
|
4818
|
+
display: flex;
|
|
4819
|
+
flex-wrap: wrap;
|
|
4820
|
+
align-items: center;
|
|
4821
|
+
justify-content: space-between;
|
|
4822
|
+
gap: var(--bp-space-1) var(--bp-space-3);
|
|
4823
|
+
padding: var(--bp-space-2) var(--bp-space-4);
|
|
4824
|
+
border-top: 1px solid var(--bp-edge);
|
|
4825
|
+
font-family: var(--bp-mono);
|
|
4826
|
+
font-size: var(--bp-label-md);
|
|
4827
|
+
letter-spacing: var(--bp-label-md-ls);
|
|
4828
|
+
color: var(--bp-text-secondary);
|
|
4829
|
+
}
|
|
4830
|
+
.docs-search__keys {
|
|
4831
|
+
display: flex;
|
|
4832
|
+
flex-wrap: wrap;
|
|
4833
|
+
align-items: center;
|
|
4834
|
+
gap: var(--bp-space-1) var(--bp-space-3);
|
|
4835
|
+
}
|
|
4836
|
+
.docs-search__key {
|
|
4837
|
+
display: inline-flex;
|
|
4838
|
+
align-items: center;
|
|
4839
|
+
gap: var(--bp-space-1);
|
|
4840
|
+
}
|
|
4841
|
+
.docs-search__foot kbd {
|
|
4842
|
+
padding: 0 4px;
|
|
4843
|
+
border-width: 1px;
|
|
4844
|
+
border-radius: var(--bp-radius-2, 2px);
|
|
4845
|
+
font-size: var(--bp-label-md);
|
|
4846
|
+
line-height: 1.5;
|
|
4847
|
+
color: var(--bp-text-secondary);
|
|
4848
|
+
}
|
|
4849
|
+
|
|
4850
|
+
/* Sidebar footer scrim token. The footer (theme switch + author/date) gets a
|
|
4851
|
+
soft fade above it so the scrollable TOC dissolves into the rail rather than
|
|
4852
|
+
colliding with the footer. The bottom band stays solid to back the footer.
|
|
4853
|
+
Interpolating `in oklch` is premultiplied, so a plain `oklch(0 0 0 / 0)` stop
|
|
4854
|
+
fades cleanly (the zero-alpha endpoint contributes no colour, no muddy
|
|
4855
|
+
mid-tone) — and our rail bg is achromatic, so no same-colour stop is needed.
|
|
4856
|
+
The plain gradient syntax stays as the fallback for engines without oklch
|
|
4857
|
+
gradient interpolation. */
|
|
4858
|
+
:root {
|
|
4859
|
+
/* Shared square control size for the corner toggle, doc-switcher trigger,
|
|
4860
|
+
theme switch, and scrim geometry — one token keeps every calc in sync. */
|
|
4861
|
+
--bp-sidebar-toggle-size: 30px;
|
|
4862
|
+
/* Content column inset — toggle, TOC pills, switcher, and footer share one
|
|
4863
|
+
left/right edge so the rail reads as an even column. */
|
|
4864
|
+
--bp-sidebar-content-inset: calc(var(--bp-space-4) + var(--bp-space-3));
|
|
4865
|
+
/* Frame line → chrome row: same gap below the top line and above the bottom. */
|
|
4866
|
+
--bp-sidebar-chrome-gap: var(--bp-space-3);
|
|
4867
|
+
--bp-sidebar-chrome-inset-top: calc(
|
|
4868
|
+
var(--bp-shell-inset-top, var(--bp-space-4)) + var(--bp-sidebar-chrome-gap)
|
|
4869
|
+
);
|
|
4870
|
+
--bp-sidebar-chrome-inset-bottom: calc(
|
|
4871
|
+
var(--bp-shell-inset-block, var(--bp-space-4)) + var(--bp-sidebar-chrome-gap)
|
|
4872
|
+
);
|
|
4873
|
+
--bp-sidebar-footer: calc(
|
|
4874
|
+
var(--bp-sidebar-chrome-inset-bottom) + var(--bp-sidebar-toggle-size)
|
|
4875
|
+
);
|
|
4876
|
+
/* Scroll clearance: footer band + breathing room for the last TOC pill. */
|
|
4877
|
+
--bp-sidebar-scroll-padding-bottom: calc(
|
|
4878
|
+
var(--bp-sidebar-footer) + var(--bp-space-4)
|
|
4879
|
+
);
|
|
4880
|
+
--bp-sidebar-fade: linear-gradient(
|
|
4881
|
+
to top,
|
|
4882
|
+
var(--bp-bg) var(--bp-sidebar-footer),
|
|
4883
|
+
oklch(0 0 0 / 0)
|
|
4884
|
+
);
|
|
4885
|
+
|
|
4886
|
+
/* Header counterpart: a circular scrim centred on the corner toggle so the
|
|
4887
|
+
TOC dissolves *around* the icon as it scrolls up under it — radiating from
|
|
4888
|
+
the icon rather than a flat top edge. Centre = toggle inset + half its box.
|
|
4889
|
+
Solid out to --bp-space-4, then fades over --bp-space-6. */
|
|
4890
|
+
--bp-sidebar-header-scrim: calc(
|
|
4891
|
+
var(--bp-sidebar-icon-center) + var(--bp-space-4) + var(--bp-space-6)
|
|
4892
|
+
);
|
|
4893
|
+
--bp-sidebar-icon-center: calc(
|
|
4894
|
+
var(--bp-sidebar-chrome-inset-top) + var(--bp-sidebar-toggle-size) / 2
|
|
4895
|
+
);
|
|
4896
|
+
--bp-sidebar-icon-fade: radial-gradient(
|
|
4897
|
+
circle at var(--bp-sidebar-icon-center) var(--bp-sidebar-icon-center),
|
|
4898
|
+
var(--bp-bg) var(--bp-space-4),
|
|
4899
|
+
oklch(0 0 0 / 0) calc(var(--bp-space-4) + var(--bp-space-6))
|
|
4900
|
+
);
|
|
4901
|
+
}
|
|
4902
|
+
@supports (
|
|
4903
|
+
background:
|
|
4904
|
+
linear-gradient(in oklch, oklch(0.5 0.1 30), oklch(0.5 0.1 240))
|
|
4905
|
+
) {
|
|
4906
|
+
:root {
|
|
4907
|
+
--bp-sidebar-fade: linear-gradient(
|
|
4908
|
+
in oklch to top,
|
|
4909
|
+
var(--bp-bg) var(--bp-sidebar-footer),
|
|
4910
|
+
oklch(0 0 0 / 0)
|
|
4911
|
+
);
|
|
4912
|
+
--bp-sidebar-icon-fade: radial-gradient(
|
|
4913
|
+
in oklch circle at var(--bp-sidebar-icon-center)
|
|
4914
|
+
var(--bp-sidebar-icon-center),
|
|
4915
|
+
var(--bp-bg) var(--bp-space-4),
|
|
4916
|
+
oklch(0 0 0 / 0) calc(var(--bp-space-4) + var(--bp-space-6))
|
|
4917
|
+
);
|
|
4918
|
+
}
|
|
4919
|
+
}
|
|
4920
|
+
|
|
4921
|
+
/* Sidebar footer: the theme switch and the author/date block read as two flex
|
|
4922
|
+
items with space between them, spanning the same band as the TOC entries
|
|
4923
|
+
(left edge on the pill, right edge at the rail's content edge). */
|
|
4924
|
+
.sidebar-footer {
|
|
4925
|
+
display: flex;
|
|
4926
|
+
align-items: center;
|
|
4927
|
+
justify-content: space-between;
|
|
4928
|
+
gap: var(--bp-space-3);
|
|
4929
|
+
}
|
|
4930
|
+
|
|
4931
|
+
/* Author / date metadata — grouped as the footer's right-hand flex item. */
|
|
4932
|
+
.sidebar-meta {
|
|
4933
|
+
display: flex;
|
|
4934
|
+
flex-direction: row;
|
|
4935
|
+
align-items: center;
|
|
4936
|
+
gap: var(--bp-space-4);
|
|
4937
|
+
}
|
|
4938
|
+
.sidebar-meta__item {
|
|
4939
|
+
display: flex;
|
|
4940
|
+
flex-direction: column;
|
|
4941
|
+
gap: 0;
|
|
4942
|
+
}
|
|
4943
|
+
.sidebar-meta__item .bp-meta {
|
|
4944
|
+
margin: 0;
|
|
4945
|
+
line-height: 1.25;
|
|
4946
|
+
}
|
|
4947
|
+
.sidebar-meta__item .bp-note {
|
|
4948
|
+
margin: 0;
|
|
4949
|
+
line-height: 1.35;
|
|
4950
|
+
}
|
|
4951
|
+
|
|
4952
|
+
/* Leave room at the bottom of the rail so the last entry clears the footer. */
|
|
4953
|
+
.bp-sidebar {
|
|
4954
|
+
--bp-theme-toggle-height: var(--bp-sidebar-toggle-size);
|
|
4955
|
+
padding-bottom: var(--bp-sidebar-scroll-padding-bottom);
|
|
4956
|
+
}
|
|
4957
|
+
|
|
4958
|
+
/* Bottom-left theme switch (Iconoir half-moon / light-bulb). Scoped to the
|
|
4959
|
+
sidebar so the code demo's in-nav theme button is unaffected. */
|
|
4960
|
+
.bp-sidebar .theme-toggle {
|
|
4961
|
+
/* A flex child of .sidebar-footer; relative so the thumb anchors to it. */
|
|
4962
|
+
position: relative;
|
|
4963
|
+
flex: 0 0 auto;
|
|
4964
|
+
display: grid;
|
|
4965
|
+
grid-template-columns: 1fr 1fr;
|
|
4966
|
+
align-items: center;
|
|
4967
|
+
width: 54px;
|
|
4968
|
+
height: var(--bp-theme-toggle-height);
|
|
4969
|
+
padding: 2px;
|
|
4970
|
+
border: 1px solid var(--bp-edge);
|
|
4971
|
+
border-radius: var(--bp-radius-6, 6px);
|
|
4972
|
+
background: var(--bp-fill-amb);
|
|
4973
|
+
color: var(--bp-text-secondary);
|
|
4974
|
+
cursor: pointer;
|
|
4975
|
+
transition: none;
|
|
4976
|
+
}
|
|
4977
|
+
.bp-sidebar .theme-toggle:hover {
|
|
4978
|
+
border-color: var(--bp-ink-line);
|
|
4979
|
+
background: var(--bp-paper);
|
|
4980
|
+
transition:
|
|
4981
|
+
border-color var(--bp-duration-fast) var(--bp-ease-out),
|
|
4982
|
+
background-color var(--bp-duration-fast) var(--bp-ease-out),
|
|
4983
|
+
color var(--bp-duration-fast) var(--bp-ease-out);
|
|
4984
|
+
}
|
|
4985
|
+
.bp-sidebar .theme-toggle:focus-visible {
|
|
4986
|
+
outline: 2px solid var(--bp-ink);
|
|
4987
|
+
outline-offset: 2px;
|
|
4988
|
+
}
|
|
4989
|
+
.bp-sidebar .theme-toggle__thumb {
|
|
4990
|
+
position: absolute;
|
|
4991
|
+
top: 2px;
|
|
4992
|
+
left: 2px;
|
|
4993
|
+
/* height − (2×border + 2×pad) keeps an even 2px gap on every side. */
|
|
4994
|
+
width: calc(var(--bp-theme-toggle-height) - 6px);
|
|
4995
|
+
height: calc(var(--bp-theme-toggle-height) - 6px);
|
|
4996
|
+
border: 1px solid var(--bp-ink-line);
|
|
4997
|
+
border-radius: var(--bp-radius-4, 4px);
|
|
4998
|
+
background: var(--bp-paper);
|
|
4999
|
+
box-shadow: 0 1px 2px oklch(0 0 0 / 0.06);
|
|
5000
|
+
pointer-events: none;
|
|
5001
|
+
}
|
|
5002
|
+
[data-obvious-theme="dark"] .bp-sidebar .theme-toggle__thumb {
|
|
5003
|
+
transform: translateX(24px);
|
|
5004
|
+
}
|
|
5005
|
+
.bp-sidebar .theme-toggle svg {
|
|
5006
|
+
display: block;
|
|
5007
|
+
}
|
|
5008
|
+
.bp-sidebar .theme-toggle__icon {
|
|
5009
|
+
position: relative;
|
|
5010
|
+
z-index: 1;
|
|
5011
|
+
display: flex;
|
|
5012
|
+
align-items: center;
|
|
5013
|
+
justify-content: center;
|
|
5014
|
+
pointer-events: none;
|
|
5015
|
+
}
|
|
5016
|
+
:not([data-obvious-theme="dark"]) .bp-sidebar .theme-toggle__icon--moon,
|
|
5017
|
+
[data-obvious-theme="dark"] .bp-sidebar .theme-toggle__icon--bulb {
|
|
5018
|
+
color: var(--bp-ink);
|
|
5019
|
+
}
|
|
5020
|
+
|
|
5021
|
+
/* =====================================================================
|
|
5022
|
+
Sidebar collapse toggle (Iconoir sidebar glyph, pinned top-left)
|
|
5023
|
+
---------------------------------------------------------------------
|
|
5024
|
+
Docs chrome that hides/shows the fixed contents rail, like the doc
|
|
5025
|
+
switcher and theme toggle above. It lives on <body> (not inside the
|
|
5026
|
+
rail) so it stays reachable once the rail is gone. The collapsed-state
|
|
5027
|
+
rules are unlayered author CSS, so they win over blueprint.css per the
|
|
5028
|
+
specificity contract. The whole rail slides as one rigid unit — its scrims
|
|
5029
|
+
+ footer ride along (no opacity tricks), and the sheet trails one space-4
|
|
5030
|
+
behind the rail's edge the entire way (shared duration + easing).
|
|
5031
|
+
===================================================================== */
|
|
5032
|
+
.sidebar-toggle {
|
|
5033
|
+
position: fixed;
|
|
5034
|
+
/* Same offset from the top frame line as the footer keeps from the bottom. */
|
|
5035
|
+
top: var(--bp-sidebar-chrome-inset-top);
|
|
5036
|
+
left: var(--bp-sidebar-content-inset);
|
|
5037
|
+
z-index: 320;
|
|
5038
|
+
display: inline-flex;
|
|
5039
|
+
align-items: center;
|
|
5040
|
+
justify-content: center;
|
|
5041
|
+
width: var(--bp-sidebar-toggle-size);
|
|
5042
|
+
height: var(--bp-sidebar-toggle-size);
|
|
5043
|
+
padding: 0;
|
|
5044
|
+
border: 1px solid var(--bp-edge);
|
|
5045
|
+
border-radius: var(--bp-radius-6, 6px);
|
|
5046
|
+
background: var(--bp-fill-amb);
|
|
5047
|
+
color: var(--bp-text-secondary);
|
|
5048
|
+
cursor: pointer;
|
|
5049
|
+
transition: none;
|
|
5050
|
+
}
|
|
5051
|
+
.sidebar-toggle:hover {
|
|
5052
|
+
border-color: var(--bp-ink-line);
|
|
5053
|
+
background: var(--bp-paper);
|
|
5054
|
+
color: var(--bp-ink);
|
|
5055
|
+
transition:
|
|
5056
|
+
border-color var(--bp-duration-fast) var(--bp-ease-out),
|
|
5057
|
+
background-color var(--bp-duration-fast) var(--bp-ease-out),
|
|
5058
|
+
color var(--bp-duration-fast) var(--bp-ease-out);
|
|
5059
|
+
}
|
|
5060
|
+
.sidebar-toggle:focus-visible {
|
|
5061
|
+
outline: 2px solid var(--bp-ink);
|
|
5062
|
+
outline-offset: 2px;
|
|
5063
|
+
}
|
|
5064
|
+
.sidebar-toggle__icons {
|
|
5065
|
+
position: relative;
|
|
5066
|
+
display: block;
|
|
5067
|
+
width: 16px;
|
|
5068
|
+
height: 16px;
|
|
5069
|
+
}
|
|
5070
|
+
.sidebar-toggle__icon {
|
|
5071
|
+
position: absolute;
|
|
5072
|
+
inset: 0;
|
|
5073
|
+
display: flex;
|
|
5074
|
+
align-items: center;
|
|
5075
|
+
justify-content: center;
|
|
5076
|
+
pointer-events: none;
|
|
5077
|
+
}
|
|
5078
|
+
.sidebar-toggle__icon--collapse {
|
|
5079
|
+
opacity: 1;
|
|
5080
|
+
}
|
|
5081
|
+
.sidebar-toggle__icon--expand {
|
|
5082
|
+
opacity: 0;
|
|
5083
|
+
}
|
|
5084
|
+
[data-sidebar="collapsed"] .sidebar-toggle__icon--collapse {
|
|
5085
|
+
opacity: 0;
|
|
5086
|
+
}
|
|
5087
|
+
[data-sidebar="collapsed"] .sidebar-toggle__icon--expand {
|
|
5088
|
+
opacity: 1;
|
|
5089
|
+
}
|
|
5090
|
+
.sidebar-toggle svg {
|
|
5091
|
+
display: block;
|
|
5092
|
+
}
|
|
5093
|
+
|
|
5094
|
+
@media (min-width: 861px) {
|
|
5095
|
+
/* Top padding lives on the panel (space-6 aligns the search row with the
|
|
5096
|
+
fixed corner toggle); zero the shell's own top padding so it isn't added
|
|
5097
|
+
on top, which would push the search below the toggle. */
|
|
5098
|
+
.bp-sidebar {
|
|
5099
|
+
display: flex;
|
|
5100
|
+
flex-direction: column;
|
|
5101
|
+
overflow: hidden;
|
|
5102
|
+
padding-top: 0;
|
|
5103
|
+
padding-bottom: 0;
|
|
5104
|
+
padding-inline: 0;
|
|
5105
|
+
}
|
|
5106
|
+
|
|
5107
|
+
/* The panel scrolls; padding-bottom reserves the fixed footer band so every
|
|
5108
|
+
TOC entry can scroll fully into view above it. scroll-padding-bottom keeps
|
|
5109
|
+
browser-managed scroll (keyboard focus, scrollIntoView, find-in-page) from
|
|
5110
|
+
landing a near-bottom entry under the fixed footer overlay. Horizontal
|
|
5111
|
+
padding aligns the TOC pills with the fixed corner toggle. */
|
|
5112
|
+
.bp-sidebar__panel {
|
|
5113
|
+
flex: 1 1 auto;
|
|
5114
|
+
min-height: 0;
|
|
5115
|
+
height: auto;
|
|
5116
|
+
overflow-x: hidden;
|
|
5117
|
+
overflow-y: auto;
|
|
5118
|
+
overscroll-behavior: contain;
|
|
5119
|
+
-webkit-overflow-scrolling: touch;
|
|
5120
|
+
padding-top: var(--bp-space-6);
|
|
5121
|
+
padding-inline: var(--bp-sidebar-content-inset);
|
|
5122
|
+
padding-bottom: var(--bp-sidebar-scroll-padding-bottom);
|
|
5123
|
+
scroll-padding-bottom: var(--bp-sidebar-scroll-padding-bottom);
|
|
5124
|
+
}
|
|
5125
|
+
|
|
5126
|
+
/* Drop the switcher below the header scrim (search stays above it on z 300). */
|
|
5127
|
+
.doc-switcher {
|
|
5128
|
+
margin-top: max(
|
|
5129
|
+
0px,
|
|
5130
|
+
calc(
|
|
5131
|
+
var(--bp-sidebar-header-scrim) - var(--bp-space-6) + var(--bp-space-2) -
|
|
5132
|
+
var(--bp-sidebar-toggle-size) - var(--bp-space-3) + var(--bp-space-2)
|
|
5133
|
+
)
|
|
5134
|
+
);
|
|
5135
|
+
}
|
|
5136
|
+
|
|
5137
|
+
/* The rail slides as one unit. At rest transform is none, so the fixed scrims
|
|
5138
|
+
(::before/::after) + footer stay viewport-anchored for the scroll dissolve;
|
|
5139
|
+
during the slide a non-none transform makes the rail their containing block,
|
|
5140
|
+
so they ride along with it (their %-based geometry resolves against the
|
|
5141
|
+
rail's own width, which is identical math — see the footer rule below).
|
|
5142
|
+
Transition only after bp-sidebar-animate is set (index.html) to skip first
|
|
5143
|
+
paint; visibility flips at the end so the rail leaves the tab order. */
|
|
5144
|
+
html.bp-sidebar-animate .bp-sidebar {
|
|
5145
|
+
transition:
|
|
5146
|
+
transform var(--bp-duration-slow) var(--bp-ease-in-out),
|
|
5147
|
+
visibility var(--bp-duration-slow);
|
|
5148
|
+
}
|
|
5149
|
+
[data-sidebar="collapsed"] .bp-sidebar {
|
|
5150
|
+
transform: translateX(-100%);
|
|
5151
|
+
visibility: hidden;
|
|
5152
|
+
pointer-events: none;
|
|
5153
|
+
}
|
|
5154
|
+
|
|
5155
|
+
/* The sheet reclaims the rail's width in step with the slide. <main> is laid
|
|
5156
|
+
out with margin-inline (blueprint.css shell rules), not `left`, so the
|
|
5157
|
+
reclaim must transition margin — transitioning `left` on a static box was a
|
|
5158
|
+
no-op, which made the sheet snap while the rail slid. Same duration/easing
|
|
5159
|
+
as the rail + frame line so all three move as one. Gated on
|
|
5160
|
+
bp-sidebar-animate so it never fires on first paint. */
|
|
5161
|
+
html.bp-sidebar-animate[data-bp-document] main {
|
|
5162
|
+
transition: margin var(--bp-duration-slow) var(--bp-ease-in-out);
|
|
5163
|
+
}
|
|
5164
|
+
html.bp-sidebar-animate[data-bp-document]::after {
|
|
5165
|
+
transition: background-position var(--bp-duration-slow) var(--bp-ease-in-out);
|
|
5166
|
+
}
|
|
5167
|
+
|
|
5168
|
+
/* Footer pins to the bottom of the rail, spanning the TOC band: left edge on
|
|
5169
|
+
the entry pill (content edge) and right edge at the rail's content edge. */
|
|
5170
|
+
.sidebar-footer {
|
|
5171
|
+
position: fixed;
|
|
5172
|
+
left: var(--bp-sidebar-content-inset);
|
|
5173
|
+
right: calc(100% - var(--bp-sidebar) + var(--bp-sidebar-content-inset));
|
|
5174
|
+
bottom: var(--bp-sidebar-chrome-inset-bottom);
|
|
5175
|
+
z-index: 300;
|
|
5176
|
+
}
|
|
5177
|
+
|
|
5178
|
+
/* Fade scrim above the footer: the TOC scrolls out beneath it (z below the
|
|
5179
|
+
footer controls), with a solid bottom band backing the footer. */
|
|
5180
|
+
.bp-sidebar::after {
|
|
5181
|
+
content: "";
|
|
5182
|
+
position: fixed;
|
|
5183
|
+
left: 0;
|
|
5184
|
+
bottom: 0;
|
|
5185
|
+
width: var(--bp-sidebar);
|
|
5186
|
+
height: calc(var(--bp-sidebar-footer) + var(--bp-space-4));
|
|
5187
|
+
background: var(--bp-sidebar-fade);
|
|
5188
|
+
pointer-events: none;
|
|
5189
|
+
z-index: 200;
|
|
5190
|
+
}
|
|
5191
|
+
|
|
5192
|
+
/* Radial scrim around the corner toggle: the TOC dissolves in a circle that
|
|
5193
|
+
radiates from the icon as entries scroll up beneath it. The box is large
|
|
5194
|
+
enough to hold the gradient's outer radius; transparent beyond it. */
|
|
5195
|
+
.bp-sidebar::before {
|
|
5196
|
+
content: "";
|
|
5197
|
+
position: fixed;
|
|
5198
|
+
top: 0;
|
|
5199
|
+
left: 0;
|
|
5200
|
+
width: var(--bp-sidebar);
|
|
5201
|
+
height: var(--bp-sidebar-header-scrim);
|
|
5202
|
+
background: var(--bp-sidebar-icon-fade);
|
|
5203
|
+
pointer-events: none;
|
|
5204
|
+
z-index: 200;
|
|
5205
|
+
}
|
|
5206
|
+
|
|
5207
|
+
/* Collapsed: the rail (slid out via the rule above) vacates its width and the
|
|
5208
|
+
sheet reclaims it, trailing one space-4 behind the rail's edge throughout. */
|
|
5209
|
+
[data-sidebar="collapsed"][data-bp-document] {
|
|
5210
|
+
--bp-shell-inset-left: var(--bp-space-4);
|
|
5211
|
+
}
|
|
5212
|
+
}
|
|
5213
|
+
|
|
5214
|
+
/* Below the rail's fixed breakpoint it becomes a static horizontal nav,
|
|
5215
|
+
where collapsing has no meaning — hide the control entirely. */
|
|
5216
|
+
@media (max-width: 860px) {
|
|
5217
|
+
.sidebar-toggle {
|
|
5218
|
+
display: none;
|
|
5219
|
+
}
|
|
5220
|
+
}
|
|
5221
|
+
|
|
5222
|
+
@media print {
|
|
5223
|
+
body {
|
|
5224
|
+
padding-top: 0;
|
|
5225
|
+
}
|
|
5226
|
+
|
|
5227
|
+
.site-nav,
|
|
5228
|
+
.bp-sidebar .theme-toggle,
|
|
5229
|
+
.sidebar-toggle {
|
|
5230
|
+
display: none;
|
|
5231
|
+
}
|
|
5232
|
+
}
|