@aortl/admin-css 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +0 -22
  2. package/dist/admin.css +2787 -248
  3. package/dist/admin.min.css +1 -1
  4. package/dist/admin.scoped.css +3252 -0
  5. package/dist/admin.scoped.min.css +46 -0
  6. package/package.json +15 -3
  7. package/src/base.css +13 -7
  8. package/src/components/accordion.css +79 -0
  9. package/src/components/alert.css +83 -0
  10. package/src/components/app-shell.css +59 -0
  11. package/src/components/badge.css +44 -0
  12. package/src/components/brand-tile.css +9 -0
  13. package/src/components/breadcrumbs.css +38 -0
  14. package/src/components/button-group.css +73 -0
  15. package/src/components/button.css +50 -1
  16. package/src/components/card.css +1 -1
  17. package/src/components/checkbox.css +38 -0
  18. package/src/components/field.css +29 -2
  19. package/src/components/file-input.css +36 -0
  20. package/src/components/footer.css +26 -0
  21. package/src/components/index.css +23 -0
  22. package/src/components/input-group.css +38 -0
  23. package/src/components/input.css +7 -0
  24. package/src/components/menu.css +88 -0
  25. package/src/components/navbar.css +66 -0
  26. package/src/components/pagination.css +43 -0
  27. package/src/components/progress.css +97 -0
  28. package/src/components/radio.css +45 -0
  29. package/src/components/select.css +114 -0
  30. package/src/components/sidebar.css +225 -0
  31. package/src/components/spinner.css +40 -0
  32. package/src/components/switch.css +62 -0
  33. package/src/components/table.css +124 -0
  34. package/src/components/tabs.css +172 -0
  35. package/src/components/textarea.css +33 -0
  36. package/src/fonts.css +88 -0
  37. package/src/index.css +1 -0
  38. package/src/theme.css +122 -29
@@ -0,0 +1,73 @@
1
+ @layer components {
2
+ .btn-group {
3
+ @apply inline-flex;
4
+ }
5
+
6
+ .btn-group > .btn {
7
+ @apply rounded-none relative focus-visible:z-10;
8
+ }
9
+
10
+ .btn-group > .btn:not(:first-child) {
11
+ @apply -ml-px;
12
+ }
13
+
14
+ .btn-group > .btn:first-child {
15
+ @apply rounded-l-lg;
16
+ }
17
+
18
+ .btn-group > .btn:last-child {
19
+ @apply rounded-r-lg;
20
+ }
21
+
22
+ /* Split-button support: a <details class="menu"> child sits in the strip
23
+ alongside .btn children, with its .menu-trigger getting the same edge
24
+ treatment as the buttons around it. inline-flex on the details makes
25
+ the <summary> stretch vertically to match sibling .btn heights, so an
26
+ icon-only trigger doesn't end up shorter than its neighbours. */
27
+ .btn-group > .menu {
28
+ @apply relative focus-visible:z-10;
29
+ display: inline-flex;
30
+ }
31
+
32
+ .btn-group > .menu:not(:first-child) {
33
+ @apply -ml-px;
34
+ }
35
+
36
+ .btn-group > .menu > .menu-trigger {
37
+ @apply rounded-none;
38
+ }
39
+
40
+ .btn-group > .menu:first-child > .menu-trigger {
41
+ @apply rounded-l-lg;
42
+ }
43
+
44
+ .btn-group > .menu:last-child > .menu-trigger {
45
+ @apply rounded-r-lg;
46
+ }
47
+
48
+ /* Divider between adjacent items so same-coloured siblings (e.g. a
49
+ split button) read as separate actions. currentColor + color-mix
50
+ means the divider works across every .btn variant — light on
51
+ coloured buttons, dark on ghost/secondary — without per-variant
52
+ rules. */
53
+ .btn-group > .btn:not(:first-child),
54
+ .btn-group > .menu:not(:first-child) > .menu-trigger {
55
+ border-left-color: color-mix(in srgb, currentColor 25%, transparent);
56
+ }
57
+
58
+ .btn-group-vertical {
59
+ @apply inline-flex flex-col;
60
+ }
61
+
62
+ .btn-group-vertical > .btn:not(:first-child) {
63
+ @apply -mt-px ml-0;
64
+ }
65
+
66
+ .btn-group-vertical > .btn:first-child {
67
+ @apply rounded-t-lg rounded-bl-none;
68
+ }
69
+
70
+ .btn-group-vertical > .btn:last-child {
71
+ @apply rounded-b-lg rounded-tr-none;
72
+ }
73
+ }
@@ -36,7 +36,56 @@
36
36
  }
