@aortl/admin-css 0.15.0 → 0.16.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.
@@ -9,7 +9,7 @@
9
9
  page (e.g. Starlight's own <Tabs> component) doesn't pick them up. */
10
10
  .tabs .tab-list {
11
11
  @apply inline-flex items-center gap-1 border-b border-border;
12
- /* Anchor for the optional .tab-indicator */
12
+ /* Containing block for the sliding ::before marker (see @supports below) */
13
13
  position: relative;
14
14
  }
15
15
 
@@ -86,8 +86,10 @@
86
86
  @apply gap-0 p-0.5 border border-border rounded-md bg-surface-muted;
87
87
  }
88
88
 
89
+ /* Sit above the sliding thumb (the anchored ::before below) so labels stay
90
+ legible while it passes behind them. */
89
91
  .tabs-boxed .tab {
90
- @apply rounded;
92
+ @apply rounded relative z-[1];
91
93
  }
92
94
 
93
95
  .tabs-boxed .tab[data-selected],
@@ -96,6 +98,83 @@
96
98
  @apply bg-surface text-text shadow-sm;
97
99
  }
98
100
 
101
+ /* Sliding active marker — the default, with zero extra DOM. The selected tab
102
+ becomes a CSS anchor; a single pseudo on the .tab-list tracks it via
103
+ anchor() insets, and the browser interpolates those insets as the anchor
104
+ moves between tabs — so vanilla `:checked` markup and React both slide.
105
+ `anchor-scope` confines the name to each list so multiple tab sets on a
106
+ page don't cross-anchor; gating the whole block on its support keeps the
107
+ effect off where it'd misbehave, leaving the per-tab marker above as the
108
+ fallback. */
109
+ @supports (anchor-scope: --x) {
110
+ .tabs .tab-list {
111
+ anchor-scope: --tab-thumb;
112
+ }
113
+
114
+ .tabs .tab[data-selected],
115
+ .tabs .tab[aria-selected="true"],
116
+ .tabs .tab-input:checked + .tab {
117
+ anchor-name: --tab-thumb;
118
+ }
119
+
120
+ .tabs .tab-list::before {
121
+ content: "";
122
+ position: absolute;
123
+ position-anchor: --tab-thumb;
124
+ }
125
+
126
+ /* Bordered: a 2px bar sliding along the list's bottom edge — replaces the
127
+ per-tab ::after grow. */
128
+ .tabs:not(.tabs-boxed) .tab::after {
129
+ display: none;
130
+ }
131
+
132
+ .tabs:not(.tabs-boxed) .tab-list::before {
133
+ @apply bg-primary;
134
+ left: anchor(left);
135
+ right: anchor(right);
136
+ inset-block-end: -1px;
137
+ block-size: 2px;
138
+ transition:
139
+ left 180ms ease,
140
+ right 180ms ease;
141
+ }
142
+
143
+ /* Vertical bordered: bar on the trailing edge, sliding vertically. */
144
+ .tabs[data-orientation="vertical"]:not(.tabs-boxed) .tab-list::before {
145
+ inset-inline: auto;
146
+ inset-inline-end: -1px;
147
+ inline-size: 2px;
148
+ top: anchor(top);
149
+ bottom: anchor(bottom);
150
+ block-size: auto;
151
+ transition:
152
+ top 180ms ease,
153
+ bottom 180ms ease;
154
+ }
155
+
156
+ /* Boxed: a full-size thumb sliding behind the active label. */
157
+ .tabs-boxed .tab[data-selected],
158
+ .tabs-boxed .tab[aria-selected="true"],
159
+ .tabs-boxed .tab-input:checked + .tab {
160
+ @apply bg-transparent shadow-none;
161
+ }
162
+
163
+ .tabs-boxed .tab-list::before {
164
+ top: anchor(top);
165
+ right: anchor(right);
166
+ bottom: anchor(bottom);
167
+ left: anchor(left);
168
+ z-index: 0;
169
+ @apply rounded bg-surface shadow-sm;
170
+ transition:
171
+ top 180ms ease,
172
+ right 180ms ease,
173
+ bottom 180ms ease,
174
+ left 180ms ease;
175
+ }
176
+ }
177
+
99
178
  /* Full width — list stretches across the container, tabs share space evenly. */
100
179
  .tabs-full-width:not([data-orientation="vertical"]) .tab-list {
101
180
  @apply flex w-full;
@@ -119,7 +198,7 @@
119
198
  @apply pt-3 outline-none;
120
199
  }
121
200
 
122
- /* Vanilla radio-input pattern: only the panel whose data-for matches the
201
+ /* Vanilla radio-input pattern: only the panel whose data-value matches the
123
202
  checked input is shown. Each .tabs root scopes its own selectors. */
124
203
  .tabs .tab-panel {
125
204
  display: none;
@@ -167,4 +246,11 @@
167
246
  .tabs[data-orientation="vertical"]:not(.tabs-boxed) .tab[aria-selected="true"]::after {
168
247
  transform: scaleY(1);
169
248
  }
249
+
250
+ @media (prefers-reduced-motion: reduce) {
251
+ .tabs .tab-list::before,
252
+ .tabs:not(.tabs-boxed) .tab::after {
253
+ transition: none;
254
+ }
255
+ }
170
256
  }
@@ -33,9 +33,9 @@
33
33
  }
34
34
 
35
35
  /* Grow with content (Chromium 123+; degrades to a fixed resizable box
36
- elsewhere). `min-h-*` / the `rows` attribute stays the floor; cap growth
37
- with a consumer `max-height`. Manual drag-resize is off — height is
38
- content-driven. */
36
+ elsewhere). The floor is the larger of the base `min-h-*` and the `rows`
37
+ attribute; cap growth with a consumer `max-height`. Manual drag-resize is
38
+ off — height is content-driven. */
39
39
  .textarea-autosize {
40
40
  field-sizing: content;
41
41
  resize: none;
package/src/theme.css CHANGED
@@ -219,6 +219,11 @@
219
219
  --color-code-surface: light-dark(var(--color-base-150), var(--color-base-950));
220
220
  --color-code-text: light-dark(var(--color-base-800), var(--color-base-200));
221
221
 
222
+ /* Modal scrim — the dimming layer behind a `<dialog>` and the mobile
223
+ sidebar drawer. One tint from black so both overlays match and stay
224
+ retintable from a single token. */
225
+ --color-scrim: color-mix(in oklab, var(--color-black) 40%, transparent);
226
+
222
227
  /* Primary — high-contrast neutral (ink). Inverts with the mode: near-black
223
228
  on light surfaces, near-white on dark ones, so a solid `btn-primary` fill
224
229
  always reads against the surface. Unlike the colored accents, `-hover`