@anyblades/blades 3.1.0-alpha.2 → 3.1.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/README.md +46 -15
  2. package/css/blades.css +158 -597
  3. package/css/blades.min.css +38 -12
  4. package/css/blades.ninja.css +4057 -0
  5. package/css/blades.ninja.min.css +190 -0
  6. package/css/float-label.css +207 -0
  7. package/css/float-label.min.css +55 -0
  8. package/css/{pico.layered.css → layered/blades.layered.css} +441 -16
  9. package/css/{pico.layered.min.css → layered/blades.layered.min.css} +74 -8
  10. package/css/layered/compact.css +54 -0
  11. package/css/layered/components/accordion.css +85 -0
  12. package/css/layered/components/card.css +48 -0
  13. package/css/layered/components/dropdown.css +191 -0
  14. package/css/layered/components/group.css +208 -0
  15. package/css/layered/components/loading.css +43 -0
  16. package/css/layered/components/modal.css +158 -0
  17. package/css/layered/components/nav.css +117 -0
  18. package/css/layered/components/progress.css +76 -0
  19. package/css/layered/components/tooltip.css +176 -0
  20. package/css/layered/components.css +1082 -0
  21. package/css/layered/content/button.css +208 -0
  22. package/css/layered/content/code.css +64 -0
  23. package/css/layered/content/embedded-content.css +41 -0
  24. package/css/layered/content/figure.css +15 -0
  25. package/css/layered/content/link.css +84 -0
  26. package/css/layered/content/misc.css +22 -0
  27. package/css/layered/content/table.css +33 -0
  28. package/css/layered/content/typography.css +159 -0
  29. package/css/layered/content.css +611 -0
  30. package/css/layered/forms/basics.css +338 -0
  31. package/css/layered/forms/checkbox-radio-switch.css +164 -0
  32. package/css/layered/forms/input-color.css +20 -0
  33. package/css/layered/forms/input-datetime.css +57 -0
  34. package/css/layered/forms/input-file.css +29 -0
  35. package/css/layered/forms/input-range.css +121 -0
  36. package/css/layered/forms/input-search.css +66 -0
  37. package/css/layered/forms.css +778 -0
  38. package/css/layered/layout/container.css +42 -0
  39. package/css/layered/layout/document.css +48 -0
  40. package/css/layered/layout/grid.css +22 -0
  41. package/css/layered/layout/landmarks.css +12 -0
  42. package/css/layered/layout/overflow-auto.css +9 -0
  43. package/css/layered/layout/section.css +9 -0
  44. package/css/layered/layout.css +119 -0
  45. package/css/layered/utilities.css +35 -0
  46. package/css/layered/variables.css +365 -0
  47. package/css/pico.conditional.css +16 -15
  48. package/css/pico.conditional.min.css +7 -7
  49. package/css/pico.css +16 -15
  50. package/css/pico.min.css +7 -7
  51. package/package.json +15 -11
  52. package/src/_compact.css +51 -0
  53. package/src/blades/_index.css +23 -0
  54. package/src/blades/float-label/_index.css +2 -0
  55. package/src/{standalone/forms/_float-label.theme.css → blades/float-label/_theme.css} +5 -1
  56. package/src/blades.css +3 -2
  57. package/src/blades.ninja.css +3 -0
  58. package/src/float-label.css +1 -0
  59. package/src/ninja/_index.css +19 -0
  60. package/src/{standalone → ninja}/_theme.css +0 -2
  61. package/src/{ninja.css → ninja/_utilities.css} +55 -6
  62. package/src/pico/_variables.css +6 -5
  63. package/src/pico/content/_button.css +1 -1
  64. package/src/pico/layout/_document.css +9 -0
  65. package/src/pico/layout/_index.css +0 -1
  66. package/src/pico/layout/_landmarks.css +1 -9
  67. package/src/pico.css +1 -0
  68. package/css/blades.standalone.css +0 -860
  69. package/css/blades.standalone.min.css +0 -37
  70. package/css/ninja.css +0 -83
  71. package/css/ninja.min.css +0 -5
  72. package/src/blades.standalone.css +0 -2
  73. package/src/standalone/_core.css +0 -32
  74. package/src/standalone/_utilities.css +0 -55
  75. package/src/standalone/forms/_float-label.css +0 -2
  76. /package/src/{standalone/content → blades}/_code.css +0 -0
  77. /package/src/{standalone/layout → blades}/_columns.css +0 -0
  78. /package/src/{standalone/components/_icon-helper.css → blades/_icon.css} +0 -0
  79. /package/src/{standalone/components → blades}/_timeline.css +0 -0
  80. /package/src/{standalone → blades}/_variables.css +0 -0
  81. /package/src/{standalone/forms/_float-label.core.css → blades/float-label/_core.css} +0 -0
  82. /package/src/{standalone/layout/_breakout.css → ninja/_container-breakout.css} +0 -0
  83. /package/src/{standalone/content/_typography.css → ninja/_heading-anchor.css} +0 -0
  84. /package/src/{standalone/content/_list.css → ninja/_list-helpers.css} +0 -0
  85. /package/src/{standalone/layout/_scroller.css → ninja/_page-anchors.css} +0 -0
  86. /package/src/{standalone/content/_table.css → ninja/_table-helpers.css} +0 -0
  87. /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
