@obvi/blueprint 1.0.9 → 1.1.0
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 +13 -433
- package/THIRD_PARTY_NOTICES.md +27 -0
- package/dist/blueprint-choices.js +567 -0
- package/dist/blueprint.css +2626 -1121
- package/dist/blueprint.js +2464 -36
- package/dist/code-highlighting/blueprint-code.css +12 -7
- package/package.json +5 -3
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,40 +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
|
-
box-shadow: inset 3px 0 0 var(--bp-ink);
|
|
1476
|
-
}
|
|
1477
|
-
:where(.bp-verdict) {
|
|
1478
|
-
display: inline-block;
|
|
1479
|
-
font-family: var(--bp-mono);
|
|
1480
|
-
font-size: var(--bp-label-sm);
|
|
1481
|
-
letter-spacing: var(--bp-label-sm-ls);
|
|
1482
|
-
text-transform: uppercase;
|
|
1483
|
-
color: var(--bp-paper);
|
|
1484
|
-
background: var(--bp-ink);
|
|
1485
|
-
padding: 2px 8px;
|
|
1486
|
-
margin-top: var(--bp-space-2);
|
|
1487
|
-
}
|
|
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. */
|
|
1488
1407
|
|
|
1489
1408
|
/* ---- 5. Numbered linear sequence --------------------------------
|
|
1490
1409
|
A linear mechanism (pipeline, escalation). NOT a comparison grid.
|
|
@@ -1517,29 +1436,6 @@
|
|
|
1517
1436
|
color: var(--bp-ink);
|
|
1518
1437
|
}
|
|
1519
1438
|
|
|
1520
|
-
/* ---- State grid -------------------------------------------------
|
|
1521
|
-
Off-happy-path state model (empty / loading / ready / error …).
|
|
1522
|
-
Built from <article>s; each gets a mono state name via .bp-label. */
|
|
1523
|
-
:where(.bp-state-grid) {
|
|
1524
|
-
display: grid;
|
|
1525
|
-
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
1526
|
-
gap: 0;
|
|
1527
|
-
border: 1px solid var(--bp-edge);
|
|
1528
|
-
margin: var(--bp-space-4) 0;
|
|
1529
|
-
}
|
|
1530
|
-
:where(.bp-state-grid > *) {
|
|
1531
|
-
padding: var(--bp-space-3);
|
|
1532
|
-
border-right: 1px solid var(--bp-edge);
|
|
1533
|
-
border-bottom: 1px solid var(--bp-edge);
|
|
1534
|
-
background: var(--bp-paper);
|
|
1535
|
-
}
|
|
1536
|
-
/* Void / fenced-off state — a dead cell (orphaned, reclaimed away).
|
|
1537
|
-
The hatch layers over the paper set above; declared after so the
|
|
1538
|
-
zero-specificity rules resolve by source order. */
|
|
1539
|
-
:where(.bp-state--void) {
|
|
1540
|
-
background-image: var(--bp-hatch);
|
|
1541
|
-
}
|
|
1542
|
-
|
|
1543
1439
|
/* ---- Hatch utility ----------------------------------------------
|
|
1544
1440
|
Drop .bp-hatch on any block element to mark a fenced / held /
|
|
1545
1441
|
out-of-bounds region with drafting section-lining. Layers the hatch
|
|
@@ -1548,994 +1444,2564 @@
|
|
|
1548
1444
|
background-image: var(--bp-hatch);
|
|
1549
1445
|
}
|
|
1550
1446
|
|
|
1551
|
-
/* ----
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
}
|
|
1557
|
-
/* Opt-in breakout: a wide table expands toward --bp-wide */
|
|
1558
|
-
:where(.bp-table-wrap--wide) {
|
|
1559
|
-
width: 100vw;
|
|
1560
|
-
max-width: var(--bp-wide);
|
|
1561
|
-
margin-inline: calc(50% - 50vw);
|
|
1562
|
-
margin-inline: max(calc(50% - 50vw), calc((100% - var(--bp-wide)) / 2));
|
|
1563
|
-
}
|
|
1447
|
+
/* ---- Interactive choice family ----------------------------------
|
|
1448
|
+
CSS-only deliberation primitives (radio / checkbox + :has() +
|
|
1449
|
+
native form reset). Author with <bp-choice>, <bp-preflight>, and
|
|
1450
|
+
related elements; blueprint-choices.js expands them to this markup.
|
|
1451
|
+
Selected items always get a full ink border — never a left-bar only. */
|
|
1564
1452
|
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
enables the copy button, and blueprint-code.css adds Prism color. */
|
|
1569
|
-
:where(bp-source) {
|
|
1453
|
+
:where(bp-choice),
|
|
1454
|
+
:where(bp-preflight),
|
|
1455
|
+
:where(bp-choice-record) {
|
|
1570
1456
|
display: block;
|
|
1571
1457
|
}
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
:where(.bp-source[open]) {
|
|
1576
|
-
padding-bottom: 0;
|
|
1458
|
+
|
|
1459
|
+
:where(.bp-choice) {
|
|
1460
|
+
margin: var(--bp-space-4) 0;
|
|
1577
1461
|
}
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
display: flex;
|
|
1462
|
+
|
|
1463
|
+
/* Verdict banner — hidden until a choice is committed. */
|
|
1464
|
+
:where(.bp-choice__verdict) {
|
|
1465
|
+
display: none;
|
|
1583
1466
|
align-items: center;
|
|
1584
|
-
gap: var(--bp-space-
|
|
1467
|
+
gap: var(--bp-space-2);
|
|
1585
1468
|
padding: var(--bp-space-2) var(--bp-space-3);
|
|
1469
|
+
background: var(--bp-ink);
|
|
1470
|
+
color: var(--bp-paper);
|
|
1471
|
+
border-radius: var(--bp-radius-0);
|
|
1472
|
+
margin-bottom: var(--bp-space-3);
|
|
1586
1473
|
}
|
|
1587
|
-
:where(.bp-
|
|
1474
|
+
:where(.bp-choice:has(.bp-choice__commit:checked)) .bp-choice__verdict,
|
|
1475
|
+
:where(.bp-choice:has(.bp-choice__pick:checked)) .bp-choice__verdict {
|
|
1476
|
+
display: flex;
|
|
1477
|
+
}
|
|
1478
|
+
:where(.bp-choice__verdict) > :where(.bp-label) {
|
|
1479
|
+
margin: 0;
|
|
1480
|
+
color: var(--bp-paper);
|
|
1481
|
+
font-size: var(--bp-label-lg);
|
|
1482
|
+
letter-spacing: var(--bp-label-lg-ls);
|
|
1483
|
+
}
|
|
1484
|
+
:where(.bp-choice__verdict-pick) {
|
|
1485
|
+
font-family: var(--bp-sans);
|
|
1486
|
+
font-weight: var(--bp-weight-strong);
|
|
1487
|
+
font-size: var(--bp-text-h4);
|
|
1488
|
+
margin: 0;
|
|
1489
|
+
}
|
|
1490
|
+
:where(.bp-choice__verdict-pick[data-for]) {
|
|
1491
|
+
display: none;
|
|
1492
|
+
}
|
|
1493
|
+
:where(.bp-choice__verdict-meta) {
|
|
1494
|
+
margin: 0 0 0 auto;
|
|
1588
1495
|
font-family: var(--bp-mono);
|
|
1589
1496
|
font-size: var(--bp-label-md);
|
|
1590
1497
|
letter-spacing: var(--bp-label-md-ls);
|
|
1591
1498
|
text-transform: uppercase;
|
|
1499
|
+
color: color-mix(in oklch, var(--bp-paper) 72%, oklch(0 0 0 / 0));
|
|
1500
|
+
}
|
|
1501
|
+
|
|
1502
|
+
:where(.bp-choice-rationale) {
|
|
1503
|
+
margin-top: var(--bp-space-2);
|
|
1504
|
+
font-size: var(--bp-text-small);
|
|
1505
|
+
line-height: var(--bp-lh-small);
|
|
1592
1506
|
color: var(--bp-text-secondary);
|
|
1593
1507
|
}
|
|
1594
|
-
:where(.bp-
|
|
1508
|
+
:where(.bp-choice-rationale) > :where(* + *) {
|
|
1509
|
+
margin-top: var(--bp-space-1);
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1512
|
+
:where(.bp-choice__actions) {
|
|
1595
1513
|
display: flex;
|
|
1596
1514
|
align-items: center;
|
|
1597
1515
|
gap: var(--bp-space-3);
|
|
1598
|
-
margin-
|
|
1516
|
+
margin-top: var(--bp-space-3);
|
|
1599
1517
|
}
|
|
1600
|
-
:where(.bp-
|
|
1518
|
+
:where(.bp-choice__hint) {
|
|
1601
1519
|
font-family: var(--bp-mono);
|
|
1602
|
-
font-size: var(--bp-label-
|
|
1603
|
-
letter-spacing: var(--bp-label-
|
|
1520
|
+
font-size: var(--bp-label-md);
|
|
1521
|
+
letter-spacing: var(--bp-label-md-ls);
|
|
1604
1522
|
text-transform: uppercase;
|
|
1605
1523
|
color: var(--bp-text-secondary);
|
|
1606
1524
|
}
|
|
1607
|
-
:where(.bp-
|
|
1525
|
+
:where(.bp-choice__reset) {
|
|
1608
1526
|
appearance: none;
|
|
1609
|
-
|
|
1610
|
-
border
|
|
1611
|
-
padding:
|
|
1612
|
-
|
|
1527
|
+
background: none;
|
|
1528
|
+
border: 0;
|
|
1529
|
+
padding: 0;
|
|
1530
|
+
cursor: pointer;
|
|
1531
|
+
font-family: var(--bp-mono);
|
|
1532
|
+
font-size: var(--bp-label-md);
|
|
1533
|
+
letter-spacing: var(--bp-label-md-ls);
|
|
1534
|
+
text-transform: uppercase;
|
|
1535
|
+
color: var(--bp-text-secondary);
|
|
1536
|
+
text-decoration: underline dotted;
|
|
1537
|
+
text-underline-offset: 3px;
|
|
1538
|
+
}
|
|
1539
|
+
:where(.bp-choice__reset:hover) {
|
|
1613
1540
|
color: var(--bp-ink);
|
|
1541
|
+
}
|
|
1542
|
+
|
|
1543
|
+
:where(.bp-choice__tag) {
|
|
1544
|
+
display: inline-flex;
|
|
1545
|
+
align-items: center;
|
|
1546
|
+
gap: 5px;
|
|
1614
1547
|
font-family: var(--bp-mono);
|
|
1615
1548
|
font-size: var(--bp-label-sm);
|
|
1616
|
-
line-height: 1;
|
|
1617
1549
|
letter-spacing: var(--bp-label-sm-ls);
|
|
1618
1550
|
text-transform: uppercase;
|
|
1619
|
-
|
|
1551
|
+
color: var(--bp-text-secondary);
|
|
1620
1552
|
}
|
|
1621
|
-
:where(.bp-
|
|
1622
|
-
|
|
1623
|
-
background: var(--bp-
|
|
1553
|
+
:where(.bp-choice__tag--ink) {
|
|
1554
|
+
color: var(--bp-paper);
|
|
1555
|
+
background: var(--bp-ink);
|
|
1556
|
+
padding: 2px 8px;
|
|
1624
1557
|
}
|
|
1625
|
-
:where(.bp-
|
|
1626
|
-
|
|
1627
|
-
|
|
1558
|
+
:where(.bp-choice__tag--out) {
|
|
1559
|
+
color: var(--bp-ink);
|
|
1560
|
+
border: 1px solid var(--bp-ink-faint);
|
|
1561
|
+
padding: 1px 7px;
|
|
1628
1562
|
}
|
|
1629
|
-
|
|
1630
|
-
|
|
1563
|
+
|
|
1564
|
+
/* ---- layout: tabs (preview drafts, then adopt) ------------------- */
|
|
1565
|
+
:where(.bp-choice--tabs) :where(.bp-choice__seg) {
|
|
1566
|
+
display: flex;
|
|
1567
|
+
flex-wrap: wrap;
|
|
1568
|
+
gap: 0;
|
|
1569
|
+
border: 1px solid var(--bp-ink-line);
|
|
1570
|
+
border-radius: var(--bp-radius-0);
|
|
1571
|
+
overflow: hidden;
|
|
1572
|
+
margin: 0 0 var(--bp-space-3);
|
|
1573
|
+
width: fit-content;
|
|
1631
1574
|
}
|
|
1632
|
-
:where(.bp-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1575
|
+
:where(.bp-choice__seg-opt) {
|
|
1576
|
+
position: relative;
|
|
1577
|
+
cursor: pointer;
|
|
1578
|
+
font-family: var(--bp-mono);
|
|
1579
|
+
font-size: var(--bp-label-md);
|
|
1580
|
+
letter-spacing: var(--bp-label-md-ls);
|
|
1581
|
+
text-transform: uppercase;
|
|
1582
|
+
color: var(--bp-text-secondary);
|
|
1583
|
+
padding: 6px 14px;
|
|
1584
|
+
border-right: 1px solid var(--bp-ink-line);
|
|
1637
1585
|
}
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
<bp-cite> renders an inline TRIGGER (the cited text) plus a top-layer
|
|
1641
|
-
POPOVER card that reveals the cited code on hover / focus / tap. The
|
|
1642
|
-
code block inside is dressed flush by blueprint-code.css (where the
|
|
1643
|
-
Prism <pre> rules live). Citation markers use --bp-illustration blue.
|
|
1644
|
-
The runtime (blueprint-code.js) owns show/hide + viewport placement. */
|
|
1645
|
-
:where(bp-cite) {
|
|
1646
|
-
display: inline;
|
|
1586
|
+
:where(.bp-choice__seg-opt:last-child) {
|
|
1587
|
+
border-right: 0;
|
|
1647
1588
|
}
|
|
1648
|
-
:where(.bp-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
border: 0;
|
|
1653
|
-
background: none;
|
|
1654
|
-
color: inherit;
|
|
1655
|
-
cursor: help;
|
|
1656
|
-
text-decoration: underline dotted var(--bp-illustration-faint);
|
|
1657
|
-
text-underline-offset: 3px;
|
|
1658
|
-
text-decoration-thickness: 1px;
|
|
1659
|
-
/* Motion: .bp-transition-colors .bp-ease (hover color shift) */
|
|
1660
|
-
transition-property: text-decoration-color;
|
|
1661
|
-
transition-duration: var(--bp-duration-fast);
|
|
1662
|
-
transition-timing-function: var(--bp-ease);
|
|
1589
|
+
:where(.bp-choice__seg-opt) :where(input) {
|
|
1590
|
+
position: absolute;
|
|
1591
|
+
opacity: 0;
|
|
1592
|
+
pointer-events: none;
|
|
1663
1593
|
}
|
|
1664
|
-
:where(.bp-
|
|
1665
|
-
|
|
1594
|
+
:where(.bp-choice__seg-opt:has(input:checked)) {
|
|
1595
|
+
background: var(--bp-ink);
|
|
1596
|
+
color: var(--bp-paper);
|
|
1666
1597
|
}
|
|
1667
|
-
:where(.bp-
|
|
1668
|
-
|
|
1598
|
+
:where(.bp-choice--tabs) :where(.bp-choice__panel) {
|
|
1599
|
+
display: none;
|
|
1669
1600
|
}
|
|
1670
|
-
:where(
|
|
1671
|
-
|
|
1601
|
+
:where(.bp-choice__panel > h3:first-child) {
|
|
1602
|
+
margin-top: 0;
|
|
1672
1603
|
}
|
|
1673
|
-
:where(.bp-
|
|
1604
|
+
:where(.bp-choice__adopt) {
|
|
1605
|
+
display: inline-flex;
|
|
1606
|
+
align-items: center;
|
|
1607
|
+
gap: 8px;
|
|
1608
|
+
cursor: pointer;
|
|
1609
|
+
border: 1px solid var(--bp-ink);
|
|
1610
|
+
border-radius: var(--bp-radius-0);
|
|
1611
|
+
padding: 6px 14px;
|
|
1674
1612
|
font-family: var(--bp-mono);
|
|
1675
|
-
font-size:
|
|
1676
|
-
letter-spacing: -
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
/* Motion: .bp-transition-colors .bp-ease (hover color shift) */
|
|
1681
|
-
transition-property: color;
|
|
1682
|
-
transition-duration: var(--bp-duration-fast);
|
|
1683
|
-
transition-timing-function: var(--bp-ease);
|
|
1613
|
+
font-size: var(--bp-label-md);
|
|
1614
|
+
letter-spacing: var(--bp-label-md-ls);
|
|
1615
|
+
text-transform: uppercase;
|
|
1616
|
+
color: var(--bp-ink);
|
|
1617
|
+
background: var(--bp-paper);
|
|
1684
1618
|
}
|
|
1685
|
-
:where(.bp-
|
|
1686
|
-
|
|
1619
|
+
:where(.bp-choice__adopt:hover) {
|
|
1620
|
+
background: var(--bp-fill-hi);
|
|
1687
1621
|
}
|
|
1688
|
-
:where(.bp-
|
|
1689
|
-
|
|
1622
|
+
:where(.bp-choice__adopt) :where(input) {
|
|
1623
|
+
position: absolute;
|
|
1624
|
+
opacity: 0;
|
|
1625
|
+
pointer-events: none;
|
|
1690
1626
|
}
|
|
1691
|
-
:where(.bp-
|
|
1692
|
-
|
|
1627
|
+
:where(.bp-choice__panel:has(.bp-choice__commit:checked)) {
|
|
1628
|
+
border: 1px solid var(--bp-ink);
|
|
1629
|
+
background: var(--bp-fill-amb);
|
|
1630
|
+
padding: var(--bp-space-3);
|
|
1631
|
+
margin-left: calc(-1 * var(--bp-space-3));
|
|
1632
|
+
margin-right: calc(-1 * var(--bp-space-3));
|
|
1633
|
+
border-radius: var(--bp-radius-0);
|
|
1693
1634
|
}
|
|
1694
|
-
:where(
|
|
1695
|
-
|
|
1635
|
+
:where(.bp-choice__panel:has(.bp-choice__commit:checked)) :where(.bp-choice__adopt) {
|
|
1636
|
+
background: var(--bp-ink);
|
|
1637
|
+
color: var(--bp-paper);
|
|
1696
1638
|
}
|
|
1697
1639
|
|
|
1698
|
-
/*
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
margin: 0;
|
|
1703
|
-
inset: auto;
|
|
1704
|
-
width: min(460px, calc(100vw - 20px));
|
|
1705
|
-
padding: 0;
|
|
1706
|
-
border: 1px solid var(--bp-ink-line);
|
|
1707
|
-
border-radius: var(--bp-radius-6);
|
|
1708
|
-
background: var(--bp-paper);
|
|
1709
|
-
color: var(--bp-text);
|
|
1710
|
-
box-shadow: var(--bp-shadow-pop);
|
|
1711
|
-
opacity: 0;
|
|
1712
|
-
transform: translateY(4px);
|
|
1713
|
-
/* Motion: .bp-transition-opacity + transform, fast + ease-out (tooltip
|
|
1714
|
-
enter/exit). overlay + display need allow-discrete for top-layer. */
|
|
1715
|
-
transition-property: opacity, transform, overlay, display;
|
|
1716
|
-
transition-duration: var(--bp-duration-fast);
|
|
1717
|
-
transition-timing-function: var(--bp-ease-out);
|
|
1718
|
-
transition-behavior: allow-discrete;
|
|
1719
|
-
}
|
|
1720
|
-
:where(.bp-cite-pop:not([popover])) {
|
|
1721
|
-
display: none;
|
|
1640
|
+
/* ---- layout: stack (all cards visible) --------------------------- */
|
|
1641
|
+
:where(.bp-choice--stack) :where(.bp-choice__stack) {
|
|
1642
|
+
display: grid;
|
|
1643
|
+
gap: var(--bp-space-3);
|
|
1722
1644
|
}
|
|
1723
|
-
:where(.bp-
|
|
1645
|
+
:where(.bp-choice__card) {
|
|
1724
1646
|
display: block;
|
|
1647
|
+
position: relative;
|
|
1648
|
+
border: 1px solid var(--bp-edge);
|
|
1649
|
+
border-radius: var(--bp-radius-0);
|
|
1650
|
+
padding: var(--bp-space-3);
|
|
1651
|
+
cursor: pointer;
|
|
1652
|
+
background: var(--bp-paper);
|
|
1725
1653
|
}
|
|
1726
|
-
:where(.bp-
|
|
1727
|
-
|
|
1728
|
-
opacity: 1;
|
|
1729
|
-
transform: translateY(0);
|
|
1730
|
-
}
|
|
1731
|
-
@starting-style {
|
|
1732
|
-
:where(.bp-cite-pop:popover-open),
|
|
1733
|
-
:where(.bp-cite-pop.is-open) {
|
|
1734
|
-
opacity: 0;
|
|
1735
|
-
transform: translateY(4px);
|
|
1736
|
-
}
|
|
1654
|
+
:where(.bp-choice__card:hover) {
|
|
1655
|
+
border-color: var(--bp-ink-line);
|
|
1737
1656
|
}
|
|
1738
|
-
|
|
1739
|
-
:where(.bp-cite-pop)::before,
|
|
1740
|
-
:where(.bp-cite-pop)::after {
|
|
1741
|
-
content: "";
|
|
1657
|
+
:where(.bp-choice__card) > :where(input.bp-choice__pick) {
|
|
1742
1658
|
position: absolute;
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1659
|
+
top: var(--bp-space-3);
|
|
1660
|
+
right: var(--bp-space-3);
|
|
1661
|
+
accent-color: var(--bp-ink);
|
|
1662
|
+
width: 16px;
|
|
1663
|
+
height: 16px;
|
|
1748
1664
|
}
|
|
1749
|
-
:where(.bp-
|
|
1750
|
-
|
|
1751
|
-
|
|
1665
|
+
:where(.bp-choice__card-head) {
|
|
1666
|
+
display: flex;
|
|
1667
|
+
align-items: baseline;
|
|
1668
|
+
gap: var(--bp-space-2);
|
|
1669
|
+
margin-bottom: var(--bp-space-1);
|
|
1752
1670
|
}
|
|
1753
|
-
:where(.bp-
|
|
1754
|
-
|
|
1755
|
-
|
|
1671
|
+
:where(.bp-choice__card) :where(h4) {
|
|
1672
|
+
margin: 0;
|
|
1673
|
+
padding-right: var(--bp-space-4);
|
|
1756
1674
|
}
|
|
1757
|
-
:where(.bp-
|
|
1758
|
-
|
|
1759
|
-
|
|
1675
|
+
:where(.bp-choice__card-chosen),
|
|
1676
|
+
:where(.bp-choice__card-rejected) {
|
|
1677
|
+
display: none;
|
|
1760
1678
|
}
|
|
1761
|
-
:where(.bp-
|
|
1762
|
-
|
|
1763
|
-
|
|
1679
|
+
:where(.bp-choice__card:has(.bp-choice__pick:checked)) {
|
|
1680
|
+
border: 2px solid var(--bp-ink);
|
|
1681
|
+
background: var(--bp-fill-amb);
|
|
1764
1682
|
}
|
|
1765
|
-
:where(.bp-
|
|
1766
|
-
display: flex;
|
|
1767
|
-
align-items: center;
|
|
1768
|
-
justify-content: space-between;
|
|
1769
|
-
gap: var(--bp-space-3);
|
|
1770
|
-
padding: var(--bp-space-2) var(--bp-space-3);
|
|
1771
|
-
border-bottom: 1px solid var(--bp-edge);
|
|
1683
|
+
:where(.bp-choice__card:has(.bp-choice__pick:checked)) :where(.bp-choice__card-chosen) {
|
|
1684
|
+
display: inline-flex;
|
|
1772
1685
|
}
|
|
1773
|
-
:where(.bp-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
letter-spacing: var(--bp-label-sm-ls);
|
|
1777
|
-
text-transform: uppercase;
|
|
1778
|
-
color: var(--bp-text);
|
|
1779
|
-
white-space: nowrap;
|
|
1780
|
-
overflow: hidden;
|
|
1781
|
-
text-overflow: ellipsis;
|
|
1686
|
+
:where(.bp-choice--stack:has(.bp-choice__pick:checked)) :where(.bp-choice__card:not(:has(.bp-choice__pick:checked))) {
|
|
1687
|
+
opacity: 0.62;
|
|
1688
|
+
background-image: var(--bp-hatch);
|
|
1782
1689
|
}
|
|
1783
|
-
:where(.bp-
|
|
1784
|
-
|
|
1785
|
-
font-family: var(--bp-mono);
|
|
1786
|
-
font-size: var(--bp-label-sm);
|
|
1787
|
-
letter-spacing: var(--bp-label-sm-ls);
|
|
1788
|
-
text-transform: uppercase;
|
|
1789
|
-
color: var(--bp-text-secondary);
|
|
1690
|
+
:where(.bp-choice--stack:has(.bp-choice__pick:checked)) :where(.bp-choice__card:not(:has(.bp-choice__pick:checked))) :where(.bp-choice__card-rejected) {
|
|
1691
|
+
display: inline-flex;
|
|
1790
1692
|
}
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
}
|
|
1799
|
-
|
|
1800
|
-
/* ---- SVG figure marks (1px hairline default via --bp-stroke) -------
|
|
1801
|
-
ILLUSTRATIONS are the one place blue lives. Node/edge line work draws
|
|
1802
|
-
in --bp-illustration; only the in-diagram TEXT labels stay neutral ink
|
|
1803
|
-
(text everywhere reads in the monochrome scale). */
|
|
1804
|
-
:where(.bp-node) {
|
|
1805
|
-
fill: var(--bp-paper);
|
|
1806
|
-
stroke: var(--bp-illustration);
|
|
1807
|
-
stroke-width: var(--bp-stroke);
|
|
1808
|
-
}
|
|
1809
|
-
:where(.bp-node--amb) {
|
|
1810
|
-
fill: var(--bp-illustration-fill);
|
|
1811
|
-
}
|
|
1812
|
-
/* Fenced node — a barrier / held step. Filled with the diagonal hatch
|
|
1813
|
-
paint server (define the <pattern> once in the figure's <defs>; see
|
|
1814
|
-
the .bp-hatch-fill / .bp-hatch-line tiles below). The .bp-node stroke
|
|
1815
|
-
keeps the illustration border. CSS gradients can't paint an SVG shape,
|
|
1816
|
-
so SVG uses a <pattern> while HTML uses the --bp-hatch gradient token. */
|
|
1817
|
-
:where(.bp-node--fenced) {
|
|
1818
|
-
fill: url(#bp-hatch);
|
|
1819
|
-
}
|
|
1820
|
-
/* Tiles for the SVG hatch <pattern> — token-driven so both themes track.
|
|
1821
|
-
The fill rect carries the illustration wash; the line is the drafting
|
|
1822
|
-
section-lining, both in the blue illustration family. */
|
|
1823
|
-
:where(.bp-hatch-fill) {
|
|
1824
|
-
fill: var(--bp-illustration-fill);
|
|
1825
|
-
}
|
|
1826
|
-
:where(.bp-hatch-line) {
|
|
1827
|
-
stroke: var(--bp-illustration-faint);
|
|
1828
|
-
stroke-width: var(--bp-stroke);
|
|
1829
|
-
}
|
|
1830
|
-
:where(.bp-edge) {
|
|
1831
|
-
fill: none;
|
|
1832
|
-
stroke: var(--bp-illustration);
|
|
1833
|
-
stroke-width: var(--bp-stroke);
|
|
1834
|
-
}
|
|
1835
|
-
:where(.bp-edge--skip) {
|
|
1836
|
-
stroke: var(--bp-illustration-soft);
|
|
1837
|
-
stroke-dasharray: 4 3;
|
|
1838
|
-
}
|
|
1839
|
-
:where(.bp-svg-label) {
|
|
1840
|
-
font-family: var(--bp-mono);
|
|
1841
|
-
font-size: 11px;
|
|
1842
|
-
fill: var(--bp-text);
|
|
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;
|
|
1843
1700
|
}
|
|
1844
|
-
:where(.bp-
|
|
1845
|
-
|
|
1846
|
-
font-size: 9px;
|
|
1847
|
-
fill: var(--bp-text-secondary);
|
|
1701
|
+
:where(.bp-choice--resolved) :where(.bp-choice__verdict-pick[data-resolved]) {
|
|
1702
|
+
display: block;
|
|
1848
1703
|
}
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1704
|
+
:where(.bp-choice--resolved) :where(.bp-choice__stack) {
|
|
1705
|
+
display: grid;
|
|
1706
|
+
gap: var(--bp-space-3);
|
|
1852
1707
|
}
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
ink. .bp-svg-dot terminates callout leaders in the illustration blue. */
|
|
1860
|
-
:where(.bp-stack-face) {
|
|
1861
|
-
fill: var(--bp-paper);
|
|
1862
|
-
stroke: var(--bp-illustration);
|
|
1863
|
-
stroke-width: var(--bp-stroke);
|
|
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);
|
|
1864
1714
|
}
|
|
1865
|
-
:where(.bp-
|
|
1866
|
-
|
|
1867
|
-
stroke: var(--bp-illustration);
|
|
1868
|
-
stroke-width: var(--bp-stroke);
|
|
1715
|
+
:where(.bp-choice__card[data-resolved]) :where(.bp-choice__card-chosen) {
|
|
1716
|
+
display: inline-flex;
|
|
1869
1717
|
}
|
|
1870
|
-
:where(.bp-
|
|
1871
|
-
|
|
1718
|
+
:where(.bp-choice--resolved) :where(.bp-choice__card:not([data-resolved])) {
|
|
1719
|
+
opacity: 0.62;
|
|
1720
|
+
background-image: var(--bp-hatch);
|
|
1872
1721
|
}
|
|
1873
|
-
:where(.bp-
|
|
1874
|
-
|
|
1875
|
-
stroke: var(--bp-illustration-faint);
|
|
1876
|
-
stroke-width: var(--bp-stroke);
|
|
1877
|
-
opacity: 0.45;
|
|
1722
|
+
:where(.bp-choice--resolved) :where(.bp-choice__card:not([data-resolved])) :where(.bp-choice__card-rejected) {
|
|
1723
|
+
display: inline-flex;
|
|
1878
1724
|
}
|
|
1879
1725
|
|
|
1880
|
-
/* ----
|
|
1881
|
-
:where(.bp-
|
|
1882
|
-
display:
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
margin-top: var(--bp-space-4);
|
|
1886
|
-
}
|
|
1887
|
-
:where(.bp-tb-cell) {
|
|
1888
|
-
flex: 0 0 auto;
|
|
1889
|
-
padding: var(--bp-space-2) var(--bp-space-3);
|
|
1890
|
-
border-right: 1px solid var(--bp-ink-line);
|
|
1726
|
+
/* ---- layout: gallery (mockup pick) ------------------------------- */
|
|
1727
|
+
:where(.bp-choice--gallery) :where(.bp-choice__gallery) {
|
|
1728
|
+
display: grid;
|
|
1729
|
+
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
1730
|
+
gap: var(--bp-space-3);
|
|
1891
1731
|
}
|
|
1892
|
-
:where(.bp-
|
|
1893
|
-
|
|
1732
|
+
:where(.bp-choice__mock) {
|
|
1733
|
+
display: block;
|
|
1734
|
+
position: relative;
|
|
1735
|
+
cursor: pointer;
|
|
1736
|
+
border: 1px solid var(--bp-edge);
|
|
1737
|
+
border-radius: var(--bp-radius-0);
|
|
1738
|
+
overflow: hidden;
|
|
1739
|
+
background: var(--bp-paper);
|
|
1894
1740
|
}
|
|
1895
|
-
:where(.bp-
|
|
1896
|
-
|
|
1741
|
+
:where(.bp-choice__mock:hover) {
|
|
1742
|
+
border-color: var(--bp-ink-line);
|
|
1897
1743
|
}
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
:where(.bp-content) {
|
|
1903
|
-
max-width: var(--bp-content);
|
|
1904
|
-
margin-inline: auto;
|
|
1905
|
-
padding: var(--bp-space-6);
|
|
1744
|
+
:where(.bp-choice__mock) > :where(input.bp-choice__pick) {
|
|
1745
|
+
position: absolute;
|
|
1746
|
+
opacity: 0;
|
|
1747
|
+
pointer-events: none;
|
|
1906
1748
|
}
|
|
1907
|
-
:where(.bp-
|
|
1908
|
-
|
|
1909
|
-
|
|
1749
|
+
:where(.bp-choice__mock-frame) {
|
|
1750
|
+
aspect-ratio: 4 / 3;
|
|
1751
|
+
border-bottom: 1px solid var(--bp-edge);
|
|
1910
1752
|
background: var(--bp-bg);
|
|
1911
|
-
|
|
1753
|
+
padding: 10px;
|
|
1754
|
+
display: grid;
|
|
1755
|
+
gap: 6px;
|
|
1912
1756
|
}
|
|
1913
|
-
:where(.bp-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
line-height: var(--bp-lh-title);
|
|
1757
|
+
:where(.bp-choice__mock-cap) {
|
|
1758
|
+
display: flex;
|
|
1759
|
+
align-items: baseline;
|
|
1760
|
+
gap: var(--bp-space-2);
|
|
1761
|
+
padding: var(--bp-space-2) var(--bp-space-3);
|
|
1919
1762
|
}
|
|
1920
|
-
:where(.bp-
|
|
1921
|
-
|
|
1922
|
-
|
|
1763
|
+
:where(.bp-choice__mock-cap) :where(h4) {
|
|
1764
|
+
margin: 0;
|
|
1765
|
+
font-size: var(--bp-text-body);
|
|
1923
1766
|
}
|
|
1924
|
-
:where(.bp-
|
|
1925
|
-
|
|
1926
|
-
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
1927
|
-
gap: 1px;
|
|
1928
|
-
border: 1px solid var(--bp-edge);
|
|
1929
|
-
background: var(--bp-edge);
|
|
1930
|
-
margin: var(--bp-space-3) 0 var(--bp-space-4);
|
|
1767
|
+
:where(.bp-choice__mock-pick) {
|
|
1768
|
+
margin-left: auto;
|
|
1931
1769
|
}
|
|
1932
|
-
:where(.bp-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
background: var(--bp-paper);
|
|
1770
|
+
:where(.bp-choice__mock-chosen),
|
|
1771
|
+
:where(.bp-choice__mock-rejected) {
|
|
1772
|
+
display: none;
|
|
1936
1773
|
}
|
|
1937
|
-
:where(.bp-
|
|
1938
|
-
|
|
1774
|
+
:where(.bp-choice__mock:has(.bp-choice__pick:checked)) {
|
|
1775
|
+
border: 2px solid var(--bp-ink);
|
|
1939
1776
|
}
|
|
1940
|
-
:where(.bp-
|
|
1941
|
-
display:
|
|
1942
|
-
width: max-content;
|
|
1943
|
-
font-family: var(--bp-mono);
|
|
1944
|
-
font-size: var(--bp-label-lg);
|
|
1945
|
-
letter-spacing: var(--bp-label-lg-ls);
|
|
1946
|
-
text-transform: uppercase;
|
|
1947
|
-
color: var(--bp-ink);
|
|
1948
|
-
margin-bottom: var(--bp-space-2);
|
|
1777
|
+
:where(.bp-choice__mock:has(.bp-choice__pick:checked)) :where(.bp-choice__mock-chosen) {
|
|
1778
|
+
display: inline-flex;
|
|
1949
1779
|
}
|
|
1950
|
-
:where(.bp-
|
|
1951
|
-
|
|
1952
|
-
max-width: 100%;
|
|
1953
|
-
margin: var(--bp-space-4) auto;
|
|
1780
|
+
:where(.bp-choice--gallery:has(.bp-choice__pick:checked)) :where(.bp-choice__mock:not(:has(.bp-choice__pick:checked))) {
|
|
1781
|
+
opacity: 0.5;
|
|
1954
1782
|
}
|
|
1955
|
-
:where(.bp-
|
|
1956
|
-
|
|
1957
|
-
width: auto;
|
|
1958
|
-
max-width: min(100%, var(--bp-diagram-w));
|
|
1959
|
-
height: auto;
|
|
1783
|
+
:where(.bp-choice--gallery:has(.bp-choice__pick:checked)) :where(.bp-choice__mock:not(:has(.bp-choice__pick:checked))) :where(.bp-choice__mock-frame) {
|
|
1784
|
+
background-image: var(--bp-hatch);
|
|
1960
1785
|
}
|
|
1961
|
-
:where(.bp-
|
|
1962
|
-
display:
|
|
1963
|
-
width: auto;
|
|
1964
|
-
max-width: 100%;
|
|
1965
|
-
height: auto;
|
|
1786
|
+
:where(.bp-choice--gallery:has(.bp-choice__pick:checked)) :where(.bp-choice__mock:not(:has(.bp-choice__pick:checked))) :where(.bp-choice__mock-rejected) {
|
|
1787
|
+
display: inline-flex;
|
|
1966
1788
|
}
|
|
1967
|
-
|
|
1789
|
+
|
|
1790
|
+
:where(.bp-choice__compare) {
|
|
1791
|
+
margin-top: var(--bp-space-3);
|
|
1792
|
+
border: 1px solid var(--bp-edge);
|
|
1793
|
+
border-radius: var(--bp-radius-0);
|
|
1794
|
+
}
|
|
1795
|
+
:where(.bp-choice__compare > summary) {
|
|
1796
|
+
cursor: pointer;
|
|
1797
|
+
list-style: none;
|
|
1798
|
+
padding: var(--bp-space-2) var(--bp-space-3);
|
|
1968
1799
|
font-family: var(--bp-mono);
|
|
1969
|
-
font-size: var(--bp-label-
|
|
1970
|
-
letter-spacing: var(--bp-label-
|
|
1800
|
+
font-size: var(--bp-label-md);
|
|
1801
|
+
letter-spacing: var(--bp-label-md-ls);
|
|
1971
1802
|
text-transform: uppercase;
|
|
1972
1803
|
color: var(--bp-text-secondary);
|
|
1973
1804
|
}
|
|
1974
|
-
:where(.bp-
|
|
1975
|
-
|
|
1976
|
-
border-collapse: collapse;
|
|
1977
|
-
font-family: var(--bp-sans);
|
|
1805
|
+
:where(.bp-choice__compare > summary)::-webkit-details-marker {
|
|
1806
|
+
display: none;
|
|
1978
1807
|
}
|
|
1979
|
-
:where(.bp-
|
|
1980
|
-
|
|
1981
|
-
|
|
1808
|
+
:where(.bp-choice__compare-body) {
|
|
1809
|
+
padding: var(--bp-space-3);
|
|
1810
|
+
border-top: 1px solid var(--bp-edge);
|
|
1982
1811
|
}
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1812
|
+
|
|
1813
|
+
/* ---- Pre-flight (decisions before drafting) ---------------------- */
|
|
1814
|
+
:where(.bp-preflight) {
|
|
1815
|
+
border: 1px solid var(--bp-ink-line);
|
|
1816
|
+
border-radius: var(--bp-radius-0);
|
|
1817
|
+
overflow: hidden;
|
|
1818
|
+
margin: var(--bp-space-4) 0;
|
|
1987
1819
|
}
|
|
1988
|
-
:where(.bp-
|
|
1989
|
-
display:
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
padding: var(--bp-space-
|
|
1820
|
+
:where(.bp-preflight__bar) {
|
|
1821
|
+
display: flex;
|
|
1822
|
+
align-items: center;
|
|
1823
|
+
gap: var(--bp-space-2);
|
|
1824
|
+
padding: var(--bp-space-2) var(--bp-space-3);
|
|
1825
|
+
background: var(--bp-ink);
|
|
1826
|
+
color: var(--bp-paper);
|
|
1993
1827
|
}
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
height of the list; a single INK GLIDE marker (the ul::after) slides
|
|
1998
|
-
smoothly to the active entry; each entry carries an auto-numbered
|
|
1999
|
-
mono index that matches the section eyebrows. blueprint.js sets
|
|
2000
|
-
--bp-toc-y / --bp-toc-h (active entry geometry) and --bp-toc-fill
|
|
2001
|
-
(read-so-far ratio); everything degrades to the aria-current rail
|
|
2002
|
-
with no JS. All neutral ink — blue stays in the illustrations. */
|
|
2003
|
-
:where(.bp-sidebar, .bp-toc) {
|
|
2004
|
-
position: fixed;
|
|
2005
|
-
top: 0;
|
|
2006
|
-
left: 0;
|
|
2007
|
-
width: var(--bp-sidebar);
|
|
2008
|
-
height: 100vh;
|
|
2009
|
-
overflow-y: auto;
|
|
2010
|
-
padding: var(--bp-space-5) var(--bp-space-4);
|
|
2011
|
-
background: var(--bp-bg);
|
|
2012
|
-
z-index: 100;
|
|
1828
|
+
:where(.bp-preflight__bar) > :where(.bp-label) {
|
|
1829
|
+
margin: 0;
|
|
1830
|
+
color: var(--bp-paper);
|
|
2013
1831
|
}
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
font-size: var(--bp-text-body);
|
|
1832
|
+
:where(.bp-preflight__count) {
|
|
1833
|
+
margin-left: auto;
|
|
1834
|
+
font-family: var(--bp-mono);
|
|
1835
|
+
font-size: var(--bp-label-md);
|
|
2019
1836
|
letter-spacing: var(--bp-label-md-ls);
|
|
2020
|
-
|
|
2021
|
-
|
|
1837
|
+
text-transform: uppercase;
|
|
1838
|
+
color: color-mix(in oklch, var(--bp-paper) 78%, oklch(0 0 0 / 0));
|
|
2022
1839
|
}
|
|
2023
|
-
:where(.bp-
|
|
2024
|
-
|
|
1840
|
+
:where(.bp-preflight__questions) {
|
|
1841
|
+
counter-reset: bp-preflight-q;
|
|
2025
1842
|
}
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
1843
|
+
:where(.bp-preflight__q) {
|
|
1844
|
+
counter-increment: bp-preflight-q;
|
|
1845
|
+
padding: var(--bp-space-3) var(--bp-space-3) var(--bp-space-3) calc(var(--bp-space-6) + 4px);
|
|
2029
1846
|
position: relative;
|
|
2030
|
-
|
|
2031
|
-
margin: 0;
|
|
2032
|
-
padding: 0;
|
|
2033
|
-
list-style: none;
|
|
1847
|
+
border-bottom: 1px solid var(--bp-edge);
|
|
2034
1848
|
}
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
:where(.bp-sidebar > ul, .bp-sidebar__panel > ul, .bp-toc > ul)::before {
|
|
2038
|
-
content: "";
|
|
1849
|
+
:where(.bp-preflight__q::before) {
|
|
1850
|
+
content: counter(bp-preflight-q, decimal-leading-zero);
|
|
2039
1851
|
position: absolute;
|
|
2040
|
-
left:
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
z-index: 0;
|
|
2047
|
-
pointer-events: none;
|
|
2048
|
-
/* Motion: slow + ease-out (large pill gliding between TOC entries). The
|
|
2049
|
-
old hand-tuned cubic-bezier was already an ease-out, so it maps onto
|
|
2050
|
-
--bp-ease-out; 0.32s rounds to the slow token. */
|
|
2051
|
-
transition-property: top, height;
|
|
2052
|
-
transition-duration: var(--bp-duration-slow);
|
|
2053
|
-
transition-timing-function: var(--bp-ease-out);
|
|
1852
|
+
left: var(--bp-space-3);
|
|
1853
|
+
top: var(--bp-space-3);
|
|
1854
|
+
font-family: var(--bp-mono);
|
|
1855
|
+
font-size: var(--bp-label-lg);
|
|
1856
|
+
letter-spacing: 0.08em;
|
|
1857
|
+
color: var(--bp-ink-soft);
|
|
2054
1858
|
}
|
|
2055
|
-
:where(.bp-
|
|
2056
|
-
|
|
2057
|
-
margin: 0;
|
|
2058
|
-
padding: 0;
|
|
1859
|
+
:where(.bp-preflight__q:has(input:checked)::before) {
|
|
1860
|
+
color: var(--bp-ink);
|
|
2059
1861
|
}
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
z-index: 1;
|
|
1862
|
+
:where(.bp-preflight__prompt) {
|
|
1863
|
+
font-family: var(--bp-sans);
|
|
1864
|
+
font-weight: var(--bp-weight-strong);
|
|
1865
|
+
font-size: var(--bp-text-h4);
|
|
1866
|
+
margin: 0 0 var(--bp-space-1);
|
|
2066
1867
|
display: flex;
|
|
2067
1868
|
align-items: baseline;
|
|
2068
1869
|
gap: var(--bp-space-2);
|
|
2069
|
-
font-family: var(--bp-sans);
|
|
2070
|
-
font-size: var(--bp-text-body);
|
|
2071
|
-
line-height: 1.35;
|
|
2072
|
-
color: var(--bp-text-secondary);
|
|
2073
|
-
text-decoration: none;
|
|
2074
|
-
padding: 6px var(--bp-space-3);
|
|
2075
|
-
border-radius: var(--bp-radius-6);
|
|
2076
|
-
/* Motion: .bp-transition-colors .bp-ease (hover color shift) */
|
|
2077
|
-
transition-property: color, background;
|
|
2078
|
-
transition-duration: var(--bp-duration-fast);
|
|
2079
|
-
transition-timing-function: var(--bp-ease);
|
|
2080
1870
|
}
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
color: var(--bp-ink-soft);
|
|
2089
|
-
/* Motion: .bp-transition-colors .bp-ease (hover color shift) */
|
|
2090
|
-
transition-property: color;
|
|
2091
|
-
transition-duration: var(--bp-duration-fast);
|
|
2092
|
-
transition-timing-function: var(--bp-ease);
|
|
1871
|
+
:where(.bp-preflight__kind) {
|
|
1872
|
+
font-family: var(--bp-mono);
|
|
1873
|
+
font-size: var(--bp-label-sm);
|
|
1874
|
+
letter-spacing: var(--bp-label-sm-ls);
|
|
1875
|
+
text-transform: uppercase;
|
|
1876
|
+
color: var(--bp-text-secondary);
|
|
1877
|
+
font-weight: var(--bp-weight-body);
|
|
2093
1878
|
}
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
margin:
|
|
2097
|
-
padding: 0 0 0 var(--bp-space-3);
|
|
2098
|
-
list-style: none;
|
|
1879
|
+
:where(.bp-preflight__resolved) {
|
|
1880
|
+
display: none;
|
|
1881
|
+
margin-left: auto;
|
|
2099
1882
|
}
|
|
2100
|
-
:where(.bp-
|
|
2101
|
-
|
|
1883
|
+
:where(.bp-preflight__q:has(input:checked)) :where(.bp-preflight__resolved) {
|
|
1884
|
+
display: inline-flex;
|
|
2102
1885
|
}
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
1886
|
+
:where(.bp-preflight__chips) {
|
|
1887
|
+
display: flex;
|
|
1888
|
+
flex-wrap: wrap;
|
|
1889
|
+
gap: var(--bp-space-2);
|
|
1890
|
+
margin-top: var(--bp-space-2);
|
|
2108
1891
|
}
|
|
2109
|
-
:where(.bp-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
1892
|
+
:where(.bp-preflight__chip) {
|
|
1893
|
+
display: inline-flex;
|
|
1894
|
+
align-items: center;
|
|
1895
|
+
gap: 7px;
|
|
1896
|
+
cursor: pointer;
|
|
1897
|
+
border: 1px solid var(--bp-ink-faint);
|
|
1898
|
+
border-radius: var(--bp-radius-0);
|
|
1899
|
+
padding: 5px 12px;
|
|
1900
|
+
font-size: var(--bp-text-small);
|
|
1901
|
+
background: var(--bp-paper);
|
|
2113
1902
|
}
|
|
2114
|
-
:where(.bp-
|
|
2115
|
-
color: var(--bp-ink);
|
|
1903
|
+
:where(.bp-preflight__chip:hover) {
|
|
1904
|
+
border-color: var(--bp-ink-line);
|
|
2116
1905
|
}
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
index with dotted leaders; its links share the same aria-current
|
|
2121
|
-
active state from blueprint.js (no gliding marker — it's a grid). */
|
|
2122
|
-
:where(.bp-contents) {
|
|
2123
|
-
margin: var(--bp-space-5) 0 var(--bp-space-6);
|
|
1906
|
+
:where(.bp-preflight__chip) :where(input) {
|
|
1907
|
+
accent-color: var(--bp-ink);
|
|
1908
|
+
margin: 0;
|
|
2124
1909
|
}
|
|
2125
|
-
:where(.bp-
|
|
2126
|
-
|
|
1910
|
+
:where(.bp-preflight__chip:has(input:checked)) {
|
|
1911
|
+
background: var(--bp-ink);
|
|
1912
|
+
color: var(--bp-paper);
|
|
1913
|
+
border-color: var(--bp-ink);
|
|
2127
1914
|
}
|
|
2128
|
-
:where(.bp-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
1915
|
+
:where(.bp-preflight__gate) {
|
|
1916
|
+
margin: var(--bp-space-3);
|
|
1917
|
+
border: 1px dashed var(--bp-ink-line);
|
|
1918
|
+
border-radius: var(--bp-radius-0);
|
|
1919
|
+
padding: var(--bp-space-4);
|
|
1920
|
+
text-align: center;
|
|
1921
|
+
background-image: var(--bp-hatch);
|
|
1922
|
+
color: var(--bp-text-secondary);
|
|
2136
1923
|
}
|
|
2137
|
-
:where(.bp-
|
|
2138
|
-
|
|
2139
|
-
margin: 0;
|
|
1924
|
+
:where(.bp-preflight__gate-ready) {
|
|
1925
|
+
display: none;
|
|
2140
1926
|
}
|
|
2141
|
-
:where(.bp-
|
|
1927
|
+
:where(.bp-preflight--ready) :where(.bp-preflight__gate) {
|
|
1928
|
+
background-image: none;
|
|
1929
|
+
border-style: solid;
|
|
1930
|
+
border-color: var(--bp-ink-line);
|
|
1931
|
+
}
|
|
1932
|
+
:where(.bp-preflight--ready) :where(.bp-preflight__gate-locked) {
|
|
1933
|
+
display: none;
|
|
1934
|
+
}
|
|
1935
|
+
:where(.bp-preflight--ready) :where(.bp-preflight__gate-ready) {
|
|
1936
|
+
display: block;
|
|
1937
|
+
}
|
|
1938
|
+
:where(.bp-preflight__draft) {
|
|
1939
|
+
display: inline-flex;
|
|
1940
|
+
align-items: center;
|
|
1941
|
+
gap: 8px;
|
|
1942
|
+
border: 1px solid var(--bp-ink);
|
|
1943
|
+
border-radius: var(--bp-radius-0);
|
|
1944
|
+
padding: 8px 16px;
|
|
1945
|
+
font-family: var(--bp-mono);
|
|
1946
|
+
font-size: var(--bp-label-md);
|
|
1947
|
+
letter-spacing: var(--bp-label-md-ls);
|
|
1948
|
+
text-transform: uppercase;
|
|
1949
|
+
background: var(--bp-ink);
|
|
1950
|
+
color: var(--bp-paper);
|
|
1951
|
+
cursor: pointer;
|
|
1952
|
+
margin-top: var(--bp-space-2);
|
|
1953
|
+
}
|
|
1954
|
+
:where(.bp-preflight__footer) {
|
|
2142
1955
|
display: flex;
|
|
1956
|
+
align-items: center;
|
|
1957
|
+
gap: var(--bp-space-3);
|
|
1958
|
+
margin-top: var(--bp-space-3);
|
|
1959
|
+
}
|
|
1960
|
+
|
|
1961
|
+
/* ---- Choice record (static decided archive) ---------------------- */
|
|
1962
|
+
:where(.bp-choice-record) {
|
|
1963
|
+
margin: var(--bp-space-4) 0;
|
|
1964
|
+
}
|
|
1965
|
+
:where(.bp-choice-record__row) {
|
|
1966
|
+
border: 1px solid var(--bp-edge);
|
|
1967
|
+
border-radius: var(--bp-radius-0);
|
|
1968
|
+
padding: var(--bp-space-2) var(--bp-space-3);
|
|
1969
|
+
display: grid;
|
|
1970
|
+
grid-template-columns: minmax(8rem, 14rem) 1fr auto;
|
|
1971
|
+
gap: var(--bp-space-2) var(--bp-space-3);
|
|
2143
1972
|
align-items: baseline;
|
|
2144
|
-
gap: var(--bp-space-2);
|
|
2145
|
-
padding: var(--bp-space-2) 0;
|
|
2146
|
-
font-family: var(--bp-sans);
|
|
2147
|
-
font-size: var(--bp-text-body);
|
|
2148
|
-
color: var(--bp-text);
|
|
2149
|
-
text-decoration: none;
|
|
2150
|
-
/* Motion: .bp-transition-colors .bp-duration-normal .bp-ease-out */
|
|
2151
|
-
transition-property: color;
|
|
2152
|
-
transition-duration: var(--bp-duration-normal);
|
|
2153
|
-
transition-timing-function: var(--bp-ease-out);
|
|
2154
1973
|
}
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
content: "";
|
|
2158
|
-
order: 2;
|
|
2159
|
-
flex: 1 1 auto;
|
|
2160
|
-
align-self: center;
|
|
2161
|
-
border-bottom: 1px dotted var(--bp-ink-faint);
|
|
2162
|
-
transition-property: border-color;
|
|
2163
|
-
transition-duration: var(--bp-duration-normal);
|
|
2164
|
-
transition-timing-function: var(--bp-ease-out);
|
|
1974
|
+
:where(.bp-choice-record__row + .bp-choice-record__row) {
|
|
1975
|
+
margin-top: var(--bp-space-2);
|
|
2165
1976
|
}
|
|
2166
|
-
:where(.bp-
|
|
2167
|
-
|
|
2168
|
-
order: 3;
|
|
2169
|
-
flex: 0 0 auto;
|
|
1977
|
+
:where(.bp-choice-record__row) :where(dt) {
|
|
1978
|
+
font-family: var(--bp-mono);
|
|
2170
1979
|
font-size: var(--bp-label-md);
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
color: var(--bp-
|
|
2174
|
-
|
|
2175
|
-
transition-property: color, transform;
|
|
2176
|
-
transition-duration: var(--bp-duration-normal);
|
|
2177
|
-
transition-timing-function: var(--bp-ease-out);
|
|
1980
|
+
letter-spacing: var(--bp-label-md-ls);
|
|
1981
|
+
text-transform: uppercase;
|
|
1982
|
+
color: var(--bp-text-secondary);
|
|
1983
|
+
margin: 0;
|
|
2178
1984
|
}
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
color: var(--bp-ink);
|
|
2183
|
-
background: none;
|
|
1985
|
+
:where(.bp-choice-record__row) :where(dd) {
|
|
1986
|
+
margin: 0;
|
|
1987
|
+
font-weight: var(--bp-weight-medium);
|
|
2184
1988
|
}
|
|
2185
|
-
|
|
2186
|
-
|
|
1989
|
+
@media (max-width: 700px) {
|
|
1990
|
+
:where(.bp-choice-record__row) {
|
|
1991
|
+
grid-template-columns: 1fr;
|
|
1992
|
+
gap: 2px;
|
|
1993
|
+
}
|
|
2187
1994
|
}
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
1995
|
+
|
|
1996
|
+
/* ---- Data-table wrap: let wide tables break past the prose measure */
|
|
1997
|
+
:where(.bp-table-wrap) {
|
|
1998
|
+
max-width: 100%;
|
|
1999
|
+
overflow-x: auto;
|
|
2000
|
+
margin: var(--bp-space-3) 0 var(--bp-space-4);
|
|
2001
|
+
}
|
|
2002
|
+
/* Opt-in breakout: a wide table expands toward --bp-wide */
|
|
2003
|
+
:where(.bp-table-wrap--wide) {
|
|
2004
|
+
width: 100vw;
|
|
2005
|
+
max-width: var(--bp-wide);
|
|
2006
|
+
margin-inline: calc(50% - 50vw);
|
|
2007
|
+
margin-inline: max(calc(50% - 50vw), calc((100% - var(--bp-wide)) / 2));
|
|
2191
2008
|
}
|
|
2192
2009
|
|
|
2193
|
-
/*
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
one unbroken hairline across the sidebar and shell. */
|
|
2208
|
-
--bp-shell-mask-z: 150;
|
|
2209
|
-
--bp-frame-line-z: 210;
|
|
2210
|
-
--bp-scroll-margin: var(--bp-space-6);
|
|
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) {
|
|
2021
|
+
display: block;
|
|
2022
|
+
max-width: 100%;
|
|
2023
|
+
margin: var(--bp-space-3) 0 var(--bp-space-4);
|
|
2211
2024
|
}
|
|
2212
|
-
|
|
2213
|
-
|
|
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;
|
|
2214
2030
|
}
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
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) {
|
|
2219
2057
|
margin: 0;
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
overscroll-behavior: contain;
|
|
2223
|
-
-webkit-overflow-scrolling: touch;
|
|
2224
|
-
background: var(--bp-paper);
|
|
2225
|
-
border: 0;
|
|
2226
|
-
border-radius: var(--bp-radius-0);
|
|
2227
|
-
box-shadow: none;
|
|
2058
|
+
width: max-content;
|
|
2059
|
+
min-width: 100%;
|
|
2228
2060
|
}
|
|
2229
|
-
/*
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
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));
|
|
2233
2067
|
}
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
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);
|
|
2243
2089
|
}
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
inset-inline: 0;
|
|
2249
|
-
pointer-events: none;
|
|
2250
|
-
z-index: var(--bp-frame-line-z);
|
|
2251
|
-
background-image:
|
|
2252
|
-
linear-gradient(var(--bp-edge), var(--bp-edge)),
|
|
2253
|
-
linear-gradient(var(--bp-edge), var(--bp-edge));
|
|
2254
|
-
background-size: var(--bp-stroke) 100%;
|
|
2255
|
-
background-repeat: no-repeat;
|
|
2256
|
-
background-position:
|
|
2257
|
-
var(--bp-shell-inset-left) 0,
|
|
2258
|
-
calc(100% - var(--bp-shell-inset-right)) 0;
|
|
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;
|
|
2259
2094
|
}
|
|
2260
|
-
/*
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
content: "";
|
|
2265
|
-
position: fixed;
|
|
2266
|
-
inset-inline: 0;
|
|
2267
|
-
top: 0;
|
|
2268
|
-
height: var(--bp-shell-inset-top);
|
|
2269
|
-
background: var(--bp-bg);
|
|
2270
|
-
pointer-events: none;
|
|
2271
|
-
z-index: var(--bp-shell-mask-z);
|
|
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);
|
|
2272
2099
|
}
|
|
2273
|
-
:where(
|
|
2274
|
-
|
|
2275
|
-
position: fixed;
|
|
2276
|
-
inset-inline: 0;
|
|
2277
|
-
height: 0;
|
|
2278
|
-
border-top: var(--bp-stroke) solid var(--bp-edge);
|
|
2279
|
-
pointer-events: none;
|
|
2280
|
-
z-index: var(--bp-frame-line-z);
|
|
2281
|
-
bottom: var(--bp-shell-inset-block);
|
|
2100
|
+
:where(bp-table tbody tr:hover :is(td, th)) {
|
|
2101
|
+
background: var(--bp-fill-amb);
|
|
2282
2102
|
}
|
|
2283
|
-
|
|
2284
|
-
|
|
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;
|
|
2285
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;
|
|
2286
2116
|
left: 0;
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
background: var(--bp-ink);
|
|
2290
|
-
transform: scaleX(0);
|
|
2291
|
-
transform-origin: left;
|
|
2292
|
-
z-index: 200;
|
|
2293
|
-
/* Motion: linear (constant motion — scroll-progress follower). Bumped
|
|
2294
|
-
from a sub-token 50ms to the instant token; the bar tracks scroll so
|
|
2295
|
-
it stays effectively immediate. */
|
|
2296
|
-
transition-property: transform;
|
|
2297
|
-
transition-duration: var(--bp-duration-instant);
|
|
2298
|
-
transition-timing-function: var(--bp-ease-linear);
|
|
2117
|
+
z-index: 2;
|
|
2118
|
+
background: var(--bp-paper);
|
|
2299
2119
|
}
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
inset: 0 auto 0 0;
|
|
2307
|
-
width: var(--sidebar);
|
|
2308
|
-
height: 100vh;
|
|
2309
|
-
overflow-y: auto;
|
|
2310
|
-
padding: 34px 20px 34px 26px;
|
|
2311
|
-
z-index: 100;
|
|
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;
|
|
2312
2126
|
}
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
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);
|
|
2317
2132
|
}
|
|
2318
|
-
:where(
|
|
2319
|
-
font:
|
|
2320
|
-
letter-spacing: 0.12em;
|
|
2321
|
-
text-transform: uppercase;
|
|
2322
|
-
color: var(--ink);
|
|
2133
|
+
:where(bp-table[density="compact"] :is(td, th[scope="row"])) {
|
|
2134
|
+
font-size: var(--bp-text-small);
|
|
2323
2135
|
}
|
|
2324
|
-
:where(
|
|
2325
|
-
font:
|
|
2326
|
-
letter-spacing:
|
|
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);
|
|
2165
|
+
font-size: var(--bp-label-md);
|
|
2166
|
+
letter-spacing: var(--bp-label-md-ls);
|
|
2327
2167
|
text-transform: uppercase;
|
|
2328
|
-
color: var(--text-secondary);
|
|
2329
|
-
margin-top: 6px;
|
|
2168
|
+
color: var(--bp-text-secondary);
|
|
2330
2169
|
}
|
|
2331
|
-
:where(.
|
|
2332
|
-
|
|
2170
|
+
:where(.bp-source-toolbar) {
|
|
2171
|
+
display: flex;
|
|
2172
|
+
align-items: center;
|
|
2173
|
+
gap: var(--bp-space-3);
|
|
2174
|
+
margin-left: auto;
|
|
2175
|
+
}
|
|
2176
|
+
:where(.bp-source-language) {
|
|
2177
|
+
font-family: var(--bp-mono);
|
|
2178
|
+
font-size: var(--bp-label-sm);
|
|
2179
|
+
letter-spacing: var(--bp-label-sm-ls);
|
|
2180
|
+
text-transform: uppercase;
|
|
2181
|
+
color: var(--bp-text-secondary);
|
|
2182
|
+
}
|
|
2183
|
+
:where(.bp-source-copy) {
|
|
2184
|
+
appearance: none;
|
|
2185
|
+
border: 1px solid var(--bp-ink-line);
|
|
2186
|
+
border-radius: var(--bp-radius-0);
|
|
2187
|
+
padding: 4px var(--bp-space-2);
|
|
2188
|
+
background: oklch(0 0 0 / 0);
|
|
2189
|
+
color: var(--bp-ink);
|
|
2190
|
+
font-family: var(--bp-mono);
|
|
2191
|
+
font-size: var(--bp-label-sm);
|
|
2192
|
+
line-height: 1;
|
|
2193
|
+
letter-spacing: var(--bp-label-sm-ls);
|
|
2194
|
+
text-transform: uppercase;
|
|
2195
|
+
cursor: pointer;
|
|
2196
|
+
}
|
|
2197
|
+
:where(.bp-source-copy:hover) {
|
|
2198
|
+
border-color: var(--bp-ink);
|
|
2199
|
+
background: var(--bp-fill-amb);
|
|
2200
|
+
}
|
|
2201
|
+
:where(.bp-source-copy[data-bp-copy-state="copied"]) {
|
|
2202
|
+
border-color: var(--bp-ink);
|
|
2203
|
+
background: var(--bp-fill-hi);
|
|
2204
|
+
}
|
|
2205
|
+
:where(.bp-source-copy[data-bp-copy-state="error"]) {
|
|
2206
|
+
border-style: dashed;
|
|
2207
|
+
}
|
|
2208
|
+
:where(.bp-source > pre) {
|
|
2209
|
+
max-height: 360px;
|
|
2210
|
+
margin: 0;
|
|
2211
|
+
border: 0;
|
|
2212
|
+
border-top: 1px solid var(--bp-edge);
|
|
2213
|
+
}
|
|
2214
|
+
|
|
2215
|
+
/* ---- Code citation tooltip ---------------------------------------
|
|
2216
|
+
<bp-cite> renders an inline TRIGGER (the cited text) plus a top-layer
|
|
2217
|
+
POPOVER card that reveals the cited code on hover / focus / tap. The
|
|
2218
|
+
code block inside is dressed flush by blueprint-code.css (where the
|
|
2219
|
+
Prism <pre> rules live). Citation markers use --bp-illustration blue.
|
|
2220
|
+
The runtime (blueprint-code.js) owns show/hide + viewport placement. */
|
|
2221
|
+
:where(bp-cite) {
|
|
2222
|
+
display: inline;
|
|
2223
|
+
}
|
|
2224
|
+
:where(.bp-cite-trigger) {
|
|
2225
|
+
font: inherit;
|
|
2333
2226
|
margin: 0;
|
|
2334
2227
|
padding: 0;
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2228
|
+
border: 0;
|
|
2229
|
+
background: none;
|
|
2230
|
+
color: inherit;
|
|
2231
|
+
cursor: help;
|
|
2232
|
+
text-decoration: underline dotted var(--bp-illustration-faint);
|
|
2233
|
+
text-underline-offset: 3px;
|
|
2234
|
+
text-decoration-thickness: 1px;
|
|
2235
|
+
/* Motion: .bp-transition-colors .bp-ease (hover color shift) */
|
|
2236
|
+
transition-property: text-decoration-color;
|
|
2237
|
+
transition-duration: var(--bp-duration-fast);
|
|
2238
|
+
transition-timing-function: var(--bp-ease);
|
|
2338
2239
|
}
|
|
2339
|
-
:where(.
|
|
2240
|
+
:where(.bp-cite-trigger:hover) {
|
|
2241
|
+
text-decoration-color: var(--bp-illustration-soft);
|
|
2242
|
+
}
|
|
2243
|
+
:where(.bp-cite-trigger[aria-expanded="true"]) {
|
|
2244
|
+
text-decoration-color: var(--bp-blue-800);
|
|
2245
|
+
}
|
|
2246
|
+
:where([data-obvious-theme="dark"] .bp-cite-trigger[aria-expanded="true"]) {
|
|
2247
|
+
text-decoration-color: var(--bp-blue-200);
|
|
2248
|
+
}
|
|
2249
|
+
:where(.bp-cite-icon) {
|
|
2250
|
+
font-family: var(--bp-mono);
|
|
2251
|
+
font-size: 0.72em;
|
|
2252
|
+
letter-spacing: -0.05em;
|
|
2253
|
+
color: var(--bp-illustration);
|
|
2254
|
+
margin-left: 0.32em;
|
|
2255
|
+
vertical-align: 0.08em;
|
|
2256
|
+
/* Motion: .bp-transition-colors .bp-ease (hover color shift) */
|
|
2257
|
+
transition-property: color;
|
|
2258
|
+
transition-duration: var(--bp-duration-fast);
|
|
2259
|
+
transition-timing-function: var(--bp-ease);
|
|
2260
|
+
}
|
|
2261
|
+
:where(.bp-cite-icon)::before {
|
|
2262
|
+
content: "</>";
|
|
2263
|
+
}
|
|
2264
|
+
:where(.bp-cite-trigger:hover .bp-cite-icon) {
|
|
2265
|
+
color: var(--bp-illustration-soft);
|
|
2266
|
+
}
|
|
2267
|
+
:where(.bp-cite-trigger[aria-expanded="true"] .bp-cite-icon) {
|
|
2268
|
+
color: var(--bp-blue-800);
|
|
2269
|
+
}
|
|
2270
|
+
:where([data-obvious-theme="dark"] .bp-cite-trigger[aria-expanded="true"] .bp-cite-icon) {
|
|
2271
|
+
color: var(--bp-blue-200);
|
|
2272
|
+
}
|
|
2273
|
+
|
|
2274
|
+
/* The popover card. Resets the UA's centered popover positioning so the
|
|
2275
|
+
runtime can place it; falls back to .is-open when popover is absent. */
|
|
2276
|
+
:where(.bp-cite-pop) {
|
|
2277
|
+
position: fixed;
|
|
2340
2278
|
margin: 0;
|
|
2279
|
+
inset: auto;
|
|
2280
|
+
width: min(460px, calc(100vw - 20px));
|
|
2341
2281
|
padding: 0;
|
|
2282
|
+
border: 1px solid var(--bp-ink-line);
|
|
2283
|
+
border-radius: var(--bp-radius-0);
|
|
2284
|
+
background: var(--bp-paper);
|
|
2285
|
+
color: var(--bp-text);
|
|
2286
|
+
box-shadow: var(--bp-shadow-pop);
|
|
2287
|
+
opacity: 0;
|
|
2288
|
+
transform: translateY(4px);
|
|
2289
|
+
/* Motion: .bp-transition-opacity + transform, fast + ease-out (tooltip
|
|
2290
|
+
enter/exit). overlay + display need allow-discrete for top-layer. */
|
|
2291
|
+
transition-property: opacity, transform, overlay, display;
|
|
2292
|
+
transition-duration: var(--bp-duration-fast);
|
|
2293
|
+
transition-timing-function: var(--bp-ease-out);
|
|
2294
|
+
transition-behavior: allow-discrete;
|
|
2342
2295
|
}
|
|
2343
|
-
:where(.
|
|
2344
|
-
|
|
2296
|
+
:where(.bp-cite-pop:not([popover])) {
|
|
2297
|
+
display: none;
|
|
2298
|
+
}
|
|
2299
|
+
:where(.bp-cite-pop.is-open) {
|
|
2345
2300
|
display: block;
|
|
2346
|
-
font: 400 12px/1.35 var(--sans);
|
|
2347
|
-
color: var(--text-secondary);
|
|
2348
|
-
text-decoration: none;
|
|
2349
|
-
padding: 7px 10px 7px 36px;
|
|
2350
2301
|
}
|
|
2351
|
-
:where(.
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
left: 10px;
|
|
2356
|
-
top: 8px;
|
|
2357
|
-
font: 400 10px/1 var(--mono);
|
|
2358
|
-
letter-spacing: 0.06em;
|
|
2359
|
-
color: var(--ink-faint);
|
|
2302
|
+
:where(.bp-cite-pop:popover-open),
|
|
2303
|
+
:where(.bp-cite-pop.is-open) {
|
|
2304
|
+
opacity: 1;
|
|
2305
|
+
transform: translateY(0);
|
|
2360
2306
|
}
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2307
|
+
@starting-style {
|
|
2308
|
+
:where(.bp-cite-pop:popover-open),
|
|
2309
|
+
:where(.bp-cite-pop.is-open) {
|
|
2310
|
+
opacity: 0;
|
|
2311
|
+
transform: translateY(4px);
|
|
2312
|
+
}
|
|
2364
2313
|
}
|
|
2365
|
-
|
|
2314
|
+
/* Hairline caret — a border triangle behind a paper triangle. */
|
|
2315
|
+
:where(.bp-cite-pop)::before,
|
|
2316
|
+
:where(.bp-cite-pop)::after {
|
|
2366
2317
|
content: "";
|
|
2367
2318
|
position: absolute;
|
|
2368
|
-
|
|
2369
|
-
width:
|
|
2370
|
-
|
|
2319
|
+
left: var(--bp-cite-caret, 50%);
|
|
2320
|
+
width: 0;
|
|
2321
|
+
height: 0;
|
|
2322
|
+
border: 7px solid oklch(0 0 0 / 0);
|
|
2323
|
+
transform: translateX(-50%);
|
|
2371
2324
|
}
|
|
2372
|
-
:where(.
|
|
2373
|
-
|
|
2325
|
+
:where(.bp-cite-pop[data-placement="top"])::before {
|
|
2326
|
+
bottom: -14px;
|
|
2327
|
+
border-top-color: var(--bp-ink-line);
|
|
2374
2328
|
}
|
|
2375
|
-
:where(.
|
|
2329
|
+
:where(.bp-cite-pop[data-placement="top"])::after {
|
|
2330
|
+
bottom: -12px;
|
|
2331
|
+
border-top-color: var(--bp-paper);
|
|
2332
|
+
}
|
|
2333
|
+
:where(.bp-cite-pop[data-placement="bottom"])::before {
|
|
2334
|
+
top: -14px;
|
|
2335
|
+
border-bottom-color: var(--bp-ink-line);
|
|
2336
|
+
}
|
|
2337
|
+
:where(.bp-cite-pop[data-placement="bottom"])::after {
|
|
2338
|
+
top: -12px;
|
|
2339
|
+
border-bottom-color: var(--bp-paper);
|
|
2340
|
+
}
|
|
2341
|
+
:where(.bp-cite-head) {
|
|
2342
|
+
display: flex;
|
|
2343
|
+
align-items: center;
|
|
2344
|
+
justify-content: space-between;
|
|
2345
|
+
gap: var(--bp-space-3);
|
|
2346
|
+
padding: var(--bp-space-2) var(--bp-space-3);
|
|
2347
|
+
border-bottom: 1px solid var(--bp-edge);
|
|
2348
|
+
}
|
|
2349
|
+
:where(.bp-cite-loc) {
|
|
2350
|
+
font-family: var(--bp-mono);
|
|
2351
|
+
font-size: var(--bp-label-sm);
|
|
2352
|
+
letter-spacing: var(--bp-label-sm-ls);
|
|
2353
|
+
text-transform: uppercase;
|
|
2354
|
+
color: var(--bp-text);
|
|
2355
|
+
white-space: nowrap;
|
|
2356
|
+
overflow: hidden;
|
|
2357
|
+
text-overflow: ellipsis;
|
|
2358
|
+
}
|
|
2359
|
+
:where(.bp-cite-lang) {
|
|
2360
|
+
flex: 0 0 auto;
|
|
2361
|
+
font-family: var(--bp-mono);
|
|
2362
|
+
font-size: var(--bp-label-sm);
|
|
2363
|
+
letter-spacing: var(--bp-label-sm-ls);
|
|
2364
|
+
text-transform: uppercase;
|
|
2365
|
+
color: var(--bp-text-secondary);
|
|
2366
|
+
}
|
|
2367
|
+
/* Code block inside the card — base treatment; blueprint-code.css makes
|
|
2368
|
+
the highlighted variant sit flush and rounds the lower corners. */
|
|
2369
|
+
:where(.bp-cite-pop pre) {
|
|
2370
|
+
max-height: 320px;
|
|
2376
2371
|
margin: 0;
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
border-left: 1px solid var(--edge);
|
|
2372
|
+
border: 0;
|
|
2373
|
+
border-radius: 0 0 var(--bp-radius-0) var(--bp-radius-0);
|
|
2380
2374
|
}
|
|
2381
|
-
|
|
2382
|
-
|
|
2375
|
+
|
|
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);
|
|
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); }
|
|
2430
|
+
|
|
2431
|
+
/* ---- Masthead title-block: a metadata strip (author/date/status) - */
|
|
2432
|
+
:where(.bp-title-block) {
|
|
2433
|
+
display: flex;
|
|
2434
|
+
flex-wrap: wrap;
|
|
2435
|
+
border: 1px solid var(--bp-ink-line);
|
|
2436
|
+
margin-top: var(--bp-space-4);
|
|
2437
|
+
}
|
|
2438
|
+
:where(.bp-tb-cell) {
|
|
2439
|
+
flex: 0 0 auto;
|
|
2440
|
+
padding: var(--bp-space-2) var(--bp-space-3);
|
|
2441
|
+
border-right: 1px solid var(--bp-ink-line);
|
|
2442
|
+
}
|
|
2443
|
+
:where(.bp-tb-cell:last-child) {
|
|
2444
|
+
border-right: 0;
|
|
2445
|
+
}
|
|
2446
|
+
:where(.bp-tb-cell--grow) {
|
|
2447
|
+
flex: 1 1 auto;
|
|
2448
|
+
}
|
|
2449
|
+
|
|
2450
|
+
/* ---- Transitional authored-markup compatibility ------------------
|
|
2451
|
+
These aliases preserve current-skill and stored Blueprint contracts while
|
|
2452
|
+
semantic markup remains the preferred API. */
|
|
2453
|
+
:where(.bp-content) {
|
|
2454
|
+
max-width: var(--bp-content);
|
|
2455
|
+
margin-inline: auto;
|
|
2456
|
+
padding: var(--bp-space-6);
|
|
2457
|
+
}
|
|
2458
|
+
:where(.bp-document) {
|
|
2459
|
+
min-height: 100vh;
|
|
2460
|
+
color: var(--bp-text);
|
|
2461
|
+
background: var(--bp-bg);
|
|
2462
|
+
font-family: var(--bp-serif);
|
|
2463
|
+
}
|
|
2464
|
+
:where(.bp-title) {
|
|
2465
|
+
font-family: var(--bp-sans);
|
|
2466
|
+
font-size: var(--bp-text-title);
|
|
2467
|
+
font-weight: var(--bp-weight-strong);
|
|
2468
|
+
letter-spacing: -0.48px;
|
|
2469
|
+
line-height: var(--bp-lh-title);
|
|
2470
|
+
}
|
|
2471
|
+
:where(.bp-placeholder) {
|
|
2472
|
+
border: 1px dashed var(--bp-ink-faint);
|
|
2473
|
+
background: var(--bp-fill-amb);
|
|
2474
|
+
}
|
|
2475
|
+
:where(.bp-layout, .bp-card-grid) {
|
|
2476
|
+
display: grid;
|
|
2477
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
2478
|
+
gap: 1px;
|
|
2479
|
+
border: 1px solid var(--bp-edge);
|
|
2480
|
+
background: var(--bp-edge);
|
|
2481
|
+
margin: var(--bp-space-3) 0 var(--bp-space-4);
|
|
2482
|
+
}
|
|
2483
|
+
:where(.bp-card) {
|
|
2484
|
+
min-width: 0;
|
|
2485
|
+
padding: var(--bp-space-3);
|
|
2486
|
+
background: var(--bp-paper);
|
|
2487
|
+
}
|
|
2488
|
+
:where(.bp-section) {
|
|
2489
|
+
margin-top: calc(var(--bp-space-7) + var(--bp-space-5));
|
|
2490
|
+
}
|
|
2491
|
+
:where(.bp-section-number) {
|
|
2492
|
+
display: block;
|
|
2493
|
+
width: max-content;
|
|
2494
|
+
font-family: var(--bp-mono);
|
|
2495
|
+
font-size: var(--bp-label-lg);
|
|
2496
|
+
letter-spacing: var(--bp-label-lg-ls);
|
|
2497
|
+
text-transform: uppercase;
|
|
2498
|
+
color: var(--bp-ink);
|
|
2499
|
+
margin-bottom: var(--bp-space-2);
|
|
2500
|
+
}
|
|
2501
|
+
:where(.bp-figure) {
|
|
2502
|
+
width: fit-content;
|
|
2503
|
+
max-width: 100%;
|
|
2504
|
+
margin: var(--bp-space-4) auto;
|
|
2505
|
+
}
|
|
2506
|
+
:where(.bp-figure svg[viewBox]) {
|
|
2507
|
+
display: block;
|
|
2508
|
+
width: auto;
|
|
2509
|
+
max-width: min(100%, var(--bp-diagram-w));
|
|
2510
|
+
height: auto;
|
|
2511
|
+
}
|
|
2512
|
+
:where(.bp-figure svg:not([viewBox])) {
|
|
2513
|
+
display: block;
|
|
2514
|
+
width: auto;
|
|
2515
|
+
max-width: 100%;
|
|
2516
|
+
height: auto;
|
|
2517
|
+
}
|
|
2518
|
+
:where(.bp-figure-caption) {
|
|
2519
|
+
font-family: var(--bp-mono);
|
|
2520
|
+
font-size: var(--bp-label-sm);
|
|
2521
|
+
letter-spacing: var(--bp-label-sm-ls);
|
|
2522
|
+
text-transform: uppercase;
|
|
2523
|
+
color: var(--bp-text-secondary);
|
|
2524
|
+
}
|
|
2525
|
+
:where(.bp-table) {
|
|
2526
|
+
width: 100%;
|
|
2527
|
+
border-collapse: collapse;
|
|
2528
|
+
font-family: var(--bp-sans);
|
|
2529
|
+
}
|
|
2530
|
+
:where(.bp-toc) {
|
|
2531
|
+
font-size: var(--bp-text-small);
|
|
2532
|
+
color: var(--bp-text-secondary);
|
|
2533
|
+
}
|
|
2534
|
+
:where(.bp-toc ul) {
|
|
2535
|
+
list-style: none;
|
|
2536
|
+
margin: 0;
|
|
2537
|
+
padding: 0;
|
|
2538
|
+
}
|
|
2539
|
+
:where(.bp-toc a) {
|
|
2540
|
+
display: block;
|
|
2541
|
+
color: var(--bp-text-secondary);
|
|
2542
|
+
text-decoration: none;
|
|
2543
|
+
padding: var(--bp-space-1) var(--bp-space-2);
|
|
2544
|
+
}
|
|
2545
|
+
|
|
2546
|
+
/* ---- Sidebar / Table of Contents + reading-progress chrome --------
|
|
2547
|
+
A drafting-grade contents rail: a hairline GUIDE TRACK runs the full
|
|
2548
|
+
height of the list; a single INK GLIDE marker (the ul::after) slides
|
|
2549
|
+
smoothly to the active entry; each entry carries an auto-numbered
|
|
2550
|
+
mono index that matches the section eyebrows. blueprint.js sets
|
|
2551
|
+
--bp-toc-y / --bp-toc-h (active entry geometry) and --bp-toc-fill
|
|
2552
|
+
(read-so-far ratio); everything degrades to the aria-current rail
|
|
2553
|
+
with no JS. All neutral ink — blue stays in the illustrations. */
|
|
2554
|
+
:where(.bp-sidebar, .bp-toc) {
|
|
2555
|
+
position: fixed;
|
|
2556
|
+
top: 0;
|
|
2557
|
+
left: 0;
|
|
2558
|
+
width: var(--bp-sidebar);
|
|
2559
|
+
height: 100vh;
|
|
2560
|
+
overflow-y: auto;
|
|
2561
|
+
padding: var(--bp-space-5) var(--bp-space-4);
|
|
2562
|
+
background: var(--bp-bg);
|
|
2563
|
+
z-index: 100;
|
|
2564
|
+
}
|
|
2565
|
+
/* Sidebar masthead — the wordmark is the panel header and must read larger
|
|
2566
|
+
than the contents list; the meta is a subordinate caption beneath it,
|
|
2567
|
+
with clear separation before the TOC. */
|
|
2568
|
+
:where(.bp-sidebar > .bp-eyebrow, .bp-toc > .bp-eyebrow) {
|
|
2569
|
+
font-size: var(--bp-text-body);
|
|
2570
|
+
letter-spacing: var(--bp-label-md-ls);
|
|
2571
|
+
font-weight: var(--bp-weight-medium);
|
|
2572
|
+
margin-bottom: var(--bp-space-1);
|
|
2573
|
+
}
|
|
2574
|
+
:where(.bp-sidebar > .bp-meta, .bp-toc > .bp-meta) {
|
|
2575
|
+
margin-bottom: var(--bp-space-5);
|
|
2576
|
+
}
|
|
2577
|
+
/* The contents list hosts a single rounded ACTIVE PILL that glides between
|
|
2578
|
+
entries as you scroll — no rail, no left border. Obvious-style. */
|
|
2579
|
+
:where(.bp-sidebar > ul, .bp-sidebar__panel > ul, .bp-toc > ul) {
|
|
2580
|
+
position: relative;
|
|
2581
|
+
counter-reset: bp-toc;
|
|
2582
|
+
margin: 0;
|
|
2583
|
+
padding: 0;
|
|
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));
|
|
2589
|
+
}
|
|
2590
|
+
/* The gliding active pill, drawn behind the entries and travelling via
|
|
2591
|
+
--bp-toc-y / --bp-toc-h (set by blueprint.js). */
|
|
2592
|
+
:where(.bp-sidebar > ul, .bp-sidebar__panel > ul, .bp-toc > ul)::before {
|
|
2593
|
+
content: "";
|
|
2594
|
+
position: absolute;
|
|
2595
|
+
left: 0;
|
|
2596
|
+
right: 0;
|
|
2597
|
+
top: var(--bp-toc-y, 0);
|
|
2598
|
+
height: var(--bp-toc-h, 0);
|
|
2599
|
+
background: var(--bp-fill-hi);
|
|
2600
|
+
border-radius: var(--bp-radius-6);
|
|
2601
|
+
z-index: 0;
|
|
2602
|
+
pointer-events: none;
|
|
2603
|
+
/* Motion: slow + ease-out (large pill gliding between TOC entries). The
|
|
2604
|
+
old hand-tuned cubic-bezier was already an ease-out, so it maps onto
|
|
2605
|
+
--bp-ease-out; 0.32s rounds to the slow token. */
|
|
2606
|
+
transition-property: top, height;
|
|
2607
|
+
transition-duration: var(--bp-duration-slow);
|
|
2608
|
+
transition-timing-function: var(--bp-ease-out);
|
|
2609
|
+
}
|
|
2610
|
+
:where(.bp-sidebar > ul > li, .bp-sidebar__panel > ul > li, .bp-toc > ul > li) {
|
|
2611
|
+
counter-increment: bp-toc;
|
|
2612
|
+
margin: 0;
|
|
2613
|
+
padding: 0;
|
|
2614
|
+
}
|
|
2615
|
+
/* TOC nav items: proportional sans, auto-numbered, comfortable target.
|
|
2616
|
+
The entry labels read as prose (Booton); only the small index tick keeps
|
|
2617
|
+
equal-width digits so the numbers stay aligned. Each is a rounded pill. */
|
|
2618
|
+
:where(.bp-sidebar ul a, .bp-toc ul a) {
|
|
2619
|
+
position: relative;
|
|
2620
|
+
z-index: 1;
|
|
2621
|
+
display: flex;
|
|
2622
|
+
align-items: baseline;
|
|
2623
|
+
gap: var(--bp-space-2);
|
|
2624
|
+
font-family: var(--bp-sans);
|
|
2625
|
+
font-size: var(--bp-text-body);
|
|
2626
|
+
line-height: 1.35;
|
|
2627
|
+
color: var(--bp-text-secondary);
|
|
2628
|
+
text-decoration: none;
|
|
2629
|
+
padding: 6px var(--bp-space-3);
|
|
2630
|
+
border-radius: var(--bp-radius-6);
|
|
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;
|
|
2634
|
+
}
|
|
2635
|
+
/* Auto-numbered index (01, 02…), tabular so the digits line up. */
|
|
2636
|
+
:where(.bp-sidebar > ul > li > a, .bp-sidebar__panel > ul > li > a, .bp-toc > ul > li > a)::before {
|
|
2637
|
+
content: counter(bp-toc, decimal-leading-zero);
|
|
2638
|
+
flex: 0 0 var(--bp-toc-index-w, 14px);
|
|
2639
|
+
min-width: var(--bp-toc-index-w, 14px);
|
|
2640
|
+
font-size: var(--bp-label-lg);
|
|
2641
|
+
font-variant-numeric: tabular-nums;
|
|
2642
|
+
letter-spacing: 0.02em;
|
|
2643
|
+
color: var(--bp-ink-soft);
|
|
2644
|
+
transition: none;
|
|
2645
|
+
}
|
|
2646
|
+
/* Nested sub-entries align with primary label text and read tighter. */
|
|
2647
|
+
:where(.bp-sidebar ul ul, .bp-toc ul ul) {
|
|
2648
|
+
margin: 0 0 var(--bp-space-1);
|
|
2649
|
+
padding: 0;
|
|
2650
|
+
list-style: none;
|
|
2651
|
+
}
|
|
2652
|
+
:where(.bp-sidebar ul ul a, .bp-toc ul ul a) {
|
|
2653
|
+
display: block;
|
|
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);
|
|
2677
|
+
}
|
|
2678
|
+
/* Hover shows its own subtle pill; the active entry rides the gliding pill
|
|
2679
|
+
above (so it keeps no own background) and reads in ink + medium weight. */
|
|
2680
|
+
:where(.bp-sidebar a:hover, .bp-toc a:hover) {
|
|
2681
|
+
color: var(--bp-ink);
|
|
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);
|
|
2686
|
+
}
|
|
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) {
|
|
2688
|
+
color: var(--bp-ink);
|
|
2689
|
+
background: none;
|
|
2690
|
+
font-weight: var(--bp-weight-medium);
|
|
2691
|
+
}
|
|
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) {
|
|
2697
|
+
color: var(--bp-ink);
|
|
2698
|
+
}
|
|
2699
|
+
/* ---- Full-width contents block -----------------------------------
|
|
2700
|
+
A table-of-contents SECTION — the inline, content-width counterpart
|
|
2701
|
+
to the fixed `.bp-sidebar` rail. A numbered, responsive multi-column
|
|
2702
|
+
index with dotted leaders; its links share the same aria-current
|
|
2703
|
+
active state from blueprint.js (no gliding marker — it's a grid). */
|
|
2704
|
+
:where(.bp-contents) {
|
|
2705
|
+
margin: var(--bp-space-5) 0 var(--bp-space-6);
|
|
2706
|
+
}
|
|
2707
|
+
:where(.bp-contents > .bp-eyebrow, .bp-contents > .bp-label, .bp-contents > .bp-meta) {
|
|
2708
|
+
margin: var(--bp-space-3) 0 var(--bp-space-1);
|
|
2709
|
+
}
|
|
2710
|
+
:where(.bp-contents > ol, .bp-contents > ul) {
|
|
2711
|
+
display: grid;
|
|
2712
|
+
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
|
|
2713
|
+
gap: 0 var(--bp-space-6);
|
|
2714
|
+
counter-reset: bp-contents;
|
|
2715
|
+
list-style: none;
|
|
2716
|
+
margin: 0;
|
|
2717
|
+
padding: 0;
|
|
2718
|
+
}
|
|
2719
|
+
:where(.bp-contents li) {
|
|
2720
|
+
counter-increment: bp-contents;
|
|
2721
|
+
margin: 0;
|
|
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
|
+
}
|
|
2742
|
+
:where(.bp-contents a) {
|
|
2743
|
+
display: flex;
|
|
2744
|
+
align-items: baseline;
|
|
2745
|
+
gap: var(--bp-space-2);
|
|
2746
|
+
padding: var(--bp-space-2) 0;
|
|
2747
|
+
font-family: var(--bp-sans);
|
|
2748
|
+
font-size: var(--bp-text-body);
|
|
2749
|
+
color: var(--bp-text);
|
|
2750
|
+
text-decoration: none;
|
|
2751
|
+
/* Motion: .bp-transition-colors .bp-duration-normal .bp-ease-out */
|
|
2752
|
+
transition-property: color;
|
|
2753
|
+
transition-duration: var(--bp-duration-normal);
|
|
2754
|
+
transition-timing-function: var(--bp-ease-out);
|
|
2755
|
+
}
|
|
2756
|
+
/* Label | dotted leader | number — flex order puts ::before after link text. */
|
|
2757
|
+
:where(.bp-contents a)::before {
|
|
2758
|
+
content: "";
|
|
2759
|
+
order: 2;
|
|
2760
|
+
flex: 1 1 auto;
|
|
2761
|
+
align-self: center;
|
|
2762
|
+
border-bottom: 1px dotted var(--bp-ink-faint);
|
|
2763
|
+
transition-property: border-color;
|
|
2764
|
+
transition-duration: var(--bp-duration-normal);
|
|
2765
|
+
transition-timing-function: var(--bp-ease-out);
|
|
2766
|
+
}
|
|
2767
|
+
:where(.bp-contents a)::after {
|
|
2768
|
+
content: counter(bp-contents, decimal-leading-zero);
|
|
2769
|
+
order: 3;
|
|
2770
|
+
flex: 0 0 auto;
|
|
2771
|
+
font-size: var(--bp-label-md);
|
|
2772
|
+
font-variant-numeric: tabular-nums;
|
|
2773
|
+
letter-spacing: 0.02em;
|
|
2774
|
+
color: var(--bp-ink-soft);
|
|
2775
|
+
/* Color + a small slide so the dotted leader visibly lengthens on hover. */
|
|
2776
|
+
transition-property: color, transform;
|
|
2777
|
+
transition-duration: var(--bp-duration-normal);
|
|
2778
|
+
transition-timing-function: var(--bp-ease-out);
|
|
2779
|
+
}
|
|
2780
|
+
/* No active/selected state: a contents index at the top of a document has
|
|
2781
|
+
no "current" entry. Hover is the only affordance. */
|
|
2782
|
+
:where(.bp-contents a:hover) {
|
|
2783
|
+
color: var(--bp-ink);
|
|
2784
|
+
background: none;
|
|
2785
|
+
}
|
|
2786
|
+
:where(.bp-contents a:hover)::before {
|
|
2787
|
+
border-bottom-color: var(--bp-ink-soft);
|
|
2788
|
+
}
|
|
2789
|
+
:where(.bp-contents a:hover)::after {
|
|
2790
|
+
color: var(--bp-ink);
|
|
2791
|
+
transform: translateX(var(--bp-space-1));
|
|
2792
|
+
}
|
|
2793
|
+
|
|
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]) {
|
|
2798
|
+
--bp-shell-inset-block: var(--bp-space-4);
|
|
2799
|
+
--bp-shell-inset-top: var(--bp-shell-inset-block);
|
|
2800
|
+
--bp-shell-inset-left: var(--bp-sidebar);
|
|
2801
|
+
--bp-shell-inset-right: var(--bp-space-4);
|
|
2802
|
+
/* Frame stack order: sidebar content (100) < margin mask < sidebar scrims +
|
|
2803
|
+
scroll-progress (200) < frame rules. The mask hides scrolling rail
|
|
2804
|
+
content in the top band; the rules ride above the scrims so they read as
|
|
2805
|
+
one unbroken hairline across the sidebar and shell. */
|
|
2806
|
+
--bp-shell-mask-z: 150;
|
|
2807
|
+
--bp-frame-line-z: 210;
|
|
2808
|
+
--bp-scroll-margin: var(--bp-space-6);
|
|
2809
|
+
}
|
|
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. */
|
|
2818
|
+
:where(html[data-bp-document] main) {
|
|
2819
|
+
max-width: none;
|
|
2820
|
+
margin: 0 var(--bp-shell-inset-right) 0 var(--bp-shell-inset-left);
|
|
2821
|
+
min-height: calc(
|
|
2822
|
+
100vh - var(--bp-shell-inset-top) - var(--bp-shell-inset-block)
|
|
2823
|
+
);
|
|
2824
|
+
background: var(--bp-paper);
|
|
2825
|
+
border: 0;
|
|
2826
|
+
border-radius: var(--bp-radius-0);
|
|
2827
|
+
box-shadow: none;
|
|
2828
|
+
}
|
|
2829
|
+
/* Same inner measure as max-width: var(--bp-content) on a padded main, and
|
|
2830
|
+
auto margins center that measure within the sheet so the reading column
|
|
2831
|
+
sits balanced between the frame rules. The sheet's own box shrinks when the
|
|
2832
|
+
rail collapses (margin-inline transition above), so the centered measure
|
|
2833
|
+
re-centers in step with the slide rather than hugging the left rule. */
|
|
2834
|
+
:where(html[data-bp-document] main > *) {
|
|
2835
|
+
max-width: min(100%, calc(var(--bp-content) - 2 * var(--bp-space-6)));
|
|
2836
|
+
margin-inline: auto;
|
|
2837
|
+
}
|
|
2838
|
+
/* TOC / hash targets — reserve top air so a heading clears the fixed top
|
|
2839
|
+
band instead of landing flush beneath it. */
|
|
2840
|
+
:where(html[data-bp-document] main :is(section[id], [id][data-sidebar])) {
|
|
2841
|
+
scroll-margin-top: var(--bp-scroll-margin);
|
|
2842
|
+
}
|
|
2843
|
+
:where(html[data-bp-document])::before {
|
|
2844
|
+
content: "";
|
|
2845
|
+
position: fixed;
|
|
2846
|
+
inset-inline: 0;
|
|
2847
|
+
top: var(--bp-shell-inset-top);
|
|
2848
|
+
height: 0;
|
|
2849
|
+
border-top: var(--bp-stroke) solid var(--bp-edge);
|
|
2850
|
+
pointer-events: none;
|
|
2851
|
+
z-index: var(--bp-frame-line-z);
|
|
2852
|
+
}
|
|
2853
|
+
:where(html[data-bp-document])::after {
|
|
2854
|
+
content: "";
|
|
2855
|
+
position: fixed;
|
|
2856
|
+
inset-block: 0;
|
|
2857
|
+
inset-inline: 0;
|
|
2858
|
+
pointer-events: none;
|
|
2859
|
+
z-index: var(--bp-frame-line-z);
|
|
2860
|
+
background-image:
|
|
2861
|
+
linear-gradient(var(--bp-edge), var(--bp-edge)),
|
|
2862
|
+
linear-gradient(var(--bp-edge), var(--bp-edge));
|
|
2863
|
+
background-size: var(--bp-stroke) 100%;
|
|
2864
|
+
background-repeat: no-repeat;
|
|
2865
|
+
background-position:
|
|
2866
|
+
var(--bp-shell-inset-left) 0,
|
|
2867
|
+
calc(100% - var(--bp-shell-inset-right)) 0;
|
|
2868
|
+
}
|
|
2869
|
+
/* Top/bottom desk bands (fixed) mask the page scrolling beneath them; the
|
|
2870
|
+
bottom band draws the lower horizontal at its top edge. Frame lines sit
|
|
2871
|
+
above rail scrims so the verticals run edge-to-edge through horizontals. */
|
|
2872
|
+
:where(html[data-bp-document] body)::before {
|
|
2873
|
+
content: "";
|
|
2874
|
+
position: fixed;
|
|
2875
|
+
inset-inline: 0;
|
|
2876
|
+
top: 0;
|
|
2877
|
+
height: var(--bp-shell-inset-top);
|
|
2878
|
+
background: var(--bp-bg);
|
|
2879
|
+
pointer-events: none;
|
|
2880
|
+
z-index: var(--bp-shell-mask-z);
|
|
2881
|
+
}
|
|
2882
|
+
:where(html[data-bp-document] body)::after {
|
|
2883
|
+
content: "";
|
|
2884
|
+
position: fixed;
|
|
2885
|
+
inset-inline: 0;
|
|
2886
|
+
bottom: 0;
|
|
2887
|
+
height: var(--bp-shell-inset-block);
|
|
2888
|
+
border-top: var(--bp-stroke) solid var(--bp-edge);
|
|
2889
|
+
background: var(--bp-bg);
|
|
2890
|
+
pointer-events: none;
|
|
2891
|
+
z-index: var(--bp-frame-line-z);
|
|
2892
|
+
}
|
|
2893
|
+
:where(.scroll-progress) {
|
|
2894
|
+
position: fixed;
|
|
2895
|
+
top: 0;
|
|
2896
|
+
left: 0;
|
|
2897
|
+
right: 0;
|
|
2898
|
+
height: 2px;
|
|
2899
|
+
background: var(--bp-ink);
|
|
2900
|
+
transform: scaleX(0);
|
|
2901
|
+
transform-origin: left;
|
|
2902
|
+
z-index: 200;
|
|
2903
|
+
/* Motion: linear (constant motion — scroll-progress follower). Bumped
|
|
2904
|
+
from a sub-token 50ms to the instant token; the bar tracks scroll so
|
|
2905
|
+
it stays effectively immediate. */
|
|
2906
|
+
transition-property: transform;
|
|
2907
|
+
transition-duration: var(--bp-duration-instant);
|
|
2908
|
+
transition-timing-function: var(--bp-ease-linear);
|
|
2909
|
+
}
|
|
2910
|
+
|
|
2911
|
+
/* ---- <bp-mock> — drafting browser frame for UX mockups ------------
|
|
2912
|
+
The frame is CHROME, so it is drawn in the neutral ink scale; the
|
|
2913
|
+
sketch inside keeps the illustration-blue ramp. `viewport` draws the
|
|
2914
|
+
canvas at a fixed pixel width and scales it to fit (crisp 1:1 when the
|
|
2915
|
+
frame is wide enough or expanded); the expand control lifts the frame
|
|
2916
|
+
into a near-fullscreen overlay over a drafting scrim. */
|
|
2917
|
+
:where(.bp-mock) {
|
|
2918
|
+
display: block;
|
|
2919
|
+
margin: var(--bp-space-4) 0;
|
|
2920
|
+
}
|
|
2921
|
+
:where(.bp-mock__frame) {
|
|
2922
|
+
display: flex;
|
|
2923
|
+
flex-direction: column;
|
|
2924
|
+
border: var(--bp-stroke) solid var(--bp-ink-line);
|
|
2925
|
+
border-radius: var(--bp-radius-0);
|
|
2926
|
+
background: var(--bp-paper);
|
|
2927
|
+
overflow: hidden;
|
|
2928
|
+
}
|
|
2929
|
+
:where(.bp-mock__bar) {
|
|
2930
|
+
display: flex;
|
|
2931
|
+
align-items: center;
|
|
2932
|
+
gap: var(--bp-space-2);
|
|
2933
|
+
min-height: 34px;
|
|
2934
|
+
padding: var(--bp-space-2) var(--bp-space-3);
|
|
2935
|
+
border-bottom: var(--bp-stroke) solid var(--bp-edge);
|
|
2936
|
+
background: var(--bp-fill-amb);
|
|
2937
|
+
}
|
|
2938
|
+
:where(.bp-mock__ticks) {
|
|
2939
|
+
display: inline-flex;
|
|
2940
|
+
gap: 5px;
|
|
2941
|
+
flex: 0 0 auto;
|
|
2942
|
+
}
|
|
2943
|
+
:where(.bp-mock__ticks i) {
|
|
2944
|
+
width: 8px;
|
|
2945
|
+
height: 8px;
|
|
2946
|
+
border-radius: var(--bp-radius-0);
|
|
2947
|
+
border: var(--bp-stroke) solid var(--bp-ink-faint);
|
|
2948
|
+
}
|
|
2949
|
+
:where(.bp-mock__label) {
|
|
2950
|
+
flex: 1 1 auto;
|
|
2951
|
+
min-width: 0;
|
|
2952
|
+
font-family: var(--bp-mono);
|
|
2953
|
+
font-size: var(--bp-label-md);
|
|
2954
|
+
letter-spacing: var(--bp-label-md-ls);
|
|
2955
|
+
color: var(--bp-text-secondary);
|
|
2956
|
+
white-space: nowrap;
|
|
2957
|
+
overflow: hidden;
|
|
2958
|
+
text-overflow: ellipsis;
|
|
2959
|
+
}
|
|
2960
|
+
:where(.bp-mock__btn) {
|
|
2961
|
+
display: inline-flex;
|
|
2962
|
+
align-items: center;
|
|
2963
|
+
justify-content: center;
|
|
2964
|
+
flex: 0 0 auto;
|
|
2965
|
+
width: 24px;
|
|
2966
|
+
height: 24px;
|
|
2967
|
+
padding: 0;
|
|
2968
|
+
border: var(--bp-stroke) solid var(--bp-edge);
|
|
2969
|
+
border-radius: var(--bp-radius-0);
|
|
2970
|
+
background: var(--bp-paper);
|
|
2971
|
+
color: var(--bp-text-secondary);
|
|
2972
|
+
cursor: pointer;
|
|
2973
|
+
}
|
|
2974
|
+
:where(.bp-mock__btn svg) {
|
|
2975
|
+
width: 14px;
|
|
2976
|
+
height: 14px;
|
|
2977
|
+
}
|
|
2978
|
+
:where(.bp-mock__btn:hover) {
|
|
2979
|
+
color: var(--bp-text);
|
|
2980
|
+
border-color: var(--bp-ink-line);
|
|
2981
|
+
}
|
|
2982
|
+
:where(.bp-mock__btn:focus-visible) {
|
|
2983
|
+
outline: 2px solid var(--bp-ink);
|
|
2984
|
+
outline-offset: 2px;
|
|
2985
|
+
}
|
|
2986
|
+
:where(.bp-mock__stage) {
|
|
2987
|
+
position: relative;
|
|
2988
|
+
overflow: hidden;
|
|
2989
|
+
background: var(--bp-bg);
|
|
2990
|
+
}
|
|
2991
|
+
:where(.bp-mock__canvas) {
|
|
2992
|
+
transform-origin: top left;
|
|
2993
|
+
transform: scale(var(--bp-mock-scale, 1));
|
|
2994
|
+
}
|
|
2995
|
+
|
|
2996
|
+
/* Expanded → near-fullscreen overlay; the frame floats over a drafting
|
|
2997
|
+
scrim (ink wash + hatch). The frame itself stays the bordered window. */
|
|
2998
|
+
:where(.bp-mock.is-expanded) {
|
|
2999
|
+
position: fixed;
|
|
3000
|
+
inset: 0;
|
|
3001
|
+
/* Above the fixed rail (100), scroll-progress (200), and frame rules
|
|
3002
|
+
(210) so the overlay fully covers the document chrome. */
|
|
3003
|
+
z-index: 300;
|
|
3004
|
+
margin: 0;
|
|
3005
|
+
display: grid;
|
|
3006
|
+
place-items: center;
|
|
3007
|
+
padding: clamp(var(--bp-space-4), 4vw, var(--bp-space-7));
|
|
3008
|
+
background-color: var(--bp-scrim);
|
|
3009
|
+
background-image: var(--bp-hatch);
|
|
3010
|
+
}
|
|
3011
|
+
:where(.bp-mock.is-expanded) :where(.bp-mock__frame) {
|
|
3012
|
+
width: min(100%, 1120px);
|
|
3013
|
+
max-height: 100%;
|
|
3014
|
+
box-shadow: var(--bp-shadow-pop);
|
|
3015
|
+
}
|
|
3016
|
+
:where(.bp-mock.is-expanded) :where(.bp-mock__stage) {
|
|
3017
|
+
overflow: auto;
|
|
3018
|
+
}
|
|
3019
|
+
|
|
3020
|
+
/* ---- <bp-gallery> — image grid with a lightbox viewer -------------
|
|
3021
|
+
A tidy responsive grid of images (screenshots, mockups, uploads).
|
|
3022
|
+
Each thumbnail wears a BLUESCALE treatment by default — the raster
|
|
3023
|
+
is desaturated and a blue veil (.bp-gallery__wash) color-blends over
|
|
3024
|
+
it — and reveals its true color on hover/focus. Activating a tile
|
|
3025
|
+
opens .bp-lightbox, a near-fullscreen viewer over a drafting scrim. */
|
|
3026
|
+
:where(.bp-gallery) {
|
|
3027
|
+
display: block;
|
|
3028
|
+
margin: var(--bp-space-5) 0;
|
|
3029
|
+
}
|
|
3030
|
+
:where(.bp-gallery__grid) {
|
|
3031
|
+
display: grid;
|
|
3032
|
+
grid-template-columns: repeat(auto-fill, minmax(min(100%, 200px), 1fr));
|
|
3033
|
+
gap: var(--bp-space-3);
|
|
3034
|
+
}
|
|
3035
|
+
:where(.bp-gallery__item) {
|
|
3036
|
+
display: flex;
|
|
3037
|
+
flex-direction: column;
|
|
3038
|
+
gap: var(--bp-space-2);
|
|
3039
|
+
min-width: 0;
|
|
3040
|
+
margin: 0;
|
|
3041
|
+
padding: 0;
|
|
3042
|
+
border: 0;
|
|
3043
|
+
background: none;
|
|
3044
|
+
text-align: left;
|
|
3045
|
+
cursor: pointer;
|
|
3046
|
+
font: inherit;
|
|
3047
|
+
color: inherit;
|
|
3048
|
+
}
|
|
3049
|
+
:where(.bp-gallery__thumb) {
|
|
3050
|
+
position: relative;
|
|
3051
|
+
display: block;
|
|
3052
|
+
overflow: hidden;
|
|
3053
|
+
aspect-ratio: 4 / 3;
|
|
3054
|
+
border: var(--bp-stroke) solid var(--bp-ink-line);
|
|
3055
|
+
border-radius: var(--bp-radius-0);
|
|
3056
|
+
background: var(--bp-bg);
|
|
3057
|
+
}
|
|
3058
|
+
:where(.bp-gallery__img) {
|
|
3059
|
+
display: block;
|
|
3060
|
+
width: 100%;
|
|
3061
|
+
height: 100%;
|
|
3062
|
+
object-fit: cover;
|
|
3063
|
+
/* Bluescale: drop saturation; the wash supplies the blue cast. */
|
|
3064
|
+
filter: grayscale(1) contrast(1.02);
|
|
3065
|
+
transition:
|
|
3066
|
+
filter var(--bp-duration-slow) var(--bp-ease-out),
|
|
3067
|
+
transform var(--bp-duration-slow) var(--bp-ease-out);
|
|
3068
|
+
}
|
|
3069
|
+
:where(.bp-gallery__wash) {
|
|
3070
|
+
position: absolute;
|
|
3071
|
+
inset: 0;
|
|
3072
|
+
background: var(--bp-illustration);
|
|
3073
|
+
mix-blend-mode: color;
|
|
3074
|
+
opacity: 0.85;
|
|
3075
|
+
transition: opacity var(--bp-duration-slow) var(--bp-ease-out);
|
|
3076
|
+
pointer-events: none;
|
|
3077
|
+
}
|
|
3078
|
+
:where(.bp-gallery__zoom) {
|
|
3079
|
+
position: absolute;
|
|
3080
|
+
inset: auto var(--bp-space-2) var(--bp-space-2) auto;
|
|
3081
|
+
display: inline-flex;
|
|
3082
|
+
align-items: center;
|
|
3083
|
+
justify-content: center;
|
|
3084
|
+
width: 28px;
|
|
3085
|
+
height: 28px;
|
|
3086
|
+
border-radius: var(--bp-radius-0);
|
|
3087
|
+
background: var(--bp-paper);
|
|
3088
|
+
color: var(--bp-text-secondary);
|
|
3089
|
+
box-shadow: var(--bp-shadow-pop);
|
|
3090
|
+
opacity: 0;
|
|
3091
|
+
transform: translateY(4px);
|
|
3092
|
+
transition:
|
|
3093
|
+
opacity var(--bp-duration-fast) var(--bp-ease-out),
|
|
3094
|
+
transform var(--bp-duration-fast) var(--bp-ease-out);
|
|
3095
|
+
pointer-events: none;
|
|
3096
|
+
}
|
|
3097
|
+
:where(.bp-gallery__zoom svg) {
|
|
3098
|
+
width: 16px;
|
|
3099
|
+
height: 16px;
|
|
3100
|
+
}
|
|
3101
|
+
/* Reveal true color on hover or keyboard focus. */
|
|
3102
|
+
:where(.bp-gallery__item:hover, .bp-gallery__item:focus-visible)
|
|
3103
|
+
:where(.bp-gallery__img) {
|
|
3104
|
+
filter: none;
|
|
3105
|
+
transform: scale(1.03);
|
|
3106
|
+
}
|
|
3107
|
+
:where(.bp-gallery__item:hover, .bp-gallery__item:focus-visible)
|
|
3108
|
+
:where(.bp-gallery__wash) {
|
|
3109
|
+
opacity: 0;
|
|
3110
|
+
}
|
|
3111
|
+
:where(.bp-gallery__item:hover, .bp-gallery__item:focus-visible)
|
|
3112
|
+
:where(.bp-gallery__zoom) {
|
|
3113
|
+
opacity: 1;
|
|
3114
|
+
transform: translateY(0);
|
|
3115
|
+
}
|
|
3116
|
+
:where(.bp-gallery__item:focus-visible) :where(.bp-gallery__thumb) {
|
|
3117
|
+
outline: 2px solid var(--bp-ink);
|
|
3118
|
+
outline-offset: 2px;
|
|
3119
|
+
}
|
|
3120
|
+
:where(.bp-gallery__caption) {
|
|
3121
|
+
font-family: var(--bp-mono);
|
|
3122
|
+
font-size: var(--bp-label-md);
|
|
3123
|
+
letter-spacing: var(--bp-label-md-ls);
|
|
3124
|
+
color: var(--bp-text-secondary);
|
|
3125
|
+
overflow: hidden;
|
|
3126
|
+
text-overflow: ellipsis;
|
|
3127
|
+
white-space: nowrap;
|
|
3128
|
+
}
|
|
3129
|
+
|
|
3130
|
+
/* The lightbox is appended to <body> by the runtime; hidden until open. */
|
|
3131
|
+
:where(.bp-lightbox) {
|
|
3132
|
+
/* Scrim inset and the room reserved for the caption row below the
|
|
3133
|
+
image, so a portrait image taller than the viewport scales down
|
|
3134
|
+
instead of pushing its caption off-screen. */
|
|
3135
|
+
--bp-lightbox-pad: clamp(var(--bp-space-4), 4vw, var(--bp-space-7));
|
|
3136
|
+
--bp-lightbox-meta: calc(var(--bp-space-3) + var(--bp-space-5));
|
|
3137
|
+
position: fixed;
|
|
3138
|
+
inset: 0;
|
|
3139
|
+
z-index: 300;
|
|
3140
|
+
display: none;
|
|
3141
|
+
/* Side columns reserve the prev/next controls; the figure rides the
|
|
3142
|
+
centered middle column and the single 1fr row fills the height so
|
|
3143
|
+
the image is centered on both axes. */
|
|
3144
|
+
grid-template-columns: auto minmax(0, 1fr) auto;
|
|
3145
|
+
grid-template-rows: minmax(0, 1fr);
|
|
3146
|
+
align-items: center;
|
|
3147
|
+
justify-items: center;
|
|
3148
|
+
gap: var(--bp-space-3);
|
|
3149
|
+
padding: var(--bp-lightbox-pad);
|
|
3150
|
+
background-color: var(--bp-scrim);
|
|
3151
|
+
background-image: var(--bp-hatch);
|
|
3152
|
+
}
|
|
3153
|
+
:where(.bp-lightbox.is-open) {
|
|
3154
|
+
display: grid;
|
|
3155
|
+
}
|
|
3156
|
+
:where(.bp-lightbox__figure) {
|
|
3157
|
+
grid-column: 2;
|
|
3158
|
+
display: flex;
|
|
3159
|
+
flex-direction: column;
|
|
3160
|
+
align-items: center;
|
|
3161
|
+
justify-content: center;
|
|
3162
|
+
gap: var(--bp-space-3);
|
|
3163
|
+
margin: 0;
|
|
3164
|
+
min-width: 0;
|
|
3165
|
+
min-height: 0;
|
|
3166
|
+
max-width: 100%;
|
|
3167
|
+
max-height: 100%;
|
|
3168
|
+
}
|
|
3169
|
+
:where(.bp-lightbox__img) {
|
|
3170
|
+
display: block;
|
|
3171
|
+
/* Width is bounded by the centered column; height is bounded by the
|
|
3172
|
+
viewport minus the scrim inset and the reserved caption row. With
|
|
3173
|
+
both maxes set and intrinsic sizing left auto, the browser scales
|
|
3174
|
+
the image down while preserving its aspect ratio. */
|
|
3175
|
+
width: auto;
|
|
3176
|
+
height: auto;
|
|
3177
|
+
max-width: 100%;
|
|
3178
|
+
max-height: calc(100dvh - 2 * var(--bp-lightbox-pad) - var(--bp-lightbox-meta));
|
|
3179
|
+
object-fit: contain;
|
|
3180
|
+
border: var(--bp-stroke) solid var(--bp-ink-line);
|
|
3181
|
+
border-radius: var(--bp-radius-0);
|
|
3182
|
+
background: var(--bp-paper);
|
|
3183
|
+
box-shadow: var(--bp-shadow-pop);
|
|
3184
|
+
}
|
|
3185
|
+
:where(.bp-lightbox__meta) {
|
|
3186
|
+
display: flex;
|
|
3187
|
+
align-items: baseline;
|
|
3188
|
+
gap: var(--bp-space-3);
|
|
3189
|
+
max-width: 100%;
|
|
3190
|
+
font-family: var(--bp-mono);
|
|
3191
|
+
font-size: var(--bp-label-md);
|
|
3192
|
+
letter-spacing: var(--bp-label-md-ls);
|
|
3193
|
+
color: var(--bp-paper);
|
|
3194
|
+
}
|
|
3195
|
+
:where(.bp-lightbox__kicker) {
|
|
3196
|
+
text-transform: uppercase;
|
|
3197
|
+
opacity: 0.7;
|
|
3198
|
+
}
|
|
3199
|
+
:where(.bp-lightbox__counter) {
|
|
3200
|
+
opacity: 0.7;
|
|
3201
|
+
}
|
|
3202
|
+
:where(.bp-lightbox__caption) {
|
|
3203
|
+
min-width: 0;
|
|
3204
|
+
overflow: hidden;
|
|
3205
|
+
text-overflow: ellipsis;
|
|
3206
|
+
white-space: nowrap;
|
|
3207
|
+
}
|
|
3208
|
+
:where(.bp-lightbox__close) {
|
|
3209
|
+
position: absolute;
|
|
3210
|
+
inset: var(--bp-space-4) var(--bp-space-4) auto auto;
|
|
3211
|
+
display: inline-flex;
|
|
3212
|
+
align-items: center;
|
|
3213
|
+
justify-content: center;
|
|
3214
|
+
width: 40px;
|
|
3215
|
+
height: 40px;
|
|
3216
|
+
padding: 0;
|
|
3217
|
+
border: var(--bp-stroke) solid var(--bp-edge);
|
|
3218
|
+
border-radius: var(--bp-radius-0);
|
|
3219
|
+
background: var(--bp-paper);
|
|
3220
|
+
color: var(--bp-text-secondary);
|
|
3221
|
+
cursor: pointer;
|
|
3222
|
+
}
|
|
3223
|
+
:where(.bp-lightbox__nav) {
|
|
3224
|
+
display: inline-flex;
|
|
3225
|
+
align-items: center;
|
|
3226
|
+
justify-content: center;
|
|
3227
|
+
width: 44px;
|
|
3228
|
+
height: 44px;
|
|
3229
|
+
padding: 0;
|
|
3230
|
+
border: var(--bp-stroke) solid var(--bp-edge);
|
|
3231
|
+
border-radius: var(--bp-radius-0);
|
|
3232
|
+
background: var(--bp-paper);
|
|
3233
|
+
color: var(--bp-text-secondary);
|
|
3234
|
+
cursor: pointer;
|
|
3235
|
+
}
|
|
3236
|
+
:where(.bp-lightbox__nav--prev) {
|
|
3237
|
+
grid-column: 1;
|
|
3238
|
+
}
|
|
3239
|
+
:where(.bp-lightbox__nav--next) {
|
|
3240
|
+
grid-column: 3;
|
|
3241
|
+
}
|
|
3242
|
+
:where(.bp-lightbox.is-single) :where(.bp-lightbox__nav) {
|
|
3243
|
+
visibility: hidden;
|
|
3244
|
+
}
|
|
3245
|
+
:where(.bp-lightbox__close:hover, .bp-lightbox__nav:hover) {
|
|
3246
|
+
color: var(--bp-text);
|
|
3247
|
+
border-color: var(--bp-ink-line);
|
|
3248
|
+
}
|
|
3249
|
+
:where(.bp-lightbox__close:focus-visible, .bp-lightbox__nav:focus-visible) {
|
|
3250
|
+
outline: 2px solid var(--bp-paper);
|
|
3251
|
+
outline-offset: 2px;
|
|
3252
|
+
}
|
|
3253
|
+
:where(.bp-lightbox__close svg) {
|
|
3254
|
+
width: 18px;
|
|
3255
|
+
height: 18px;
|
|
3256
|
+
}
|
|
3257
|
+
:where(.bp-lightbox__nav svg) {
|
|
3258
|
+
width: 22px;
|
|
3259
|
+
height: 22px;
|
|
3260
|
+
}
|
|
3261
|
+
}
|
|
3262
|
+
|
|
3263
|
+
/* Stored Blueprint shell contracts. New documents use bp-* components. */
|
|
3264
|
+
@layer components {
|
|
3265
|
+
:where(.sidebar) {
|
|
3266
|
+
position: fixed;
|
|
3267
|
+
inset: 0 auto 0 0;
|
|
3268
|
+
width: var(--sidebar);
|
|
3269
|
+
height: 100vh;
|
|
3270
|
+
overflow-y: auto;
|
|
3271
|
+
padding: 34px 20px 34px 26px;
|
|
3272
|
+
z-index: 100;
|
|
3273
|
+
}
|
|
3274
|
+
:where(.sidebar-head) {
|
|
3275
|
+
padding-bottom: 16px;
|
|
3276
|
+
border-bottom: 1px solid var(--edge);
|
|
3277
|
+
margin-bottom: 16px;
|
|
3278
|
+
}
|
|
3279
|
+
:where(.sidebar-title) {
|
|
3280
|
+
font: 500 11px/1.4 var(--mono);
|
|
3281
|
+
letter-spacing: 0.12em;
|
|
3282
|
+
text-transform: uppercase;
|
|
3283
|
+
color: var(--ink);
|
|
3284
|
+
}
|
|
3285
|
+
:where(.sidebar-doc) {
|
|
3286
|
+
font: 400 10px/1.4 var(--mono);
|
|
3287
|
+
letter-spacing: 0.08em;
|
|
3288
|
+
text-transform: uppercase;
|
|
3289
|
+
color: var(--text-secondary);
|
|
3290
|
+
margin-top: 6px;
|
|
3291
|
+
}
|
|
3292
|
+
:where(.sidebar ul) {
|
|
3293
|
+
list-style: none;
|
|
3294
|
+
margin: 0;
|
|
3295
|
+
padding: 0;
|
|
3296
|
+
counter-reset: navsec;
|
|
3297
|
+
display: flex;
|
|
3298
|
+
flex-direction: column;
|
|
3299
|
+
}
|
|
3300
|
+
:where(.sidebar li) {
|
|
3301
|
+
margin: 0;
|
|
3302
|
+
padding: 0;
|
|
3303
|
+
}
|
|
3304
|
+
:where(.sidebar a) {
|
|
3305
|
+
position: relative;
|
|
3306
|
+
display: block;
|
|
3307
|
+
font: 400 12px/1.35 var(--sans);
|
|
3308
|
+
color: var(--text-secondary);
|
|
3309
|
+
text-decoration: none;
|
|
3310
|
+
padding: 7px 10px 7px 36px;
|
|
3311
|
+
}
|
|
3312
|
+
:where(.sidebar a)::before {
|
|
3313
|
+
counter-increment: navsec;
|
|
3314
|
+
content: counter(navsec, decimal-leading-zero);
|
|
3315
|
+
position: absolute;
|
|
3316
|
+
left: 10px;
|
|
3317
|
+
top: 8px;
|
|
3318
|
+
font: 400 10px/1 var(--mono);
|
|
3319
|
+
letter-spacing: 0.06em;
|
|
3320
|
+
color: var(--ink-faint);
|
|
3321
|
+
}
|
|
3322
|
+
:where(.sidebar a:hover, .sidebar a[aria-current="location"]) {
|
|
3323
|
+
color: var(--ink);
|
|
3324
|
+
background: var(--fill-amb);
|
|
3325
|
+
}
|
|
3326
|
+
:where(.sidebar a[aria-current="location"])::after {
|
|
3327
|
+
content: "";
|
|
3328
|
+
position: absolute;
|
|
3329
|
+
inset: 0 auto 0 0;
|
|
3330
|
+
width: 2px;
|
|
3331
|
+
background: var(--ink);
|
|
3332
|
+
}
|
|
3333
|
+
:where(.page-body) {
|
|
3334
|
+
margin-left: var(--sidebar);
|
|
3335
|
+
}
|
|
3336
|
+
:where(.sheet) {
|
|
3337
|
+
margin: 0;
|
|
3338
|
+
min-height: 100vh;
|
|
3339
|
+
background: var(--paper);
|
|
3340
|
+
border-left: 1px solid var(--edge);
|
|
3341
|
+
}
|
|
3342
|
+
:where(.hero) {
|
|
3343
|
+
padding: 48px 56px 36px;
|
|
2383
3344
|
border-bottom: 1px solid var(--ink-line);
|
|
2384
3345
|
font-family: var(--sans);
|
|
2385
3346
|
}
|
|
2386
|
-
:where(.hero-meta) {
|
|
2387
|
-
font: 400 11px/1.4 var(--mono);
|
|
2388
|
-
letter-spacing: 0.14em;
|
|
2389
|
-
text-transform: uppercase;
|
|
2390
|
-
color: var(--ink-soft);
|
|
2391
|
-
margin-bottom: 16px;
|
|
3347
|
+
:where(.hero-meta) {
|
|
3348
|
+
font: 400 11px/1.4 var(--mono);
|
|
3349
|
+
letter-spacing: 0.14em;
|
|
3350
|
+
text-transform: uppercase;
|
|
3351
|
+
color: var(--ink-soft);
|
|
3352
|
+
margin-bottom: 16px;
|
|
3353
|
+
}
|
|
3354
|
+
:where(.hero h1) {
|
|
3355
|
+
font: 600 24px/32px var(--sans);
|
|
3356
|
+
letter-spacing: -0.48px;
|
|
3357
|
+
margin: 10px 0 14px;
|
|
3358
|
+
}
|
|
3359
|
+
:where(.hero-sub) {
|
|
3360
|
+
font: 400 14px/20px var(--serif);
|
|
3361
|
+
text-align: justify;
|
|
3362
|
+
hyphens: auto;
|
|
3363
|
+
}
|
|
3364
|
+
:where(.title-block) {
|
|
3365
|
+
margin-top: 34px;
|
|
3366
|
+
border: 1px solid var(--ink-line);
|
|
3367
|
+
display: flex;
|
|
3368
|
+
flex-wrap: wrap;
|
|
3369
|
+
}
|
|
3370
|
+
:where(.tb-cell) {
|
|
3371
|
+
flex: 0 0 auto;
|
|
3372
|
+
padding: 10px 20px 11px 14px;
|
|
3373
|
+
border-right: 1px solid var(--ink-line);
|
|
3374
|
+
}
|
|
3375
|
+
:where(.tb-cell--grow) {
|
|
3376
|
+
flex: 1 1 auto;
|
|
3377
|
+
}
|
|
3378
|
+
:where(.tb-cell:last-child) {
|
|
3379
|
+
border-right: 0;
|
|
3380
|
+
}
|
|
3381
|
+
:where(.tb-label) {
|
|
3382
|
+
font: 400 10px/1.4 var(--mono);
|
|
3383
|
+
letter-spacing: 0.1em;
|
|
3384
|
+
text-transform: uppercase;
|
|
3385
|
+
color: var(--ink-soft);
|
|
3386
|
+
margin-bottom: 3px;
|
|
3387
|
+
}
|
|
3388
|
+
:where(.tb-value) {
|
|
3389
|
+
font: 400 12px/1.4 var(--sans);
|
|
3390
|
+
color: var(--text);
|
|
3391
|
+
}
|
|
3392
|
+
:where(.body) {
|
|
3393
|
+
padding: 8px 56px 56px;
|
|
3394
|
+
}
|
|
3395
|
+
:where(.prose) {
|
|
3396
|
+
max-width: var(--content);
|
|
3397
|
+
margin-inline: auto;
|
|
3398
|
+
}
|
|
3399
|
+
:where(.oq) {
|
|
3400
|
+
display: flex;
|
|
3401
|
+
gap: 12px;
|
|
3402
|
+
padding: 10px 0;
|
|
3403
|
+
border-bottom: 1px solid var(--edge);
|
|
3404
|
+
}
|
|
3405
|
+
:where(.oq-tag) {
|
|
3406
|
+
font: 400 10px/1.4 var(--mono);
|
|
3407
|
+
letter-spacing: 0.08em;
|
|
3408
|
+
text-transform: uppercase;
|
|
3409
|
+
color: var(--ink);
|
|
3410
|
+
border: 1px solid var(--ink-faint);
|
|
3411
|
+
padding: 2px 7px;
|
|
3412
|
+
height: max-content;
|
|
3413
|
+
white-space: nowrap;
|
|
3414
|
+
}
|
|
3415
|
+
:where(.assumption .oq-tag) {
|
|
3416
|
+
color: var(--text-secondary);
|
|
3417
|
+
border-color: var(--edge);
|
|
3418
|
+
}
|
|
3419
|
+
:where(.states) {
|
|
3420
|
+
display: grid;
|
|
3421
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
3422
|
+
border: 1px solid var(--edge);
|
|
3423
|
+
margin: 20px 0;
|
|
3424
|
+
}
|
|
3425
|
+
:where(.state) {
|
|
3426
|
+
padding: 14px 16px;
|
|
3427
|
+
border-right: 1px solid var(--edge);
|
|
3428
|
+
border-bottom: 1px solid var(--edge);
|
|
3429
|
+
}
|
|
3430
|
+
:where(.state:nth-child(2n)) {
|
|
3431
|
+
border-right: 0;
|
|
3432
|
+
}
|
|
3433
|
+
:where(.state-name, .states-label) {
|
|
3434
|
+
font: 400 10px/1.4 var(--mono);
|
|
3435
|
+
letter-spacing: 0.08em;
|
|
3436
|
+
text-transform: uppercase;
|
|
3437
|
+
color: var(--ink);
|
|
3438
|
+
}
|
|
3439
|
+
:where(.state-name) {
|
|
3440
|
+
margin-bottom: 6px;
|
|
3441
|
+
}
|
|
3442
|
+
:where(.state-desc) {
|
|
3443
|
+
font-size: 13px;
|
|
3444
|
+
line-height: 18px;
|
|
3445
|
+
color: var(--text-secondary);
|
|
3446
|
+
}
|
|
3447
|
+
:where(.states-label) {
|
|
3448
|
+
margin-top: 26px;
|
|
3449
|
+
}
|
|
3450
|
+
:where(.states-label + .states) {
|
|
3451
|
+
margin-top: 10px;
|
|
3452
|
+
}
|
|
3453
|
+
:where(.figure) {
|
|
3454
|
+
width: fit-content;
|
|
3455
|
+
max-width: 100%;
|
|
3456
|
+
margin: 32px auto;
|
|
3457
|
+
}
|
|
3458
|
+
:where(.figure svg[viewBox]) {
|
|
3459
|
+
display: block;
|
|
3460
|
+
width: auto;
|
|
3461
|
+
max-width: min(100%, var(--bp-diagram-w));
|
|
3462
|
+
height: auto;
|
|
3463
|
+
}
|
|
3464
|
+
:where(.figure svg:not([viewBox])) {
|
|
3465
|
+
display: block;
|
|
3466
|
+
width: auto;
|
|
3467
|
+
max-width: 100%;
|
|
3468
|
+
height: auto;
|
|
3469
|
+
}
|
|
3470
|
+
:where(.fig-cap) {
|
|
3471
|
+
font: 400 10px/1.4 var(--mono);
|
|
3472
|
+
letter-spacing: 0.06em;
|
|
3473
|
+
text-transform: uppercase;
|
|
3474
|
+
color: var(--text-secondary);
|
|
3475
|
+
text-align: center;
|
|
3476
|
+
margin-top: 14px;
|
|
3477
|
+
}
|
|
3478
|
+
}
|
|
3479
|
+
|
|
3480
|
+
/* =====================================================================
|
|
3481
|
+
@layer components — <bp-workplan>
|
|
3482
|
+
|
|
3483
|
+
A live "work plan": typed, dependent tasks that resolve into waves,
|
|
3484
|
+
rendered four ways (list · gantt · kanban · swimlanes). Light-DOM,
|
|
3485
|
+
token-only, theme-aware. Chrome is ink; the only non-ink token is
|
|
3486
|
+
--bp-positive for a passing/approved PR. The element renders only
|
|
3487
|
+
<div>/<span> for structure, so the base layer's semantic-element
|
|
3488
|
+
styling never applies — no resets needed.
|
|
3489
|
+
===================================================================== */
|
|
3490
|
+
@layer components {
|
|
3491
|
+
:where(.bp-workplan) {
|
|
3492
|
+
font-family: var(--bp-sans);
|
|
3493
|
+
color: var(--bp-text);
|
|
3494
|
+
container-type: inline-size;
|
|
3495
|
+
}
|
|
3496
|
+
|
|
3497
|
+
/* ---- plan header + summary stats ---------------------------- */
|
|
3498
|
+
:where(.wp-head) {
|
|
3499
|
+
display: flex;
|
|
3500
|
+
flex-wrap: wrap;
|
|
3501
|
+
gap: var(--bp-space-3);
|
|
3502
|
+
align-items: flex-end;
|
|
3503
|
+
justify-content: space-between;
|
|
3504
|
+
padding-bottom: var(--bp-space-3);
|
|
3505
|
+
margin-bottom: var(--bp-space-3);
|
|
3506
|
+
border-bottom: 1px solid var(--bp-ink-line);
|
|
3507
|
+
}
|
|
3508
|
+
:where(.wp-head__name) {
|
|
3509
|
+
font-size: var(--bp-text-h3);
|
|
3510
|
+
line-height: var(--bp-lh-h3);
|
|
3511
|
+
font-weight: var(--bp-weight-strong);
|
|
3512
|
+
margin: 0;
|
|
3513
|
+
}
|
|
3514
|
+
:where(.wp-head__sub) {
|
|
3515
|
+
font-size: var(--bp-text-small);
|
|
3516
|
+
color: var(--bp-text-secondary);
|
|
3517
|
+
margin: 2px 0 0;
|
|
3518
|
+
}
|
|
3519
|
+
:where(.wp-stats) {
|
|
3520
|
+
display: flex;
|
|
3521
|
+
gap: var(--bp-space-4);
|
|
3522
|
+
margin: 0;
|
|
3523
|
+
}
|
|
3524
|
+
:where(.wp-stat) { text-align: right; }
|
|
3525
|
+
:where(.wp-stat__k) {
|
|
3526
|
+
display: block;
|
|
3527
|
+
font-family: var(--bp-mono);
|
|
3528
|
+
font-size: var(--bp-label-sm);
|
|
3529
|
+
letter-spacing: var(--bp-label-sm-ls);
|
|
3530
|
+
text-transform: uppercase;
|
|
3531
|
+
color: var(--bp-text-secondary);
|
|
3532
|
+
}
|
|
3533
|
+
:where(.wp-stat__v) {
|
|
3534
|
+
display: block;
|
|
3535
|
+
margin-top: 2px;
|
|
3536
|
+
font-variant-numeric: tabular-nums;
|
|
3537
|
+
font-size: var(--bp-text-h4);
|
|
3538
|
+
font-weight: var(--bp-weight-medium);
|
|
3539
|
+
}
|
|
3540
|
+
|
|
3541
|
+
/* ---- toolbar: built-in view selector + gantt unit toggle ---- */
|
|
3542
|
+
:where(.wp-toolbar) {
|
|
3543
|
+
display: flex;
|
|
3544
|
+
flex-wrap: wrap;
|
|
3545
|
+
gap: var(--bp-space-3);
|
|
3546
|
+
align-items: center;
|
|
3547
|
+
justify-content: space-between;
|
|
3548
|
+
margin-bottom: var(--bp-space-3);
|
|
3549
|
+
}
|
|
3550
|
+
:where(.wp-modes) { display: flex; flex-wrap: wrap; gap: var(--bp-space-1); }
|
|
3551
|
+
:where(.wp-modes--unit) { margin-left: auto; }
|
|
3552
|
+
:where(.wp-modes__btn) {
|
|
3553
|
+
font: inherit;
|
|
3554
|
+
font-size: var(--bp-text-small);
|
|
3555
|
+
line-height: 1;
|
|
3556
|
+
padding: var(--bp-space-1) var(--bp-space-3);
|
|
3557
|
+
border: 1px solid var(--bp-edge);
|
|
3558
|
+
border-radius: var(--bp-radius-0);
|
|
3559
|
+
background: var(--bp-paper);
|
|
3560
|
+
color: var(--bp-text-secondary);
|
|
3561
|
+
cursor: pointer;
|
|
3562
|
+
}
|
|
3563
|
+
:where(.wp-modes__btn):hover { background: var(--bp-fill-amb); }
|
|
3564
|
+
:where(.wp-modes__btn[aria-selected="true"]) {
|
|
3565
|
+
border-color: var(--bp-ink);
|
|
3566
|
+
color: var(--bp-text);
|
|
3567
|
+
background: var(--bp-fill-amb);
|
|
3568
|
+
}
|
|
3569
|
+
|
|
3570
|
+
/* ---- type badge (inline mono, not a pill) ------------------- */
|
|
3571
|
+
:where(.wp-type) {
|
|
3572
|
+
display: inline-flex;
|
|
3573
|
+
align-items: center;
|
|
3574
|
+
gap: 5px;
|
|
3575
|
+
font-family: var(--bp-mono);
|
|
3576
|
+
font-size: var(--bp-label-md);
|
|
3577
|
+
letter-spacing: var(--bp-label-md-ls);
|
|
3578
|
+
text-transform: uppercase;
|
|
3579
|
+
color: var(--bp-text-secondary);
|
|
3580
|
+
white-space: nowrap;
|
|
3581
|
+
}
|
|
3582
|
+
:where(.wp-type__glyph) { color: var(--bp-ink-soft); flex: none; }
|
|
3583
|
+
:where(.wp-type__label) { line-height: 1; }
|
|
3584
|
+
|
|
3585
|
+
/* ---- phase dot (status without color) ----------------------- */
|
|
3586
|
+
:where(.wp-dot) {
|
|
3587
|
+
--d: 10px;
|
|
3588
|
+
width: var(--d);
|
|
3589
|
+
height: var(--d);
|
|
3590
|
+
border-radius: var(--bp-radius-0);
|
|
3591
|
+
flex: none;
|
|
3592
|
+
box-sizing: border-box;
|
|
3593
|
+
}
|
|
3594
|
+
:where(.wp-dot--done) { background: var(--bp-ink); }
|
|
3595
|
+
:where(.wp-dot--active) {
|
|
3596
|
+
background: var(--bp-ink);
|
|
3597
|
+
box-shadow: 0 0 0 2px var(--bp-paper), 0 0 0 3px var(--bp-ink);
|
|
3598
|
+
}
|
|
3599
|
+
:where(.wp-dot--ready) {
|
|
3600
|
+
background: oklch(0 0 0 / 0);
|
|
3601
|
+
border: 1.5px solid var(--bp-ink-soft);
|
|
3602
|
+
}
|
|
3603
|
+
:where(.wp-dot--blocked) {
|
|
3604
|
+
background: oklch(0 0 0 / 0);
|
|
3605
|
+
border: 1.5px dashed var(--bp-ink-faint);
|
|
3606
|
+
}
|
|
3607
|
+
|
|
3608
|
+
/* ---- PR status — inline mono text, NO pill ------------------ */
|
|
3609
|
+
:where(.wp-pr) {
|
|
3610
|
+
display: inline-flex;
|
|
3611
|
+
align-items: center;
|
|
3612
|
+
gap: 6px;
|
|
3613
|
+
font-family: var(--bp-mono);
|
|
3614
|
+
font-size: var(--bp-label-md);
|
|
3615
|
+
letter-spacing: 0.01em;
|
|
3616
|
+
color: var(--bp-text-secondary);
|
|
3617
|
+
white-space: nowrap;
|
|
3618
|
+
min-width: 0;
|
|
3619
|
+
}
|
|
3620
|
+
:where(.wp-pr__glyph) { flex: none; width: 13px; height: 13px; }
|
|
3621
|
+
:where(.wp-pr__num) { color: var(--bp-text); font-weight: var(--bp-weight-medium); }
|
|
3622
|
+
:where(.wp-pr__ci) { color: var(--bp-text-secondary); }
|
|
3623
|
+
:where(.wp-pr__diff) { color: var(--bp-text-secondary); }
|
|
3624
|
+
:where(.wp-pr__add) { color: var(--bp-positive); }
|
|
3625
|
+
|
|
3626
|
+
:where(.wp-pr--passed .wp-pr__ci),
|
|
3627
|
+
:where(.wp-pr--approved .wp-pr__ci) { color: var(--bp-positive); }
|
|
3628
|
+
:where(.wp-pr--failed .wp-pr__glyph) { color: var(--bp-text); stroke-width: 1.8; }
|
|
3629
|
+
:where(.wp-pr--running .wp-pr__glyph) {
|
|
3630
|
+
color: var(--bp-ink-soft);
|
|
3631
|
+
animation: wp-spin var(--bp-duration-spin) var(--bp-ease-linear) infinite;
|
|
3632
|
+
}
|
|
3633
|
+
@keyframes wp-spin { to { transform: rotate(360deg); } }
|
|
3634
|
+
@media (prefers-reduced-motion: reduce) {
|
|
3635
|
+
:where(.wp-pr--running .wp-pr__glyph) { animation: none; }
|
|
3636
|
+
}
|
|
3637
|
+
|
|
3638
|
+
/* ---- owner mark — agent (square + spark) vs human (circle) -- */
|
|
3639
|
+
:where(.wp-owner) {
|
|
3640
|
+
display: inline-grid;
|
|
3641
|
+
place-items: center;
|
|
3642
|
+
width: 22px;
|
|
3643
|
+
height: 22px;
|
|
3644
|
+
flex: none;
|
|
3645
|
+
font-family: var(--bp-mono);
|
|
3646
|
+
font-size: 9px;
|
|
3647
|
+
letter-spacing: 0.02em;
|
|
3648
|
+
}
|
|
3649
|
+
:where(.wp-owner--human) {
|
|
3650
|
+
border-radius: var(--bp-radius-0);
|
|
3651
|
+
background: var(--bp-fill-hi);
|
|
3652
|
+
border: 1px solid var(--bp-edge);
|
|
3653
|
+
color: var(--bp-text-secondary);
|
|
3654
|
+
}
|
|
3655
|
+
:where(.wp-owner--agent) {
|
|
3656
|
+
border-radius: var(--bp-radius-0);
|
|
3657
|
+
border: 1px solid var(--bp-ink-line);
|
|
3658
|
+
color: var(--bp-text-secondary);
|
|
3659
|
+
}
|
|
3660
|
+
:where(.wp-owner__glyph) { width: 12px; height: 12px; }
|
|
3661
|
+
|
|
3662
|
+
/* ---- waiting note — quiet inline text ----------------------- */
|
|
3663
|
+
:where(.wp-wait) {
|
|
3664
|
+
display: block;
|
|
3665
|
+
font-size: var(--bp-text-small);
|
|
3666
|
+
color: var(--bp-text-secondary);
|
|
3667
|
+
white-space: nowrap;
|
|
3668
|
+
overflow: hidden;
|
|
3669
|
+
text-overflow: ellipsis;
|
|
3670
|
+
}
|
|
3671
|
+
|
|
3672
|
+
/* greyed-out-until-ready treatment, shared across views */
|
|
3673
|
+
:where([data-locked="true"]) { opacity: 0.66; }
|
|
3674
|
+
|
|
3675
|
+
/* ---- LIST view ---------------------------------------------- */
|
|
3676
|
+
:where(.wp-view--list) { display: grid; gap: var(--bp-space-3); }
|
|
3677
|
+
:where(.wp-wave__head) {
|
|
3678
|
+
display: flex;
|
|
3679
|
+
align-items: baseline;
|
|
3680
|
+
justify-content: space-between;
|
|
3681
|
+
gap: var(--bp-space-2);
|
|
3682
|
+
margin-bottom: 6px;
|
|
3683
|
+
padding: 0 2px;
|
|
3684
|
+
}
|
|
3685
|
+
:where(.wp-wave__no),
|
|
3686
|
+
:where(.wp-wave__count) {
|
|
3687
|
+
font-family: var(--bp-mono);
|
|
3688
|
+
font-size: var(--bp-label-md);
|
|
3689
|
+
letter-spacing: var(--bp-label-md-ls);
|
|
3690
|
+
text-transform: uppercase;
|
|
3691
|
+
}
|
|
3692
|
+
:where(.wp-wave__no) { color: var(--bp-text); }
|
|
3693
|
+
:where(.wp-wave__count) { color: var(--bp-text-secondary); }
|
|
3694
|
+
:where(.wp-row) {
|
|
3695
|
+
display: grid;
|
|
3696
|
+
grid-template-columns: auto 84px minmax(0, 1fr) auto auto;
|
|
3697
|
+
align-items: center;
|
|
3698
|
+
gap: var(--bp-space-3);
|
|
3699
|
+
padding: 11px var(--bp-space-3);
|
|
3700
|
+
border: 1px solid var(--bp-edge);
|
|
3701
|
+
border-top: none;
|
|
3702
|
+
background: var(--bp-paper);
|
|
3703
|
+
}
|
|
3704
|
+
:where(.wp-row:first-child) {
|
|
3705
|
+
border-top: 1px solid var(--bp-edge);
|
|
3706
|
+
border-radius: var(--bp-radius-0) var(--bp-radius-0) 0 0;
|
|
3707
|
+
}
|
|
3708
|
+
:where(.wp-row:last-child) { border-radius: 0 0 var(--bp-radius-0) var(--bp-radius-0); }
|
|
3709
|
+
:where(.wp-row__main) { position: relative; min-width: 0; }
|
|
3710
|
+
:where(.wp-row__name) {
|
|
3711
|
+
display: block;
|
|
3712
|
+
font-size: var(--bp-text-body);
|
|
3713
|
+
font-weight: var(--bp-weight-medium);
|
|
3714
|
+
white-space: nowrap;
|
|
3715
|
+
overflow: hidden;
|
|
3716
|
+
text-overflow: ellipsis;
|
|
3717
|
+
}
|
|
3718
|
+
/* Waiting note overlays the name and is revealed on hover, so a locked
|
|
3719
|
+
row reads as its title at rest and its blockers on demand. */
|
|
3720
|
+
:where(.wp-row__main .wp-wait) {
|
|
3721
|
+
position: absolute;
|
|
3722
|
+
inset: 0;
|
|
3723
|
+
display: flex;
|
|
3724
|
+
align-items: center;
|
|
3725
|
+
margin: 0;
|
|
3726
|
+
background: var(--bp-paper);
|
|
3727
|
+
opacity: 0;
|
|
3728
|
+
pointer-events: none;
|
|
3729
|
+
transition: opacity var(--bp-duration-fast) var(--bp-ease-out);
|
|
2392
3730
|
}
|
|
2393
|
-
:where(.
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
3731
|
+
:where(.wp-row[data-locked="true"]:hover .wp-row__name) { opacity: 0; }
|
|
3732
|
+
:where(.wp-row[data-locked="true"]:hover .wp-row__main .wp-wait) { opacity: 1; }
|
|
3733
|
+
:where(.wp-row--done .wp-row__name) {
|
|
3734
|
+
color: var(--bp-text-secondary);
|
|
3735
|
+
text-decoration: line-through;
|
|
3736
|
+
text-decoration-color: var(--bp-ink-faint);
|
|
2397
3737
|
}
|
|
2398
|
-
:where(.
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
3738
|
+
:where(.wp-row__pr) { justify-self: end; }
|
|
3739
|
+
|
|
3740
|
+
/* ---- KANBAN view — min-width columns, horizontal scroll ----- */
|
|
3741
|
+
:where(.wp-view--kanban) {
|
|
3742
|
+
display: grid;
|
|
3743
|
+
grid-auto-flow: column;
|
|
3744
|
+
grid-auto-columns: minmax(216px, 1fr);
|
|
3745
|
+
gap: var(--bp-space-3);
|
|
3746
|
+
align-items: start;
|
|
3747
|
+
overflow-x: auto;
|
|
3748
|
+
padding-bottom: var(--bp-space-2);
|
|
2402
3749
|
}
|
|
2403
|
-
:where(.
|
|
2404
|
-
|
|
2405
|
-
border: 1px solid var(--
|
|
3750
|
+
:where(.wp-col) {
|
|
3751
|
+
background: var(--bp-bg);
|
|
3752
|
+
border: 1px solid var(--bp-edge);
|
|
3753
|
+
border-radius: var(--bp-radius-0);
|
|
3754
|
+
padding: var(--bp-space-2);
|
|
2406
3755
|
display: flex;
|
|
2407
|
-
flex-
|
|
3756
|
+
flex-direction: column;
|
|
3757
|
+
min-width: 0;
|
|
2408
3758
|
}
|
|
2409
|
-
:where(.
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
3759
|
+
:where(.wp-col__head) {
|
|
3760
|
+
display: flex;
|
|
3761
|
+
align-items: center;
|
|
3762
|
+
justify-content: space-between;
|
|
3763
|
+
padding: 4px var(--bp-space-1) var(--bp-space-2);
|
|
2413
3764
|
}
|
|
2414
|
-
:where(.
|
|
2415
|
-
|
|
3765
|
+
:where(.wp-col__title) {
|
|
3766
|
+
font-family: var(--bp-mono);
|
|
3767
|
+
font-size: var(--bp-label-md);
|
|
3768
|
+
letter-spacing: var(--bp-label-md-ls);
|
|
3769
|
+
text-transform: uppercase;
|
|
3770
|
+
color: var(--bp-text);
|
|
2416
3771
|
}
|
|
2417
|
-
:where(.
|
|
2418
|
-
|
|
3772
|
+
:where(.wp-col__count) {
|
|
3773
|
+
font-family: var(--bp-mono);
|
|
3774
|
+
font-size: var(--bp-label-sm);
|
|
3775
|
+
color: var(--bp-text-secondary);
|
|
3776
|
+
font-variant-numeric: tabular-nums;
|
|
2419
3777
|
}
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
3778
|
+
/* One full-width track — minmax(0,1fr) keeps cards at the column width
|
|
3779
|
+
so nowrap text truncates instead of stretching the card. */
|
|
3780
|
+
:where(.wp-col__body) {
|
|
3781
|
+
display: grid;
|
|
3782
|
+
grid-template-columns: minmax(0, 1fr);
|
|
3783
|
+
gap: var(--bp-space-2);
|
|
3784
|
+
align-content: start;
|
|
3785
|
+
min-width: 0;
|
|
3786
|
+
}
|
|
3787
|
+
:where(.wp-col__empty) {
|
|
3788
|
+
font-family: var(--bp-mono);
|
|
3789
|
+
font-size: var(--bp-label-sm);
|
|
3790
|
+
letter-spacing: var(--bp-label-sm-ls);
|
|
2423
3791
|
text-transform: uppercase;
|
|
2424
|
-
color: var(--ink-
|
|
2425
|
-
margin
|
|
3792
|
+
color: var(--bp-ink-faint);
|
|
3793
|
+
margin: var(--bp-space-1) 0 var(--bp-space-2);
|
|
3794
|
+
padding-left: var(--bp-space-1);
|
|
2426
3795
|
}
|
|
2427
|
-
:where(.
|
|
2428
|
-
|
|
2429
|
-
|
|
3796
|
+
:where(.wp-card) {
|
|
3797
|
+
background: var(--bp-paper);
|
|
3798
|
+
border: 1px solid var(--bp-edge);
|
|
3799
|
+
border-radius: var(--bp-radius-0);
|
|
3800
|
+
padding: 10px var(--bp-space-2);
|
|
3801
|
+
display: grid;
|
|
3802
|
+
grid-template-columns: minmax(0, 1fr);
|
|
3803
|
+
gap: 7px;
|
|
3804
|
+
min-width: 0;
|
|
2430
3805
|
}
|
|
2431
|
-
:where(.
|
|
2432
|
-
|
|
3806
|
+
:where(.wp-card__top) {
|
|
3807
|
+
display: flex;
|
|
3808
|
+
align-items: center;
|
|
3809
|
+
justify-content: space-between;
|
|
2433
3810
|
}
|
|
2434
|
-
:where(.
|
|
2435
|
-
|
|
2436
|
-
|
|
3811
|
+
:where(.wp-card__name) {
|
|
3812
|
+
margin: 0;
|
|
3813
|
+
font-size: var(--bp-text-small);
|
|
3814
|
+
font-weight: var(--bp-weight-medium);
|
|
3815
|
+
line-height: 1.35;
|
|
2437
3816
|
}
|
|
2438
|
-
:where(.
|
|
3817
|
+
:where(.wp-card--done .wp-card__name) { color: var(--bp-text-secondary); }
|
|
3818
|
+
:where(.wp-card__pr) { min-width: 0; overflow: hidden; }
|
|
3819
|
+
:where(.wp-card__pr .wp-pr) { font-size: var(--bp-label-sm); max-width: 100%; }
|
|
3820
|
+
:where(.wp-card__pr .wp-pr__ci) {
|
|
3821
|
+
overflow: hidden;
|
|
3822
|
+
text-overflow: ellipsis;
|
|
3823
|
+
}
|
|
3824
|
+
:where(.wp-card__foot) {
|
|
2439
3825
|
display: flex;
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
3826
|
+
align-items: center;
|
|
3827
|
+
justify-content: space-between;
|
|
3828
|
+
gap: var(--bp-space-2);
|
|
3829
|
+
margin-top: 1px;
|
|
2443
3830
|
}
|
|
2444
|
-
:where(.
|
|
2445
|
-
font:
|
|
2446
|
-
|
|
3831
|
+
:where(.wp-card__wave) {
|
|
3832
|
+
font-family: var(--bp-mono);
|
|
3833
|
+
font-size: var(--bp-label-sm);
|
|
3834
|
+
letter-spacing: var(--bp-label-sm-ls);
|
|
2447
3835
|
text-transform: uppercase;
|
|
2448
|
-
color: var(--
|
|
2449
|
-
border: 1px solid var(--ink-faint);
|
|
2450
|
-
padding: 2px 7px;
|
|
2451
|
-
height: max-content;
|
|
2452
|
-
white-space: nowrap;
|
|
2453
|
-
}
|
|
2454
|
-
:where(.assumption .oq-tag) {
|
|
2455
|
-
color: var(--text-secondary);
|
|
2456
|
-
border-color: var(--edge);
|
|
3836
|
+
color: var(--bp-text-secondary);
|
|
2457
3837
|
}
|
|
2458
|
-
|
|
3838
|
+
|
|
3839
|
+
/* ---- SWIMLANES view (type × wave grid) — single-line chips -- */
|
|
3840
|
+
:where(.wp-view--swim) {
|
|
2459
3841
|
display: grid;
|
|
2460
|
-
grid-template-columns: repeat(
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
border-right: 1px solid var(--edge);
|
|
2467
|
-
border-bottom: 1px solid var(--edge);
|
|
2468
|
-
}
|
|
2469
|
-
:where(.state:nth-child(2n)) {
|
|
2470
|
-
border-right: 0;
|
|
3842
|
+
grid-template-columns: 120px repeat(var(--wp-waves), minmax(168px, 1fr));
|
|
3843
|
+
gap: 1px;
|
|
3844
|
+
background: var(--bp-edge);
|
|
3845
|
+
border: 1px solid var(--bp-edge);
|
|
3846
|
+
border-radius: var(--bp-radius-0);
|
|
3847
|
+
overflow: hidden;
|
|
2471
3848
|
}
|
|
2472
|
-
:where(.
|
|
2473
|
-
|
|
2474
|
-
|
|
3849
|
+
:where(.wp-swim__corner),
|
|
3850
|
+
:where(.wp-swim__whead),
|
|
3851
|
+
:where(.wp-swim__lanehead),
|
|
3852
|
+
:where(.wp-swim__cell) { background: var(--bp-paper); padding: var(--bp-space-2); min-width: 0; }
|
|
3853
|
+
:where(.wp-swim__corner),
|
|
3854
|
+
:where(.wp-swim__whead) {
|
|
3855
|
+
font-family: var(--bp-mono);
|
|
3856
|
+
font-size: var(--bp-label-sm);
|
|
3857
|
+
letter-spacing: var(--bp-label-sm-ls);
|
|
2475
3858
|
text-transform: uppercase;
|
|
2476
|
-
color: var(--
|
|
2477
|
-
|
|
2478
|
-
:where(.state-name) {
|
|
2479
|
-
margin-bottom: 6px;
|
|
2480
|
-
}
|
|
2481
|
-
:where(.state-desc) {
|
|
2482
|
-
font-size: 13px;
|
|
2483
|
-
line-height: 18px;
|
|
2484
|
-
color: var(--text-secondary);
|
|
3859
|
+
color: var(--bp-text-secondary);
|
|
3860
|
+
background: var(--bp-bg);
|
|
2485
3861
|
}
|
|
2486
|
-
:where(.
|
|
2487
|
-
|
|
3862
|
+
:where(.wp-swim__lanehead) { background: var(--bp-bg); display: flex; align-items: center; }
|
|
3863
|
+
:where(.wp-swim__cell) { display: grid; gap: 6px; align-content: start; }
|
|
3864
|
+
:where(.wp-chip) {
|
|
3865
|
+
display: grid;
|
|
3866
|
+
gap: 5px;
|
|
3867
|
+
padding: 7px 9px;
|
|
3868
|
+
border: 1px solid var(--bp-edge);
|
|
3869
|
+
border-radius: var(--bp-radius-0);
|
|
3870
|
+
background: var(--bp-paper);
|
|
3871
|
+
min-width: 0;
|
|
2488
3872
|
}
|
|
2489
|
-
:where(.
|
|
2490
|
-
|
|
3873
|
+
:where(.wp-chip__head) {
|
|
3874
|
+
display: grid;
|
|
3875
|
+
grid-template-columns: auto minmax(0, 1fr) auto;
|
|
3876
|
+
align-items: center;
|
|
3877
|
+
gap: 7px;
|
|
2491
3878
|
}
|
|
2492
|
-
:where(.
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
3879
|
+
:where(.wp-chip__name) {
|
|
3880
|
+
font-size: var(--bp-text-small);
|
|
3881
|
+
font-weight: var(--bp-weight-medium);
|
|
3882
|
+
line-height: 1.2;
|
|
3883
|
+
white-space: nowrap;
|
|
3884
|
+
overflow: hidden;
|
|
3885
|
+
text-overflow: ellipsis;
|
|
2496
3886
|
}
|
|
2497
|
-
:where(.
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
3887
|
+
:where(.wp-chip--done .wp-chip__name) { color: var(--bp-text-secondary); }
|
|
3888
|
+
:where(.wp-chip__pr) { min-width: 0; overflow: hidden; }
|
|
3889
|
+
:where(.wp-chip__pr .wp-pr) { font-size: var(--bp-label-sm); max-width: 100%; }
|
|
3890
|
+
:where(.wp-chip[data-locked="true"]) { border-style: dashed; }
|
|
3891
|
+
|
|
3892
|
+
/* ---- GANTT view (longest-path schedule) --------------------- */
|
|
3893
|
+
:where(.wp-view--gantt) { display: grid; gap: 4px; }
|
|
3894
|
+
:where(.wp-gantt__row) {
|
|
3895
|
+
display: grid;
|
|
3896
|
+
grid-template-columns: 264px 1fr;
|
|
3897
|
+
gap: var(--bp-space-3);
|
|
3898
|
+
align-items: center;
|
|
2502
3899
|
}
|
|
2503
|
-
:where(.
|
|
2504
|
-
display:
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
3900
|
+
:where(.wp-gantt__label) {
|
|
3901
|
+
display: grid;
|
|
3902
|
+
grid-template-columns: 84px minmax(0, 1fr) auto;
|
|
3903
|
+
gap: var(--bp-space-2);
|
|
3904
|
+
align-items: center;
|
|
3905
|
+
min-width: 0;
|
|
2508
3906
|
}
|
|
2509
|
-
:where(.
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
3907
|
+
:where(.wp-gantt__name) {
|
|
3908
|
+
font-size: var(--bp-text-small);
|
|
3909
|
+
font-weight: var(--bp-weight-medium);
|
|
3910
|
+
white-space: nowrap;
|
|
3911
|
+
overflow: hidden;
|
|
3912
|
+
text-overflow: ellipsis;
|
|
2513
3913
|
}
|
|
2514
|
-
:where(.
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
3914
|
+
:where(.wp-gantt__row--done .wp-gantt__name) { color: var(--bp-text-secondary); }
|
|
3915
|
+
:where(.wp-gantt__track) {
|
|
3916
|
+
position: relative;
|
|
3917
|
+
height: 26px;
|
|
3918
|
+
background: var(--bp-fill-amb);
|
|
3919
|
+
border-radius: var(--bp-radius-0);
|
|
3920
|
+
background-image: repeating-linear-gradient(
|
|
3921
|
+
to right,
|
|
3922
|
+
oklch(0 0 0 / 0) 0 calc(100% / var(--span, 10) - 1px),
|
|
3923
|
+
var(--bp-edge) calc(100% / var(--span, 10) - 1px) calc(100% / var(--span, 10))
|
|
3924
|
+
);
|
|
2518
3925
|
}
|
|
2519
|
-
:where(.
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
3926
|
+
:where(.wp-gantt__bar) {
|
|
3927
|
+
position: absolute;
|
|
3928
|
+
top: 3px;
|
|
3929
|
+
bottom: 3px;
|
|
3930
|
+
display: flex;
|
|
3931
|
+
align-items: center;
|
|
3932
|
+
gap: 6px;
|
|
3933
|
+
padding: 0 8px;
|
|
3934
|
+
border-radius: var(--bp-radius-0);
|
|
3935
|
+
border: 1px solid var(--bp-ink-line);
|
|
3936
|
+
background: var(--bp-paper);
|
|
3937
|
+
min-width: 28px;
|
|
3938
|
+
}
|
|
3939
|
+
:where(.wp-gantt__bar--done) { background: var(--bp-ink); border-color: var(--bp-ink); }
|
|
3940
|
+
:where(.wp-gantt__bar--done .wp-gantt__bar-label),
|
|
3941
|
+
:where(.wp-gantt__bar--done .wp-dot) { color: var(--bp-paper); }
|
|
3942
|
+
:where(.wp-gantt__bar--done .wp-dot--done) { background: var(--bp-paper); }
|
|
3943
|
+
:where(.wp-gantt__bar--active) { background: var(--bp-fill-hi); border-color: var(--bp-ink); }
|
|
3944
|
+
:where(.wp-gantt__bar--blocked) { border-style: dashed; }
|
|
3945
|
+
:where(.wp-gantt__bar-label) {
|
|
3946
|
+
font-family: var(--bp-mono);
|
|
3947
|
+
font-size: var(--bp-label-sm);
|
|
3948
|
+
letter-spacing: 0.02em;
|
|
3949
|
+
color: var(--bp-text-secondary);
|
|
2523
3950
|
}
|
|
2524
|
-
:where(.
|
|
2525
|
-
|
|
2526
|
-
|
|
3951
|
+
:where(.wp-gantt__track--axis) {
|
|
3952
|
+
position: relative;
|
|
3953
|
+
height: 18px;
|
|
3954
|
+
background: none;
|
|
3955
|
+
background-image: none;
|
|
2527
3956
|
}
|
|
2528
|
-
:where(.
|
|
2529
|
-
|
|
2530
|
-
|
|
3957
|
+
:where(.wp-gantt__tick) {
|
|
3958
|
+
position: absolute;
|
|
3959
|
+
left: calc(var(--at) / var(--span) * 100%);
|
|
3960
|
+
transform: translateX(-50%);
|
|
3961
|
+
font-family: var(--bp-mono);
|
|
3962
|
+
font-size: var(--bp-label-sm);
|
|
3963
|
+
color: var(--bp-text-secondary);
|
|
3964
|
+
font-variant-numeric: tabular-nums;
|
|
2531
3965
|
}
|
|
2532
|
-
:where(.
|
|
2533
|
-
|
|
2534
|
-
|
|
3966
|
+
:where(.wp-gantt__label--axis) {
|
|
3967
|
+
display: block;
|
|
3968
|
+
font-family: var(--bp-mono);
|
|
3969
|
+
font-size: var(--bp-label-sm);
|
|
3970
|
+
letter-spacing: var(--bp-label-sm-ls);
|
|
2535
3971
|
text-transform: uppercase;
|
|
2536
|
-
color: var(--text-secondary);
|
|
3972
|
+
color: var(--bp-text-secondary);
|
|
3973
|
+
}
|
|
3974
|
+
:where(.wp-gantt__row--axis) { border-bottom: 1px solid var(--bp-edge); padding-bottom: 4px; }
|
|
3975
|
+
|
|
3976
|
+
/* ---- EMPTY / no-data state ---------------------------------- */
|
|
3977
|
+
:where(.wp-empty) {
|
|
3978
|
+
display: grid;
|
|
3979
|
+
place-items: center;
|
|
3980
|
+
gap: var(--bp-space-2);
|
|
2537
3981
|
text-align: center;
|
|
2538
|
-
|
|
3982
|
+
padding: var(--bp-space-6) var(--bp-space-4);
|
|
3983
|
+
border: 1px dashed var(--bp-ink-line);
|
|
3984
|
+
border-radius: var(--bp-radius-0);
|
|
3985
|
+
background-color: var(--bp-fill-amb);
|
|
3986
|
+
background-image: var(--bp-hatch);
|
|
3987
|
+
color: var(--bp-text-secondary);
|
|
3988
|
+
}
|
|
3989
|
+
:where(.wp-empty__art) { color: var(--bp-ink-soft); margin-bottom: var(--bp-space-1); }
|
|
3990
|
+
:where(.wp-empty__title) {
|
|
3991
|
+
margin: 0;
|
|
3992
|
+
font-size: var(--bp-text-h4);
|
|
3993
|
+
font-weight: var(--bp-weight-strong);
|
|
3994
|
+
color: var(--bp-text);
|
|
3995
|
+
}
|
|
3996
|
+
:where(.wp-empty__hint) { margin: 0; max-width: 42ch; font-size: var(--bp-text-small); }
|
|
3997
|
+
:where(.wp-mono) { font-family: var(--bp-mono); font-size: 0.92em; }
|
|
3998
|
+
|
|
3999
|
+
/* ---- responsive: collapse the dense grids on narrow containers */
|
|
4000
|
+
@container (max-width: 560px) {
|
|
4001
|
+
:where(.wp-row) { grid-template-columns: auto minmax(0, 1fr) auto; }
|
|
4002
|
+
:where(.wp-row .wp-type) { display: none; }
|
|
4003
|
+
:where(.wp-row__pr) { grid-column: 2 / -1; justify-self: start; }
|
|
4004
|
+
:where(.wp-gantt__row) { grid-template-columns: 1fr; gap: 4px; }
|
|
2539
4005
|
}
|
|
2540
4006
|
}
|
|
2541
4007
|
|
|
@@ -2589,6 +4055,29 @@
|
|
|
2589
4055
|
:where(.bp-ease-overshoot) { transition-timing-function: var(--bp-ease-overshoot); }
|
|
2590
4056
|
:where(.bp-ease-linear) { transition-timing-function: var(--bp-ease-linear); }
|
|
2591
4057
|
|
|
4058
|
+
/* Theme flip — mute per-element transitions while the root crossfade runs.
|
|
4059
|
+
TOC links, inputs, and other token-bound surfaces bake color motion into
|
|
4060
|
+
@layer components; that fights the view transition the same way
|
|
4061
|
+
.bp-transition-colors utilities do. blueprint.js sets
|
|
4062
|
+
data-bp-theme-switching for the duration of startViewTransition().
|
|
4063
|
+
Keep the data-attribute and typed selectors in separate rules — an
|
|
4064
|
+
unknown :active-view-transition-type() in a comma list invalidates the
|
|
4065
|
+
whole block in engines that lack typed View Transition selector support. */
|
|
4066
|
+
html[data-bp-theme-switching] :where(*) {
|
|
4067
|
+
transition-property: none;
|
|
4068
|
+
}
|
|
4069
|
+
html:active-view-transition-type(bp-theme) :where(*) {
|
|
4070
|
+
transition-property: none;
|
|
4071
|
+
}
|
|
4072
|
+
html[data-bp-theme-switching] *::before,
|
|
4073
|
+
html[data-bp-theme-switching] *::after {
|
|
4074
|
+
transition-property: none;
|
|
4075
|
+
}
|
|
4076
|
+
html:active-view-transition-type(bp-theme) *::before,
|
|
4077
|
+
html:active-view-transition-type(bp-theme) *::after {
|
|
4078
|
+
transition-property: none;
|
|
4079
|
+
}
|
|
4080
|
+
|
|
2592
4081
|
/* Responsive: keep section navigation reachable while collapsing the rail. */
|
|
2593
4082
|
@media (max-width: 860px) {
|
|
2594
4083
|
:where(.bp-sidebar, .bp-toc, .sidebar) {
|
|
@@ -2608,6 +4097,16 @@
|
|
|
2608
4097
|
padding-bottom: var(--bp-space-1);
|
|
2609
4098
|
}
|
|
2610
4099
|
:where(.bp-sidebar li, .bp-toc li, .sidebar li) { flex: 0 0 auto; }
|
|
4100
|
+
/* In the collapsed horizontal nav the group eyebrow rides inline as a
|
|
4101
|
+
quiet separator ahead of its entries rather than a stacked header. */
|
|
4102
|
+
:where(.bp-sidebar .bp-nav-group, .bp-toc .bp-nav-group) {
|
|
4103
|
+
display: flex;
|
|
4104
|
+
align-items: center;
|
|
4105
|
+
margin: 0;
|
|
4106
|
+
}
|
|
4107
|
+
:where(.bp-nav-group__label) {
|
|
4108
|
+
padding: var(--bp-space-1) var(--bp-space-2);
|
|
4109
|
+
}
|
|
2611
4110
|
/* The gliding pill only makes sense in the fixed column; in the collapsed
|
|
2612
4111
|
horizontal nav the active entry just shows its own static pill. */
|
|
2613
4112
|
:where(.bp-sidebar > ul, .bp-sidebar__panel > ul, .bp-toc > ul)::before { content: none; }
|
|
@@ -2615,7 +4114,7 @@
|
|
|
2615
4114
|
background: var(--bp-fill-hi);
|
|
2616
4115
|
}
|
|
2617
4116
|
/* Rail is now on top; the sheet floats with a uniform margin. */
|
|
2618
|
-
:where(html
|
|
4117
|
+
:where(html[data-bp-document]) {
|
|
2619
4118
|
--bp-shell-inset-block: var(--bp-space-3);
|
|
2620
4119
|
--bp-shell-inset-top: var(--bp-shell-inset-block);
|
|
2621
4120
|
--bp-shell-inset-left: var(--bp-space-3);
|
|
@@ -2627,26 +4126,29 @@
|
|
|
2627
4126
|
:where(main, article) {
|
|
2628
4127
|
padding: var(--bp-space-4) var(--bp-space-3);
|
|
2629
4128
|
}
|
|
2630
|
-
/* Edge-to-edge on phones — the float costs too much width here. */
|
|
2631
|
-
:where(
|
|
2632
|
-
|
|
4129
|
+
/* Edge-to-edge on phones — the desk float costs too much width here. */
|
|
4130
|
+
:where(html[data-bp-document] body) {
|
|
4131
|
+
padding-top: 0;
|
|
4132
|
+
padding-bottom: 0;
|
|
2633
4133
|
}
|
|
2634
|
-
:where(
|
|
2635
|
-
position: static;
|
|
2636
|
-
inset: auto;
|
|
4134
|
+
:where(html[data-bp-document] main) {
|
|
2637
4135
|
margin: 0;
|
|
2638
|
-
|
|
4136
|
+
max-width: var(--bp-content);
|
|
4137
|
+
min-height: 0;
|
|
2639
4138
|
border: 0;
|
|
2640
4139
|
border-radius: var(--bp-radius-0);
|
|
2641
4140
|
box-shadow: none;
|
|
2642
4141
|
}
|
|
2643
|
-
:where(html
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
:where(
|
|
4142
|
+
:where(html[data-bp-document] main > *) {
|
|
4143
|
+
max-width: none;
|
|
4144
|
+
}
|
|
4145
|
+
:where(html[data-bp-document])::before,
|
|
4146
|
+
:where(html[data-bp-document])::after,
|
|
4147
|
+
:where(html[data-bp-document] body)::before,
|
|
4148
|
+
:where(html[data-bp-document] body)::after {
|
|
2647
4149
|
content: none;
|
|
2648
4150
|
}
|
|
2649
|
-
:where(.bp-
|
|
4151
|
+
:where(.bp-card-grid, .bp-layout) {
|
|
2650
4152
|
grid-template-columns: 1fr;
|
|
2651
4153
|
}
|
|
2652
4154
|
:where(.bp-content) {
|
|
@@ -2667,22 +4169,25 @@
|
|
|
2667
4169
|
:where(.bp-sidebar, .bp-toc, .sidebar, .scroll-progress, .bp-no-print) {
|
|
2668
4170
|
display: none !important;
|
|
2669
4171
|
}
|
|
2670
|
-
:where(
|
|
2671
|
-
:where(
|
|
2672
|
-
|
|
4172
|
+
:where(html[data-bp-document] main, .page-body, .sheet) { margin: 0; border: 0; border-radius: var(--bp-radius-0); box-shadow: none; }
|
|
4173
|
+
:where(html[data-bp-document] body) {
|
|
4174
|
+
padding-top: 0;
|
|
4175
|
+
padding-bottom: 0;
|
|
2673
4176
|
}
|
|
2674
|
-
:where(
|
|
2675
|
-
|
|
2676
|
-
inset: auto;
|
|
4177
|
+
:where(html[data-bp-document] main) {
|
|
4178
|
+
min-height: 0;
|
|
2677
4179
|
overflow: visible;
|
|
2678
4180
|
}
|
|
2679
|
-
:where(html
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
:where(
|
|
4181
|
+
:where(html[data-bp-document] main > *) {
|
|
4182
|
+
max-width: none;
|
|
4183
|
+
}
|
|
4184
|
+
:where(html[data-bp-document])::before,
|
|
4185
|
+
:where(html[data-bp-document])::after,
|
|
4186
|
+
:where(html[data-bp-document] body)::before,
|
|
4187
|
+
:where(html[data-bp-document] body)::after {
|
|
2683
4188
|
content: none;
|
|
2684
4189
|
}
|
|
2685
|
-
:where(.bp-
|
|
4190
|
+
:where(.bp-callout, .bp-card, .bp-section, .bp-figure, figure, details) {
|
|
2686
4191
|
break-inside: avoid;
|
|
2687
4192
|
}
|
|
2688
4193
|
}
|