layout-style-css 3.0.2 → 3.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 (39) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +25 -8
  3. package/dist/core.css +1 -1
  4. package/dist/foundation.css +156 -15
  5. package/dist/layout-style-css.css +178 -50
  6. package/dist/layout-style-css.min.css +1 -1
  7. package/dist/personalities/bauhaus.css +1 -1
  8. package/dist/personalities/bento.css +1 -1
  9. package/dist/personalities/brutalism.css +1 -1
  10. package/dist/personalities/cyberpunk.css +1 -1
  11. package/dist/personalities/f-pattern.css +1 -1
  12. package/dist/personalities/maximalist.css +1 -1
  13. package/dist/personalities/minimal-saas.css +1 -1
  14. package/dist/personalities/mondrian.css +1 -1
  15. package/dist/personalities/neumorphism.css +1 -1
  16. package/dist/personalities/retro-glass.css +1 -1
  17. package/dist/personalities/retrofuturism.css +1 -1
  18. package/dist/personalities/split-screen.css +1 -1
  19. package/dist/personalities/synthwave.css +1 -1
  20. package/dist/personalities/tactile.css +1 -1
  21. package/dist/personalities/y2k.css +1 -1
  22. package/dist/personalities/z-pattern.css +1 -1
  23. package/dist/personalities.css +1 -1
  24. package/dist/primitives.css +9 -2
  25. package/dist/recipes.css +1 -1
  26. package/dist/utilities.css +11 -35
  27. package/dist/wrappers.css +5 -1
  28. package/docs/wiki/Getting-Started.md +9 -4
  29. package/docs/wiki/Home.md +3 -1
  30. package/docs/wiki/Installation-And-CDN.md +6 -5
  31. package/docs/wiki/Layout-Primitives.md +12 -3
  32. package/docs/wiki/Layout-Recipes.md +2 -0
  33. package/docs/wiki/Layout-Styles.md +5 -1
  34. package/docs/wiki/Migrating-To-3.1.md +62 -0
  35. package/docs/wiki/Release-And-Publishing.md +5 -5
  36. package/docs/wiki/_Sidebar.md +1 -0
  37. package/manifest.json +16 -6
  38. package/package.json +1 -1
  39. package/personalities.json +1 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,26 @@
2
2
 
3
3
  All notable changes to `layout-style-css` are documented here. This project follows semantic versioning.
4
4
 
5
+ ## [3.1.0] - 2026-08-25
6
+
7
+ ### Added
8
+
9
+ - Added compact, normal, and spacious density contexts that can be applied at the root or to a nested layout subtree.
10
+ - Added the `96rem` workspace Wrapper, all ten local gap utilities, explicit bounded and viewport-relative Scroll modifiers, and recipe-owned threshold metadata.
11
+
12
+ ### Changed
13
+
14
+ - Made normal section spacing more conservative while retaining the former marketing rhythm through spacious density.
15
+ - Made gap utilities local to the element carrying the class and made base Scroll rely on its containing layout for height constraints.
16
+
17
+ ### Migration
18
+
19
+ - Use spacious density for the former section rhythm, explicit inherited gap tokens for a shared spacing context, and `ly-scroll--viewport` for the former viewport-relative Scroll behavior.
20
+
21
+ ### Tests
22
+
23
+ - Added density, workspace utilization, nested-gap isolation, Scroll-mode, public-token liveness, threshold metadata, cross-height, generated-output, package, and Pages contracts.
24
+
5
25
  ## [3.0.2] - 2026-08-25
6
26
 
7
27
  ### Fixed
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Zero-configuration, dependency-free structural CSS that responds to the width and height a layout actually receives.
4
4
 
5
- `layout-style-css@3.0.2` is the current v3 patch release and preserves the clean-break structural contract introduced in 3.0.0. It provides intrinsic wrappers, composition primitives, seven semantic recipes, and sixteen spatial personalities. Layout owns structure; UI Style Kit owns paint; Interactive Surface owns interaction styling.
5
+ `layout-style-css@3.1.0` is the current additive v3 release. It provides intrinsic wrappers, composition primitives, seven semantic recipes, explicit local density controls, and sixteen spatial personalities. Layout owns structure; UI Style Kit owns paint; Interactive Surface owns interaction styling.
6
6
 
7
7
  ## Requirements
8
8
 
@@ -13,7 +13,7 @@ Zero-configuration, dependency-free structural CSS that responds to the width an
13
13
  ## Install
14
14
 
15
15
  ```bash
16
- npm install layout-style-css@3.0.2
16
+ npm install layout-style-css@3.1.0
17
17
  ```
18
18
 
19
19
  Most applications need one import:
@@ -44,6 +44,17 @@ Use `.ly-root` as the responsive boundary and keep the mobile DOM order authorit
44
44
 
45
45
  `.ly-root`, wrappers, and recipe roots establish the named `ly-scope` inline-size container. A recipe works directly in the root; when it is nested in a wrapper, it responds to that nearest wrapper.
46
46
 