- --pico-primary-focus: light-dark(rgba(2, 154, 232, 0.5), rgba(1, 170, 255, 0.375));
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(rgba(93, 107, 137, 0.25), rgba(144, 158, 190, 0.25));
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(rgba(93, 107, 137, 0.25), rgba(207, 213, 226, 0.25));
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(149.5, 74, 80)
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(183.25, 63.5, 59)
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;
@@ -3021,135 +3013,6 @@ progress::-moz-progress-bar {
3021
3013
 
3022
3014
  /* Layout */
3023
3015
 
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
3016
  /*\3c !--section:docs-->
3154
3017
 
3155
3018
  `.columns` automatically creates columns with at least 30 characters each:
@@ -3177,250 +3040,9 @@ Useful for tables of contents and long lists.
3177
3040
  -moz-column-break-inside: avoid;
3178
3041
  break-inside: avoid;
3179
3042
  }
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
3043
  /* Content */
3191
3044
  /*\3c !--section:docs-->
3192
3045
 
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
3046
  The `<pre><code>` blocks are Prism-compatible and support captions via `data-caption="..."` attribute:
3425
3047
 
3426
3048
  ```treeview {data-caption="Blades CSS ships:"}
@@ -3551,6 +3173,113 @@ The `:has(*:placeholder-shown:not(:focus))` trick allows this input state inform
3551
3173
  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
3174
 
3553
3175
  */
3176
+ label:has(> span):has(
3177
+ input:not([type="checkbox"], [type="radio"], [type="range"]),
3178
+ textarea,
3179
+ select
3180
+ ),
3181
+ .has-float-label {
3182
+
3183
+ /* Enlarged state */
3184
+ }
3185
+ /* Default/fallback state */
3186
+ label:has(> span):has(
3187
+ input:not([type="checkbox"], [type="radio"], [type="range"]),
3188
+ textarea,
3189
+ select
3190
+ ) > span,
3191
+ label:has(> span):has(
3192
+ input:not([type="checkbox"], [type="radio"], [type="range"]),
3193
+ textarea,
3194
+ select
3195
+ ) label,
3196
+ .has-float-label > span,
3197
+ .has-float-label label {
3198
+ padding-inline-start: calc(1rem + 1px); /* match Pico's padding + border */
3199
+ padding-block-start: 0.25rem;
3200
+ opacity: 75%;
3201
+ transition: all 0.25s;
3202
+ }
3203
+ label:has(> span):has(
3204
+ input:not([type="checkbox"], [type="radio"], [type="range"]),
3205
+ textarea,
3206
+ select
3207
+ ) input,
3208
+ label:has(> span):has(
3209
+ input:not([type="checkbox"], [type="radio"], [type="range"]),
3210
+ textarea,
3211
+ select
3212
+ ) textarea,
3213
+ label:has(> span):has(
3214
+ input:not([type="checkbox"], [type="radio"], [type="range"]),
3215
+ textarea,
3216
+ select
3217
+ ) select,
3218
+ .has-float-label input,
3219
+ .has-float-label textarea,
3220
+ .has-float-label select {
3221
+ margin-block-start: 0; /* reset Pico */
3222
+ padding-inline-start: 1rem; /* match Pico */
3223
+ padding-block: 1.125rem 0.375rem; /* match Pico's total: 2 x 0.75rem = 1.5rem */
3224
+ }
3225
+ label:has(> span):has(
3226
+ input:not([type="checkbox"], [type="radio"], [type="range"]),
3227
+ textarea,
3228
+ select
3229
+ ) input::-moz-placeholder, label:has(> span):has(
3230
+ input:not([type="checkbox"], [type="radio"], [type="range"]),
3231
+ textarea,
3232
+ select
3233
+ ) textarea::-moz-placeholder, label:has(> span):has(
3234
+ input:not([type="checkbox"], [type="radio"], [type="range"]),
3235
+ textarea,
3236
+ select
3237
+ ) select::-moz-placeholder, .has-float-label input::-moz-placeholder, .has-float-label textarea::-moz-placeholder, .has-float-label select::-moz-placeholder {
3238
+ opacity: 100%;
3239
+ -moz-transition: all 0.25s;
3240
+ transition: all 0.25s;
3241
+ }
3242
+ label:has(> span):has(
3243
+ input:not([type="checkbox"], [type="radio"], [type="range"]),
3244
+ textarea,
3245
+ select
3246
+ ) input::placeholder, label:has(> span):has(
3247
+ input:not([type="checkbox"], [type="radio"], [type="range"]),
3248
+ textarea,
3249
+ select
3250
+ ) textarea::placeholder, label:has(> span):has(
3251
+ input:not([type="checkbox"], [type="radio"], [type="range"]),
3252
+ textarea,
3253
+ select
3254
+ ) select::placeholder, .has-float-label input::placeholder, .has-float-label textarea::placeholder, .has-float-label select::placeholder {
3255
+ opacity: 100%;
3256
+ transition: all 0.25s;
3257
+ }
3258
+ label:has(> span):has(
3259
+ input:not([type="checkbox"], [type="radio"], [type="range"]),
3260
+ textarea,
3261
+ select
3262
+ ):has(*:-moz-placeholder:not(:focus)) > span, label:has(> span):has(
3263
+ input:not([type="checkbox"], [type="radio"], [type="range"]),
3264
+ textarea,
3265
+ select
3266
+ ):has(*:-moz-placeholder:not(:focus)) label, .has-float-label:has(*:-moz-placeholder:not(:focus)) > span, .has-float-label:has(*:-moz-placeholder:not(:focus)) label {
3267
+ padding-block: 0.75rem; /* match Pico */
3268
+ }
3269
+ label:has(> span):has(
3270
+ input:not([type="checkbox"], [type="radio"], [type="range"]),
3271
+ textarea,
3272
+ select
3273
+ ):has(*:placeholder-shown:not(:focus)) > span,
3274
+ label:has(> span):has(
3275
+ input:not([type="checkbox"], [type="radio"], [type="range"]),
3276
+ textarea,
3277
+ select
3278
+ ):has(*:placeholder-shown:not(:focus)) label,
3279
+ .has-float-label:has(*:placeholder-shown:not(:focus)) > span,
3280
+ .has-float-label:has(*:placeholder-shown:not(:focus)) label {
3281
+ padding-block: 0.75rem; /* match Pico */
3282
+ }
3554
3283
  /* Components */
3555
3284
  /* Extends https://github.com/picocss/pico/blob/main/scss/content/_link.scss
3556
3285
  \3c !--section:code-->
@@ -3630,222 +3359,54 @@ dl.timeline dd, .has-timeline > dl dd {
3630
3359
  padding: 0.25rem 0 0.75rem 1rem;
3631
3360
  border-inline-start: 0.25rem solid var(--blades-timeline-border-color);
3632
3361
  }
3633
- /* Utilities */
3634
- /*\3c !--section:docs-->
3635
-
3636
- ## Dark auto
3637
-
3638
- `.dark-auto` automatically creates a simple dark version of any element:
3639
-
3640
- <article data-theme="dark">
3641
- <p>Look how cool <big class="dark-auto">🔥🕷️🐦‍⬛🐄🦓</big> can look in the dark!</p>
3642
- </article>
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%;
3677
- }
3678
- .faded:hover {
3679
- opacity: 87.5%;
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;
3687
- }
3688
- /*\3c !--section:code-->```css */
3689
- /* Default/fallback state */
3690
- label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) > span,
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;
3698
- }
3699
- label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) input,
3700
- label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) textarea,
3701
- label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) select,
3702
- .has-float-label input,
3703
- .has-float-label textarea,
3704
- .has-float-label select {
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 */
3708
- }
3709
- label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) input::-moz-placeholder, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) textarea::-moz-placeholder, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) select::-moz-placeholder, .has-float-label input::-moz-placeholder, .has-float-label textarea::-moz-placeholder, .has-float-label select::-moz-placeholder {
3710
- opacity: 100%;
3711
- -moz-transition: all 0.25s;
3712
- transition: all 0.25s;
3713
- }
3714
- label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) input::placeholder, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) textarea::placeholder, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) select::placeholder, .has-float-label input::placeholder, .has-float-label textarea::placeholder, .has-float-label select::placeholder {
3715
- opacity: 100%;
3716
- transition: all 0.25s;
3717
- }
3718
- /* Enlarged state */
3719
- label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) > span, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) label, .has-float-label:has(*:-moz-placeholder:not(:focus)) > span, .has-float-label:has(*:-moz-placeholder:not(:focus)) label {
3720
- padding-block: 0.75rem; /* match Pico */
3721
- }
3722
- label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) > span,
3723
- label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) label,
3724
- .has-float-label:has(*:placeholder-shown:not(:focus)) > span,
3725
- .has-float-label:has(*:placeholder-shown:not(:focus)) label {
3726
- padding-block: 0.75rem; /* match Pico */
3727
- }
3728
- html {
3729
- /* Prevent horizontal overflow and scrolling, modern way. */
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;
3753
- }
3754
-
3755
- body {
3756
- hyphens: auto;
3757
- text-wrap: pretty;
3362
+ /*
3363
+ * Compact: opt-in denser sizing and a more current look, applied under `data-compact` on
3364
+ * <html> (whole page) or on any element such as a single <form>. Without the attribute it
3365
+ * changes nothing. Part of blades.css (and blades.layered.css); with per-part imports, import it
3366
+ * last (in the same layer as the other parts).
3367
+ *
3368
+ * The extra selectors keep the values winning where Pico re-declares them at the same
3369
+ * specificity: nested [data-theme] sections, the `.pico` root when combined with the conditional build,
3370
+ * and a shadow host.
3371
+ */
3372
+ [data-compact],
3373
+ [data-compact] :is([data-theme], .pico),
3374
+ .pico[data-compact],
3375
+ :host([data-compact]),
3376
+ :host([data-compact]) [data-theme] {
3377
+ --pico-border-radius: 0.5rem;
3378
+ --pico-outline-width: 0.1875rem;
3379
+ --pico-block-spacing-vertical: 1.5rem;
3380
+ --pico-block-spacing-horizontal: 1.5rem;
3381
+ --pico-form-element-spacing-vertical: 0.375rem;
3382
+ --pico-form-element-spacing-horizontal: 0.75rem;
3383
+ --pico-form-label-font-weight: 500;
3384
+ --pico-button-font-weight: 500;
3385
+ --pico-form-element-background-color: light-dark(#fff, rgb(28, 33, 43.5));
3386
+ --pico-card-border-color: var(--pico-muted-border-color);
3387
+ --pico-card-box-shadow:
3388
+ 0 0 0 var(--pico-border-width) var(--pico-card-border-color), 0 1px 2px rgba(0, 0, 0, 0.05);
3389
+ --pico-card-sectioning-background-color: var(--pico-card-background-color);
3390
+ }
3391
+
3392
+ /* Search fields keep their pill shape */
3393
+ [data-compact]:is([role="search"], [type="search"]) {
3394
+ --pico-border-radius: 5rem;
3758
3395
  }
3759
3396
 
3760
- body a,
3761
- body table {
3762
- hyphens: none;
3763
- }
3764
-
3765
- a:not([href^="#"]) {
3766
- text-decoration-thickness: 1px;
3767
- }
3768
-
3769
- a:not([href^="#"]):hover {
3770
- text-decoration-thickness: 2px;
3771
- }
3772
-
3773
- h1,
3774
- h2,
3775
- h3,
3776
- h4,
3777
- h5,
3778
- h6 {
3779
- text-wrap: balance;
3780
- }
3781
- h1 {
3782
- margin-bottom: 1rem; /* for tw-typography */
3783
- font-size: 2.5em; /* for pico.css & tw-typography */
3397
+ /* Page-level only: everything is sized in rem, so the root size can't change per element */
3398
+ :root[data-compact],
3399
+ :host([data-compact]) {
3400
+ --pico-font-size: 100%;
3784
3401
  }
3785
3402
 
3786
- hr {
3787
- margin-block: 2em; /* for pico.css & tw-typography */
3403
+ [data-compact] :is(h1, h2, h3, h4, h5, h6),
3404
+ :host([data-compact]) :is(h1, h2, h3, h4, h5, h6) {
3405
+ --pico-font-weight: 600;
3788
3406
  }
3789
3407
 
3790
- ul ul {
3791
- font-size: 87.5%;
3792
- }
3793
-
3794
- dl dt {
3795
- margin-block: 0.25rem;
3796
- font-weight: 500;
3797
- }
3798
-
3799
- dl dd {
3800
- margin-block-end: 1rem;
3801
- }
3802
-
3803
- pre small {
3804
- font-weight: lighter;
3805
- opacity: 75%;
3806
- }
3807
-
3808
- pre:has(code) {
3809
- background: #181c25 !important;
3810
- }
3811
-
3812
- table th {
3813
- font-weight: bold;
3814
- vertical-align: bottom;
3815
- }
3816
-
3817
- table td {
3818
- vertical-align: top;
3819
- }
3820
-
3821
- table pre {
3822
- margin-bottom: 0.25rem;
3823
- }
3824
-
3825
- [href="#top"] {
3826
- opacity: 25%;
3408
+ /* Keep helper text at the normal weight under the 500-weight labels */
3409
+ [data-compact] :where(input, select, textarea, fieldset, .grid) + small,
3410
+ :host([data-compact]) :where(input, select, textarea, fieldset, .grid) + small {
3411
+ font-weight: var(--pico-font-weight);
3827
3412
  }
3828
-
3829
- [href="#top"]:hover {
3830
- opacity: 75%;
3831
- }
3832
-
3833
- [href="#top"] > i {
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
- }
3841
-
3842
- .breakout > img,
3843
- .breakout > figure,
3844
- .breakout-all > img,
3845
- .breakout-all > figure {
3846
- margin-bottom: 1rem;
3847
- }
3848
-
3849
- .faded a {
3850
- text-decoration-style: dotted;
3851
- }