37
37
 
38
38
  /* Modifiers */
39
- .btn-block {
39
+ .btn-full-width {
40
40
  @apply w-full;
41
41
  }
42
+
43
+ /* Icon-only — equalises padding so the button reads as a square. The React
44
+ wrapper adds this automatically when `.btn` has an icon but no text
45
+ children; vanilla callers add it themselves. Pair with `aria-label`. */
46
+ .btn-square {
47
+ @apply px-2;
48
+ }
49
+
50
+ .btn-sm.btn-square {
51
+ @apply px-1.5;
52
+ }
53
+
54
+ .btn-lg.btn-square {
55
+ @apply px-2.5;
56
+ }
57
+
58
+ /* Loading state — paints a spinner via ::before, so no extra markup is
59
+ required. Sized in `em` so it tracks btn-sm / btn-lg. Pair with the
60
+ `disabled` attribute (or the React wrapper, which sets it for you) for
61
+ keyboard a11y; the visual disable lives here so vanilla still feels right
62
+ without it. */
63
+ .btn-loading {
64
+ @apply opacity-50 cursor-not-allowed pointer-events-none;
65
+ }
66
+
67
+ .btn-loading::before {
68
+ content: "";
69
+ display: inline-block;
70
+ width: 1em;
71
+ height: 1em;
72
+ flex-shrink: 0;
73
+ border-radius: 9999px;
74
+ border: 0.125em solid color-mix(in oklab, currentColor 25%, transparent);
75
+ border-top-color: currentColor;
76
+ animation: spinner-spin 0.6s linear infinite;
77
+ }
78
+
79
+ /* Suppress a leading icon while loading so we don't show two glyphs.
80
+ Trailing icons stay visible — they may convey structural meaning
81
+ (e.g. a dropdown chevron on a split-button trigger). */
82
+ .btn-loading > :is(i, svg):first-child {
83
+ display: none;
84
+ }
85
+
86
+ @media (prefers-reduced-motion: reduce) {
87
+ .btn-loading::before {
88
+ animation-duration: 2s;
89
+ }
90
+ }
42
91
  }
@@ -13,7 +13,7 @@
13
13
  }
14
14
 
15
15
  .card-title {
16
- @apply text-lg font-semibold leading-tight;
16
+ @apply flex items-center gap-2 text-lg font-semibold leading-tight;
17
17
  }
18
18
 
19
19
  .card-description {
@@ -0,0 +1,38 @@
1
+ @layer components {
2
+ .checkbox {
3
+ @apply inline-flex items-center justify-center size-4 shrink-0
4
+ rounded-sm border bg-surface
5
+ cursor-pointer
6
+ transition-colors duration-150
7
+ focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary
8
+ disabled:opacity-50 disabled:cursor-not-allowed;
9
+ }
10
+
11
+ .checkbox[data-unchecked] {
12
+ @apply border-border-strong hover:border-text-muted;
13
+ }
14
+
15
+ .checkbox[data-checked],
16
+ .checkbox[data-indeterminate] {
17
+ @apply bg-primary border-primary hover:bg-primary-hover;
18
+ }
19
+
20
+ .checkbox[data-disabled] {
21
+ @apply opacity-50 cursor-not-allowed;
22
+ }
23
+
24
+ .checkbox-indicator {
25
+ @apply inline-flex items-center justify-center size-3 text-primary-content;
26
+ }
27
+
28
+ /* A <label> wrapping a checkbox + text lays out inline with a small gap.
29
+ Covers both the vanilla input.checkbox and Base UI's button.checkbox. */
30
+ label:has(> .checkbox) {
31
+ @apply inline-flex items-center gap-2 cursor-pointer;
32
+ }
33
+
34
+ label:has(> .checkbox:disabled),
35
+ label:has(> .checkbox[data-disabled]) {
36
+ @apply opacity-60 cursor-not-allowed;
37
+ }
38
+ }
@@ -3,10 +3,25 @@
3
3
  @apply flex flex-col gap-1.5;
4
4
  }
5
5
 