47
+ ## Density Contexts
48
+
49
+ Normal density is the zero-configuration default. Use `data-ly-density="compact"`, `data-ly-density="normal"`, or `data-ly-density="spacious"` on `.ly-root` or any nested layout subtree. A nested density explicitly resets inherited gaps and section rhythm, so task controls can remain compact inside a spacious marketing page.
50
+
51
+ ```html
52
+ <main class="ly-root" data-ly-density="normal">
53
+ <section data-ly-density="compact">Dense application controls</section>
54
+ <section data-ly-density="spacious">Campaign presentation</section>
55
+ </main>
56
+ ```
57
+
47
58
  ## Wrappers
48
59
 
49
60
  Wrappers are optional measure and nesting controls. Every wrapper uses logical properties, fluid container-relative gutters, safe-area compensation, and shrink-safe sizing.
@@ -54,6 +65,7 @@ Wrappers are optional measure and nesting controls. Every wrapper uses logical p
54
65
  | `.ly-wrapper--compact` | `40rem` compact measure |
55
66
  | `.ly-wrapper--prose` | `68ch` reading measure |
56
67
  | `.ly-wrapper--content` | `72rem` content measure |
68
+ | `.ly-wrapper--workspace` | `96rem` task-oriented application measure |
57
69
  | `.ly-wrapper--wide` | `112rem` wide measure |
58
70
  | `.ly-wrapper--full` | Full available inline size |
59
71
  | `.ly-wrapper--breakout` | Clamped content, feature, and full lanes |
@@ -79,7 +91,9 @@ The core includes:
79
91
  - `.ly-panes` and `.ly-media`
80
92
  - `.ly-reel`, `.ly-frame`, and `.ly-scroll`
81
93
 
82
- Grid and flex primitives wrap intrinsically whenever track wrapping can replace a query. Page, cover, and bounded-scroll sizing use `vh` fallbacks followed by `100dvh`-aware behavior. Only `.ly-reel` deliberately scrolls horizontally; only `.ly-scroll` deliberately creates a bounded vertical scroll region.
94
+ Grid and flex primitives wrap intrinsically whenever track wrapping can replace a query. Base `.ly-scroll` owns overflow but no height cap. Add `.ly-scroll--bounded` for the stable `--ly-scroll-max` cap or `.ly-scroll--viewport` for height-aware `--ly-scroll-viewport-max` behavior. Only `.ly-reel` deliberately scrolls horizontally; only the Scroll family deliberately creates vertical scrolling.
95
+
96
+ Gap utilities `.ly-gap-0` through `.ly-gap-9` assign `gap` only on the element carrying the class. They do not alter inherited primitive gap variables. Override `--ly-gap`, `--ly-grid-gap`, `--ly-stack-gap`, or `--ly-cluster-gap` when a shared spacing context is intentional.
83
97
 
84
98
  ## Automatic Recipe Engine
85
99
 
@@ -95,6 +109,8 @@ Recipes use attributes only. The stacked semantic source order is always safe, a
95
109
  | `data-ly-recipe="gallery"` | Intrinsic tracks; no topology breakpoint |
96
110
  | `data-ly-recipe="card-grid"` | Intrinsic tracks; no topology breakpoint |
97
111
 
112
+ The same ownership is available in `manifest.json` through `thresholds.recipes`, alongside the generic container-width and viewport-height arrays. Release checks verify every mapping against authored queries and require every public geometry token to reach a runtime CSS declaration.
113
+
98
114
  App Shell base, medium, and wide topologies own matching row definitions. This keeps the primary workspace flexible while header and footer tracks remain intrinsic, including personality-specific four-row topologies.
99
115
 
100
116
  Canonical regions use `data-ly-area`, including `header`, `sidebar`, `nav`, `main`, `aside`, `footer`, `content`, `media`, `actions`, `primary`, and `secondary`.
@@ -162,7 +178,7 @@ Each personality is a token/topology profile consumed by the shared recipe engin
162
178
  | `layout-style-css/personalities.json` | Public layout-to-visual pairing recommendations |
163
179
  | `layout-style-css/package.json` | Package metadata |
164
180
 
165
- The cascade order is `ly.reset`, `ly.tokens`, `ly.wrappers`, `ly.primitives`, `ly.recipes`, `ly.utilities`, and `ly.personalities`.
181
+ The cascade order is `ly.reset`, `ly.tokens`, `ly.wrappers`, `ly.primitives`, `ly.recipes`, `ly.utilities`, `ly.personalities`, and `ly.context`. Unlayered application CSS remains stronger than every library layer.
166
182
 
167
183
  ## Ecosystem Imports
168
184
 
@@ -177,18 +193,18 @@ import "layout-style-css";
177
193
 
178
194
  This order lets UI Style Kit establish paint and theme roles, Interactive Surface add interaction states, and Layout apply structure.
179
195
 
