@stnd/styles 0.10.15 → 0.11.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @stnd/styles
2
2
 
3
+ ## 0.11.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Auto-bumped @stnd/styles due to modified code.
8
+
3
9
  ## 0.10.15
4
10
 
5
11
  ### Patch Changes
package/README.md CHANGED
@@ -147,7 +147,7 @@ File-by-file pass, adding WHY-comments and checking for cascade/scope bugs. Fixe
147
147
  - **`body`'s own dead `--max-width` fallback** (`_standard-07-base.scss`)
148
148
  — `max-width: var(--body-max-width, var(--max-width))`, left over from *my own* `--max-width` removal earlier this session (missed this one file at the time). `--body-max-width` always has a value, so the fallback never fired — harmless, but stale. Now matches `.prose`'s equivalent rule (`var(--body-max-width)`, no fallback).
149
149
  - **Garbled leftover comment** (`_standard-07-base.scss`) — a `[id]`
150
- block's comment repeated the same incomplete CSS fragment (`background: var(--color-surface-highest);`) four times, pure noise. Replaced with an actual explanation of what `scroll-margin-top` there is for (keeps anchor-linked headings clear of the sticky header).
150
+ block's comment repeated the same incomplete CSS fragment (`background: var(--color-surface-light-2);`) four times, pure noise. Replaced with an actual explanation of what `scroll-margin-top` there is for (keeps anchor-linked headings clear of the sticky header).
151
151
  - **`.negate-body-padding*` docblock described a nonexistent API**
152
152
  (`_standard-07-base.scss`) — those three class names, and the usage example, don't match the real implementation (`.no-body-margin`, and far more restrictive: only `<footer>`/`<header>` that are direct children of `<body>` and first/last-of-type). Neither name is used anywhere in `apps/` today, so nothing broke in practice, but the docs would have misled whoever reached for it next. Rewrote to match reality.
153
153
  - **Duplicate identical `font-family` on `select`** (`_standard-11-forms.scss`)
