@anydigital/blades 0.27.0-beta.9 → 0.28.0-alpha.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.
package/assets/blades.css CHANGED
@@ -3,34 +3,23 @@
3
3
  /* Layout */
4
4
 
5
5
  /* Extends https://github.com/picocss/pico/blob/main/scss/layout/
6
- <!--section:docs-->
6
+ <!--section:docs-intro-->
7
7
 
8
8
  Global styles:
9
- - Prevent horizontal overflow and scrolling, modern way.
10
9
  ```css */
11
10
 
12
11
  html {
12
+ /* Prevent horizontal overflow and scrolling, modern way. */
13
13
  overflow-x: clip;
14
14
  }
15
15
 
16
- /*```
17
-
18
- ### Landmarks
19
- - Ensure `body` takes at least the full height of the viewport (using dynamic viewport height for better mobile support).
20
- - 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.
21
- ```css */
22
-
23
16
  body {
17
+ /* Ensure `body` takes at least the full height of the viewport (using dynamic viewport height for better mobile support). */
24
18
  min-height: 100dvh;
25
-
26
- display: flex;
27
- flex-direction: column;
28
- > main {
29
- flex-grow: 1;
30
- }
31
19
  }
32
20
 
33
21
  /*```
22
+ <!--section:docs-->
34
23
 
35
24
  ### Auto-columns
36
25
  ```css */
@@ -151,10 +140,14 @@ Table of contents (`[data-is-toc]`) has auto-columns by default.
151
140
  }
152
141
  }
153
142
 
154
- /*```<!--section:docs-->
143
+ /*```
144
+ <!--section:docs,summary-->
145
+
155
146
  Framework-agnostic utilities for breaking out images and figures beyond their container width.
156
147
 
157
- Use the `.breakout` class to allow elements to extend beyond their parent container:
148
+ Use the `.breakout` class to allow elements to extend beyond their parent container.
149
+
150
+ <!--section:docs-->
158
151
 
159
152
  ```html
160
153
  <div class="breakout">
@@ -163,12 +156,13 @@ Use the `.breakout` class to allow elements to extend beyond their parent contai
163
156
  ```
164
157
 
165
158
  The breakout container has `10%` inline padding and a max-width of `calc(10% + 65ch + 10%)`. The breakout utilities support images, pictures, figures, canvas, audio, video, tables, pre, iframe, and other media elements. Tables inside `.breakout` are specifically enhanced for horizontal scrolling and full-bleed mobile display. This is automatically included when you import the stylesheet.
159
+
166
160
  <!--section--> */
167
161
 
168
162
  /* Content */
169
163
 
170
164
  /* Extends https://github.com/picocss/pico/blob/main/scss/content/_typography.scss
171
- <!--section:docs-->
165
+ <!--section:docs-intro-->
172
166
 
173
167
  Global styles:
174
168
  ```css */
@@ -180,6 +174,8 @@ html {
180
174
  }
181
175
 