180
- `data-ly-layout`, `data-ui`, `data-theme`, and `data-mode` are independently selectable. See [Layout Styles](docs/wiki/Layout-Styles.md#visual-pairing-guidance) for the full recommendation matrix; pairings are never dependencies.
196
+ `data-ly-layout`, `data-ly-density`, `data-ui`, `data-theme`, and `data-mode` are independently selectable. See [Layout Styles](docs/wiki/Layout-Styles.md#visual-pairing-guidance) for the full recommendation matrix; pairings are never dependencies.
181
197
 
182
198
  ## CDN
183
199
 
184
200
  ```html
185
- <link rel="stylesheet" href="https://unpkg.com/layout-style-css@3.0.2/dist/layout-style-css.min.css">
186
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/layout-style-css@3.0.2/dist/layout-style-css.min.css">
201
+ <link rel="stylesheet" href="https://unpkg.com/layout-style-css@3.1.0/dist/layout-style-css.min.css">
202
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/layout-style-css@3.1.0/dist/layout-style-css.min.css">
187
203
  ```
188
204
 
189
205
  ## Clean-Break Migration
190
206
 
191
- v3 has no compatibility bundle. It removes `legacy.css`, the deprecated UI Style Kit structural bridge, v1/v2 aliases, responsive `ly-md-*` and `ly-lg-*` utilities, and all visual-order utilities. See [Migrating To 3.0](docs/wiki/Migrating-To-3.0.md) for exact mappings.
207
+ v3 has no compatibility bundle. It removes `legacy.css`, the deprecated UI Style Kit structural bridge, v1/v2 aliases, responsive `ly-md-*` and `ly-lg-*` utilities, and all visual-order utilities. See [Migrating To 3.0](docs/wiki/Migrating-To-3.0.md) for the major-version mappings and [Migrating To 3.1](docs/wiki/Migrating-To-3.1.md) for density, local gap, and Scroll behavior changes.
192
208
 
193
209
  ## Demo And Verification
194
210
 
@@ -214,6 +230,7 @@ npm run release:verify
214
230
  - [Layout Recipes](docs/wiki/Layout-Recipes.md)
215
231
  - [Layout Styles](docs/wiki/Layout-Styles.md)
216
232
  - [Migrating To 3.0](docs/wiki/Migrating-To-3.0.md)
233
+ - [Migrating To 3.1](docs/wiki/Migrating-To-3.1.md)
217
234
  - [Demo And GitHub Pages](docs/wiki/Demo-And-GitHub-Pages.md)
218
235
  - [Release And Publishing](docs/wiki/Release-And-Publishing.md)
219
236
  - [Security And Support](docs/wiki/Security-And-Support.md)
package/dist/core.css CHANGED
@@ -1,4 +1,4 @@
1
- @layer ly.reset, ly.tokens, ly.wrappers, ly.primitives, ly.recipes, ly.utilities, ly.personalities;
1
+ @layer ly.reset, ly.tokens, ly.wrappers, ly.primitives, ly.recipes, ly.utilities, ly.personalities, ly.context;
2
2
 
3
3
  @import url("./foundation.css");
4
4
  @import url("./wrappers.css");
@@ -1,4 +1,4 @@
1
- @layer ly.reset, ly.tokens, ly.wrappers, ly.primitives, ly.recipes, ly.utilities, ly.personalities;
1
+ @layer ly.reset, ly.tokens, ly.wrappers, ly.primitives, ly.recipes, ly.utilities, ly.personalities, ly.context;
2
2
 
3
3
  /*
4
4
  Foundation owns only shared spatial tokens, containment, and defensive
@@ -21,6 +21,7 @@
21
21
  --ly-wrapper-compact: 40rem;
22
22
  --ly-wrapper-prose: 68ch;
23
23
  --ly-wrapper-content: 72rem;
24
+ --ly-wrapper-workspace: 96rem;
24
25
  --ly-wrapper-wide: 112rem;
25
26
  --ly-page-padding-inline: clamp(1rem, 3vw, 3rem);
26
27
  --ly-safe-area-inline: max(
@@ -36,13 +37,14 @@
36
37
  --ly-grid-gap: var(--ly-gap);
37
38
  --ly-stack-gap: var(--ly-space-4);
38
39
  --ly-cluster-gap: var(--ly-space-3);
39
- --ly-section-padding-block: clamp(3rem, 7vh, 6rem);
40
- --ly-section-padding-block-compact: clamp(1.5rem, 3.5vh, 3rem);
40
+ --ly-section-padding-block: clamp(2rem, 4vh, 4rem);
41
+ --ly-section-padding-block-compact: clamp(1rem, 2.5vh, 2rem);
41
42
  --ly-header-height: 4.5rem;
42
43
  --ly-sticky-position: sticky;
43
44
  --ly-cover-min: 100vh;
44
45
  --ly-shell-min: 100vh;
45
- --ly-scroll-max: min(70vh, 50rem);
46
+ --ly-scroll-max: 50rem;
47
+ --ly-scroll-viewport-max: min(70vh, 50rem);
46
48
 
47
49
  --ly-switcher-threshold: 42rem;
48
50
  --ly-sidebar-size: 18rem;
@@ -141,7 +143,7 @@
141
143
  :where(.ly-root) {
142
144
  --ly-cover-min: 100dvh;
143
145
  --ly-shell-min: 100dvh;
144
- --ly-scroll-max: min(70dvh, 50rem);
146
+ --ly-scroll-viewport-max: min(70dvh, 50rem);
145
147
  }
146
148
  }
147
149
  }
@@ -172,19 +174,19 @@
172
174
  --ly-grid-gap: var(--ly-gap);
173
175
  --ly-stack-gap: min(var(--ly-space-4), 3vh);
174
176
  --ly-cluster-gap: min(var(--ly-space-3), 2vh);
175
- --ly-section-padding-block: clamp(1.5rem, 6vh, 3rem);
176
- --ly-section-padding-block-compact: clamp(0.75rem, 3vh, 1.25rem);
177
+ --ly-section-padding-block: clamp(1.25rem, 4vh, 2rem);
178
+ --ly-section-padding-block-compact: clamp(0.75rem, 2vh, 1.25rem);
177
179
  --ly-header-height: 3.5rem;
178
- --ly-scroll-max: min(62vh, 34rem);
180
+ --ly-scroll-viewport-max: min(62vh, 34rem);
179
181
  }
180
182
 
181
183
  @supports (height: 100dvh) {
182
184
  :where(.ly-root) {
183
185
  --ly-stack-gap: min(var(--ly-space-4), 3dvh);
184
186
  --ly-cluster-gap: min(var(--ly-space-3), 2dvh);
185
- --ly-section-padding-block: clamp(1.5rem, 6dvh, 3rem);
186
- --ly-section-padding-block-compact: clamp(0.75rem, 3dvh, 1.25rem);
187
- --ly-scroll-max: min(62dvh, 34rem);
187
+ --ly-section-padding-block: clamp(1.25rem, 4dvh, 2rem);
188
+ --ly-section-padding-block-compact: clamp(0.75rem, 2dvh, 1.25rem);
189
+ --ly-scroll-viewport-max: min(62dvh, 34rem);
188
190
  }
189
191
  }
190
192
  }
@@ -194,15 +196,154 @@
194
196
  --ly-cover-min: auto;
195
197
  --ly-shell-min: auto;
196
198
  --ly-sticky-position: static;
197
- --ly-section-padding-block: var(--ly-space-5);
198
- --ly-section-padding-block-compact: var(--ly-space-3);
199
- --ly-scroll-max: max(12rem, calc(100vh - 8rem));
199
+ --ly-section-padding-block: var(--ly-space-4);
200
+ --ly-section-padding-block-compact: var(--ly-space-2);
201
+ --ly-scroll-viewport-max: max(12rem, calc(100vh - 8rem));
200
202
  }
201
203
 
202
204
  @supports (height: 100dvh) {
203
205
  :where(.ly-root) {
204
- --ly-scroll-max: max(12rem, calc(100dvh - 8rem));
206
+ --ly-scroll-viewport-max: max(12rem, calc(100dvh - 8rem));
207
+ }
208
+ }
209
+ }
210
+ }
211
+
212
+ @layer ly.context {
213
+ :where(
214
+ .ly-root[data-ly-density="compact"],
215
+ .ly-root [data-ly-density="compact"]
216
+ ) {
217
+ --ly-gap: var(--ly-space-3);
218
+ --ly-grid-gap: var(--ly-space-3);
219
+ --ly-stack-gap: var(--ly-space-3);
220
+ --ly-cluster-gap: var(--ly-space-2);
221
+ --ly-section-padding-block: clamp(1rem, 2.5vh, 2rem);
222
+ --ly-section-padding-block-compact: clamp(0.5rem, 1.5vh, 1rem);
223
+ }
224
+
225
+ :where(
226
+ .ly-root[data-ly-density="normal"],
227
+ .ly-root [data-ly-density="normal"]
228
+ ) {
229
+ --ly-gap: var(--ly-profile-gap);
230
+ --ly-grid-gap: var(--ly-gap);
231
+ --ly-stack-gap: var(--ly-space-4);
232
+ --ly-cluster-gap: var(--ly-space-3);
233
+ --ly-section-padding-block: clamp(2rem, 4vh, 4rem);
234
+ --ly-section-padding-block-compact: clamp(1rem, 2.5vh, 2rem);
235
+ }
236
+
237
+ :where(
238
+ .ly-root[data-ly-density="spacious"],
239
+ .ly-root [data-ly-density="spacious"]
240
+ ) {
241
+ --ly-gap: max(var(--ly-profile-gap), var(--ly-space-6));
242
+ --ly-grid-gap: var(--ly-gap);
243
+ --ly-stack-gap: var(--ly-space-5);
244
+ --ly-cluster-gap: var(--ly-space-4);
245
+ --ly-section-padding-block: clamp(3rem, 7vh, 6rem);
246
+ --ly-section-padding-block-compact: clamp(1.5rem, 3.5vh, 3rem);
247
+ }
248
+
249
+ @media (max-height: 44rem) {
250
+ :where(
251
+ .ly-root[data-ly-density="compact"],
252
+ .ly-root [data-ly-density="compact"]
253
+ ) {
254
+ --ly-gap: var(--ly-space-3);
255
+ --ly-grid-gap: var(--ly-space-3);
256
+ --ly-stack-gap: var(--ly-space-3);
257
+ --ly-cluster-gap: var(--ly-space-2);
258
+ --ly-section-padding-block: clamp(0.75rem, 2vh, 1.25rem);
259
+ --ly-section-padding-block-compact: var(--ly-space-2);
260
+ }
261
+
262
+ :where(
263
+ .ly-root[data-ly-density="normal"],
264
+ .ly-root [data-ly-density="normal"]
265
+ ) {
266
+ --ly-gap: min(var(--ly-profile-gap), var(--ly-space-4));
267
+ --ly-grid-gap: var(--ly-gap);
268
+ --ly-stack-gap: var(--ly-space-4);
269
+ --ly-cluster-gap: var(--ly-space-3);
270
+ --ly-section-padding-block: clamp(1.25rem, 4vh, 2rem);
271
+ --ly-section-padding-block-compact: clamp(0.75rem, 2vh, 1.25rem);
272
+ }
273
+
274
+ :where(
275
+ .ly-root[data-ly-density="spacious"],
276
+ .ly-root [data-ly-density="spacious"]
277
+ ) {
278
+ --ly-gap: var(--ly-space-5);
279
+ --ly-grid-gap: var(--ly-space-5);
280
+ --ly-stack-gap: var(--ly-space-4);
281
+ --ly-cluster-gap: var(--ly-space-3);
282
+ --ly-section-padding-block: clamp(1.5rem, 6vh, 3rem);
283
+ --ly-section-padding-block-compact: clamp(0.75rem, 3vh, 1.25rem);
284
+ }
285
+
286
+ @supports (height: 100dvh) {
287
+ :where(
288
+ .ly-root[data-ly-density="compact"],
289
+ .ly-root [data-ly-density="compact"]
290
+ ) {
291
+ --ly-section-padding-block: clamp(0.75rem, 2dvh, 1.25rem);
205
292
  }
293
+
294
+ :where(
295
+ .ly-root[data-ly-density="normal"],
296
+ .ly-root [data-ly-density="normal"]
297
+ ) {
298
+ --ly-section-padding-block: clamp(1.25rem, 4dvh, 2rem);
299
+ --ly-section-padding-block-compact: clamp(0.75rem, 2dvh, 1.25rem);
300
+ }
301
+
302
+ :where(
303
+ .ly-root[data-ly-density="spacious"],
304
+ .ly-root [data-ly-density="spacious"]
305
+ ) {
306
+ --ly-section-padding-block: clamp(1.5rem, 6dvh, 3rem);
307
+ --ly-section-padding-block-compact: clamp(0.75rem, 3dvh, 1.25rem);
308
+ }
309
+ }
310
+ }
311
+
312
+ @media (max-height: 30rem) {
313
+ :where(
314
+ .ly-root[data-ly-density="compact"],
315
+ .ly-root [data-ly-density="compact"]
316
+ ) {
317
+ --ly-gap: var(--ly-space-2);
318
+ --ly-grid-gap: var(--ly-space-2);
319
+ --ly-stack-gap: var(--ly-space-2);
320
+ --ly-cluster-gap: var(--ly-space-1);
321
+ --ly-section-padding-block: var(--ly-space-3);
322
+ --ly-section-padding-block-compact: var(--ly-space-2);
323
+ }
324
+
325
+ :where(
326
+ .ly-root[data-ly-density="normal"],
327
+ .ly-root [data-ly-density="normal"]
328
+ ) {
329
+ --ly-gap: var(--ly-space-3);
330
+ --ly-grid-gap: var(--ly-space-3);
331
+ --ly-stack-gap: var(--ly-space-3);
332
+ --ly-cluster-gap: var(--ly-space-2);
333
+ --ly-section-padding-block: var(--ly-space-4);
334
+ --ly-section-padding-block-compact: var(--ly-space-2);
335
+ }
336
+
337
+ :where(
338
+ .ly-root[data-ly-density="spacious"],
339
+ .ly-root [data-ly-density="spacious"]
340
+ ) {
341
+ --ly-gap: var(--ly-space-4);
342
+ --ly-grid-gap: var(--ly-space-4);
343
+ --ly-stack-gap: var(--ly-space-4);
344
+ --ly-cluster-gap: var(--ly-space-3);
345
+ --ly-section-padding-block: var(--ly-space-5);
346
+ --ly-section-padding-block-compact: var(--ly-space-3);
206
347
  }
207
348
  }
208
349
  }
@@ -1,4 +1,4 @@
1
- @layer ly.reset, ly.tokens, ly.wrappers, ly.primitives, ly.recipes, ly.utilities, ly.personalities;
1
+ @layer ly.reset, ly.tokens, ly.wrappers, ly.primitives, ly.recipes, ly.utilities, ly.personalities, ly.context;
2
2
 
3
3
  /* layout-style-css v3 bundle. Generated from focused styles/ modules. */
4
4
 
@@ -24,6 +24,7 @@
24
24
  --ly-wrapper-compact: 40rem;
25
25
  --ly-wrapper-prose: 68ch;
26
26
  --ly-wrapper-content: 72rem;
27
+ --ly-wrapper-workspace: 96rem;
27
28
  --ly-wrapper-wide: 112rem;
28
29
  --ly-page-padding-inline: clamp(1rem, 3vw, 3rem);
29
30
  --ly-safe-area-inline: max(
@@ -39,13 +40,14 @@
39
40
  --ly-grid-gap: var(--ly-gap);
40
41
  --ly-stack-gap: var(--ly-space-4);
41
42
  --ly-cluster-gap: var(--ly-space-3);
42
- --ly-section-padding-block: clamp(3rem, 7vh, 6rem);
43
- --ly-section-padding-block-compact: clamp(1.5rem, 3.5vh, 3rem);
43
+ --ly-section-padding-block: clamp(2rem, 4vh, 4rem);
44
+ --ly-section-padding-block-compact: clamp(1rem, 2.5vh, 2rem);
44
45
  --ly-header-height: 4.5rem;
45
46
  --ly-sticky-position: sticky;
46
47
  --ly-cover-min: 100vh;
47
48
  --ly-shell-min: 100vh;
48
- --ly-scroll-max: min(70vh, 50rem);
49
+ --ly-scroll-max: 50rem;
50
+ --ly-scroll-viewport-max: min(70vh, 50rem);
49
51
 
50
52
  --ly-switcher-threshold: 42rem;
51
53
  --ly-sidebar-size: 18rem;
@@ -144,7 +146,7 @@
144
146
  :where(.ly-root) {
145
147
  --ly-cover-min: 100dvh;
146
148
  --ly-shell-min: 100dvh;
147
- --ly-scroll-max: min(70dvh, 50rem);
149
+ --ly-scroll-viewport-max: min(70dvh, 50rem);
148
150
  }
149
151
  }
150
152
  }
@@ -175,19 +177,19 @@
175
177
  --ly-grid-gap: var(--ly-gap);
176
178
  --ly-stack-gap: min(var(--ly-space-4), 3vh);
177
179
  --ly-cluster-gap: min(var(--ly-space-3), 2vh);
178
- --ly-section-padding-block: clamp(1.5rem, 6vh, 3rem);
179
- --ly-section-padding-block-compact: clamp(0.75rem, 3vh, 1.25rem);
180
+ --ly-section-padding-block: clamp(1.25rem, 4vh, 2rem);
181
+ --ly-section-padding-block-compact: clamp(0.75rem, 2vh, 1.25rem);
180
182
  --ly-header-height: 3.5rem;
181
- --ly-scroll-max: min(62vh, 34rem);
183
+ --ly-scroll-viewport-max: min(62vh, 34rem);
182
184
  }