@@ -162,7 +162,7 @@ Every flagged item below got fixed except three, which are real judgment calls a
162
162
  - `_standard-02-color.scss`: dark-mode purple/pink/brown now reassign to their `--color-dark-*` counterparts (in both the `prefers-color-scheme: dark` block and the `[data-color-mode="dark"]` blocks); added the missing Stage 8 non-OKLCH fallback hex for all three; deleted the dead `0 solid transparent` `--border` line (kept `none` — see deferred items, the *value* wasn't touched); collapsed `--shadow`'s duplicated `--shadow-ambient` layer to one.
163
163
  - `_standard-03-typography.scss`: `grid-line-height` mixin now reads `var(--font-header-line-height, ...)` instead of ignoring the token outright — headings actually respond to the frontmatter token now; deleted the dead hardcoded second `.font-interface` block.
164
164
  - `_standard-04-grid.scss`: deleted the dead `--grid-gap` copy of `.grid.compact`/`.relaxed`; replaced every `[class^="grid-"]`/`[class|="grid"]` attribute selector with an explicit, order-independent `$grid-selectors` list (confirmed fix against real markup: `apps/stnd.build/modules/core/routes/index.astro`'s `class="cover grid-12"`).
165
- - `_standard-06-prose.scss`: `.mycelial-graft` now uses real tokens (`--color-muted`, `--color-accent`, `--color-surface-high`); deleted the stale `h1:first-child` comment.
165
+ - `_standard-06-prose.scss`: `.mycelial-graft` now uses real tokens (`--color-muted`, `--color-accent`, `--color-surface-light-1`); deleted the stale `h1:first-child` comment.
166
166
  - `_standard-07-base.scss`: mobile header padding-negation now sets `margin-block-start` (matching the desktop rule and the footer's symmetric block), not `margin-block-end`.
167
167
  - `_standard-08-media.scss`: deleted the dead `--gap-body` padding line on `.image-zoom-overlay`; hardcoded `768px` → `#{$small}`.
168
168
  - `_standard-09-lists.scss` / `_standard-50-utilities.scss`: removed all 5 dead `--base-gap` lines; `.display-flex` → `.flex` (the real class).
@@ -148,7 +148,10 @@
148
148
  --filter-glass: blur(20px);
149
149
  --stroke-width: max(1px, 0.06rem);
150
150
  --stroke-width-lg: calc(var(--stroke-width) * 2);
151
- --radius: var(--trim);
151
+ /* `--corner` is the documented hook (see Theme Authoring Hooks) — an app or
152
+ theme sets it and this follows. It was documented and never read, so
153
+ `--corner: 6px` in app.scss left --radius at --trim (~1.3px). */
154
+ --radius: var(--corner, var(--trim));
152
155
  --radius-sm: 4px;
153
156
 
154
157
  /**
@@ -14,9 +14,9 @@
14
14
  * @property input, textarea Zero-class text controls with interface typography, raised shadow, and accent focus rings.
15
15
  * @property select Custom styled dropdown with double-chevron indicator and rhythm-aligned padding.
16
16
  * @property input[role=switch] Accessible toggle switch with animated sliding thumb.
17
- * @property --switch-height Primary height sizing knob for toggle switch controls.
17
+ * @property --switch-height Primary height sizing knob for toggle switch controls. Set it anywhere — on the switch, a class, or a container — and width and thumb follow.
18
18
  * @property --switch-width Width sizing token for toggle switches (`calc(var(--switch-height) * 2)`).
19
- * @property --switch-padding Inset padding controlling the toggle switch thumb gap (`2px`).
19
+ * @property --switch-padding Inset padding controlling the toggle switch thumb gap (`0px`).
20
20
  * @property --slider-value Percentage value driving custom filled range slider tracks.
21
21
  *
22
22
  * @example html - A switch (role=switch on a checkbox)
@@ -117,7 +117,10 @@ select {
117
117
  text-shadow: none !important;
118
118
  text-box-trim: trim;
119
119
 
120
- padding: 0 var(--trim);
120
+ /* Room on the right for the chevron drawn below: without it a long value
121
+ ran under the arrow. */
122
+ padding: 0 calc(1em + var(--space-d4)) 0 var(--trim);
123
+ text-overflow: ellipsis;
121
124
 
122
125
  appearance: none;
123
126
  /* Match Combobox double-chevron */
@@ -134,6 +137,28 @@ select {
134
137
  }
135
138
  }
136
139
 
140
+ /* A colour input is a swatch, not a text field: fill the control with the
141
+ colour instead of inheriting the text-input padding around a tiny chip. */
142
+ input[type="color"] {
143
+ height: var(--space-2);
144
+ padding: var(--space-d8);
145
+ cursor: pointer;
146
+
147
+ &::-webkit-color-swatch-wrapper {
148
+ padding: 0;
149
+ }
150
+
151
+ &::-webkit-color-swatch {
152
+ border: none;
153
+ border-radius: calc(var(--radius-sm) - var(--stroke-width));
154
+ }
155
+
156
+ &:disabled {
157
+ opacity: 0.4;
158
+ cursor: default;
159
+ }
160
+ }
161
+
137
162
  textarea {
138
163
  resize: vertical;
139
164
  min-height: var(--space-2);
@@ -250,24 +275,33 @@ input[type="radio"] {
250
275
  }
251
276
 
252
277
  input[type="checkbox"][role="switch"] {
253
- --switch-height: calc(var(--space) - var(--space-d3));
254
- --switch-width: calc(var(--switch-height) * 2);
278
+ /* The public knobs (--switch-height, --switch-width, --switch-padding) are
279
+ only READ here, never declared on the element. Declaring them on the
280
+ input itself made them impossible to set from outside: a value on a
281
+ container is shadowed by the element's own declaration, and a value on
282
+ the input loses to this rule's specificity — it only ever worked for an
283
+ inline style, or for a consumer that happened to out-rank this selector
284
+ by source order. The resolved values live in private --_switch-* props,
285
+ computed from whatever the cascade supplies, so a knob set anywhere
286
+ (ancestor, class, inline) takes effect and the others follow it. */
287
+ --_switch-height: var(--switch-height, calc(var(--space) - var(--space-d3)));
288
+ --_switch-width: var(--switch-width, calc(var(--_switch-height) * 2));
255
289
  /* Was a fixed 2px — correct-looking at the default ~16px-tall switch
256
290
  (an 8px thumb inset by 2px on each side), but any consumer overriding
257
- --switch-height alone (a smaller, denser control panel, say) kept that
258
- same fixed inset and ended up with a visibly undersized thumb, since
259
- the padding never scaled down with it. Went to 0 (Francis, iterating
260
- live: the thumb should fill the track, full height, no ring of bare
261
- track color around it) — the thumb's own diameter now equals the
262
- track's height exactly. */
263
- --switch-padding: 0px;
291
+ the height alone (a smaller, denser control panel, say) kept that same
292
+ fixed inset and ended up with a visibly undersized thumb, since the
293
+ padding never scaled down with it. Went to 0 (Francis, iterating live:
294
+ the thumb should fill the track, full height, no ring of bare track
295
+ color around it) — the thumb's own diameter now equals the track's
296
+ height exactly. */
297
+ --_switch-padding: var(--switch-padding, 0px);
264
298
 
265
299
  appearance: none;
266
300
  box-sizing: border-box; /* Reset content-box from base checkbox rule */
267
301
  position: relative;
268
302
  top: 0; /* Reset top: 50% from base checkbox rule */
269
- width: var(--switch-width);
270
- height: var(--switch-height);
303
+ width: var(--_switch-width);
304
+ height: var(--_switch-height);
271
305
  border-radius: 9999px;
272
306
  border: none;
273
307
  cursor: pointer;
@@ -304,10 +338,10 @@ input[type="checkbox"][role="switch"] {
304
338
  &::before {
305
339
  content: "";
306
340
  position: absolute;
307
- top: var(--switch-padding);
308
- left: var(--switch-padding);
309
- width: calc(var(--switch-height) - var(--switch-padding) * 2);
310
- height: calc(var(--switch-height) - var(--switch-padding) * 2);
341
+ top: var(--_switch-padding);
342
+ left: var(--_switch-padding);
343
+ width: calc(var(--_switch-height) - var(--_switch-padding) * 2);
344
+ height: calc(var(--_switch-height) - var(--_switch-padding) * 2);
311
345
  border-radius: 50%;
312
346
  background: var(--color-surface-light-2);
313
347
  /* Not --shadow-raised here on purpose — its ambient component
@@ -332,7 +366,7 @@ input[type="checkbox"][role="switch"] {
332
366
  background: var(--color-accent);
333
367
  &::before {
334
368
  background: var(--color-surface-light-2);
335
- transform: translateX(calc(var(--switch-width) - var(--switch-height)));
369
+ transform: translateX(calc(var(--_switch-width) - var(--_switch-height)));
336
370
  }
337
371
  }
338
372
 
@@ -345,6 +379,37 @@ input[type="checkbox"][role="switch"] {
345
379
  }
346
380
  }
347
381
 
382
+ /* Progress: a filled track, the way a range is, for work that has a known
383
+ length. Indeterminate (no value) shows the empty track. */
384
+ progress {
385
+ -webkit-appearance: none;
386
+ appearance: none;
387
+ display: block;
388
+ width: 100%;
389
+ height: var(--space-d4);
390
+ border: none;
391
+ border-radius: 9999px;
392
+ overflow: hidden;
393
+ background: var(--color-surface-dark-2);
394
+ color: var(--color-accent);
395
+
396
+ &::-webkit-progress-bar {
397
+ background: var(--color-surface-dark-2);
398
+ border-radius: inherit;
399
+ }
400
+
401
+ &::-webkit-progress-value {
402
+ background: var(--color-accent);
403
+ border-radius: inherit;
404
+ transition: width var(--duration-standard) var(--ease-soft);
405
+ }
406
+
407
+ &::-moz-progress-bar {
408
+ background: var(--color-accent);
409
+ border-radius: inherit;
410
+ }
411
+ }
412
+
348
413
  input[type="range"] {
349
414
  -webkit-appearance: none;
350
415
  /* Webkit/Blink */
@@ -371,10 +436,10 @@ input[type="range"] {
371
436
  actually renders. */
372
437
  background: linear-gradient(
373
438
  to right,
374
- var(--color-background, var(--color-accent)) 0%,
375
- var(--color-background, var(--color-accent)) var(--slider-value, 50%),
376
- var(--color-red, var(--color-surface)) var(--slider-value, 50%),
377
- var(--color-red, var(--color-surface)) 100%
439
+ var(--color-accent) 0%,
440
+ var(--color-accent) var(--slider-value, 50%),
441
+ var(--color-surface-dark-2) var(--slider-value, 50%),
442
+ var(--color-surface-dark-2) 100%
378
443
  );
379
444
  }
380
445
 
@@ -241,6 +241,53 @@ a.btn:disabled {
241
241
  cursor: not-allowed !important;
242
242
  pointer-events: none !important;
243
243
  }
244
+ /* A toggle button that is currently ON (aria-pressed): the accent, the same
245
+ cue whichever variant it wears. Zero-class so any variant or consumer rule
246
+ still wins over it. */
247
+ :where(button):is([aria-pressed="true"], [aria-current]:not([aria-current="false"])) {
248
+ color: var(--color-accent);
249
+ }
250
+
251
+ /* Segmented button group — the either/or control (Frames | Editorial, a row
252
+ of tabs). Documented in the header and referenced by the form spacing rules
253
+ for a long time, but never actually defined. The pressed one is marked the
254
+ way assistive tech reads it — aria-pressed / aria-selected / aria-checked /
255
+ aria-current — so the look can never disagree with the state. */
256
+ .btn-group {
257
+ display: inline-flex;
258
+ gap: 1px;
259
+ padding: 1px;
260
+ border-radius: var(--radius);
261
+ background: var(--color-surface-dark-1);
262
+ box-shadow: var(--shadow-inset);
263
+
264
+ > :where(button, a.btn) {
265
+ flex: 1 1 0;
266
+ min-width: 0;
267
+ background-color: transparent;
268
+ box-shadow: none;
269
+ color: var(--color-muted);
270
+ border-radius: calc(var(--radius) - 1px);
271
+
272
+ &:hover {
273
+ background-color: var(--color-surface);
274
+ color: var(--color-foreground);
275
+ box-shadow: none;
276
+ }
277
+
278
+ &:is(
279
+ [aria-pressed="true"],
280
+ [aria-selected="true"],
281
+ [aria-checked="true"],
282
+ [aria-current]:not([aria-current="false"])
283
+ ) {
284
+ background-color: var(--color-surface-light-2);
285
+ color: var(--color-foreground);
286
+ box-shadow: var(--shadow);
287
+ }
288
+ }
289
+ }
290
+
244
291
  /*
245
292
  :is(:where(button), .btn) svg {
246
293
  height: 100%;
@@ -1056,7 +1103,7 @@ a.skip-link {
1056
1103
 
1057
1104
  .std-menu-content {
1058
1105
  padding: var(--space-d4);
1059
- background: var(--color-surface-high);
1106
+ background: var(--color-surface-light-1);
1060
1107
  border: none;
1061
1108
  border-radius: var(--radius);
1062
1109
  box-shadow: var(--shadow-raised), var(--shadow-glow);
@@ -1112,12 +1159,12 @@ a.skip-link {
1112
1159
  text-decoration: none;
1113
1160
 
1114
1161
  &:hover:not(.disabled) {
1115
- background: var(--color-surface-highest);
1162
+ background: var(--color-surface-light-2);
1116
1163
  box-shadow: var(--shadow);
1117
1164
  }
1118
1165
 
1119
1166
  &:active:not(.disabled) {
1120
- background: var(--color-surface-low);
1167
+ background: var(--color-surface-dark-1);
1121
1168
  box-shadow: var(--shadow-inset);
1122
1169
  }
1123
1170
 
package/app.scss CHANGED
@@ -18,6 +18,18 @@
18
18
  * @property --window-inset Gap between the window edge and a floating pane.
19
19
  * @property --pane-radius Corner of a pane floating inside the window.
20
20
  * @property --titlebar-height Band centred on the OS traffic lights.
21
+ *
22
+ * Everything an application window needs that a document does not — this
23
+ * sheet is where it lives, so nothing has to be hunted for or rebuilt in an app:
24
+ *
25
+ * @property .pane A surface floating inside the window: inset, concentric corner, raised.
26
+ * @property .list, .item A column of rows. `.item` hovers, and reads aria-current / aria-selected as "this one".
27
+ * @property .hud A floating translucent chip or panel over the content (a toast, a status readout).
28
+ * @property .divider A hairline between groups.
29
+ * @property .window-controls, .window-close, .window-minimize, .window-zoom The traffic lights.
30
+ * @property .is-dragging, .is-drop-target The two states of a drag and drop.
31
+ * @property [data-reveal-host], [data-reveal] A control that only shows while its host is hovered or focused.
32
+ * @property .muted, .fine Secondary text and small print.
21
33
  */
22
34
  :root {
23
35
  /* ---- Type ------------------------------------------------------------
@@ -83,3 +95,227 @@
83
95
  window top (same capture as --window-radius), band = twice that. */
84
96
  --titlebar-height: 41.5px;
85
97
  }
98
+
99
+ /* ---- Images -------------------------------------------------------------
100
+ standard.scss zooms an image on press (a lightbox fallback that needs no
101
+ script) — right for a document, wrong for an app, where an image is a
102
+ workflow item you select and drag. Switch that behaviour off here so an
103
+ app never has to fight it with !important of its own. */
104
+ img,
105
+ img:not([data-no-zoom]) {
106
+ cursor: inherit !important;
107
+ }
108
+
109
+ html img:active,
110
+ html:not(.js-image-zoom-enabled) img:active {
111
+ position: static !important;
112
+ z-index: auto !important;
113
+ transform: none !important;
114
+ max-height: none !important;
115
+ max-width: none !important;
116
+ margin: 0 !important;
117
+ top: auto !important;
118
+ left: auto !important;
119
+ cursor: inherit !important;
120
+ }
121
+
122
+ html:has(img:active)::before,
123
+ html:not(.js-image-zoom-enabled):has(img:active)::before {
124
+ display: none !important;
125
+ content: none !important;
126
+ }
127
+
128
+ /* ---- Panes --------------------------------------------------------------
129
+ A sidebar, an inspector, a tray: a surface that floats inside the window,
130
+ --window-inset from its edge, corner concentric with the window's. Every
131
+ one of them used to spell these five lines out for itself. Layout (width,
132
+ flex, padding) stays with the pane; this is only what makes it a pane. */
133
+ .pane {
134
+ margin: var(--window-inset);
135
+ background: var(--color-surface-light-1);
136
+ border-radius: var(--pane-radius);
137
+ box-shadow: var(--shadow);
138
+ overflow: hidden;
139
+ }
140
+
141
+ /* ---- States ---------------------------------------------------------------
142
+ The "current" state of anything is said with ARIA, never a class of the
143
+ app's own: aria-current (this row, this page), aria-selected (this tab,
144
+ this option), aria-pressed (this toggle), aria-expanded, aria-disabled.
145
+ The kit below styles those, so the look can never disagree with what a
146
+ screen reader is told. Drag and drop has no ARIA of its own; it has two
147
+ classes. */
148
+ .is-dragging {
149
+ opacity: 0.4;
150
+ }
151
+
152
+ /* A region switched off by the state of something else (a row of AI options
153
+ while AI is off). Native controls inside keep their own disabled styling. */
154
+ [aria-disabled="true"]:not(.item, button, a, input, select, textarea) {
155
+ opacity: 0.5;
156
+ }
157
+
158
+ .is-drop-target {
159
+ background: color-mix(in srgb, var(--color-accent) 18%, transparent);
160
+ box-shadow: inset 0 0 0 var(--stroke-width) var(--color-accent);
161
+ }
162
+
163
+ /* Shown only while the host is hovered or holds focus — the quiet controls
164
+ of a row or a photo (remove, grip, reorder) that would clutter it at rest. */
165
+ [data-reveal] {
166
+ opacity: 0;
167
+ transition: opacity var(--duration-fast) var(--ease-soft);
168
+ }
169
+
170
+ [data-reveal-host]:is(:hover, :focus-within) [data-reveal],
171
+ [data-reveal]:is(:hover, :focus-visible) {
172
+ opacity: 1;
173
+ }
174
+
175
+ /* ---- Lists ----------------------------------------------------------------
176
+ A column of rows: folders, notes, settings, a queue. */
177
+ .list {
178
+ display: flex;
179
+ flex-direction: column;
180
+ min-width: 0;
181
+ }
182
+
183
+ .list.divided > :not(:last-child) {
184
+ border-bottom: var(--border);
185
+ }
186
+
187
+ /* A card whose content is rows: no padding of its own, rows run edge to edge. */
188
+ .card.flush {
189
+ padding: 0;
190
+ overflow: hidden;
191
+ }
192
+
193
+ .item {
194
+ display: flex;
195
+ align-items: center;
196
+ justify-content: flex-start;
197
+ gap: var(--space-d2);
198
+ min-width: 0;
199
+ padding: var(--space-d5) var(--space-d2);
200
+ border-radius: var(--radius-sm);
201
+ /* Works on a div or a button alike: a row is not a raised control. */
202
+ background: transparent;
203
+ box-shadow: none;
204
+ text-align: left;
205
+ color: var(--color-muted);
206
+ cursor: pointer;
207
+ transition:
208
+ background var(--duration-instant) var(--ease-soft),
209
+ color var(--duration-instant) var(--ease-soft);
210
+
211
+ &:hover {
212
+ background: var(--color-surface);
213
+ color: var(--color-foreground);
214
+ }
215
+
216
+ &:is([aria-current]:not([aria-current="false"]), [aria-selected="true"]) {
217
+ background: var(--color-surface-dark-1);
218
+ color: var(--color-foreground);
219
+ font-weight: var(--font-weight-bold);
220
+ }
221
+
222
+ &:is(:disabled, [aria-disabled="true"]) {
223
+ opacity: 0.5;
224
+ cursor: default;
225
+ pointer-events: none;
226
+ }
227
+ }
228
+
229
+ /* ---- HUD ------------------------------------------------------------------
230
+ A translucent chip over the content: a toast, an export readout, a
231
+ legend. Not a pane — it carries no chrome of the window, it just floats. */
232
+ .hud {
233
+ display: inline-flex;
234
+ align-items: center;
235
+ gap: var(--space-d2);
236
+ padding: var(--space-d4) var(--space-d2);
237
+ border-radius: 999px;
238
+ background: color-mix(in srgb, var(--color-surface-light-1) 88%, transparent);
239
+ backdrop-filter: var(--filter-blur);
240
+ box-shadow: var(--shadow-raised);
241
+ color: var(--color-foreground);
242
+ font-size: var(--scale-d2);
243
+ white-space: nowrap;
244
+
245
+ &.panel {
246
+ display: flex;
247
+ border-radius: var(--radius-lg);
248
+ white-space: normal;
249
+ }
250
+ }
251
+
252
+ .divider {
253
+ flex-shrink: 0;
254
+ height: var(--stroke-width);
255
+ margin: 0;
256
+ border: none;
257
+ background: var(--color-border);
258
+ }
259
+
260
+ .muted {
261
+ color: var(--color-muted);
262
+ }
263
+
264
+ .fine {
265
+ font-size: var(--scale-d2);
266
+ color: var(--color-muted);
267
+ }
268
+
269
+ /* ---- Window controls ------------------------------------------------------
270
+ The traffic lights, drawn by the page because the native ones are hidden
271
+ (an overlay title bar). At rest they are three quiet dots; over the group
272
+ they take the system colours and their glyphs. The three colours are
273
+ macOS's own, not the theme's. */
274
+ .window-controls {
275
+ display: flex;
276
+ gap: var(--space-d2);
277
+
278
+ > button {
279
+ all: unset;
280
+ box-sizing: border-box;
281
+ position: relative;
282
+ width: 12px;
283
+ height: 12px;
284
+ border-radius: 50%;
285
+ cursor: default;
286
+ background: var(--color-foreground);
287
+ opacity: 0.35;
288
+ transition:
289
+ opacity var(--duration-instant) var(--ease-soft),
290
+ background-color var(--duration-instant) var(--ease-soft);
291
+ }
292
+
293
+ &:has(> button:hover) > button {
294
+ opacity: 1;
295
+
296
+ &::after {
297
+ position: absolute;
298
+ inset: 0;
299
+ display: grid;
300
+ place-items: center;
301
+ color: rgb(0 0 0 / 55%);
302
+ font-family: sans-serif;
303
+ font-size: 8px;
304
+ font-weight: 700;
305
+ line-height: 1;
306
+ }
307
+ }
308
+
309
+ &:has(> button:hover) > .window-close {
310
+ background: #ff5f57;
311
+ &::after { content: "×"; }
312
+ }
313
+ &:has(> button:hover) > .window-minimize {
314
+ background: #febc2e;
315
+ &::after { content: "−"; }
316
+ }
317
+ &:has(> button:hover) > .window-zoom {
318
+ background: #28c840;
319
+ &::after { content: "+"; }
320
+ }
321
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stnd/styles",
3
- "version": "0.10.15",
3
+ "version": "0.11.0",
4
4
  "type": "module",
5
5
  "author": "Francis Fontaine",
6
6
  "license": "MIT",