layout-style-css 2.0.0 → 2.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.
package/demo/demo.js CHANGED
@@ -1,3 +1,82 @@
1
+ const UI_STYLE_KIT_VERSION = "2.1.0";
2
+ const UI_STYLE_KIT_MANIFEST_URL = `https://unpkg.com/ui-style-kit-css@${UI_STYLE_KIT_VERSION}/manifest.json`;
3
+ const UI_STYLE_KIT_MANIFEST_FALLBACK = Object.freeze({
4
+ version: UI_STYLE_KIT_VERSION,
5
+ presets: Object.freeze([
6
+ Object.freeze({ id: "minimal-saas", label: "Minimal SaaS", prefix: "saas" }),
7
+ Object.freeze({ id: "bento", label: "Bento", prefix: "bento" }),
8
+ Object.freeze({ id: "maximalist", label: "Maximalist", prefix: "max" }),
9
+ Object.freeze({ id: "bauhaus", label: "Bauhaus", prefix: "bau" }),
10
+ Object.freeze({ id: "tactile", label: "Tactile", prefix: "tactile" }),
11
+ Object.freeze({ id: "neumorphism", label: "Neumorphism", prefix: "neo" }),
12
+ Object.freeze({ id: "retrofuturism", label: "Retrofuturism", prefix: "retro" }),
13
+ Object.freeze({ id: "brutalism", label: "Brutalism", prefix: "brutal" }),
14
+ Object.freeze({ id: "cyberpunk", label: "Cyberpunk", prefix: "cyber" }),
15
+ Object.freeze({ id: "y2k", label: "Y2K", prefix: "y2k" }),
16
+ Object.freeze({ id: "retro-glass", label: "Retro Glass", prefix: "rg" })
17
+ ]),
18
+ themes: Object.freeze([
19
+ "midnight-gold",
20
+ "ocean-steel",
21
+ "forest-moss",
22
+ "sunset-ember",
23
+ "royal-plum",
24
+ "graphite-cyan",
25
+ "desert-sage",
26
+ "rose-quartz",
27
+ "cyber-lime",
28
+ "arctic-indigo"
29
+ ]),
30
+ modes: Object.freeze(["light", "dark", "contrast"])
31
+ });
32
+
33
+ function normalizeUiStyleKitManifest(manifest) {
34
+ const normalized = {
35
+ version: String(manifest?.version ?? UI_STYLE_KIT_VERSION),
36
+ presets: Array.isArray(manifest?.presets) ? manifest.presets : [],
37
+ themes: Array.isArray(manifest?.themes) ? manifest.themes : [],
38
+ modes: Array.isArray(manifest?.modes) ? manifest.modes : []
39
+ };
40
+ const presets = normalized.presets
41
+ .map((preset) => ({
42
+ id: String(preset?.id ?? ""),
43
+ label: String(preset?.label ?? preset?.id ?? ""),
44
+ prefix: String(preset?.prefix ?? "")
45
+ }))
46
+ .filter((preset) => preset.id && preset.prefix);
47
+
48
+ if (presets.length === 0 || normalized.themes.length === 0 || normalized.modes.length === 0) {
49
+ throw new Error("UI Style Kit manifest is missing presets, themes, or modes.");
50
+ }
51
+
52
+ return Object.freeze({
53
+ version: normalized.version,
54
+ presets: Object.freeze(presets.map((preset) => Object.freeze(preset))),
55
+ themes: Object.freeze(normalized.themes.map(String)),
56
+ modes: Object.freeze(normalized.modes.map(String))
57
+ });
58
+ }
59
+
60
+ async function loadUiStyleKitManifest() {
61
+ try {
62
+ const response = await fetch(UI_STYLE_KIT_MANIFEST_URL, { cache: "force-cache" });
63
+
64
+ if (!response.ok) {
65
+ throw new Error(`HTTP ${response.status}`);
66
+ }
67
+
68
+ return normalizeUiStyleKitManifest(await response.json());
69
+ } catch (error) {
70
+ /*
71
+ The published demo can render before the companion UI release reaches every CDN edge.
72
+ The fallback mirrors the 2.1 manifest contract so layout behavior stays testable.
73
+ */
74
+ console.warn("UI Style Kit 2.1 manifest unavailable; using the packaged fallback.", error);
75
+ return UI_STYLE_KIT_MANIFEST_FALLBACK;
76
+ }
77
+ }
78
+
79
+ const UI_STYLE_KIT_MANIFEST = await loadUiStyleKitManifest();
1
80
  const ALLOWLISTS = Object.freeze({
2
81
  wrapper: Object.freeze(["default", "compact", "prose", "content", "wide", "full", "breakout"]),
3
82
  recipe: Object.freeze([
@@ -29,31 +108,9 @@ const ALLOWLISTS = Object.freeze({
29
108
  ]),
30
109
  container: Object.freeze(["auto", "40rem", "47rem", "49rem", "63rem", "65rem", "80rem"]),
31
110
  density: Object.freeze(["compact", "comfortable", "spacious"]),
32
- ui: Object.freeze([
33
- "minimal-saas",
34
- "bento",
35
- "maximalist",
36
- "bauhaus",
37
- "tactile",
38
- "neumorphism",
39
- "retrofuturism",
40
- "brutalism",
41
- "cyberpunk",
42
- "y2k",
43
- "retro-glass"
44
- ]),
45
- theme: Object.freeze([
46
- "arctic-indigo",
47
- "ocean-steel",
48
- "graphite-cyan",
49
- "forest-moss",
50
- "rose-quartz",
51
- "desert-sage",
52
- "midnight-gold",
53
- "cyber-lime",
54
- "sunset-ember"
55
- ]),
56
- mode: Object.freeze(["light", "dark", "contrast"]),
111
+ ui: Object.freeze(UI_STYLE_KIT_MANIFEST.presets.map((preset) => preset.id)),
112
+ theme: Object.freeze(UI_STYLE_KIT_MANIFEST.themes),
113
+ mode: Object.freeze(UI_STYLE_KIT_MANIFEST.modes),
57
114
  ecosystem: Object.freeze(["layout-only", "layout-ui", "all-three"])
58
115
  });
59
116
 
@@ -85,19 +142,9 @@ const DENSITY_GAPS = Object.freeze({
85
142
  spacious: "1.5rem"
86
143
  });
87
144
 
88
- const UI_CLASS_PREFIXES = Object.freeze({
89
- "minimal-saas": "saas",
90
- bento: "bento",
91
- maximalist: "max",
92
- bauhaus: "bau",
93
- tactile: "tactile",
94
- neumorphism: "neo",
95
- retrofuturism: "retro",
96
- brutalism: "brutal",
97
- cyberpunk: "cyber",
98
- y2k: "y2k",
99
- "retro-glass": "rg"
100
- });
145
+ const UI_CLASS_PREFIXES = Object.freeze(
146
+ Object.fromEntries(UI_STYLE_KIT_MANIFEST.presets.map((preset) => [preset.id, preset.prefix]))
147
+ );
101
148
 
102
149
  const RECIPE_CLASSES = Object.freeze({
103
150
  "app-shell": "ly-app-shell",
@@ -120,14 +167,13 @@ const RECIPE_AREAS = Object.freeze({
120
167
  const ECOSYSTEM_IMPORTS = Object.freeze({
121
168
  "layout-only": Object.freeze(['import "layout-style-css";']),
122
169
  "layout-ui": Object.freeze([
123
- 'import "ui-style-kit-css/with-bridge.css";',
124
- 'import "layout-style-css/integrations/ui-style-kit.css";',
170
+ 'import "ui-style-kit-css/visual.css";',
125
171
  'import "layout-style-css";'
126
172
  ]),
127
173
  "all-three": Object.freeze([
128
- 'import "ui-style-kit-css/with-bridge.css";',
174
+ 'import "ui-style-kit-css/visual.css";',
175
+ 'import "ui-style-kit-css/interactive-surface-theme.css";',
129
176
  'import "interactive-surface-css/state-core.css";',
130
- 'import "layout-style-css/integrations/ui-style-kit.css";',
131
177
  'import "layout-style-css";'
132
178
  ])
133
179
  });
@@ -152,6 +198,7 @@ const copyStatus = document.querySelector("#copyStatus");
152
198
  const ecosystemStatus = document.querySelector("#ecosystemStatus");
153
199
  const containerReadout = document.querySelector("#containerReadout");
154
200
  const uiKitStylesheet = document.querySelector("#uiKitStylesheet");
201
+ const uiKitInteractiveThemeStylesheet = document.querySelector("#uiKitInteractiveThemeStylesheet");
155
202
  const interactiveSurfaceStylesheet = document.querySelector("#interactiveSurfaceStylesheet");
156
203
  const layoutIntegrationStylesheet = document.querySelector("#layoutIntegrationStylesheet");
157
204
  const layoutCoreStylesheet = document.querySelector("#layoutCoreStylesheet");
@@ -162,6 +209,9 @@ const drawerBackdrop = document.querySelector("#demoControlsBackdrop");
162
209
  const stateToggle = document.querySelector("#stateToggle");
163
210
  const mobileControlsQuery = window.matchMedia("(max-width: 63.999rem)");
164
211
 
212
+ body.dataset.uiManifestVersion = UI_STYLE_KIT_MANIFEST.version;
213
+ syncUiManifestSelectOptions();
214
+
165
215
  let state = readStateFromQuery();
166
216
  let drawerReturnFocus = null;
167
217
  let querySyncTimer = null;
@@ -302,6 +352,40 @@ function formatLabel(value) {
302
352
  .join(" ");
303
353
  }
304
354
 
355
+ function syncUiManifestSelectOptions() {
356
+ const optionGroups = {
357
+ ui: UI_STYLE_KIT_MANIFEST.presets.map((preset) => ({
358
+ value: preset.id,
359
+ label: preset.label || formatLabel(preset.id)
360
+ })),
361
+ theme: UI_STYLE_KIT_MANIFEST.themes.map((theme) => ({
362
+ value: theme,
363
+ label: formatLabel(theme)
364
+ })),
365
+ mode: UI_STYLE_KIT_MANIFEST.modes.map((mode) => ({
366
+ value: mode,
367
+ label: mode === "contrast" ? "High contrast" : formatLabel(mode)
368
+ }))
369
+ };
370
+
371
+ for (const [key, options] of Object.entries(optionGroups)) {
372
+ const select = controls[key];
373
+
374
+ if (!select) {
375
+ continue;
376
+ }
377
+
378
+ select.replaceChildren(
379
+ ...options.map(({ value, label }) => {
380
+ const option = document.createElement("option");
381
+ option.value = value;
382
+ option.textContent = label;
383
+ return option;
384
+ })
385
+ );
386
+ }
387
+ }
388
+
305
389
  function syncUiKitClasses() {
306
390
  const prefix = UI_CLASS_PREFIXES[state.ui];
307
391
 
@@ -330,8 +414,9 @@ function syncEcosystem() {
330
414
  const includesInteractiveSurface = state.ecosystem === "all-three";
331
415
 
332
416
  uiKitStylesheet.disabled = !includesUi;
417
+ uiKitInteractiveThemeStylesheet.disabled = !includesInteractiveSurface;
333
418
  interactiveSurfaceStylesheet.disabled = !includesInteractiveSurface;
334
- layoutIntegrationStylesheet.disabled = !includesUi;
419
+ layoutIntegrationStylesheet.disabled = true;
335
420
  layoutCoreStylesheet.disabled = false;
336
421
  ecosystemStatus.textContent = ECOSYSTEM_LABELS[state.ecosystem];
337
422
  }
package/demo/index.html CHANGED
@@ -5,8 +5,8 @@
5
5
  <meta http-equiv="x-ua-compatible" content="IE=edge">
6
6
  <meta http-equiv="content-language" content="en-US">
7
7
  <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
8
- <meta name="title" content="layout-style-css 2.0 Interactive Layout Lab">
9
- <meta name="description" content="Explore container-first wrappers, recipes, and layout personalities in layout-style-css 2.0 with optional UI Style Kit and Interactive Surface integrations.">
8
+ <meta name="title" content="layout-style-css 2.1 Interactive Layout Lab">
9
+ <meta name="description" content="Explore container-first wrappers, recipes, and layout personalities in layout-style-css 2.1 with optional UI Style Kit and Interactive Surface integrations.">
10
10
  <meta name="keywords" content="CSS layout library, container queries, layout recipes, UI Style Kit CSS, Interactive Surface CSS, responsive CSS">
11
11
  <meta name="author" content="Foscat">
12
12
  <meta name="creator" content="Foscat">
@@ -36,7 +36,7 @@
36
36
  <meta name="color-scheme" content="light dark">
37
37
  <meta property="og:type" content="website">
38
38
  <meta property="og:locale" content="en_US">
39
- <meta property="og:title" content="layout-style-css 2.0 Interactive Layout Lab">
39
+ <meta property="og:title" content="layout-style-css 2.1 Interactive Layout Lab">
40
40
  <meta property="og:description" content="Test semantic wrappers, container-responsive recipes, and sixteen spatial personalities without coupling layout to paint.">
41
41
  <meta property="og:image" content="https://foscat.github.io/layout-style-css/assets/social-card.png">
42
42
  <meta property="og:image:secure_url" content="https://foscat.github.io/layout-style-css/assets/social-card.png">
@@ -48,11 +48,11 @@
48
48
  <meta property="og:site_name" content="layout-style-css">
49
49
  <meta property="og:updated_time" content="2026-07-20T00:00:00-05:00">
50
50
  <meta name="twitter:card" content="summary_large_image">
51
- <meta name="twitter:title" content="layout-style-css 2.0 Interactive Layout Lab">
52
- <meta name="twitter:description" content="Container-first responsive layouts that pair cleanly with UI Style Kit CSS 2.0.1 and Interactive Surface CSS 1.4.0.">
51
+ <meta name="twitter:title" content="layout-style-css 2.1 Interactive Layout Lab">
52
+ <meta name="twitter:description" content="Container-first responsive layouts that pair cleanly with UI Style Kit CSS 2.1 visual builds and Interactive Surface CSS 1.5.0.">
53
53
  <meta name="twitter:image" content="https://foscat.github.io/layout-style-css/assets/social-card.png">
54
54
  <meta name="twitter:image:alt" content="layout-style-css interactive layout lab social card">
55
- <meta itemprop="name" content="layout-style-css 2.0 Interactive Layout Lab">
55
+ <meta itemprop="name" content="layout-style-css 2.1 Interactive Layout Lab">
56
56
  <meta itemprop="description" content="A live workbench for semantic wrappers, responsive recipes, and spatial personalities.">
57
57
  <meta itemprop="image" content="https://foscat.github.io/layout-style-css/assets/social-card.png">
58
58
  <link rel="canonical" href="https://foscat.github.io/layout-style-css/">
@@ -65,11 +65,12 @@
65
65
  <link rel="mask-icon" href="./assets/favicon.svg" color="#111827">
66
66
  <link rel="manifest" href="./site.webmanifest">
67
67
  <link rel="sitemap" type="application/xml" title="Sitemap" href="./sitemap.xml">
68
- <title>layout-style-css 2.0 Interactive Layout Lab</title>
68
+ <title>layout-style-css 2.1 Interactive Layout Lab</title>
69
69
 
70
- <link id="uiKitStylesheet" rel="stylesheet" href="https://unpkg.com/ui-style-kit-css@2.0.1/dist/ui-style-kit.with-bridge.min.css" integrity="sha384-3i/xBAMjaAMQiR/vK1Tq7SzY0TFLUvdYKQKJa4t4zMXXOSfZKY+FOtFtk43F/2J+" crossorigin="anonymous">
71
- <link id="interactiveSurfaceStylesheet" rel="stylesheet" href="https://unpkg.com/interactive-surface-css@1.4.0/state-core.css" integrity="sha384-D2077FYjcZbu1Mk9p80y2x1I9XdkK3L6ndN1wyvfRq8icCgIXWdpsY0on2NSakA6" crossorigin="anonymous">
72
- <link id="layoutIntegrationStylesheet" rel="stylesheet" href="../dist/integrations/ui-style-kit.css">
70
+ <link id="uiKitStylesheet" rel="stylesheet" href="https://unpkg.com/ui-style-kit-css@2.1.0/dist/ui-style-kit.visual.min.css" integrity="sha384-DUhB5MkNLJffjy7NRg13prdEcPTUR6zdPtameCyfq3tId/cM8o3ojpyvU/xdxZ8t" crossorigin="anonymous">
71
+ <link id="uiKitInteractiveThemeStylesheet" rel="stylesheet" href="https://unpkg.com/ui-style-kit-css@2.1.0/styles/interactive-surface-theme.css" integrity="sha384-t7ZuirMM/Qoeoz+/5+S4JxIGXs076pqlgMxv6FymZW3tGj7snT8J2ZlV2+sH6++j" crossorigin="anonymous">
72
+ <link id="interactiveSurfaceStylesheet" rel="stylesheet" href="https://unpkg.com/interactive-surface-css@1.5.0/state-core.css" integrity="sha384-v2NwNOzOcQ5ed7W7OHahaKHXspqfD0p8XO+kueqrsyfEcuBO2izsAQb/J/PxF0eX" crossorigin="anonymous">
73
+ <link id="layoutIntegrationStylesheet" rel="stylesheet" href="../dist/integrations/ui-style-kit.css" disabled data-deprecated="true">
73
74
  <link id="layoutCoreStylesheet" rel="stylesheet" href="../dist/layout-style-css.css">
74
75
  <link rel="stylesheet" href="./demo.css">
75
76
 
@@ -78,7 +79,7 @@
78
79
  "@context": "https://schema.org",
79
80
  "@type": "SoftwareSourceCode",
80
81
  "name": "layout-style-css",
81
- "version": "2.0.0",
82
+ "version": "2.1.0",
82
83
  "description": "A dependency-free, container-first CSS layout library for semantic wrappers, composition primitives, responsive recipes, and spatial personalities.",
83
84
  "programmingLanguage": "CSS",
84
85
  "applicationCategory": "DeveloperApplication",
@@ -97,7 +98,7 @@
97
98
 
98
99
  <header class="demo-topbar">
99
100
  <div class="demo-brand">
100
- <span class="demo-kicker">layout-style-css 2.0</span>
101
+ <span class="demo-kicker">layout-style-css 2.1</span>
101
102
  <strong>Interactive Layout Lab</strong>
102
103
  </div>
103
104
  <div class="demo-topbar-actions">
@@ -206,15 +207,16 @@
206
207
 
207
208
  <label for="themeSelect">Theme
208
209
  <select id="themeSelect" data-query-key="theme" data-ui-kit="select">
209
- <option value="arctic-indigo">Arctic Indigo</option>
210
+ <option value="midnight-gold">Midnight Gold</option>
210
211
  <option value="ocean-steel">Ocean Steel</option>
211
- <option value="graphite-cyan">Graphite Cyan</option>
212
212
  <option value="forest-moss">Forest Moss</option>
213
- <option value="rose-quartz">Rose Quartz</option>
213
+ <option value="sunset-ember">Sunset Ember</option>
214
+ <option value="royal-plum">Royal Plum</option>
215
+ <option value="graphite-cyan">Graphite Cyan</option>
214
216
  <option value="desert-sage">Desert Sage</option>
215
- <option value="midnight-gold">Midnight Gold</option>
217
+ <option value="rose-quartz">Rose Quartz</option>
216
218
  <option value="cyber-lime">Cyber Lime</option>
217
- <option value="sunset-ember">Sunset Ember</option>
219
+ <option value="arctic-indigo">Arctic Indigo</option>
218
220
  </select>
219
221
  </label>
220
222
 
@@ -246,7 +248,7 @@
246
248
  </p>
247
249
  </div>
248
250
  <div class="demo-state-panel">
249
- <span>Interactive Surface 1.4.0 state</span>
251
+ <span>Interactive Surface 1.5.0 state</span>
250
252
  <button type="button" id="stateToggle" class="interactive-surface" aria-pressed="false" data-surface-level="2" data-surface-variant="primary" data-demo-button data-ui-kit="button button-primary">
251
253
  Toggle active state
252
254
  </button>
package/demo/robots.txt CHANGED
@@ -1,4 +1,4 @@
1
- User-agent: *
2
- Allow: /
3
-
4
- Sitemap: https://foscat.github.io/layout-style-css/sitemap.xml
1
+ User-agent: *
2
+ Allow: /
3
+
4
+ Sitemap: https://foscat.github.io/layout-style-css/sitemap.xml
@@ -1,23 +1,23 @@
1
- {
2
- "name": "layout-style-css",
3
- "short_name": "Layout CSS",
4
- "description": "Container-first layout-style-css 2.0 lab for wrappers, recipes, personalities, and optional ecosystem integrations.",
5
- "start_url": "./index.html",
6
- "display": "standalone",
7
- "background_color": "#111827",
8
- "theme_color": "#111827",
9
- "icons": [
10
- {
11
- "src": "./assets/favicon.svg",
12
- "sizes": "64x64",
13
- "type": "image/svg+xml",
14
- "purpose": "any"
15
- },
16
- {
17
- "src": "./assets/apple-touch-icon.svg",
18
- "sizes": "180x180",
19
- "type": "image/svg+xml",
20
- "purpose": "any maskable"
21
- }
22
- ]
23
- }
1
+ {
2
+ "name": "layout-style-css",
3
+ "short_name": "Layout CSS",
4
+ "description": "Container-first layout-style-css 2.1 lab for wrappers, recipes, personalities, and optional ecosystem integrations.",
5
+ "start_url": "./index.html",
6
+ "display": "standalone",
7
+ "background_color": "#111827",
8
+ "theme_color": "#111827",
9
+ "icons": [
10
+ {
11
+ "src": "./assets/favicon.svg",
12
+ "sizes": "64x64",
13
+ "type": "image/svg+xml",
14
+ "purpose": "any"
15
+ },
16
+ {
17
+ "src": "./assets/apple-touch-icon.svg",
18
+ "sizes": "180x180",
19
+ "type": "image/svg+xml",
20
+ "purpose": "any maskable"
21
+ }
22
+ ]
23
+ }
package/demo/sitemap.xml CHANGED
@@ -1,9 +1,9 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
3
- <url>
4
- <loc>https://foscat.github.io/layout-style-css/</loc>
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
3
+ <url>
4
+ <loc>https://foscat.github.io/layout-style-css/</loc>
5
5
  <lastmod>2026-07-20</lastmod>
6
- <changefreq>weekly</changefreq>
7
- <priority>0.8</priority>
8
- </url>
9
- </urlset>
6
+ <changefreq>weekly</changefreq>
7
+ <priority>0.8</priority>
8
+ </url>
9
+ </urlset>