183
185
 
184
186
  @supports (height: 100dvh) {
185
187
  :where(.ly-root) {
186
188
  --ly-stack-gap: min(var(--ly-space-4), 3dvh);
187
189
  --ly-cluster-gap: min(var(--ly-space-3), 2dvh);
188
- --ly-section-padding-block: clamp(1.5rem, 6dvh, 3rem);
189
- --ly-section-padding-block-compact: clamp(0.75rem, 3dvh, 1.25rem);
190
- --ly-scroll-max: min(62dvh, 34rem);
190
+ --ly-section-padding-block: clamp(1.25rem, 4dvh, 2rem);
191
+ --ly-section-padding-block-compact: clamp(0.75rem, 2dvh, 1.25rem);
192
+ --ly-scroll-viewport-max: min(62dvh, 34rem);
191
193
  }
192
194
  }
193
195
  }
@@ -197,17 +199,156 @@
197
199
  --ly-cover-min: auto;
198
200
  --ly-shell-min: auto;
199
201
  --ly-sticky-position: static;
200
- --ly-section-padding-block: var(--ly-space-5);
201
- --ly-section-padding-block-compact: var(--ly-space-3);
202
- --ly-scroll-max: max(12rem, calc(100vh - 8rem));
202
+ --ly-section-padding-block: var(--ly-space-4);
203
+ --ly-section-padding-block-compact: var(--ly-space-2);
204
+ --ly-scroll-viewport-max: max(12rem, calc(100vh - 8rem));
203
205
  }