6
+ /* Horizontal layout — pairs a control (typically a switch) with its label
7
+ on one row. Use when the label belongs beside the control, not above it. */
8
+ .field-row {
9
+ @apply flex-row items-center gap-3;
10
+ }
11
+
6
12
  .field-label {
7
13
  @apply text-sm font-medium text-text leading-none;
8
14
  }
9
15
 
16
+ .field-label[data-required]::after {
17
+ content: " *";
18
+ @apply text-danger;
19
+ }
20
+
21
+ .asteriskField {
22
+ @apply text-danger;
23
+ }
24
+
10
25
  .field-description {
11
26
  @apply text-xs text-text-muted leading-relaxed;
12
27
  }
@@ -15,9 +30,21 @@
15
30
  @apply text-xs text-danger leading-relaxed;
16
31
  }
17
32
 
18
- /* When the field is in an invalid state, tint the contained input.
33
+ /* When the field is in an invalid state, tint the contained control.
19
34
  Base UI applies data-invalid on the Field root once validation fails. */
20
- .field[data-invalid] .input {
35
+ .field[data-invalid] .input,
36
+ .field[data-invalid] .textarea,
37
+ .field[data-invalid] .select,
38
+ .field[data-invalid] .file-input {
21
39
  @apply border-danger;
22
40
  }
41
+
42
+ .field[data-invalid] .checkbox[data-unchecked],
43
+ .field[data-invalid] .radio[data-unchecked] {
44
+ @apply border-danger;
45
+ }
46
+
47
+ .field[data-invalid] .switch[data-unchecked] {
48
+ @apply ring-1 ring-danger;
49
+ }
23
50
  }
@@ -0,0 +1,36 @@
1
+ @layer components {
2
+ .file-input {
3
+ @apply inline-flex items-center w-full pr-3 text-sm leading-none
4
+ bg-surface text-text
5
+ border border-transparent rounded-lg overflow-hidden
6
+ transition-colors duration-150
7
+ focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary
8
+ disabled:opacity-50 disabled:cursor-not-allowed
9
+ file:px-3 file:py-2 file:mr-3
10
+ file:text-sm file:font-medium file:leading-none
11
+ file:bg-surface-muted file:text-text hover:file:bg-surface-strong
12
+ file:border-0 file:border-r file:border-border
13
+ file:cursor-pointer;
14
+ }
15
+
16
+ .file-input-bordered {
17
+ @apply border-border hover:border-border-strong;
18
+ }
19
+
20
+ .file-input-ghost {
21
+ @apply bg-transparent hover:bg-surface-muted;
22
+ }
23
+
24
+ .file-input-danger {
25
+ @apply border-danger focus-visible:outline-danger;
26
+ }
27
+
28
+ /* Sizes */
29
+ .file-input-sm {
30
+ @apply text-xs file:text-xs file:px-2.5 file:py-1.5 file:mr-2.5;
31
+ }
32
+
33
+ .file-input-lg {
34
+ @apply text-base file:text-base file:px-4 file:py-2.5 file:mr-4;
35
+ }
36
+ }
@@ -0,0 +1,26 @@
1
+ @layer components {
2
+ /* 2px top stripe mirrors the navbar's bottom stripe — both default to
3
+ a neutral gray via `--color-system-accent` and brand-shift together
4
+ when the consuming app overrides that variable at :root. */
5
+ .footer {
6
+ @apply flex flex-wrap items-center justify-between gap-3 px-4 py-3
7
+ bg-surface-muted text-text-muted
8
+ border-t-2 border-system-accent
9
+ text-xs;
10
+ }
11
+
12
+ .footer-links {
13
+ @apply flex flex-wrap items-center gap-3;
14
+ }
15
+
16
+ .footer-link {
17
+ @apply text-text-muted no-underline
18
+ hover:text-text hover:underline
19
+ focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary
20
+ rounded-sm;
21
+ }
22
+
23
+ .footer-meta {
24
+ @apply text-text-muted;
25
+ }
26
+ }
@@ -1,4 +1,27 @@
1
+ @import "./accordion.css";
2
+ @import "./alert.css";
3
+ @import "./app-shell.css";
4
+ @import "./badge.css";
5
+ @import "./brand-tile.css";
6
+ @import "./spinner.css";
7
+ @import "./progress.css";
8
+ @import "./breadcrumbs.css";
9
+ @import "./pagination.css";
1
10
  @import "./button.css";
