@anyblades/blades 3.1.0-alpha.2 → 3.1.0-beta.4
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 +48 -23
- package/css/blades.css +301 -593
- package/css/blades.min.css +4 -148
- package/css/blades.ninja.css +4204 -0
- package/css/blades.ninja.min.css +12 -0
- package/css/float-label.css +207 -0
- package/css/float-label.min.css +6 -0
- package/css/{pico.layered.css → layered/blades.layered.css} +589 -17
- package/css/layered/blades.layered.min.css +14 -0
- package/css/layered/compact.css +54 -0
- package/css/layered/components/accordion.css +85 -0
- package/css/layered/components/card.css +48 -0
- package/css/layered/components/dropdown.css +191 -0
- package/css/layered/components/group.css +208 -0
- package/css/layered/components/loading.css +61 -0
- package/css/layered/components/modal.css +158 -0
- package/css/layered/components/nav.css +117 -0
- package/css/layered/components/progress.css +76 -0
- package/css/layered/components/tooltip.css +176 -0
- package/css/layered/components.css +1099 -0
- package/css/layered/content/button.css +208 -0
- package/css/layered/content/code.css +64 -0
- package/css/layered/content/embedded-content.css +41 -0
- package/css/layered/content/figure.css +15 -0
- package/css/layered/content/link.css +84 -0
- package/css/layered/content/misc.css +22 -0
- package/css/layered/content/table.css +33 -0
- package/css/layered/content/typography.css +159 -0
- package/css/layered/content.css +611 -0
- package/css/layered/forms/basics.css +338 -0
- package/css/layered/forms/checkbox-radio-switch.css +164 -0
- package/css/layered/forms/input-color.css +20 -0
- package/css/layered/forms/input-datetime.css +57 -0
- package/css/layered/forms/input-file.css +29 -0
- package/css/layered/forms/input-range.css +121 -0
- package/css/layered/forms/input-search.css +66 -0
- package/css/layered/forms.css +778 -0
- package/css/layered/layout/container.css +42 -0
- package/css/layered/layout/document.css +48 -0
- package/css/layered/layout/grid.css +22 -0
- package/css/layered/layout/landmarks.css +12 -0
- package/css/layered/layout/overflow-auto.css +9 -0
- package/css/layered/layout/section.css +9 -0
- package/css/layered/layout.css +119 -0
- package/css/layered/utilities.css +35 -0
- package/css/layered/variables.css +365 -0
- package/css/pico.conditional.css +34 -16
- package/css/pico.conditional.min.css +2 -111
- package/css/pico.css +34 -16
- package/css/pico.min.css +2 -111
- package/package.json +16 -12
- package/src/blades/_compact.css +51 -0
- package/src/blades/_dropdown-popover.css +107 -0
- package/src/blades/_index.css +28 -0
- package/src/blades/_modal.css +26 -0
- package/src/blades/float-label/_index.css +2 -0
- package/src/{standalone/forms/_float-label.theme.css → blades/float-label/_theme.css} +5 -1
- package/src/blades.css +2 -2
- package/src/blades.ninja.css +3 -0
- package/src/float-label.css +1 -0
- package/src/ninja/LICENSE +22 -0
- package/src/ninja/README.md +1 -0
- package/src/ninja/_index.css +19 -0
- package/src/{standalone → ninja}/_theme.css +0 -2
- package/src/{ninja.css → ninja/_utilities.css} +55 -6
- package/src/pico/_variables.css +6 -5
- package/src/pico/components/_loading.css +27 -1
- package/src/pico/content/_button.css +1 -1
- package/src/pico/layout/_document.css +9 -0
- package/src/pico/layout/_index.css +0 -1
- package/src/pico/layout/_landmarks.css +1 -9
- package/src/pico.css +1 -0
- package/css/blades.standalone.css +0 -860
- package/css/blades.standalone.min.css +0 -37
- package/css/ninja.css +0 -83
- package/css/ninja.min.css +0 -5
- package/css/pico.layered.min.css +0 -118
- package/src/blades.standalone.css +0 -2
- package/src/standalone/_core.css +0 -32
- package/src/standalone/_utilities.css +0 -55
- package/src/standalone/forms/_float-label.css +0 -2
- /package/src/{standalone/content → blades}/_code.css +0 -0
- /package/src/{standalone/layout → blades}/_columns.css +0 -0
- /package/src/{standalone/components/_icon-helper.css → blades/_icon.css} +0 -0
- /package/src/{standalone/components → blades}/_timeline.css +0 -0
- /package/src/{standalone → blades}/_variables.css +0 -0
- /package/src/{standalone/forms/_float-label.core.css → blades/float-label/_core.css} +0 -0
- /package/src/{standalone/layout/_breakout.css → ninja/_container-breakout.css} +0 -0
- /package/src/{standalone/content/_typography.css → ninja/_heading-anchor.css} +0 -0
- /package/src/{standalone/content/_list.css → ninja/_list-helpers.css} +0 -0
- /package/src/{standalone/layout/_scroller.css → ninja/_page-anchors.css} +0 -0
- /package/src/{standalone/content/_table.css → ninja/_table-helpers.css} +0 -0
- /package/src/{standalone/content → ninja}/_table-responsive.css +0 -0
package/css/blades.css
CHANGED
|
@@ -234,7 +234,8 @@ details summary[role="button"]:not(.outline)::after {
|
|
|
234
234
|
--pico-primary-hover-background: light-dark(#02659a, #017fc0);
|
|
235
235
|
--pico-primary-hover-border: var(--pico-primary-hover-background);
|
|
236
236
|
--pico-primary-hover-underline: var(--pico-primary-hover);
|
|
237
|
-
|
|
237
|
+
/* Focus rings are opaque: at 25–50% alpha they composite below 3:1 (SC 1.4.11), see #167 */
|
|
238
|
+
--pico-primary-focus: light-dark(rgb(2, 138, 212), rgb(1, 170, 255));
|
|
238
239
|
--pico-primary-inverse: #fff;
|
|
239
240
|
--pico-secondary: light-dark(#5d6b89, #969eaf);
|
|
240
241
|
--pico-secondary-background: #525f7a;
|
|
@@ -244,7 +245,7 @@ details summary[role="button"]:not(.outline)::after {
|
|
|
244
245
|
--pico-secondary-hover-background: light-dark(#48536b, #5d6b89);
|
|
245
246
|
--pico-secondary-hover-border: var(--pico-secondary-hover-background);
|
|
246
247
|
--pico-secondary-hover-underline: var(--pico-secondary-hover);
|
|
247
|
-
--pico-secondary-focus: light-dark(
|
|
248
|
+
--pico-secondary-focus: light-dark(rgb(93, 107, 137), rgb(144, 158, 190));
|
|
248
249
|
--pico-secondary-inverse: #fff;
|
|
249
250
|
--pico-contrast: light-dark(#181c25, #dfe3eb);
|
|
250
251
|
--pico-contrast-background: light-dark(#181c25, #eff1f4);
|
|
@@ -257,7 +258,7 @@ details summary[role="button"]:not(.outline)::after {
|
|
|
257
258
|
var(--pico-secondary-hover),
|
|
258
259
|
var(--pico-contrast-hover)
|
|
259
260
|
);
|
|
260
|
-
--pico-contrast-focus: light-dark(
|
|
261
|
+
--pico-contrast-focus: light-dark(rgb(93, 107, 137), rgb(207, 213, 226));
|
|
261
262
|
--pico-contrast-inverse: light-dark(#fff, #000);
|
|
262
263
|
--pico-box-shadow: 0 0.5rem 2.5rem light-dark(rgba(129, 145, 181, 0.2), rgba(7, 8.5, 12, 0.2));
|
|
263
264
|
--pico-h1-color: light-dark(#2d3138, #f0f1f3);
|
|
@@ -291,11 +292,11 @@ details summary[role="button"]:not(.outline)::after {
|
|
|
291
292
|
--pico-form-element-disabled-opacity: 0.5;
|
|
292
293
|
--pico-form-element-invalid-border-color: light-dark(
|
|
293
294
|
rgb(183.5, 105.5, 106.5),
|
|
294
|
-
rgb(
|
|
295
|
+
rgb(200.25, 79.25, 72.25)
|
|
295
296
|
);
|
|
296
297
|
--pico-form-element-invalid-active-border-color: light-dark(
|
|
297
298
|
rgb(200.25, 79.25, 72.25),
|
|
298
|
-
rgb(
|
|
299
|
+
rgb(214, 92, 86)
|
|
299
300
|
);
|
|
300
301
|
--pico-form-element-invalid-focus-color: var(--pico-form-element-invalid-active-border-color);
|
|
301
302
|
--pico-form-element-valid-border-color: light-dark(rgb(76, 154.5, 137.5), #2a7b6f);
|
|
@@ -406,9 +407,6 @@ progress,
|
|
|
406
407
|
tab-size: 4;
|
|
407
408
|
}
|
|
408
409
|
|
|
409
|
-
/**
|
|
410
|
-
* Landmarks
|
|
411
|
-
*/
|
|
412
410
|
body {
|
|
413
411
|
width: 100%;
|
|
414
412
|
margin: 0;
|
|
@@ -418,12 +416,6 @@ main {
|
|
|
418
416
|
display: block;
|
|
419
417
|
}
|
|
420
418
|
|
|
421
|
-
body > header,
|
|
422
|
-
body > main,
|
|
423
|
-
body > footer {
|
|
424
|
-
padding-block: var(--pico-block-spacing-vertical);
|
|
425
|
-
}
|
|
426
|
-
|
|
427
419
|
/**
|
|
428
420
|
* Section
|
|
429
421
|
*/
|
|
@@ -767,7 +759,7 @@ button,
|
|
|
767
759
|
background-color: var(--pico-background-color);
|
|
768
760
|
box-shadow: var(--pico-box-shadow);
|
|
769
761
|
color: var(--pico-color);
|
|
770
|
-
font-weight: var(--pico-font-weight);
|
|
762
|
+
font-weight: var(--pico-button-font-weight, var(--pico-font-weight));
|
|
771
763
|
font-size: 1rem;
|
|
772
764
|
line-height: var(--pico-line-height);
|
|
773
765
|
text-align: center;
|
|
@@ -2411,7 +2403,11 @@ label > details.dropdown {
|
|
|
2411
2403
|
--pico-loading-spinner-opacity: 0.5;
|
|
2412
2404
|
}
|
|
2413
2405
|
|
|
2414
|
-
[aria-busy="true"]:not(input, select, textarea, html, form)
|
|
2406
|
+
[aria-busy="true"]:not(input, select, textarea, html, form):not(
|
|
2407
|
+
:where(button, [type="submit"], [type="button"], [type="reset"], [role="button"])
|
|
2408
|
+
) {
|
|
2409
|
+
/* :where() zeroes the specificity of the button list inside :not(), so this rule stays
|
|
2410
|
+
* low-specificity and doesn't override the more specific button rules below */
|
|
2415
2411
|
white-space: nowrap;
|
|
2416
2412
|
}
|
|
2417
2413
|
[aria-busy="true"]:not(input, select, textarea, html, form)::before {
|
|
@@ -2440,6 +2436,19 @@ a[aria-busy="true"] {
|
|
|
2440
2436
|
pointer-events: none;
|
|
2441
2437
|
}
|
|
2442
2438
|
|
|
2439
|
+
/* Buttons keep their size: the label stays in place but hidden, the spinner sits on top */
|
|
2440
|
+
button[aria-busy="true"]:not(:empty), [type="submit"][aria-busy="true"]:not(:empty), [type="button"][aria-busy="true"]:not(:empty), [type="reset"][aria-busy="true"]:not(:empty), [role="button"][aria-busy="true"]:not(:empty) {
|
|
2441
|
+
position: relative;
|
|
2442
|
+
color: transparent;
|
|
2443
|
+
}
|
|
2444
|
+
button[aria-busy="true"]:not(:empty) > *, [type="submit"][aria-busy="true"]:not(:empty) > *, [type="button"][aria-busy="true"]:not(:empty) > *, [type="reset"][aria-busy="true"]:not(:empty) > *, [role="button"][aria-busy="true"]:not(:empty) > * {
|
|
2445
|
+
opacity: 0;
|
|
2446
|
+
}
|
|
2447
|
+
button[aria-busy="true"]:not(:empty)::before, [type="submit"][aria-busy="true"]:not(:empty)::before, [type="button"][aria-busy="true"]:not(:empty)::before, [type="reset"][aria-busy="true"]:not(:empty)::before, [role="button"][aria-busy="true"]:not(:empty)::before {
|
|
2448
|
+
position: absolute;
|
|
2449
|
+
margin: auto;
|
|
2450
|
+
inset: 0;
|
|
2451
|
+
}
|
|
2443
2452
|
/**
|
|
2444
2453
|
* Modal (<dialog>)
|
|
2445
2454
|
*/
|
|
@@ -3021,135 +3030,6 @@ progress::-moz-progress-bar {
|
|
|
3021
3030
|
|
|
3022
3031
|
/* Layout */
|
|
3023
3032
|
|
|
3024
|
-
/*
|
|
3025
|
-
\3c !--section:code-->
|
|
3026
|
-
```css */
|
|
3027
|
-
.breakout,
|
|
3028
|
-
.breakout-all {
|
|
3029
|
-
max-width: calc(10% + 65ch + 10%);
|
|
3030
|
-
/* Prepare the container for breakout elements */
|
|
3031
|
-
padding-inline: 10%;
|
|
3032
|
-
}
|
|
3033
|
-
@media (width < 768px) {
|
|
3034
|
-
.breakout,
|
|
3035
|
-
.breakout-all {
|
|
3036
|
-
max-width: calc(1rem + 65ch + 1rem);
|
|
3037
|
-
padding-inline: 1rem
|
|
3038
|
-
}
|
|
3039
|
-
}
|
|
3040
|
-
/* Breakout direct children only */
|
|
3041
|
-
.breakout > *:is(
|
|
3042
|
-
table,
|
|
3043
|
-
pre,
|
|
3044
|
-
figure, video, iframe, canvas,
|
|
3045
|
-
img, picture,
|
|
3046
|
-
|
|
3047
|
-
.breakout-item,
|
|
3048
|
-
.breakout-item-max
|
|
3049
|
-
),
|
|
3050
|
-
.breakout-all > *:is(
|
|
3051
|
-
table,
|
|
3052
|
-
pre,
|
|
3053
|
-
figure, video, iframe, canvas,
|
|
3054
|
-
img, picture,
|
|
3055
|
-
|
|
3056
|
-
.breakout-item,
|
|
3057
|
-
.breakout-item-max
|
|
3058
|
-
) {
|
|
3059
|
-
width: -moz-fit-content;
|
|
3060
|
-
width: fit-content;
|
|
3061
|
-
min-width: 100%;
|
|
3062
|
-
max-width: min(125%, 100dvw);
|
|
3063
|
-
margin-left: 50%;
|
|
3064
|
-
transform: translateX(-50%);
|
|
3065
|
-
}
|
|
3066
|
-
/* Respect img/picture min-width */
|
|
3067
|
-
.breakout > *:is(img, picture):not(.does-not-exist), .breakout-all > *:is(img, picture):not(.does-not-exist) /* soft win specificity over .breakout-item above */ {
|
|
3068
|
-
min-width: auto;
|
|
3069
|
-
}
|
|
3070
|
-
/* Max out the width of the element */
|
|
3071
|
-
.breakout > *.breakout-item-max, .breakout-all > *.breakout-item-max {
|
|
3072
|
-
width: min(125%, 100dvw) !important;
|
|
3073
|
-
/* !important is for cases like figure.breakout-item-max @TODO */
|
|
3074
|
-
}
|
|
3075
|
-
|
|
3076
|
-
.breakout-all > *:is(h2, h3, h4, h5, h6, hr):not([class]) {
|
|
3077
|
-
position: relative;
|
|
3078
|
-
}
|
|
3079
|
-
|
|
3080
|
-
.breakout-all > *:is(h2, h3, h4, h5, h6, hr):not([class])::before {
|
|
3081
|
-
display: block;
|
|
3082
|
-
position: absolute;
|
|
3083
|
-
background: gray;
|
|
3084
|
-
content: "";
|
|
3085
|
-
opacity: 12.5%;
|
|
3086
|
-
}
|
|
3087
|
-
|
|
3088
|
-
.breakout-all > *:is(h2, h3, h4, h5, h6):not([class])::before {
|
|
3089
|
-
top: 50%;
|
|
3090
|
-
right: 100%;
|
|
3091
|
-
width: 10em;
|
|
3092
|
-
height: 0.25em;
|
|
3093
|
-
margin-right: 0.8ch;
|
|
3094
|
-
transform: translateY(-50%);
|
|
3095
|
-
background: linear-gradient(to left, gray, transparent);
|
|
3096
|
-
}
|
|
3097
|
-
|
|
3098
|
-
/* @TODO: add to tricks-wiki why `*` works here, but `&` fails */
|
|
3099
|
-
|
|
3100
|
-
.breakout-all > *:is(h2, h3, h4, h5, h6):not([class]):where(hr:not([class]) + *)::before {
|
|
3101
|
-
display: none !important;
|
|
3102
|
-
}
|
|
3103
|
-
|
|
3104
|
-
.breakout-all > *:is(hr):not([class]) {
|
|
3105
|
-
height: 0.5rem;
|
|
3106
|
-
overflow: visible;
|
|
3107
|
-
border: none;
|
|
3108
|
-
}
|
|
3109
|
-
|
|
3110
|
-
.breakout-all > *:is(hr):not([class])::before {
|
|
3111
|
-
left: 50%;
|
|
3112
|
-
width: 100dvw;
|
|
3113
|
-
height: 100%;
|
|
3114
|
-
transform: translateX(-50%);
|
|
3115
|
-
}
|
|
3116
|
-
/*```
|
|
3117
|
-
\3c !--section:docs-->
|
|
3118
|
-
|
|
3119
|
-
The `.breakout` layout allows images, tables, and other figures to automatically extend or bleed beyond their parent container’s width.
|
|
3120
|
-
|
|
3121
|
-
Break out a wide image from the text flow:
|
|
3122
|
-
|
|
3123
|
-
<div>\3c !-- Dummy div to avoid p tag in Markdown --></div><img
|
|
3124
|
-
src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='3000' height='300'><rect width='100%' height='100%' fill='gray'/></svg>">
|
|
3125
|
-
|
|
3126
|
-
Or table:
|
|
3127
|
-
|
|
3128
|
-
| Imagine<hr> | a<hr> | really<hr> | wide<hr> | table<hr> | here<hr> |
|
|
3129
|
-
| ----------- | ----- | ---------- | -------- | --------- | -------- |
|
|
3130
|
-
| ... |
|
|
3131
|
-
|
|
3132
|
-
Or code block:
|
|
3133
|
-
|
|
3134
|
-
```html
|
|
3135
|
-
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam, quod. Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam, quod.</p>
|
|
3136
|
-
```
|
|
3137
|
-
|
|
3138
|
-
Or anything else:
|
|
3139
|
-
|
|
3140
|
-
<article class="breakout-item-max" data-theme="dark">
|
|
3141
|
-
|
|
3142
|
-
Using `.breakout-item` and `.breakout-item-max` helpers {style=margin:0}
|
|
3143
|
-
</article>
|
|
3144
|
-
|
|
3145
|
-
<div><hr></div>
|
|
3146
|
-
|
|
3147
|
-
`.breakout-all` also visually breaks out headings and horizontal rules:
|
|
3148
|
-
|
|
3149
|
-
<h2>Heading 2</h2><h3>Heading 3</h3><h4>Heading 4</h4><h5>Heading 5</h5><h6>Heading 6</h6>
|
|
3150
|
-
<hr>
|
|
3151
|
-
|
|
3152
|
-
\3c !--section--> */
|
|
3153
3033
|
/*\3c !--section:docs-->
|
|
3154
3034
|
|
|
3155
3035
|
`.columns` automatically creates columns with at least 30 characters each:
|
|
@@ -3177,250 +3057,9 @@ Useful for tables of contents and long lists.
|
|
|
3177
3057
|
-moz-column-break-inside: avoid;
|
|
3178
3058
|
break-inside: avoid;
|
|
3179
3059
|
}
|
|
3180
|
-
/*```\3c !--section:docs-->
|
|
3181
|
-
|
|
3182
|
-
`<a href="#top">` is automatically fixed to the bottom-right corner with extra top padding for easier clicking:
|
|
3183
|
-
```css */
|
|
3184
|
-
[href="#top"] {
|
|
3185
|
-
position: fixed;
|
|
3186
|
-
right: 0;
|
|
3187
|
-
bottom: 0;
|
|
3188
|
-
padding-top: 50vh;
|
|
3189
|
-
}
|
|
3190
3060
|
/* Content */
|
|
3191
3061
|
/*\3c !--section:docs-->
|
|
3192
3062
|
|
|
3193
|
-
## Heading anchors
|
|
3194
|
-
|
|
3195
|
-
Links with `href="#..."` inside headings are automatically displayed as anchors:
|
|
3196
|
-
|
|
3197
|
-
<article>
|
|
3198
|
-
<h2 style="margin: 0 0 0 1.5rem">Heading with anchor <a aria-hidden="true" style="visibility: visible">#</a></h2>
|
|
3199
|
-
</article>
|
|
3200
|
-
|
|
3201
|
-
How it works:
|
|
3202
|
-
```css */
|
|
3203
|
-
h1,
|
|
3204
|
-
h2,
|
|
3205
|
-
h3,
|
|
3206
|
-
h4,
|
|
3207
|
-
h5,
|
|
3208
|
-
h6 {
|
|
3209
|
-
position: relative;
|
|
3210
|
-
}
|
|
3211
|
-
h1 a[aria-hidden="true"], h2 a[aria-hidden="true"], h3 a[aria-hidden="true"], h4 a[aria-hidden="true"], h5 a[aria-hidden="true"], h6 a[aria-hidden="true"] {
|
|
3212
|
-
visibility: hidden;
|
|
3213
|
-
position: absolute;
|
|
3214
|
-
top: 50%;
|
|
3215
|
-
right: 100%;
|
|
3216
|
-
padding-right: 0.2ch;
|
|
3217
|
-
transform: translateY(-50%);
|
|
3218
|
-
color: silver;
|
|
3219
|
-
text-decoration: none;
|
|
3220
|
-
}
|
|
3221
|
-
@media /* to avoid double-tap on touch devices */ (hover: hover) {
|
|
3222
|
-
h1:hover a[aria-hidden="true"], h2:hover a[aria-hidden="true"], h3:hover a[aria-hidden="true"], h4:hover a[aria-hidden="true"], h5:hover a[aria-hidden="true"], h6:hover a[aria-hidden="true"] {
|
|
3223
|
-
visibility: visible;
|
|
3224
|
-
}
|
|
3225
|
-
}
|
|
3226
|
-
/*\3c !--section:docs-->
|
|
3227
|
-
|
|
3228
|
-
## Custom markers
|
|
3229
|
-
|
|
3230
|
-
Customize markers using inline `style="--list-marker:..."` on `<ul>/<ol>` or even individual `<li>`:
|
|
3231
|
-
|
|
3232
|
-
<article>
|
|
3233
|
-
|
|
3234
|
-
- you
|
|
3235
|
-
- can
|
|
3236
|
-
- make
|
|
3237
|
-
- really
|
|
3238
|
-
- cool markers {style="--list-marker:'🧊 '"}
|
|
3239
|
-
- with
|
|
3240
|
-
- *Bl*ades {style="--list-marker:'🥷 '"}
|
|
3241
|
-
|
|
3242
|
-
{style="--list-marker:'→ '"}
|
|
3243
|
-
</article>
|
|
3244
|
-
|
|
3245
|
-
How it works:
|
|
3246
|
-
```css */
|
|
3247
|
-
ul[style*="--list-marker:"], ol[style*="--list-marker:"] {
|
|
3248
|
-
list-style-type: var(--list-marker);
|
|
3249
|
-
}
|
|
3250
|
-
ul[style*="--list-marker:"] > li, ol[style*="--list-marker:"] > li {
|
|
3251
|
-
list-style-type: inherit;
|
|
3252
|
-
}
|
|
3253
|
-
ul li[style*="--list-marker:"], ol li[style*="--list-marker:"] {
|
|
3254
|
-
list-style-type: var(--list-marker);
|
|
3255
|
-
}
|
|
3256
|
-
ul li[data-marker]::marker, ol li[data-marker]::marker {
|
|
3257
|
-
content: attr(data-marker) " "; /* ⚠️ Chrome and Firefox only */
|
|
3258
|
-
}
|
|
3259
|
-
/*```
|
|
3260
|
-
|
|
3261
|
-
## Markerless
|
|
3262
|
-
|
|
3263
|
-
`.markerless` removes markers and reduces padding:
|
|
3264
|
-
|
|
3265
|
-
<article>
|
|
3266
|
-
|
|
3267
|
-
- 1️⃣ so you can use
|
|
3268
|
-
- 2️⃣ emojis or images
|
|
3269
|
-
- 3️⃣ instead of bullets
|
|
3270
|
-
|
|
3271
|
-
{.markerless}
|
|
3272
|
-
</article>
|
|
3273
|
-
|
|
3274
|
-
How it works:
|
|
3275
|
-
```css */
|
|
3276
|
-
ul.markerless, ol.markerless {
|
|
3277
|
-
padding-inline-start: 1.25rem;
|
|
3278
|
-
}
|
|
3279
|
-
ul.markerless li, ol.markerless li {
|
|
3280
|
-
list-style: none;
|
|
3281
|
-
}
|
|
3282
|
-
/*```
|
|
3283
|
-
|
|
3284
|
-
## Unlist
|
|
3285
|
-
|
|
3286
|
-
`.unlist` removes list styling at all:
|
|
3287
|
-
|
|
3288
|
-
<article>
|
|
3289
|
-
|
|
3290
|
-
- One: <article>1</article>
|
|
3291
|
-
- Two: <article>2</article>
|
|
3292
|
-
- Three: <article>3</article>
|
|
3293
|
-
|
|
3294
|
-
{.unlist .grid style=margin:0}
|
|
3295
|
-
</article>
|
|
3296
|
-
|
|
3297
|
-
`.unlist-all` removes styling from all nested lists too.
|
|
3298
|
-
|
|
3299
|
-
How it works:
|
|
3300
|
-
```css */
|
|
3301
|
-
ul.unlist,
|
|
3302
|
-
ul.unlist-all,
|
|
3303
|
-
.unlist-all ul,
|
|
3304
|
-
ol.unlist,
|
|
3305
|
-
ol.unlist-all,
|
|
3306
|
-
.unlist-all ol {
|
|
3307
|
-
padding-inline-start: 0;
|
|
3308
|
-
}
|
|
3309
|
-
ul.unlist > li, ul.unlist-all > li, .unlist-all ul > li, ol.unlist > li, ol.unlist-all > li, .unlist-all ol > li {
|
|
3310
|
-
list-style: none;
|
|
3311
|
-
}
|
|
3312
|
-
/*\3c !--section:docs-->
|
|
3313
|
-
|
|
3314
|
-
## Column expanders
|
|
3315
|
-
|
|
3316
|
-
Place `<hr>` element inside `<th>` column to expand it horizontally:
|
|
3317
|
-
|
|
3318
|
-
<article>
|
|
3319
|
-
|
|
3320
|
-
| Column with `<hr>`<hr> | Same column without `<hr>` | ... {style=width:100%} |
|
|
3321
|
-
| --- | --- | --- |
|
|
3322
|
-
| (012) 345-6789 | (012) 345-6789 |
|
|
3323
|
-
</article>
|
|
3324
|
-
|
|
3325
|
-
Living examples of big tables with `<hr>`-expanders: \3c !--A-Z-->
|
|
3326
|
-
- https://blades.ninja/ai/ide/
|
|
3327
|
-
- https://blades.ninja/build-awesome-11ty/starters/
|
|
3328
|
-
- https://blades.ninja/css/frameworks/
|
|
3329
|
-
- https://blades.ninja/ssg/
|
|
3330
|
-
|
|
3331
|
-
How it works:
|
|
3332
|
-
```css */
|
|
3333
|
-
th hr {
|
|
3334
|
-
visibility: hidden;
|
|
3335
|
-
width: 12ch; /* min ~65/12 = ~5 cols */
|
|
3336
|
-
height: 0;
|
|
3337
|
-
margin: 0;
|
|
3338
|
-
}
|
|
3339
|
-
th hr.lg {
|
|
3340
|
-
width: 18ch;
|
|
3341
|
-
}
|
|
3342
|
-
th hr.x2 {
|
|
3343
|
-
width: 24ch;
|
|
3344
|
-
}
|
|
3345
|
-
/*```
|
|
3346
|
-
|
|
3347
|
-
## Borderless table
|
|
3348
|
-
|
|
3349
|
-
`.borderless` removes all default borders:
|
|
3350
|
-
|
|
3351
|
-
<article>
|
|
3352
|
-
|
|
3353
|
-
| Less | borders |
|
|
3354
|
-
| ---- | ------- |
|
|
3355
|
-
| More | fun |
|
|
3356
|
-
|
|
3357
|
-
{.borderless}
|
|
3358
|
-
</article>
|
|
3359
|
-
|
|
3360
|
-
\3c !--section-->*/
|
|
3361
|
-
table.borderless th,
|
|
3362
|
-
table.borderless td {
|
|
3363
|
-
border: none;
|
|
3364
|
-
}
|
|
3365
|
-
/*
|
|
3366
|
-
\3c !--section:code-->
|
|
3367
|
-
```css */
|
|
3368
|
-
table.responsive,
|
|
3369
|
-
.breakout > table:not(.does-not-exist),
|
|
3370
|
-
.breakout-all > table:not(.does-not-exist) {
|
|
3371
|
-
|
|
3372
|
-
/* Let them scroll */
|
|
3373
|
-
display: block;
|
|
3374
|
-
|
|
3375
|
-
/* Let them full-bleed */
|
|
3376
|
-
width: -moz-max-content;
|
|
3377
|
-
width: max-content;
|
|
3378
|
-
min-width: auto;
|
|
3379
|
-
max-width: 100dvw;
|
|
3380
|
-
/* Center horizontally */
|
|
3381
|
-
margin-left: 50%;
|
|
3382
|
-
padding-inline: 7.5%;
|
|
3383
|
-
overflow-x: auto;
|
|
3384
|
-
transform: translateX(-50%);
|
|
3385
|
-
-webkit-overflow-scrolling: touch; /* Smooth scroll for iOS */
|
|
3386
|
-
}
|
|
3387
|
-
table.responsive th,
|
|
3388
|
-
table.responsive td,
|
|
3389
|
-
.breakout > table:not(.does-not-exist) th,
|
|
3390
|
-
.breakout > table:not(.does-not-exist) td,
|
|
3391
|
-
.breakout-all > table:not(.does-not-exist) th,
|
|
3392
|
-
.breakout-all > table:not(.does-not-exist) td {
|
|
3393
|
-
padding-inline-start: 0;
|
|
3394
|
-
}
|
|
3395
|
-
/*```
|
|
3396
|
-
`table:not(.does-not-exist)` trick (inspired by postcss) is used here to increase specificity against selectors like `&:is(table, .table)`
|
|
3397
|
-
|
|
3398
|
-
\3c !--section:summary-->
|
|
3399
|
-
|
|
3400
|
-
`.responsive` makes a table full-bleed and scroll on mobile, without a need for a redundant wrapper (finally).
|
|
3401
|
-
Tables inside https://blades.ninja/css/breakout/ are responsive by default.
|
|
3402
|
-
|
|
3403
|
-
\3c !--section:docs-->
|
|
3404
|
-
|
|
3405
|
-
### Demo table
|
|
3406
|
-
|
|
3407
|
-
| Term | Description <hr class="x2"> | Link |
|
|
3408
|
-
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- |
|
|
3409
|
-
| Responsive design | Approach to web design that aims to make web pages render well on a variety of devices and window or screen sizes from minimum to maximum display size to ensure usability and satisfaction. | https://en.wikipedia.org/wiki/Responsive_web_design |
|
|
3410
|
-
|
|
3411
|
-
{.responsive}
|
|
3412
|
-
|
|
3413
|
-
---
|
|
3414
|
-
|
|
3415
|
-
Living examples: \3c !--A-Z-->
|
|
3416
|
-
- https://blades.ninja/ai/ide/
|
|
3417
|
-
- https://blades.ninja/build-awesome-11ty/starters/
|
|
3418
|
-
- https://blades.ninja/css/frameworks/
|
|
3419
|
-
- https://blades.ninja/ssg/
|
|
3420
|
-
|
|
3421
|
-
\3c !--section--> */
|
|
3422
|
-
/*\3c !--section:docs-->
|
|
3423
|
-
|
|
3424
3063
|
The `<pre><code>` blocks are Prism-compatible and support captions via `data-caption="..."` attribute:
|
|
3425
3064
|
|
|
3426
3065
|
```treeview {data-caption="Blades CSS ships:"}
|
|
@@ -3551,7 +3190,139 @@ The `:has(*:placeholder-shown:not(:focus))` trick allows this input state inform
|
|
|
3551
3190
|
Historically, this was not possible: the float label had to be placed after the input field to be targeted using the `input:focus + label` selector.
|
|
3552
3191
|
|
|
3553
3192
|
*/
|
|
3193
|
+
label:has(> span):has(
|
|
3194
|
+
input:not([type="checkbox"], [type="radio"], [type="range"]),
|
|
3195
|
+
textarea,
|
|
3196
|
+
select
|
|
3197
|
+
),
|
|
3198
|
+
.has-float-label {
|
|
3199
|
+
|
|
3200
|
+
/* Enlarged state */
|
|
3201
|
+
}
|
|
3202
|
+
/* Default/fallback state */
|
|
3203
|
+
label:has(> span):has(
|
|
3204
|
+
input:not([type="checkbox"], [type="radio"], [type="range"]),
|
|
3205
|
+
textarea,
|
|
3206
|
+
select
|
|
3207
|
+
) > span,
|
|
3208
|
+
label:has(> span):has(
|
|
3209
|
+
input:not([type="checkbox"], [type="radio"], [type="range"]),
|
|
3210
|
+
textarea,
|
|
3211
|
+
select
|
|
3212
|
+
) label,
|
|
3213
|
+
.has-float-label > span,
|
|
3214
|
+
.has-float-label label {
|
|
3215
|
+
padding-inline-start: calc(1rem + 1px); /* match Pico's padding + border */
|
|
3216
|
+
padding-block-start: 0.25rem;
|
|
3217
|
+
opacity: 75%;
|
|
3218
|
+
transition: all 0.25s;
|
|
3219
|
+
}
|
|
3220
|
+
label:has(> span):has(
|
|
3221
|
+
input:not([type="checkbox"], [type="radio"], [type="range"]),
|
|
3222
|
+
textarea,
|
|
3223
|
+
select
|
|
3224
|
+
) input,
|
|
3225
|
+
label:has(> span):has(
|
|
3226
|
+
input:not([type="checkbox"], [type="radio"], [type="range"]),
|
|
3227
|
+
textarea,
|
|
3228
|
+
select
|
|
3229
|
+
) textarea,
|
|
3230
|
+
label:has(> span):has(
|
|
3231
|
+
input:not([type="checkbox"], [type="radio"], [type="range"]),
|
|
3232
|
+
textarea,
|
|
3233
|
+
select
|
|
3234
|
+
) select,
|
|
3235
|
+
.has-float-label input,
|
|
3236
|
+
.has-float-label textarea,
|
|
3237
|
+
.has-float-label select {
|
|
3238
|
+
margin-block-start: 0; /* reset Pico */
|
|
3239
|
+
padding-inline-start: 1rem; /* match Pico */
|
|
3240
|
+
padding-block: 1.125rem 0.375rem; /* match Pico's total: 2 x 0.75rem = 1.5rem */
|
|
3241
|
+
}
|
|
3242
|
+
label:has(> span):has(
|
|
3243
|
+
input:not([type="checkbox"], [type="radio"], [type="range"]),
|
|
3244
|
+
textarea,
|
|
3245
|
+
select
|
|
3246
|
+
) input::-moz-placeholder, label:has(> span):has(
|
|
3247
|
+
input:not([type="checkbox"], [type="radio"], [type="range"]),
|
|
3248
|
+
textarea,
|
|
3249
|
+
select
|
|
3250
|
+
) textarea::-moz-placeholder, label:has(> span):has(
|
|
3251
|
+
input:not([type="checkbox"], [type="radio"], [type="range"]),
|
|
3252
|
+
textarea,
|
|
3253
|
+
select
|
|
3254
|
+
) select::-moz-placeholder, .has-float-label input::-moz-placeholder, .has-float-label textarea::-moz-placeholder, .has-float-label select::-moz-placeholder {
|
|
3255
|
+
opacity: 100%;
|
|
3256
|
+
-moz-transition: all 0.25s;
|
|
3257
|
+
transition: all 0.25s;
|
|
3258
|
+
}
|
|
3259
|
+
label:has(> span):has(
|
|
3260
|
+
input:not([type="checkbox"], [type="radio"], [type="range"]),
|
|
3261
|
+
textarea,
|
|
3262
|
+
select
|
|
3263
|
+
) input::placeholder, label:has(> span):has(
|
|
3264
|
+
input:not([type="checkbox"], [type="radio"], [type="range"]),
|
|
3265
|
+
textarea,
|
|
3266
|
+
select
|
|
3267
|
+
) textarea::placeholder, label:has(> span):has(
|
|
3268
|
+
input:not([type="checkbox"], [type="radio"], [type="range"]),
|
|
3269
|
+
textarea,
|
|
3270
|
+
select
|
|
3271
|
+
) select::placeholder, .has-float-label input::placeholder, .has-float-label textarea::placeholder, .has-float-label select::placeholder {
|
|
3272
|
+
opacity: 100%;
|
|
3273
|
+
transition: all 0.25s;
|
|
3274
|
+
}
|
|
3275
|
+
label:has(> span):has(
|
|
3276
|
+
input:not([type="checkbox"], [type="radio"], [type="range"]),
|
|
3277
|
+
textarea,
|
|
3278
|
+
select
|
|
3279
|
+
):has(*:-moz-placeholder:not(:focus)) > span, label:has(> span):has(
|
|
3280
|
+
input:not([type="checkbox"], [type="radio"], [type="range"]),
|
|
3281
|
+
textarea,
|
|
3282
|
+
select
|
|
3283
|
+
):has(*:-moz-placeholder:not(:focus)) label, .has-float-label:has(*:-moz-placeholder:not(:focus)) > span, .has-float-label:has(*:-moz-placeholder:not(:focus)) label {
|
|
3284
|
+
padding-block: 0.75rem; /* match Pico */
|
|
3285
|
+
}
|
|
3286
|
+
label:has(> span):has(
|
|
3287
|
+
input:not([type="checkbox"], [type="radio"], [type="range"]),
|
|
3288
|
+
textarea,
|
|
3289
|
+
select
|
|
3290
|
+
):has(*:placeholder-shown:not(:focus)) > span,
|
|
3291
|
+
label:has(> span):has(
|
|
3292
|
+
input:not([type="checkbox"], [type="radio"], [type="range"]),
|
|
3293
|
+
textarea,
|
|
3294
|
+
select
|
|
3295
|
+
):has(*:placeholder-shown:not(:focus)) label,
|
|
3296
|
+
.has-float-label:has(*:placeholder-shown:not(:focus)) > span,
|
|
3297
|
+
.has-float-label:has(*:placeholder-shown:not(:focus)) label {
|
|
3298
|
+
padding-block: 0.75rem; /* match Pico */
|
|
3299
|
+
}
|
|
3554
3300
|
/* Components */
|
|
3301
|
+
/*\3c !--section:docs-->
|
|
3302
|
+
|
|
3303
|
+
A `<dialog>` opened with `dialog.showModal()` fades in and its `<article>` zooms in, without JS classes.
|
|
3304
|
+
Pico's modal JS (`.modal-is-open`, `.modal-is-opening`, `.modal-is-closing`) still works on top of it.
|
|
3305
|
+
|
|
3306
|
+
- `dialog.close()` closes it at once, as before.
|
|
3307
|
+
- `<dialog open>` in markup and non-modal `dialog.show()` aren't animated.
|
|
3308
|
+
- Browsers without `@starting-style`, and reduced motion, open it at once.
|
|
3309
|
+
|
|
3310
|
+
\3c !--section:code-->```css */
|
|
3311
|
+
dialog:modal {
|
|
3312
|
+
transition: opacity var(--pico-transition);
|
|
3313
|
+
}
|
|
3314
|
+
dialog:modal > article {
|
|
3315
|
+
transition: transform var(--pico-transition);
|
|
3316
|
+
}
|
|
3317
|
+
@starting-style {
|
|
3318
|
+
dialog:modal {
|
|
3319
|
+
opacity: 0;
|
|
3320
|
+
}
|
|
3321
|
+
|
|
3322
|
+
dialog:modal > article {
|
|
3323
|
+
transform: scale(0.96);
|
|
3324
|
+
}
|
|
3325
|
+
}
|
|
3555
3326
|
/* Extends https://github.com/picocss/pico/blob/main/scss/content/_link.scss
|
|
3556
3327
|
\3c !--section:code-->
|
|
3557
3328
|
```css */
|
|
@@ -3611,241 +3382,178 @@ How we made it: https://codepen.io/editor/anydigital/pen/019d2b94-5616-75dc-a23e
|
|
|
3611
3382
|
\3c !--section--> */
|
|
3612
3383
|
/*\3c !--section:docs-->
|
|
3613
3384
|
|
|
3614
|
-
|
|
3615
|
-
|
|
3385
|
+
A `<ul>` or `<menu>` with the `popover` attribute is styled like a dropdown and opens next to the button
|
|
3386
|
+
that toggles it, with no JS:
|
|
3616
3387
|
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3388
|
+
```html
|
|
3389
|
+
<button popovertarget="actions">Actions</button>
|
|
3390
|
+
<ul id="actions" popover>
|
|
3391
|
+
<li><a href="#">Edit</a></li>
|
|
3392
|
+
<li><a href="#">Duplicate</a></li>
|
|
3393
|
+
</ul>
|
|
3394
|
+
```
|
|
3624
3395
|
|
|
3625
|
-
|
|
3396
|
+
- Clicking outside or pressing Esc closes it, and it's drawn on top of everything (no `z-index`, no clipping by `overflow`).
|
|
3397
|
+
- It opens below the button (on the reading side, also in RTL) and flips when there's no room.
|
|
3398
|
+
Open it with `popovertarget`, `commandfor` or `showPopover({ source })`, so it knows its button.
|
|
3399
|
+
- Browsers without CSS anchor positioning show it in the middle of the screen instead, like a plain popover.
|
|
3400
|
+
- It uses the dropdown colours (`--pico-dropdown-*`, from `components/dropdown`).
|
|
3626
3401
|
|
|
3627
3402
|
\3c !--section:code-->```css */
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
How it works:
|
|
3645
|
-
```css */
|
|
3646
|
-
/* Per https://picocss.com/docs/css-variables#css-variables-for-color-schemes */
|
|
3647
|
-
:root {
|
|
3648
|
-
--blades-dark-filter: invert(100%) hue-rotate(180deg);
|
|
3649
|
-
}
|
|
3650
|
-
.dark-auto {
|
|
3651
|
-
/* Dark color scheme (Forced) */
|
|
3652
|
-
}
|
|
3653
|
-
/* Dark color scheme (Auto) */
|
|
3654
|
-
@media (prefers-color-scheme: dark) {
|
|
3655
|
-
.dark-auto {
|
|
3656
|
-
filter: var(--blades-dark-filter)
|
|
3657
|
-
}
|
|
3658
|
-
}
|
|
3659
|
-
.dark-auto[data-theme="dark"],
|
|
3660
|
-
.dark-auto:where([data-theme="dark"] *) {
|
|
3661
|
-
filter: var(--blades-dark-filter);
|
|
3662
|
-
}
|
|
3663
|
-
/*```
|
|
3664
|
-
|
|
3665
|
-
## Faded
|
|
3666
|
-
|
|
3667
|
-
`.faded` reduces the opacity of an element:
|
|
3668
|
-
|
|
3669
|
-
<article class="faded">
|
|
3670
|
-
Hover to unfade me!
|
|
3671
|
-
</article>
|
|
3672
|
-
|
|
3673
|
-
How it works:
|
|
3674
|
-
```css */
|
|
3675
|
-
.faded {
|
|
3676
|
-
opacity: 50%;
|
|
3403
|
+
:is(ul, menu)[popover] {
|
|
3404
|
+
min-width: -moz-fit-content;
|
|
3405
|
+
min-width: fit-content;
|
|
3406
|
+
margin: auto;
|
|
3407
|
+
padding: 0;
|
|
3408
|
+
border: var(--pico-border-width) solid var(--pico-dropdown-border-color);
|
|
3409
|
+
border-radius: var(--pico-border-radius);
|
|
3410
|
+
background-color: var(--pico-dropdown-background-color);
|
|
3411
|
+
box-shadow: var(--pico-dropdown-box-shadow);
|
|
3412
|
+
color: var(--pico-dropdown-color);
|
|
3413
|
+
white-space: nowrap;
|
|
3414
|
+
opacity: 0;
|
|
3415
|
+
transition:
|
|
3416
|
+
opacity var(--pico-transition),
|
|
3417
|
+
overlay var(--pico-transition) allow-discrete,
|
|
3418
|
+
display var(--pico-transition) allow-discrete;
|
|
3677
3419
|
}
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
/*```
|
|
3682
|
-
\3c !--section--> */
|
|
3683
|
-
|
|
3684
|
-
/* Fix the scrollbar color when inverted by https://tailwindcss.com/docs/filter-invert */
|
|
3685
|
-
.invert ::-webkit-scrollbar {
|
|
3686
|
-
filter: invert(1) !important;
|
|
3420
|
+
/* Beats `nav ul` / `aside ul`, which would otherwise show the closed menu */
|
|
3421
|
+
:is(ul, menu)[popover]:not(:popover-open) {
|
|
3422
|
+
display: none;
|
|
3687
3423
|
}
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) label,
|
|
3692
|
-
.has-float-label > span,
|
|
3693
|
-
.has-float-label label {
|
|
3694
|
-
padding-inline-start: calc(1rem + 1px); /* match Pico's padding + border */
|
|
3695
|
-
padding-block-start: 0.25rem;
|
|
3696
|
-
opacity: 75%;
|
|
3697
|
-
transition: all 0.25s;
|
|
3424
|
+
:is(ul, menu)[popover]:popover-open {
|
|
3425
|
+
display: block;
|
|
3426
|
+
opacity: 1;
|
|
3698
3427
|
}
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
margin-block-start: 0; /* reset Pico */
|
|
3706
|
-
padding-inline-start: 1rem; /* match Pico */
|
|
3707
|
-
padding-block: 1.125rem 0.375rem; /* match Pico's total: 2 x 0.75rem = 1.5rem */
|
|
3428
|
+
:is(ul, menu)[popover] li {
|
|
3429
|
+
display: block;
|
|
3430
|
+
margin-bottom: 0;
|
|
3431
|
+
padding: calc(var(--pico-form-element-spacing-vertical) * 0.5)
|
|
3432
|
+
var(--pico-form-element-spacing-horizontal);
|
|
3433
|
+
list-style: none;
|
|
3708
3434
|
}
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
-moz-transition: all 0.25s;
|
|
3712
|
-
transition: all 0.25s;
|
|
3435
|
+
:is(ul, menu)[popover] li:first-of-type {
|
|
3436
|
+
margin-top: calc(var(--pico-form-element-spacing-vertical) * 0.5);
|
|
3713
3437
|
}
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
transition: all 0.25s;
|
|
3438
|
+
:is(ul, menu)[popover] li:last-of-type {
|
|
3439
|
+
margin-bottom: calc(var(--pico-form-element-spacing-vertical) * 0.5);
|
|
3717
3440
|
}
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
padding-block: 0.75rem; /* match Pico */
|
|
3441
|
+
:is(ul, menu)[popover] li:has(label):hover {
|
|
3442
|
+
background-color: var(--pico-dropdown-hover-background-color);
|
|
3721
3443
|
}
|
|
3722
|
-
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
|
|
3444
|
+
:is(ul, menu)[popover] li a {
|
|
3445
|
+
display: block;
|
|
3446
|
+
margin: calc(var(--pico-form-element-spacing-vertical) * -0.5)
|
|
3447
|
+
calc(var(--pico-form-element-spacing-horizontal) * -1);
|
|
3448
|
+
padding: calc(var(--pico-form-element-spacing-vertical) * 0.5)
|
|
3449
|
+
var(--pico-form-element-spacing-horizontal);
|
|
3450
|
+
overflow: hidden;
|
|
3451
|
+
border-radius: 0;
|
|
3452
|
+
color: var(--pico-dropdown-color);
|
|
3453
|
+
text-decoration: none;
|
|
3454
|
+
text-overflow: ellipsis;
|
|
3455
|
+
}
|
|
3456
|
+
:is(ul, menu)[popover] li a:is(:hover, :focus, :active, :focus-visible, [aria-current]:not([aria-current="false"])) {
|
|
3457
|
+
background-color: var(--pico-dropdown-hover-background-color);
|
|
3727
3458
|
}
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
overflow-x: clip;
|
|
3731
|
-
|
|
3732
|
-
/* Enable font smoothing */
|
|
3733
|
-
-webkit-font-smoothing: antialiased;
|
|
3734
|
-
-moz-osx-font-smoothing: grayscale;
|
|
3735
|
-
}
|
|
3736
|
-
|
|
3737
|
-
body {
|
|
3738
|
-
|
|
3739
|
-
/* Make the `body` a flex container with column layout, and `main` to automatically fill available space. This is useful for creating sticky footers and full-height layouts. */
|
|
3740
|
-
display: flex;
|
|
3741
|
-
flex-direction: column;
|
|
3742
|
-
/* Ensure `body` takes at least the full height of the viewport (using dynamic viewport height for better mobile support). */
|
|
3743
|
-
min-height: 100dvh;
|
|
3744
|
-
|
|
3745
|
-
/* Evaluates the last ~4 lines of text blocks to prevent a single word from sitting on the final line. */
|
|
3746
|
-
|
|
3747
|
-
/* Enable global hyphenation */
|
|
3748
|
-
/* ... except for links and tables which are better (safer) without hyphenation */
|
|
3749
|
-
}
|
|
3750
|
-
|
|
3751
|
-
body > main {
|
|
3752
|
-
flex-grow: 1;
|
|
3459
|
+
:is(ul, menu)[popover] li label {
|
|
3460
|
+
width: 100%;
|
|
3753
3461
|
}
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
text-wrap: pretty;
|
|
3462
|
+
/* Beats Pico's `nav ul:first-of-type` / `:last-of-type` margins */
|
|
3463
|
+
nav :is(ul, menu)[popover] {
|
|
3464
|
+
margin: auto;
|
|
3758
3465
|
}
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
hyphens: none;
|
|
3466
|
+
@starting-style {
|
|
3467
|
+
:is(ul, menu)[popover]:popover-open {
|
|
3468
|
+
opacity: 0;
|
|
3763
3469
|
}
|
|
3470
|
+
}
|
|
3764
3471
|
|
|
3765
|
-
|
|
3766
|
-
|
|
3472
|
+
/* Next to the button that opened it (its implicit anchor) */
|
|
3473
|
+
@supports (position-area: bottom) {
|
|
3474
|
+
:is(ul, menu)[popover],
|
|
3475
|
+
nav :is(ul, menu)[popover] {
|
|
3476
|
+
position-area: bottom span-right;
|
|
3477
|
+
position-try-fallbacks: flip-block, flip-inline;
|
|
3478
|
+
margin: 0;
|
|
3479
|
+
margin-top: var(--pico-outline-width);
|
|
3480
|
+
inset: auto;
|
|
3767
3481
|
}
|
|
3768
3482
|
|
|
3769
|
-
|
|
3770
|
-
|
|
3483
|
+
:is(ul, menu)[popover]:dir(rtl), nav :is(ul, menu)[popover]:dir(rtl) {
|
|
3484
|
+
position-area: bottom span-left;
|
|
3771
3485
|
}
|
|
3772
|
-
|
|
3773
|
-
h1,
|
|
3774
|
-
h2,
|
|
3775
|
-
h3,
|
|
3776
|
-
h4,
|
|
3777
|
-
h5,
|
|
3778
|
-
h6 {
|
|
3779
|
-
text-wrap: balance;
|
|
3780
3486
|
}
|
|
3781
|
-
|
|
3782
|
-
margin-bottom: 1rem; /* for tw-typography */
|
|
3783
|
-
font-size: 2.5em; /* for pico.css & tw-typography */
|
|
3784
|
-
}
|
|
3785
|
-
|
|
3786
|
-
hr {
|
|
3787
|
-
margin-block: 2em; /* for pico.css & tw-typography */
|
|
3788
|
-
}
|
|
3789
|
-
|
|
3790
|
-
ul ul {
|
|
3791
|
-
font-size: 87.5%;
|
|
3792
|
-
}
|
|
3793
|
-
|
|
3794
|
-
dl dt {
|
|
3795
|
-
margin-block: 0.25rem;
|
|
3796
|
-
font-weight: 500;
|
|
3797
|
-
}
|
|
3487
|
+
/*\3c !--section:docs-->
|
|
3798
3488
|
|
|
3799
|
-
dl
|
|
3800
|
-
|
|
3801
|
-
}
|
|
3489
|
+
Use `dl.timeline` or wrap a `<dl>` with `.has-timeline` to style it as a
|
|
3490
|
+
vertical timeline — each `<dd>` gets a left border strip acting as the track:
|
|
3802
3491
|
|
|
3803
|
-
|
|
3804
|
-
font-weight: lighter;
|
|
3805
|
-
opacity: 75%;
|
|
3806
|
-
}
|
|
3492
|
+
<article class="has-timeline">
|
|
3807
3493
|
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
}
|
|
3494
|
+
May 11, 2026
|
|
3495
|
+
: First Blades CSS stable release (v2.2.0).
|
|
3811
3496
|
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
vertical-align: bottom;
|
|
3815
|
-
}
|
|
3497
|
+
Mar 15, 2025
|
|
3498
|
+
: Last Pico CSS update (v2.1.1).
|
|
3816
3499
|
|
|
3817
|
-
|
|
3818
|
-
vertical-align: top;
|
|
3819
|
-
}
|
|
3500
|
+
</article>
|
|
3820
3501
|
|
|
3821
|
-
|
|
3822
|
-
|
|
3502
|
+
\3c !--section:code-->```css */
|
|
3503
|
+
dl.timeline dd, .has-timeline > dl dd {
|
|
3504
|
+
margin-block: 0;
|
|
3505
|
+
padding: 0.25rem 0 0.75rem 1rem;
|
|
3506
|
+
border-inline-start: 0.25rem solid var(--blades-timeline-border-color);
|
|
3823
3507
|
}
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
3508
|
+
/* Compact version (opt-in via `data-compact` attr anywhere) */
|
|
3509
|
+
/*
|
|
3510
|
+
* Compact: opt-in denser sizing and a more current look, applied under `data-compact` on
|
|
3511
|
+
* <html> (whole page) or on any element such as a single <form>. Without the attribute it
|
|
3512
|
+
* changes nothing. Part of blades.css (and blades.layered.css); with per-part imports, import it
|
|
3513
|
+
* last (in the same layer as the other parts).
|
|
3514
|
+
*
|
|
3515
|
+
* The extra selectors keep the values winning where Pico re-declares them at the same
|
|
3516
|
+
* specificity: nested [data-theme] sections, the `.pico` root when combined with the conditional build,
|
|
3517
|
+
* and a shadow host.
|
|
3518
|
+
*/
|
|
3519
|
+
[data-compact],
|
|
3520
|
+
[data-compact] :is([data-theme], .pico),
|
|
3521
|
+
.pico[data-compact],
|
|
3522
|
+
:host([data-compact]),
|
|
3523
|
+
:host([data-compact]) [data-theme] {
|
|
3524
|
+
--pico-border-radius: 0.5rem;
|
|
3525
|
+
--pico-outline-width: 0.1875rem;
|
|
3526
|
+
--pico-block-spacing-vertical: 1.5rem;
|
|
3527
|
+
--pico-block-spacing-horizontal: 1.5rem;
|
|
3528
|
+
--pico-form-element-spacing-vertical: 0.375rem;
|
|
3529
|
+
--pico-form-element-spacing-horizontal: 0.75rem;
|
|
3530
|
+
--pico-form-label-font-weight: 500;
|
|
3531
|
+
--pico-button-font-weight: 500;
|
|
3532
|
+
--pico-form-element-background-color: light-dark(#fff, rgb(28, 33, 43.5));
|
|
3533
|
+
--pico-card-border-color: var(--pico-muted-border-color);
|
|
3534
|
+
--pico-card-box-shadow:
|
|
3535
|
+
0 0 0 var(--pico-border-width) var(--pico-card-border-color), 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
3536
|
+
--pico-card-sectioning-background-color: var(--pico-card-background-color);
|
|
3537
|
+
}
|
|
3538
|
+
|
|
3539
|
+
/* Search fields keep their pill shape */
|
|
3540
|
+
[data-compact]:is([role="search"], [type="search"]) {
|
|
3541
|
+
--pico-border-radius: 5rem;
|
|
3827
3542
|
}
|
|
3828
3543
|
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
display: inline-block;
|
|
3835
|
-
margin: 0.5rem;
|
|
3836
|
-
padding: 0.25rem 0.375rem;
|
|
3837
|
-
border-color: black;
|
|
3838
|
-
color: black;
|
|
3839
|
-
font-size: 0.75rem;
|
|
3840
|
-
}
|
|
3544
|
+
/* Page-level only: everything is sized in rem, so the root size can't change per element */
|
|
3545
|
+
:root[data-compact],
|
|
3546
|
+
:host([data-compact]) {
|
|
3547
|
+
--pico-font-size: 100%;
|
|
3548
|
+
}
|
|
3841
3549
|
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
margin-bottom: 1rem;
|
|
3847
|
-
}
|
|
3550
|
+
[data-compact] :is(h1, h2, h3, h4, h5, h6),
|
|
3551
|
+
:host([data-compact]) :is(h1, h2, h3, h4, h5, h6) {
|
|
3552
|
+
--pico-font-weight: 600;
|
|
3553
|
+
}
|
|
3848
3554
|
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3555
|
+
/* Keep helper text at the normal weight under the 500-weight labels */
|
|
3556
|
+
[data-compact] :where(input, select, textarea, fieldset, .grid) + small,
|
|
3557
|
+
:host([data-compact]) :where(input, select, textarea, fieldset, .grid) + small {
|
|
3558
|
+
font-weight: var(--pico-font-weight);
|
|
3559
|
+
}
|