204
206
 
205
207
  @supports (height: 100dvh) {
206
208
  :where(.ly-root) {
207
- --ly-scroll-max: max(12rem, calc(100dvh - 8rem));
209
+ --ly-scroll-viewport-max: max(12rem, calc(100dvh - 8rem));
210
+ }
211
+ }
212
+ }
213
+ }
214
+
215
+ @layer ly.context {
216
+ :where(
217
+ .ly-root[data-ly-density="compact"],
218
+ .ly-root [data-ly-density="compact"]
219
+ ) {
220
+ --ly-gap: var(--ly-space-3);
221
+ --ly-grid-gap: var(--ly-space-3);
222
+ --ly-stack-gap: var(--ly-space-3);
223
+ --ly-cluster-gap: var(--ly-space-2);
224
+ --ly-section-padding-block: clamp(1rem, 2.5vh, 2rem);
225
+ --ly-section-padding-block-compact: clamp(0.5rem, 1.5vh, 1rem);
226
+ }
227
+
228
+ :where(
229
+ .ly-root[data-ly-density="normal"],
230
+ .ly-root [data-ly-density="normal"]
231
+ ) {
232
+ --ly-gap: var(--ly-profile-gap);
233
+ --ly-grid-gap: var(--ly-gap);
234
+ --ly-stack-gap: var(--ly-space-4);
235
+ --ly-cluster-gap: var(--ly-space-3);
236
+ --ly-section-padding-block: clamp(2rem, 4vh, 4rem);
237
+ --ly-section-padding-block-compact: clamp(1rem, 2.5vh, 2rem);
238
+ }
239
+
240
+ :where(
241
+ .ly-root[data-ly-density="spacious"],
242
+ .ly-root [data-ly-density="spacious"]
243
+ ) {
244
+ --ly-gap: max(var(--ly-profile-gap), var(--ly-space-6));
245
+ --ly-grid-gap: var(--ly-gap);
246
+ --ly-stack-gap: var(--ly-space-5);
247
+ --ly-cluster-gap: var(--ly-space-4);
248
+ --ly-section-padding-block: clamp(3rem, 7vh, 6rem);
249
+ --ly-section-padding-block-compact: clamp(1.5rem, 3.5vh, 3rem);
250
+ }
251
+
252
+ @media (max-height: 44rem) {
253
+ :where(
254
+ .ly-root[data-ly-density="compact"],
255
+ .ly-root [data-ly-density="compact"]
256
+ ) {
257
+ --ly-gap: var(--ly-space-3);
258
+ --ly-grid-gap: var(--ly-space-3);
259
+ --ly-stack-gap: var(--ly-space-3);
260
+ --ly-cluster-gap: var(--ly-space-2);
261
+ --ly-section-padding-block: clamp(0.75rem, 2vh, 1.25rem);
262
+ --ly-section-padding-block-compact: var(--ly-space-2);
263
+ }
264
+
265
+ :where(
266
+ .ly-root[data-ly-density="normal"],
267
+ .ly-root [data-ly-density="normal"]
268
+ ) {
269
+ --ly-gap: min(var(--ly-profile-gap), var(--ly-space-4));
270
+ --ly-grid-gap: var(--ly-gap);
271
+ --ly-stack-gap: var(--ly-space-4);
272
+ --ly-cluster-gap: var(--ly-space-3);
273
+ --ly-section-padding-block: clamp(1.25rem, 4vh, 2rem);
274
+ --ly-section-padding-block-compact: clamp(0.75rem, 2vh, 1.25rem);
275
+ }
276
+
277
+ :where(
278
+ .ly-root[data-ly-density="spacious"],
279
+ .ly-root [data-ly-density="spacious"]
280
+ ) {
281
+ --ly-gap: var(--ly-space-5);
282
+ --ly-grid-gap: var(--ly-space-5);
283
+ --ly-stack-gap: var(--ly-space-4);
284
+ --ly-cluster-gap: var(--ly-space-3);
285
+ --ly-section-padding-block: clamp(1.5rem, 6vh, 3rem);
286
+ --ly-section-padding-block-compact: clamp(0.75rem, 3vh, 1.25rem);
287
+ }
288
+
289
+ @supports (height: 100dvh) {
290
+ :where(
291
+ .ly-root[data-ly-density="compact"],
292
+ .ly-root [data-ly-density="compact"]
293
+ ) {
294
+ --ly-section-padding-block: clamp(0.75rem, 2dvh, 1.25rem);
295
+ }
296
+
297
+ :where(
298
+ .ly-root[data-ly-density="normal"],
299
+ .ly-root [data-ly-density="normal"]
300
+ ) {
301
+ --ly-section-padding-block: clamp(1.25rem, 4dvh, 2rem);
302
+ --ly-section-padding-block-compact: clamp(0.75rem, 2dvh, 1.25rem);
303
+ }
304
+
305
+ :where(
306
+ .ly-root[data-ly-density="spacious"],
307
+ .ly-root [data-ly-density="spacious"]
308
+ ) {
309
+ --ly-section-padding-block: clamp(1.5rem, 6dvh, 3rem);
310
+ --ly-section-padding-block-compact: clamp(0.75rem, 3dvh, 1.25rem);
208
311
  }
209
312
  }
210
313
  }
314
+
315
+ @media (max-height: 30rem) {
316
+ :where(
317
+ .ly-root[data-ly-density="compact"],
318
+ .ly-root [data-ly-density="compact"]
319
+ ) {
320
+ --ly-gap: var(--ly-space-2);
321
+ --ly-grid-gap: var(--ly-space-2);
322
+ --ly-stack-gap: var(--ly-space-2);
323
+ --ly-cluster-gap: var(--ly-space-1);
324
+ --ly-section-padding-block: var(--ly-space-3);
325
+ --ly-section-padding-block-compact: var(--ly-space-2);
326
+ }
327
+
328
+ :where(
329
+ .ly-root[data-ly-density="normal"],
330
+ .ly-root [data-ly-density="normal"]
331
+ ) {
332
+ --ly-gap: var(--ly-space-3);
333
+ --ly-grid-gap: var(--ly-space-3);
334
+ --ly-stack-gap: var(--ly-space-3);
335
+ --ly-cluster-gap: var(--ly-space-2);
336
+ --ly-section-padding-block: var(--ly-space-4);
337
+ --ly-section-padding-block-compact: var(--ly-space-2);
338
+ }
339
+
340
+ :where(
341
+ .ly-root[data-ly-density="spacious"],
342
+ .ly-root [data-ly-density="spacious"]
343
+ ) {
344
+ --ly-gap: var(--ly-space-4);
345
+ --ly-grid-gap: var(--ly-space-4);
346
+ --ly-stack-gap: var(--ly-space-4);
347
+ --ly-cluster-gap: var(--ly-space-3);
348
+ --ly-section-padding-block: var(--ly-space-5);
349
+ --ly-section-padding-block-compact: var(--ly-space-3);
350
+ }
351
+ }
211
352
  }