11
+ @import "./button-group.css";
2
12
  @import "./input.css";
13
+ @import "./input-group.css";
14
+ @import "./textarea.css";
15
+ @import "./checkbox.css";
16
+ @import "./radio.css";
17
+ @import "./switch.css";
18
+ @import "./select.css";
3
19
  @import "./card.css";
4
20
  @import "./field.css";
21
+ @import "./file-input.css";
22
+ @import "./footer.css";
23
+ @import "./menu.css";
24
+ @import "./navbar.css";
25
+ @import "./sidebar.css";
26
+ @import "./tabs.css";
27
+ @import "./table.css";
@@ -0,0 +1,38 @@
1
+ @layer components {
2
+ .input-group {
3
+ @apply inline-flex w-full;
4
+ }
5
+
6
+ /* Clear all corners, then re-apply the outer ones on the first/last
7
+ child. Equal-specificity rules win because input-group.css imports
8
+ after input.css. */
9
+ .input-group > * {
10
+ @apply rounded-none;
11
+ }
12
+
13
+ .input-group > :first-child {
14
+ @apply rounded-l-lg;
15
+ }
16
+
17
+ .input-group > :last-child {
18
+ @apply rounded-r-lg;
19
+ }
20
+
21
+ /* Collapse the shared edge between adjacent children. */
22
+ .input-group > :not(:first-child) {
23
+ margin-left: -1px;
24
+ }
25
+
26
+ /* Float the focused element so its outline ring and accented border
27
+ can't be clipped by its neighbour's overlapping edge. */
28
+ .input-group > :focus,
29
+ .input-group > :focus-within {
30
+ @apply relative z-10;
31
+ }
32
+
33
+ .input-group-addon {
34
+ @apply inline-flex items-center px-3 text-sm leading-none whitespace-nowrap
35
+ bg-surface-muted text-text-muted
36
+ border border-border;
37
+ }
38
+ }
@@ -30,4 +30,11 @@
30
30
  .input-lg {
31
31
  @apply text-base px-4 py-2.5;
32
32
  }
33
+
34
+ /* Native date/time picker glyph. The browser handles dark-mode coloring
35
+ via the inherited `color-scheme` set on [data-theme]; we just tone the
36
+ glyph down at rest and brighten it on hover so it reads as interactive. */
37
+ .input::-webkit-calendar-picker-indicator {
38
+ @apply opacity-60 cursor-pointer hover:opacity-100;
39
+ }
33
40
  }