182
176
  body {
177
+ /* Evaluates the last ~4 lines of text blocks to prevent a single word from sitting on the final line. */
178
+ text-wrap: pretty;
183
179
  /* Enable global hyphenation */
184
180
  hyphens: auto;
185
181
  /* ... except for links and tables which are better (safer) without hyphenation */
@@ -190,6 +186,7 @@ body {
190
186
  }
191
187
 
192
188
  /*```
189
+ <!--section:docs-->
193
190
 
194
191
  ### Heading anchors
195
192
 
@@ -209,13 +206,14 @@ h6 {
209
206
  position: relative;
210
207
 
211
208
  [data-is-anchor] {
212
- visibility: hidden;
213
209
  position: absolute;
214
- top: 0;
215
210
  right: 100%;
211
+ top: 50%;
212
+ transform: translateY(-50%);
216
213
  padding-right: 0.2ch;
217
214
  color: silver;
218
215
  text-decoration: none;
216
+ visibility: hidden;
219
217
  }
220
218
  /* Avoid double-tap on touch devices */
221
219
  @media (hover: hover) {
@@ -263,14 +261,20 @@ ol {
263
261
  /* ⚠️ `data-marker` works only in Chrome and Firefox */
264
262
  content: attr(data-marker) " ";
265
263
  }
264
+ }
266
265
 
267
- /* Helper class to remove list styling at all */
268
- &.unlist {
269
- padding-inline-start: 0;
266
+ /*```
270
267
 
271
- > li {
272
- list-style: none;
273
- }
268
+ ### Unlist
269
+
270
+ Helper class to remove list styling at all:
271
+ ```css */
272
+
273
+ .unlist {
274
+ padding-inline-start: 0;
275
+
276
+ > li {
277
+ list-style: none;
274
278
  }
275
279
  }
276
280
 
@@ -282,17 +286,32 @@ ol {
282
286
  ```css */
283
287
 
284
288
  a {
285
- /* Helper to handle [fav]icons in links */
289
+ /* Use inline flex only if link contains an icon */
290
+ &:has(> i) {
291
+ display: inline-flex;
292
+ gap: 0.375ch; /* =3/8 */
293
+ overflow-y: clip; /* to work in pair with text-underline-offset in Safari */
294
+ }
286
295
  > i {
287
- display: inline-block;
288
296
  font-style: normal;
297
+ float: left; /* ✅ Chrome ❌ Safari */
298
+ text-underline-offset: -2em; /* ❌ Chrome ✅ Safari - to clip it with overflow-y */
289
299
 
300
+ /* Favicons */
290
301
  > img {
291
302
  height: 1.25em;
292
303
  margin-block: calc(-0.25em / 2);
304
+ display: inline-block; /* for Tailwind CSS Typography */
305
+ }
293
306
 
294
- /* for tw-typography (.prose) */
295
- display: inline-block;
307
+ /* Font Awesome */
308
+ &[class^="fa-"],
309
+ &[class*=" fa-"] {
310
+ line-height: inherit;
311
+ --fa-width: auto;
312
+ }
313
+ &.fa-lg {
314
+ line-height: normal;
296
315
  }
297
316
  }
298
317
  }
@@ -300,29 +319,23 @@ a {
300
319
  /*```
301
320
  > **PRO-TIP** for 11ty: https://blades.ninja/build-awesome-11ty/processors/#auto-link-favicons
302
321
 
322
+ <!--section:docs,summary-->
323
+
324
+ Use Blades' `<i>`-helper to wrap emojis, favicons, or simply drop Font Awesome icons inside links. It automatically handles sizing and alignment while preventing underline on icons.
325
+
303
326
  <!--section:docs-->
304
327
 
305
- ### Link [fav]icons
328
+ Compare:
306
329
 
307
- Wrap [fav]icons inside links using `<i>...&nbsp;</i>` helper to size automatically and avoid underline. Compare:
330
+ | Without Blades <hr class="lg"> | With Blades' `<i>`-helper <hr class="lg"> | Clean HTML without `<span>ning` <hr class="x2"> |
331
+ | ------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- |
332
+ | [🥷 Link with emoji](#) | [<i>🥷</i> Link with emoji](#) | `<a><i>🥷</i> Text</a>` |
333
+ | [![](https://www.google.com/s2/favicons?domain=any.digital&sz=64) Multi-line link <br> with favicon](#) | [<i>![](https://www.google.com/s2/favicons?domain=any.digital&sz=64)</i> Multi-line link <br> with favicon](#) | `<a><i><img src="..."></i> Text</a>` |
334
+ | [<b class="fa-brands fa-github fa-lg"></b> Link with Font Awesome icon](#) | [<i class="fa-brands fa-github fa-lg"></i> Link with Font Awesome icon](#) | `<a><i class="fa-..."></i> Text</a>` |
308
335
 
309
- <big class="grid">
310
- <article><a href="https://github.com/anydigital/blades">
311
- 🥷 Blades
312
- </a></article>
313
- <article><a href="https://github.com/anydigital/blades">
314
- <i>🥷&nbsp;</i>Blades
315
- </a></article>
316
- </big>
336
+ ---
317
337
 
318
- <big class="grid">
319
- <article><a href="https://github.com/anydigital/blades">
320
- <img src="https://www.google.com/s2/favicons?domain=github.com&amp;sz=64" >/anydigital/blades
321
- </a></article>
322
- <article><a href="https://github.com/anydigital/blades">
323
- <i><img src="https://www.google.com/s2/favicons?domain=github.com&amp;sz=64">&nbsp;</i>/anydigital/blades
324
- </a></article>
325
- </big>
338
+ [How we made it ↗ &nbsp;<small>(on Codepen)</small>](https://codepen.io/editor/anydigital/pen/019d2b94-5616-75dc-a23e-e111869d5237){role=button .outline}
326
339
 
327
340
  <!--section--> */
328
341
 
@@ -362,6 +375,9 @@ table {
362
375
  margin: 0;
363
376
  visibility: hidden;
364
377
 
378
+ &.lg {
379
+ width: 18ch;
380
+ }
365
381
  &.x2 {
366
382
  width: 24ch;
367
383
  }
@@ -370,8 +386,6 @@ table {
370
386
  }
371
387
 
372
388
  /*```
373
- ---
374
-
375
389
  ### Borderless table
376
390
 
377
391
  `<table class="borderless">` removes all default borders:
@@ -429,21 +443,24 @@ Soft-increase selector specificity trick:
429
443
 
430
444
  `table:not(.does-not-exist)` (inspired by postcss) is used here to increase specificity against selectors like `&:is(table, .table)`
431
445
 
432
- <!--section:docs-->
446
+ <!--section:docs,summary-->
447
+
448
+ `<table class="responsive">` allows a table to full-bleed and scroll on mobile.
433
449
 
434
- `<table class="responsive">` allows a table to full-bleed and scroll on mobile:
435
- <hr><div>
450
+ <!--section:docs-->
436
451
 
437
- | Term | Description <hr class="x2"> | Link |
438
- | --- | --- | --- |
452
+ | Term | Description <hr class="x2"> | Link |
453
+ | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- |
439
454
  | 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 |
440
455
 
441
456
  {.responsive}
442
- </div><hr>
457
+
458
+ ---
443
459
 
444
460
  Tables inside https://blades.ninja/css/breakout/ are responsive by default.
445
461
 
446
462
  Living examples:
463
+
447
464
  - https://any.digital/insights/ai-ide/
448
465
  - https://any.digital/insights/css-frameworks/
449
466
  - https://any.digital/insights/ssg/
@@ -500,6 +517,55 @@ code {
500
517
 
501
518
  /*``` <!--section--> */
502
519
 
520
+ /* Forms */
521
+
522
+ /* Moved here from https://github.com/anydigital/float-label-css for easier maintenance
523
+ <!--section:docs-->
524
+
525
+ First, we target either:
526
+ 1. `<label>` which `:has` inner form inputs (classless approach)
527
+ 2. or explicit `.has-float-label` class (alternative approach)
528
+ ```css */
529
+
530
+ label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select),
531
+ .has-float-label {
532
+ display: block;
533
+ position: relative;
534
+ /*
535
+ ```
536
+ Then, we define the default/fallback state (when the float label should be minimized):
537
+ ```css */
538
+ > span,
539
+ label {
540
+ position: absolute;
541
+ left: 0;
542
+ top: 0;
543
+ cursor: text;
544
+ font-size: 75%;
545
+ }
546
+ /*
547
+ ```
548
+ Finally, we detect if placeholder is shown, but not in focus. That means we can safely hide it, and enlarge the float label instead:
549
+ ```css */
550
+ *:placeholder-shown:not(:focus)::placeholder {
551
+ opacity: 0;
552
+ }
553
+ &:has(*:placeholder-shown:not(:focus)) {
554
+ > span,
555
+ label {
556
+ font-size: inherit;
557
+ opacity: 50%;
558
+ }
559
+ }
560
+ }
561
+
562
+ /*
563
+ ```
564
+ The `:has(*:placeholder-shown:not(:focus))` trick allows this input state information to *propagate* to the parent level. This enables modern CSS to target inner float label (`<span>` or `<label>`) regardless of its position relative to the input field.
565
+
566
+ 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.
567
+ <!--section--> */
568
+
503
569
  /* Utilities */
504
570
 
505
571
  /*
@@ -543,3 +609,147 @@ code {
543
609
  }
544
610
 
545
611
  /*``` <!--section--> */
612
+
613
+ /* <!--section:code-->
614
+ ```css */
615
+
616
+ label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select),
617
+ .has-float-label {
618
+ /* Default/fallback state */
619
+ > span,
620
+ label {
621
+ padding-inline-start: calc(1rem + 1px); /* match Pico's padding + border */
622
+ padding-block-start: 0.25rem;
623
+ opacity: 75%;
624
+ transition: all 0.25s;
625
+ }
626
+ input,
627
+ textarea,
628
+ select {
629
+ margin-block-start: 0; /* reset Pico */
630
+ padding-inline-start: 1rem; /* match Pico */
631
+ padding-block: 1.125rem 0.375rem; /* match Pico's total: 2 x 0.75rem = 1.5rem */
632
+
633
+ &::placeholder {
634
+ opacity: 100%;
635
+ transition: all 0.25s;
636
+ }
637
+ }
638
+
639
+ /* Enlarged state */
640
+ &:has(*:placeholder-shown:not(:focus)) {
641
+ > span,
642
+ label {
643
+ padding-block: 0.75rem; /* match Pico */
644
+ }
645
+ }
646
+ }
647
+
648
+ body {
649
+ /* 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. */
650
+ display: flex;
651
+ flex-direction: column;
652
+ > main {
653
+ flex-grow: 1;
654
+ }
655
+ }
656
+
657
+ a {
658
+ &:not([href^="#"]) {
659
+ text-decoration-thickness: 1px;
660
+ &:hover {
661
+ text-decoration-thickness: 2px;
662
+ }
663
+ }
664
+ }
665
+
666
+ h1 {
667
+ font-size: 2.5em; /* for pico.css & tw-typography */
668
+ margin-bottom: 1rem; /* for tw-typography */
669
+ }
670
+
671
+ /* Potential fix https://github.com/picocss/pico/blob/main/css/pico.css for the very first headings
672
+ :where(article, address, blockquote, dl, figure, form, ol, p, pre, table, ul) ~ :is(h1, h2, h3, h4, h5, h6) {
673
+ margin-top: var(--pico-typography-spacing-top);
674
+ }
675
+ h1,
676
+ h2,
677
+ h3,
678
+ h4,
679
+ h5,
680
+ h6 {
681
+ & ~ & {
682
+ margin-bottom: 2rem;
683
+ }
684
+ }
685
+ NOTE: be careful with wrapped headings, i.e. inside nav: https://blades.ninja/build-awesome-11ty/#usage
686
+ */
687
+
688
+ hr {
689
+ margin-block: 2em; /* for pico.css & tw-typography */
690
+ }
691
+
692
+ ul {
693
+ ul {
694
+ font-size: 87.5%;
695
+ }
696
+ }
697
+
698
+ pre {
699
+ small {
700
+ opacity: 75%;
701
+ font-weight: lighter;
702
+ }
703
+ }
704
+
705
+ table {
706
+ th {
707
+ vertical-align: bottom;
708
+ font-weight: bold;
709
+ }
710
+ td {
711
+ vertical-align: top;
712
+ }
713
+ pre {
714
+ margin-bottom: 0.25rem;
715
+ }
716
+ }
717
+
718
+ [data-jump-to="top"] {
719
+ > i {
720
+ display: inline-block;
721
+ padding: 0.25rem 0.375rem;
722
+ margin: 0.5rem;
723
+ font-size: 0.75rem;
724
+ color: black;
725
+ border-color: black;
726
+ }
727
+ }
728
+
729
+ [data-is-toc] {
730
+ font-size: 87.5%;
731
+
732
+ a {
733
+ text-decoration: none;
734
+ }
735
+ > ul > * > a {
736
+ font-weight: 500;
737
+ }
738
+ }
739
+
740
+ .breakout,
741
+ .breakout-all {
742
+ > img,
743
+ > figure {
744
+ margin-bottom: 1rem;
745
+ }
746
+ }
747
+
748
+ .faded {
749
+ a {
750
+ text-decoration-style: dotted;
751
+ }
752
+ }
753
+
754
+ /*```
755
+ <!--section--> */
@@ -1,5 +1,44 @@
1
1
  /* <!--section:code-->
2
2
  ```css */
3
+ label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select),
4
+ .has-float-label {
5
+ /* Default/fallback state */
6
+ > span,
7
+ label {
8
+ padding-inline-start: calc(1rem + 1px); /* match Pico's padding + border */
9
+ padding-block-start: 0.25rem;
10
+ opacity: 75%;
11
+ transition: all 0.25s;
12
+ }
13
+ input,
14
+ textarea,
15
+ select {
16
+ margin-block-start: 0; /* reset Pico */
17
+ padding-inline-start: 1rem; /* match Pico */
18
+ padding-block: 1.125rem 0.375rem; /* match Pico's total: 2 x 0.75rem = 1.5rem */
19
+
20
+ &::placeholder {
21
+ opacity: 100%;
22
+ transition: all 0.25s;
23
+ }
24
+ }
25
+
26
+ /* Enlarged state */
27
+ &:has(*:placeholder-shown:not(:focus)) {
28
+ > span,
29
+ label {
30
+ padding-block: 0.75rem; /* match Pico */
31
+ }
32
+ }
33
+ }
34
+ body {
35
+ /* 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. */
36
+ display: flex;
37
+ flex-direction: column;
38
+ > main {
39
+ flex-grow: 1;
40
+ }
41
+ }
3
42
  a {
4
43
  &:not([href^="#"]) {
5
44
  text-decoration-thickness: 1px;
@@ -12,11 +51,10 @@ h1 {
12
51
  font-size: 2.5em; /* for pico.css & tw-typography */
13
52
  margin-bottom: 1rem; /* for tw-typography */
14
53
  }
15
- /* Fix https://github.com/picocss/pico/blob/main/css/pico.css for the very first headings
54
+ /* Potential fix https://github.com/picocss/pico/blob/main/css/pico.css for the very first headings
16
55
  :where(article, address, blockquote, dl, figure, form, ol, p, pre, table, ul) ~ :is(h1, h2, h3, h4, h5, h6) {
17
56
  margin-top: var(--pico-typography-spacing-top);
18
57
  }
19
- */
20
58
  h1,
21
59
  h2,
22
60
  h3,
@@ -24,9 +62,11 @@ h4,
24
62
  h5,
25
63
  h6 {
26
64
  & ~ & {
27
- margin-top: 2rem;
65
+ margin-bottom: 2rem;
28
66
  }
29
67
  }
68
+ NOTE: be careful with wrapped headings, i.e. inside nav: https://blades.ninja/build-awesome-11ty/#usage
69
+ */
30
70
  hr {
31
71
  margin-block: 2em; /* for pico.css & tw-typography */
32
72
  }
@@ -56,7 +96,7 @@ table {
56
96
  [data-jump-to="top"] {
57
97
  > i {
58
98
  display: inline-block;
59
- padding: 0.25rem;
99
+ padding: 0.25rem 0.375rem;
60
100
  margin: 0.5rem;
61
101
  font-size: 0.75rem;
62
102
  color: black;
@@ -78,10 +78,14 @@
78
78
  }
79
79
  }
80
80
  }
81
- /*```<!--section:docs-->
81
+ /*```
82
+ <!--section:docs,summary-->
83
+
82
84
  Framework-agnostic utilities for breaking out images and figures beyond their container width.
83
85
 
84
- Use the `.breakout` class to allow elements to extend beyond their parent container:
86
+ Use the `.breakout` class to allow elements to extend beyond their parent container.
87
+
88
+ <!--section:docs-->
85
89
 
86
90
  ```html
87
91
  <div class="breakout">
@@ -90,4 +94,5 @@ Use the `.breakout` class to allow elements to extend beyond their parent contai
90
94
  ```
91
95
 
92
96
  The breakout container has `10%` inline padding and a max-width of `calc(10% + 65ch + 10%)`. The breakout utilities support images, pictures, figures, canvas, audio, video, tables, pre, iframe, and other media elements. Tables inside `.breakout` are specifically enhanced for horizontal scrolling and full-bleed mobile display. This is automatically included when you import the stylesheet.
97
+
93
98
  <!--section--> */
@@ -0,0 +1,44 @@
1
+ /* Moved here from https://github.com/anydigital/float-label-css for easier maintenance
2
+ <!--section:docs-->
3
+
4
+ First, we target either:
5
+ 1. `<label>` which `:has` inner form inputs (classless approach)
6
+ 2. or explicit `.has-float-label` class (alternative approach)
7
+ ```css */
8
+ label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select),
9
+ .has-float-label {
10
+ display: block;
11
+ position: relative;
12
+ /*
13
+ ```
14
+ Then, we define the default/fallback state (when the float label should be minimized):
15
+ ```css */
16
+ > span,
17
+ label {
18
+ position: absolute;
19
+ left: 0;
20
+ top: 0;
21
+ cursor: text;
22
+ font-size: 75%;
23
+ }
24
+ /*
25
+ ```
26
+ Finally, we detect if placeholder is shown, but not in focus. That means we can safely hide it, and enlarge the float label instead:
27
+ ```css */
28
+ *:placeholder-shown:not(:focus)::placeholder {
29
+ opacity: 0;
30
+ }
31
+ &:has(*:placeholder-shown:not(:focus)) {
32
+ > span,
33
+ label {
34
+ font-size: inherit;
35
+ opacity: 50%;
36
+ }
37
+ }
38
+ }
39
+ /*
40
+ ```
41
+ The `:has(*:placeholder-shown:not(:focus))` trick allows this input state information to *propagate* to the parent level. This enables modern CSS to target inner float label (`<span>` or `<label>`) regardless of its position relative to the input field.
42
+
43
+ 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.
44
+ <!--section--> */
@@ -0,0 +1,76 @@
1
+ /* Float Label CSS v2.0.0-alpha */
2
+ /* Moved here from https://github.com/anydigital/float-label-css for easier maintenance
3
+ <!--section:docs-->
4
+
5
+ First, we target either:
6
+ 1. `<label>` which `:has` inner form inputs (classless approach)
7
+ 2. or explicit `.has-float-label` class (alternative approach)
8
+ ```css */
9
+ label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select),
10
+ .has-float-label {
11
+ display: block;
12
+ position: relative;
13
+ /*
14
+ ```
15
+ Then, we define the default/fallback state (when the float label should be minimized):
16
+ ```css */
17
+ > span,
18
+ label {
19
+ position: absolute;
20
+ left: 0;
21
+ top: 0;
22
+ cursor: text;
23
+ font-size: 75%;
24
+ }
25
+ /*
26
+ ```
27
+ Finally, we detect if placeholder is shown, but not in focus. That means we can safely hide it, and enlarge the float label instead:
28
+ ```css */
29
+ *:placeholder-shown:not(:focus)::placeholder {
30
+ opacity: 0;
31
+ }
32
+ &:has(*:placeholder-shown:not(:focus)) {
33
+ > span,
34
+ label {
35
+ font-size: inherit;
36
+ opacity: 50%;
37
+ }
38
+ }
39
+ }
40
+ /*
41
+ ```
42
+ The `:has(*:placeholder-shown:not(:focus))` trick allows this input state information to *propagate* to the parent level. This enables modern CSS to target inner float label (`<span>` or `<label>`) regardless of its position relative to the input field.
43
+
44
+ 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.
45
+ <!--section--> */
46
+ label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select),
47
+ .has-float-label {
48
+ /* Default/fallback state */
49
+ > span,
50
+ label {
51
+ padding-inline-start: calc(1rem + 1px); /* match Pico's padding + border */
52
+ padding-block-start: 0.25rem;
53
+ opacity: 75%;
54
+ transition: all 0.25s;
55
+ }
56
+ input,
57
+ textarea,
58
+ select {
59
+ margin-block-start: 0; /* reset Pico */
60
+ padding-inline-start: 1rem; /* match Pico */
61
+ padding-block: 1.125rem 0.375rem; /* match Pico's total: 2 x 0.75rem = 1.5rem */
62
+
63
+ &::placeholder {
64
+ opacity: 100%;
65
+ transition: all 0.25s;
66
+ }
67
+ }
68
+
69
+ /* Enlarged state */
70
+ &:has(*:placeholder-shown:not(:focus)) {
71
+ > span,
72
+ label {
73
+ padding-block: 0.75rem; /* match Pico */
74
+ }
75
+ }
76
+ }