212
353
 
213
354
  /* wrappers.css */
@@ -242,6 +383,10 @@
242
383
  --ly-wrapper-max: var(--ly-wrapper-content);
243
384
  }
244
385
 
386
+ .ly-wrapper--workspace {
387
+ --ly-wrapper-max: var(--ly-wrapper-workspace);
388
+ }
389
+
245
390
  .ly-wrapper--wide {
246
391
  --ly-wrapper-max: var(--ly-wrapper-wide);
247
392
  }
@@ -473,11 +618,18 @@
473
618
 
474
619
  .ly-scroll {
475
620
  min-block-size: 0;
476
- max-block-size: var(--ly-scroll-max);
477
621
  overflow-x: clip;
478
622
  overflow-y: auto;
479
623
  overscroll-behavior-block: contain;
480
624
  }
625
+
626
+ .ly-scroll--bounded {
627
+ max-block-size: var(--ly-scroll-max);
628
+ }
629
+
630
+ .ly-scroll--viewport {
631
+ max-block-size: var(--ly-scroll-viewport-max);
632
+ }
481
633
  }
482
634
 
483
635
  /* recipes.css */
@@ -694,40 +846,16 @@
694
846
  .ly-span-4 { grid-column: span 4; }
695
847
  .ly-span-full { grid-column: 1 / -1; }