@@ -0,0 +1,88 @@
1
+ @layer components {
2
+ /* Native <details> drives open state — no JS needed. The popup is a
3
+ position: absolute child of the relative .menu root. */
4
+ .menu {
5
+ @apply relative inline-block;
6
+ }
7
+
8
+ /* Behaviour — applied always so the trigger works regardless of
9
+ additional visual classes (e.g. `btn btn-primary` for a split button). */
10
+ .menu-trigger {
11
+ @apply inline-flex items-center gap-1.5
12
+ cursor-pointer select-none
13
+ transition-colors duration-150
14
+ focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary;
15
+ list-style: none;
16
+ }
17
+
18
+ .menu-trigger::-webkit-details-marker {
19
+ display: none;
20
+ }
21
+
22
+ /* Default appearance — bows out when `.btn` is also on the trigger so
23
+ button classes (bg, hover, padding, text colour) take over cleanly. */
24
+ .menu-trigger:not(.btn) {
25
+ @apply px-2.5 py-1.5 rounded-md text-sm leading-none
26
+ text-text bg-transparent
27
+ hover:bg-surface-strong;
28
+ }
29
+
30
+ /* Chevron uses currentColor so it tracks the trigger's text colour —
31
+ muted text on the default trigger, content colour on a btn-primary
32
+ split button, etc. Sized in em so it scales with btn-sm / btn-lg. */
33
+ .menu-trigger::after {
34
+ content: "";
35
+ width: 0.5em;
36
+ height: 0.5em;
37
+ border-right: 2px solid currentColor;
38
+ border-bottom: 2px solid currentColor;
39
+ transform: rotate(45deg);
40
+ transition: transform 150ms ease;
41
+ flex-shrink: 0;
42
+ }
43
+
44
+ /* Icon-only triggers (e.g. the dropdown half of a split button) center
45
+ their chevron instead of letting it sit at the start. */
46
+ .menu-trigger:empty {
47
+ @apply justify-center;
48
+ }
49
+
50
+ .menu[open] > .menu-trigger::after {
51
+ transform: rotate(-135deg);
52
+ }
53
+
54
+ .menu-popup {
55
+ @apply absolute top-full left-0 z-30 mt-1
56
+ min-w-44 max-h-72 overflow-auto
57
+ py-1
58
+ bg-surface text-text
59
+ border border-border rounded-lg shadow-md;
60
+ }
61
+
62
+ .menu-item {
63
+ @apply flex items-center gap-2 w-full px-3 py-1.5 text-sm leading-none
64
+ text-text bg-transparent
65
+ border-0
66
+ text-left no-underline
67
+ cursor-pointer select-none
68
+ hover:bg-surface-muted
69
+ focus-visible:bg-surface-muted focus-visible:outline-none
70
+ disabled:opacity-50 disabled:cursor-not-allowed;
71
+ }
72
+
73
+ .menu-item[aria-disabled="true"] {
74
+ @apply opacity-50 cursor-not-allowed;
75
+ }
76
+
77
+ .menu-separator {
78
+ @apply h-px my-1 bg-border border-0;
79
+ }
80
+
81
+ .menu-group {
82
+ @apply flex flex-col;
83
+ }
84
+
85
+ .menu-group-label {
86
+ @apply px-3 pt-2 pb-1 text-xs uppercase tracking-wide text-text-muted;
87
+ }
88
+ }
@@ -0,0 +1,66 @@
1
+ @layer components {
2
+ /* 2px bottom stripe is always rendered — defaults to a neutral gray via
3
+ `--color-system-accent` and brand-shifts when the consuming app overrides
4
+ that variable at :root (see also `.footer` and `.brand-tile`). */
5
+ .navbar {
6
+ @apply flex items-center gap-3 px-4 h-12
7
+ bg-surface-muted text-text
8
+ border-b-2 border-system-accent;
9
+ }
10
+
11
+ .navbar-brand {
12
+ @apply flex items-center gap-2 font-semibold text-sm shrink-0 text-text;
13
+ }
14
+
15
+ .navbar-items {
16
+ @apply flex items-center gap-0.5;
17
+ }
18
+
19
+ .navbar-item {
20
+ @apply inline-flex items-center gap-1.5 px-2.5 py-1.5
21
+ rounded-md text-sm leading-none
22
+ text-text bg-transparent
23
+ hover:bg-surface-strong
24
+ cursor-pointer select-none
25
+ transition-colors duration-150
26
+ focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary;
27
+ }
28
+
29
+ .navbar-item[aria-current="page"],
30
+ .navbar-item[data-active] {
31
+ @apply bg-primary-muted text-primary;
32
+ }
33
+
34
+ /* Right-aligned slot for actions: shop selector, user menu, etc. */
35
+ .navbar-actions {
36
+ @apply flex items-center gap-2 ml-auto;
37
+ }
38
+
39
+ /* Hamburger; hidden above the md breakpoint. The three lines are drawn
40
+ with one element + two box-shadow strokes — no SVG needed. */
41
+ .navbar-mobile-toggle {
42
+ @apply inline-flex items-center justify-center size-9 -ml-2
43
+ rounded-md text-text bg-transparent
44
+ hover:bg-surface-strong
45
+ cursor-pointer
46
+ focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary;
47
+ }
48
+
49
+ .navbar-mobile-toggle::before {
50
+ content: "";
51
+ display: block;
52
+ width: 18px;
53
+ height: 2px;
54
+ background: currentColor;
55
+ border-radius: 1px;
56
+ box-shadow:
57
+ 0 -6px 0 currentColor,
58
+ 0 6px 0 currentColor;
59
+ }
60
+
61
+ @media (min-width: 48rem) {
62
+ .navbar-mobile-toggle {
63
+ display: none;
64
+ }
65
+ }
66
+ }
@@ -0,0 +1,43 @@
1
+ @layer components {
2
+ .pagination > ol,
3
+ .pagination > ul {
4
+ @apply inline-flex items-center gap-1 m-0 p-0 list-none;
5
+ }
6
+
7
+ .page-item {
8
+ @apply inline-flex;
9
+ }
10
+
11
+ /* Square button shared by number, prev/next, and ellipsis containers. */
12
+ .page-link {
13
+ @apply inline-flex items-center justify-center
14
+ min-w-8 h-8 px-2
15
+ rounded-md
16
+ text-sm font-medium leading-none
17
+ text-text bg-transparent
18
+ border border-transparent
19
+ hover:bg-surface-muted
20
+ cursor-pointer select-none no-underline
21
+ transition-colors duration-150
22
+ focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary
23
+ disabled:opacity-50 disabled:cursor-not-allowed disabled:pointer-events-none;
24
+ }
25
+
26
+ /* Current page — same surface as a sidebar's active item so the visual
27
+ metaphor is consistent. */
28
+ .page-link.active,
29
+ .page-link[aria-current="page"] {
30
+ @apply bg-primary-muted text-primary border-primary-muted;
31
+ }
32
+
33
+ .page-link[aria-disabled="true"] {
34
+ @apply opacity-50 cursor-not-allowed pointer-events-none;
35
+ }
36
+
37
+ /* Ellipsis — non-interactive placeholder between groups of pages. */
38
+ .page-ellipsis {
39
+ @apply inline-flex items-center justify-center
40
+ min-w-8 h-8 px-2
41
+ text-sm text-text-muted select-none;
42
+ }
43
+ }
@@ -0,0 +1,97 @@
1
+ @layer components {
2
+ /* Native <progress> styled across engines. `appearance: none` strips the
3
+ platform default; the track is the element itself, the fill comes from
4
+ ::-webkit-progress-value / ::-moz-progress-bar. */
5
+ .progress {
6
+ appearance: none;
7
+ -webkit-appearance: none;
8
+ display: block;
9
+ width: 100%;
10
+ height: 0.375rem;
11
+ border: 0;
12
+ border-radius: 9999px;
13
+ overflow: hidden;
14
+ background-color: var(--color-surface-strong);
15
+ color: var(--color-primary);
16
+ }
17
+
18
+ .progress::-webkit-progress-bar {
19
+ background-color: var(--color-surface-strong);
20
+ border-radius: 9999px;
21
+ }
22
+
23
+ .progress::-webkit-progress-value {
24
+ background-color: currentColor;
25
+ border-radius: 9999px;
26
+ transition: inline-size 200ms ease;
27
+ }
28
+
29
+ .progress::-moz-progress-bar {
30
+ background-color: currentColor;
31
+ border-radius: 9999px;
32
+ transition: inline-size 200ms ease;
33
+ }
34
+
35
+ /* Sizes */
36
+ .progress-sm {
37
+ height: 0.25rem;
38
+ }
39
+
40
+ .progress-lg {
41
+ height: 0.5rem;
42
+ }
43
+
44
+ /* Variants — recolour the fill via currentColor */
45
+ .progress-success {
46
+ color: var(--color-success);
47
+ }
48
+
49
+ .progress-warning {
50
+ color: var(--color-warning);
51
+ }
52
+
53
+ .progress-danger {
54
+ color: var(--color-danger);
55
+ }
56
+
57
+ /* Indeterminate — no value attribute. WebKit hides the value pseudo, Firefox
58
+ draws it full-width; in both cases we paint an animated gradient on the
59
+ bar itself. */
60
+ .progress:indeterminate {
61
+ background-image: linear-gradient(
62
+ 90deg,
63
+ var(--color-surface-strong) 0%,
64
+ var(--color-surface-strong) 40%,
65
+ currentColor 50%,
66
+ var(--color-surface-strong) 60%,
67
+ var(--color-surface-strong) 100%
68
+ );
69
+ background-size: 250% 100%;
70
+ background-repeat: no-repeat;
71
+ animation: progress-indeterminate 1.2s linear infinite;
72
+ }
73
+
74
+ .progress:indeterminate::-webkit-progress-bar {
75
+ background-color: transparent;
76
+ }
77
+
78
+ .progress:indeterminate::-webkit-progress-value,
79
+ .progress:indeterminate::-moz-progress-bar {
80
+ background-color: transparent;
81
+ }
82
+
83
+ @media (prefers-reduced-motion: reduce) {
84
+ .progress:indeterminate {
85
+ animation-duration: 3s;
86
+ }
87
+ }
88
+
89
+ @keyframes progress-indeterminate {
90
+ from {
91
+ background-position: 100% 0;
92
+ }
93
+ to {
94
+ background-position: 0 0;
95
+ }
96
+ }
97
+ }