696
848
 
697
- .ly-gap-0 {
698
- --ly-gap: var(--ly-space-0);
699
- --ly-grid-gap: var(--ly-space-0);
700
- --ly-stack-gap: var(--ly-space-0);
701
- --ly-cluster-gap: var(--ly-space-0);
702
- }
703
-
704
- .ly-gap-2 {
705
- --ly-gap: var(--ly-space-2);
706
- --ly-grid-gap: var(--ly-space-2);
707
- --ly-stack-gap: var(--ly-space-2);
708
- --ly-cluster-gap: var(--ly-space-2);
709
- }
710
-
711
- .ly-gap-4 {
712
- --ly-gap: var(--ly-space-4);
713
- --ly-grid-gap: var(--ly-space-4);
714
- --ly-stack-gap: var(--ly-space-4);
715
- --ly-cluster-gap: var(--ly-space-4);
716
- }
717
-
718
- .ly-gap-6 {
719
- --ly-gap: var(--ly-space-6);
720
- --ly-grid-gap: var(--ly-space-6);
721
- --ly-stack-gap: var(--ly-space-6);
722
- --ly-cluster-gap: var(--ly-space-6);
723
- }
724
-
725
- .ly-gap-8 {
726
- --ly-gap: var(--ly-space-8);
727
- --ly-grid-gap: var(--ly-space-8);
728
- --ly-stack-gap: var(--ly-space-8);
729
- --ly-cluster-gap: var(--ly-space-8);
730
- }
849
+ .ly-gap-0 { gap: var(--ly-space-0); }
850
+ .ly-gap-1 { gap: var(--ly-space-1); }
851
+ .ly-gap-2 { gap: var(--ly-space-2); }
852
+ .ly-gap-3 { gap: var(--ly-space-3); }
853
+ .ly-gap-4 { gap: var(--ly-space-4); }
854
+ .ly-gap-5 { gap: var(--ly-space-5); }
855
+ .ly-gap-6 { gap: var(--ly-space-6); }
856
+ .ly-gap-7 { gap: var(--ly-space-7); }
857
+ .ly-gap-8 { gap: var(--ly-space-8); }
858
+ .ly-gap-9 { gap: var(--ly-space-9); }
731
859
 
732
860
  .ly-pad-0 { padding: var(--ly-space-0); }
733
861
  .ly-pad-2 { padding: var(--ly-space-2); }