ui-style-kit-css 2.1.0 → 2.2.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.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * UI Style Kit CSS v2.1.0
2
+ * UI Style Kit CSS v2.2.0
3
3
  * CSS theme and UI style preset library.
4
4
  * License: MIT
5
5
  */
@@ -846,6 +846,22 @@
846
846
  --usk-native-shadow: none;
847
847
  --usk-native-shadow-md: var(--usk-native-shadow);
848
848
  --usk-native-focus-ring: 0 0 0 3px rgb(var(--usk-focus-rgb) / .28);
849
+ --usk-motion-duration: 140ms;
850
+ --usk-motion-easing: cubic-bezier(0.2, 0, 0.2, 1);
851
+
852
+ /* Shared semantic values are fully typed so optional companion and third-party consumers can use them directly. */
853
+ --ui-color-bg: rgb(var(--usk-bg-rgb));
854
+ --ui-color-surface: var(--usk-native-surface-strong);
855
+ --ui-color-text: var(--usk-native-text);
856
+ --ui-color-muted: var(--usk-native-text-muted);
857
+ --ui-color-primary: var(--usk-native-primary);
858
+ --ui-color-on-primary: var(--usk-native-on-primary);
859
+ --ui-color-border: var(--usk-native-border);
860
+ --ui-radius-control: var(--usk-native-radius);
861
+ --ui-shadow-control: var(--usk-native-shadow);
862
+ --ui-focus-color: var(--usk-native-focus);
863
+ --ui-motion-duration: var(--usk-motion-duration);
864
+ --ui-motion-easing: var(--usk-motion-easing);
849
865
  }
850
866
 
851
867
  [data-ui][data-theme][data-mode] :where(h1, h2, h3, h4, h5, h6) {
@@ -1536,7 +1552,7 @@
1536
1552
  [class~="rg-alert"],
1537
1553
  [class~="rg-table-wrap"],
1538
1554
  [class~="rg-nav"]
1539
- ) {
1555
+ ), [data-ui]:where([data-ui="y2k"])[data-theme][data-mode] :where([class~="saas-surface"],[class~="saas-surface-sm"],[class~="saas-surface-lg"],.ui-card,[class~="saas-panel"],.ui-toolbar,[class~="saas-well"],[class~="saas-inset"],.ui-field,.ui-alert,.ui-table-wrap,.ui-nav,[class~="bento-surface"],[class~="bento-surface-sm"],[class~="bento-surface-lg"],.ui-card,[class~="bento-panel"],.ui-toolbar,[class~="bento-well"],[class~="bento-inset"],.ui-field,.ui-alert,.ui-table-wrap,.ui-nav,[class~="max-surface"],[class~="max-surface-sm"],[class~="max-surface-lg"],.ui-card,[class~="max-panel"],.ui-toolbar,[class~="max-well"],[class~="max-inset"],.ui-field,.ui-alert,.ui-table-wrap,.ui-nav,[class~="bau-surface"],[class~="bau-surface-sm"],[class~="bau-surface-lg"],.ui-card,[class~="bau-panel"],.ui-toolbar,[class~="bau-well"],[class~="bau-inset"],.ui-field,.ui-alert,.ui-table-wrap,.ui-nav,[class~="tactile-surface"],[class~="tactile-surface-sm"],[class~="tactile-surface-lg"],.ui-card,[class~="tactile-panel"],.ui-toolbar,[class~="tactile-well"],[class~="tactile-inset"],.ui-field,.ui-alert,.ui-table-wrap,.ui-nav,[class~="neo-surface"],[class~="neo-surface-sm"],[class~="neo-surface-lg"],.ui-card,[class~="neo-panel"],.ui-toolbar,[class~="neo-well"],[class~="neo-inset"],.ui-field,.ui-alert,.ui-table-wrap,.ui-nav,[class~="retro-surface"],[class~="retro-surface-sm"],[class~="retro-surface-lg"],.ui-card,[class~="retro-panel"],.ui-toolbar,[class~="retro-well"],[class~="retro-inset"],.ui-field,.ui-alert,.ui-table-wrap,.ui-nav,[class~="brutal-surface"],.ui-card,[class~="brutal-panel"],.ui-toolbar,[class~="brutal-well"],[class~="brutal-inset"],.ui-field,.ui-alert,.ui-table-wrap,.ui-nav,.ui-card,[class~="cyber-panel"],.ui-toolbar,[class~="cyber-well"],[class~="cyber-inset"],.ui-field,.ui-alert,.ui-table-wrap,.ui-nav,.ui-card,[class~="y2k-panel"],.ui-toolbar,[class~="y2k-well"],[class~="y2k-inset"],.ui-field,.ui-alert,.ui-table-wrap,.ui-nav,.ui-card,[class~="rg-panel"],.ui-toolbar,[class~="rg-well"],[class~="rg-inset"],.ui-field,.ui-alert,.ui-table-wrap,.ui-nav) {
1540
1556
  max-inline-size: 100%;
1541
1557
  min-inline-size: 0;
1542
1558
  overflow-wrap: anywhere;
@@ -1587,7 +1603,7 @@
1587
1603
  [class~="rg-icon-button"],
1588
1604
  [class~="rg-badge"],
1589
1605
  [class~="rg-nav-link"]
1590
- ) {
1606
+ ), [data-ui]:where([data-ui="y2k"])[data-theme][data-mode] :where(.ui-button,.ui-icon-button,.ui-badge,.ui-nav-link,.ui-button,.ui-icon-button,.ui-badge,.ui-nav-link,.ui-button,.ui-icon-button,.ui-badge,.ui-nav-link,.ui-button,.ui-icon-button,.ui-badge,.ui-nav-link,.ui-button,.ui-icon-button,.ui-badge,.ui-nav-link,.ui-button,.ui-icon-button,.ui-badge,.ui-nav-link,.ui-button,.ui-icon-button,.ui-badge,.ui-nav-link,.ui-button,.ui-icon-button,.ui-badge,.ui-nav-link,.ui-button,.ui-icon-button,.ui-badge,.ui-nav-link,.ui-button,.ui-icon-button,.ui-badge,.ui-nav-link,.ui-button,.ui-icon-button,.ui-badge,.ui-nav-link) {
1591
1607
  max-inline-size: 100%;
1592
1608
  min-inline-size: 0;
1593
1609
  white-space: normal;
@@ -1627,7 +1643,7 @@
1627
1643
  .rg-button,
1628
1644
  .rg-icon-button,
1629
1645
  .rg-button-pill
1630
- ) {
1646
+ ), [data-ui]:where([data-ui="y2k"])[data-theme][data-mode] :where(.ui-button,.ui-icon-button,.saas-button-pill,.ui-button,.ui-icon-button,.bento-button-pill,.ui-button,.ui-icon-button,.max-button-pill,.ui-button,.ui-icon-button,.bau-button-pill,.ui-button,.ui-icon-button,.tactile-button-pill,.ui-button,.ui-icon-button,.neo-button-pill,.ui-button,.ui-icon-button,.retro-button-pill,.ui-button,.ui-icon-button,.brutal-button-pill,.ui-button,.ui-icon-button,.cyber-button-pill,.ui-button,.ui-icon-button,.y2k-button-pill,.ui-button,.ui-icon-button,.rg-button-pill) {
1631
1647
  box-sizing: border-box;
1632
1648
  display: inline-flex;
1633
1649
  align-items: center;
@@ -1951,13 +1967,13 @@
1951
1967
  .saas-divider, .bento-divider, .max-divider, .bau-divider, .tactile-divider, .neo-divider, .retro-divider, .brutal-divider, .cyber-divider, .y2k-divider, .rg-divider { inline-size: 100%; block-size: 1px; border: 0; background: var(--usk-native-border); }
1952
1968
  .saas-disabled, .bento-disabled, .max-disabled, .bau-disabled, .tactile-disabled, .neo-disabled, .retro-disabled, .brutal-disabled, .cyber-disabled, .y2k-disabled, .rg-disabled { opacity: .55; cursor: not-allowed; pointer-events: none; }
1953
1969
 
1954
- .saas-button-ghost, .bento-button-ghost, .max-button-ghost, .bau-button-ghost, .tactile-button-ghost, .neo-button-ghost, .retro-button-ghost, .brutal-button-ghost, .cyber-button-ghost, .y2k-button-ghost, .rg-button-ghost {
1970
+ .saas-button-ghost, .bento-button-ghost, .max-button-ghost, .bau-button-ghost, .tactile-button-ghost, .neo-button-ghost, .retro-button-ghost, .brutal-button-ghost, .cyber-button-ghost, .y2k-button-ghost, .rg-button-ghost, :where([data-ui="y2k"]) .ui-button:where([data-ui-variant="ghost"]) {
1955
1971
  color: var(--usk-native-primary);
1956
1972
  background: transparent;
1957
1973
  border-color: var(--usk-native-border);
1958
1974
  }
1959
1975
 
1960
- .saas-check, .saas-radio, .saas-switch, .bento-check, .bento-radio, .bento-switch, .max-check, .max-radio, .max-switch, .bau-check, .bau-radio, .bau-switch, .tactile-check, .tactile-radio, .tactile-switch, .neo-check, .neo-radio, .neo-switch, .retro-check, .retro-radio, .retro-switch, .brutal-check, .brutal-radio, .brutal-switch, .cyber-check, .cyber-radio, .cyber-switch, .y2k-check, .y2k-radio, .y2k-switch, .rg-check, .rg-radio, .rg-switch {
1976
+ .saas-check, .saas-radio, .saas-switch, .bento-check, .bento-radio, .bento-switch, .max-check, .max-radio, .max-switch, .bau-check, .bau-radio, .bau-switch, .tactile-check, .tactile-radio, .tactile-switch, .neo-check, .neo-radio, .neo-switch, .retro-check, .retro-radio, .retro-switch, .brutal-check, .brutal-radio, .brutal-switch, .cyber-check, .cyber-radio, .cyber-switch, .y2k-check, .y2k-radio, .y2k-switch, .rg-check, .rg-radio, .rg-switch, :where([data-ui="y2k"]) .ui-check, :where([data-ui="y2k"]) .ui-radio, :where([data-ui="y2k"]) .ui-switch {
1961
1977
  display: inline-flex;
1962
1978
  align-items: center;
1963
1979
  gap: var(--usk-native-field-gap);
@@ -1965,13 +1981,13 @@
1965
1981
  color: var(--usk-native-text);
1966
1982
  }
1967
1983
 
1968
- .saas-check-control, .saas-radio-control, .bento-check-control, .bento-radio-control, .max-check-control, .max-radio-control, .bau-check-control, .bau-radio-control, .tactile-check-control, .tactile-radio-control, .neo-check-control, .neo-radio-control, .retro-check-control, .retro-radio-control, .brutal-check-control, .brutal-radio-control, .cyber-check-control, .cyber-radio-control, .y2k-check-control, .y2k-radio-control, .rg-check-control, .rg-radio-control {
1984
+ .saas-check-control, .saas-radio-control, .bento-check-control, .bento-radio-control, .max-check-control, .max-radio-control, .bau-check-control, .bau-radio-control, .tactile-check-control, .tactile-radio-control, .neo-check-control, .neo-radio-control, .retro-check-control, .retro-radio-control, .brutal-check-control, .brutal-radio-control, .cyber-check-control, .cyber-radio-control, .y2k-check-control, .y2k-radio-control, .rg-check-control, .rg-radio-control, :where([data-ui="y2k"]) .ui-check-control, :where([data-ui="y2k"]) .ui-radio-control {
1969
1985
  inline-size: 1.5rem;
1970
1986
  block-size: 1.5rem;
1971
1987
  accent-color: var(--usk-native-primary);
1972
1988
  }
1973
1989
 
1974
- .saas-switch-track, .bento-switch-track, .max-switch-track, .bau-switch-track, .tactile-switch-track, .neo-switch-track, .retro-switch-track, .brutal-switch-track, .cyber-switch-track, .y2k-switch-track, .rg-switch-track {
1990
+ .saas-switch-track, .bento-switch-track, .max-switch-track, .bau-switch-track, .tactile-switch-track, .neo-switch-track, .retro-switch-track, .brutal-switch-track, .cyber-switch-track, .y2k-switch-track, .rg-switch-track, :where([data-ui="y2k"]) .ui-switch-track {
1975
1991
  position: relative;
1976
1992
  display: inline-flex;
1977
1993
  align-items: center;
@@ -1983,7 +1999,7 @@
1983
1999
  border-radius: 999px;
1984
2000
  }
1985
2001
 
1986
- .saas-switch-thumb, .bento-switch-thumb, .max-switch-thumb, .bau-switch-thumb, .tactile-switch-thumb, .neo-switch-thumb, .retro-switch-thumb, .brutal-switch-thumb, .cyber-switch-thumb, .y2k-switch-thumb, .rg-switch-thumb {
2002
+ .saas-switch-thumb, .bento-switch-thumb, .max-switch-thumb, .bau-switch-thumb, .tactile-switch-thumb, .neo-switch-thumb, .retro-switch-thumb, .brutal-switch-thumb, .cyber-switch-thumb, .y2k-switch-thumb, .rg-switch-thumb, :where([data-ui="y2k"]) .ui-switch-thumb {
1987
2003
  inline-size: 1rem;
1988
2004
  block-size: 1rem;
1989
2005
  background: var(--usk-native-thumb);
@@ -2002,7 +2018,7 @@
2002
2018
  .brutal-switch:has(input:checked) .brutal-switch-track,
2003
2019
  .cyber-switch:has(input:checked) .cyber-switch-track,
2004
2020
  .y2k-switch:has(input:checked) .y2k-switch-track,
2005
- .rg-switch:has(input:checked) .rg-switch-track {
2021
+ .rg-switch:has(input:checked) .rg-switch-track, :where([data-ui="y2k"]) .ui-switch:has(input:checked) .ui-switch-track {
2006
2022
  background: var(--usk-native-track-fill);
2007
2023
  }
2008
2024
 
@@ -2016,7 +2032,7 @@
2016
2032
  .brutal-switch:has(input:checked) .brutal-switch-thumb,
2017
2033
  .cyber-switch:has(input:checked) .cyber-switch-thumb,
2018
2034
  .y2k-switch:has(input:checked) .y2k-switch-thumb,
2019
- .rg-switch:has(input:checked) .rg-switch-thumb {
2035
+ .rg-switch:has(input:checked) .rg-switch-thumb, :where([data-ui="y2k"]) .ui-switch:has(input:checked) .ui-switch-thumb {
2020
2036
  transform: translateX(1.25rem);
2021
2037
  }
2022
2038
 
@@ -2233,7 +2249,7 @@
2233
2249
  color: var(--y2k-on-primary);
2234
2250
  }
2235
2251
 
2236
- .y2k-title, .y2k-heading, .y2k-kicker, .y2k-button, .y2k-badge, .y2k-nav-link {
2252
+ .y2k-title, .y2k-heading, .y2k-kicker, .y2k-button, .y2k-badge, .y2k-nav-link, :where([data-ui="y2k"]) .ui-button, :where([data-ui="y2k"]) .ui-badge, :where([data-ui="y2k"]) .ui-nav-link {
2237
2253
  font-family: var(--y2k-font-heading);
2238
2254
  }
2239
2255
 
@@ -2271,7 +2287,7 @@
2271
2287
  color: var(--y2k-text-muted);
2272
2288
  }
2273
2289
 
2274
- .y2k-card, .y2k-panel, .y2k-bubble, .y2k-toolbar, .y2k-table-wrap {
2290
+ .y2k-card, .y2k-panel, .y2k-bubble, .y2k-toolbar, .y2k-table-wrap, :where([data-ui="y2k"]) .ui-card, :where([data-ui="y2k"]) .ui-toolbar, :where([data-ui="y2k"]) .ui-table-wrap {
2275
2291
  background: linear-gradient(145deg,#ffffff6b,#ffffff14),var(--y2k-surface);
2276
2292
  color: var(--y2k-text);
2277
2293
  border: 1px solid #ffffff61;
@@ -2284,7 +2300,7 @@
2284
2300
  overflow: hidden;
2285
2301
  }
2286
2302
 
2287
- .y2k-card:before, .y2k-panel:before, .y2k-bubble:before {
2303
+ .y2k-card:before, .y2k-panel:before, .y2k-bubble:before, :where([data-ui="y2k"]) .ui-card:before {
2288
2304
  content: "";
2289
2305
  pointer-events: none;
2290
2306
  background: radial-gradient(circle at 20% 0%,#ffffff6b,transparent 22%),linear-gradient(120deg,transparent 0 55%,rgb(var(--y2k-accent-rgb)/.12));
@@ -2292,11 +2308,11 @@
2292
2308
  inset: 0;
2293
2309
  }
2294
2310
 
2295
- .y2k-card, .y2k-panel, .y2k-bubble {
2311
+ .y2k-card, .y2k-panel, .y2k-bubble, :where([data-ui="y2k"]) .ui-card {
2296
2312
  padding: var(--y2k-space-6);
2297
2313
  }
2298
2314
 
2299
- .y2k-toolbar {
2315
+ .y2k-toolbar, :where([data-ui="y2k"]) .ui-toolbar {
2300
2316
  justify-content: space-between;
2301
2317
  align-items: center;
2302
2318
  gap: var(--y2k-space-4);
@@ -2322,7 +2338,7 @@
2322
2338
  padding: var(--y2k-space-5);
2323
2339
  }
2324
2340
 
2325
- .y2k-button, .y2k-icon-button {
2341
+ .y2k-button, .y2k-icon-button, :where([data-ui="y2k"]) .ui-button, :where([data-ui="y2k"]) .ui-icon-button {
2326
2342
  appearance: none;
2327
2343
  justify-content: center;
2328
2344
  align-items: center;
@@ -2344,56 +2360,56 @@
2344
2360
  display: inline-flex;
2345
2361
  }
2346
2362
 
2347
- .y2k-button:hover, .y2k-icon-button:hover {
2363
+ .y2k-button:hover, .y2k-icon-button:hover, :where([data-ui="y2k"]) .ui-button:hover, :where([data-ui="y2k"]) .ui-icon-button:hover {
2348
2364
  box-shadow: var(--y2k-shadow-md),0 0 26px var(--y2k-glow-accent);
2349
2365
  transform: translateY(-2px);
2350
2366
  }
2351
2367
 
2352
- .y2k-button:active, .y2k-icon-button:active, .y2k-button.is-active, .y2k-button[aria-pressed="true"] {
2368
+ .y2k-button:active, .y2k-icon-button:active, .y2k-button.is-active, .y2k-button[aria-pressed="true"], :where([data-ui="y2k"]) .ui-button:active, :where([data-ui="y2k"]) .ui-icon-button:active, :where([data-ui="y2k"]) .ui-button.is-active, :where([data-ui="y2k"]) .ui-button[aria-pressed="true"] {
2353
2369
  transform: translateY(1px) scale(.99);
2354
2370
  box-shadow: inset 0 8px 16px #00000024;
2355
2371
  }
2356
2372
 
2357
- .y2k-button-primary {
2373
+ .y2k-button-primary, :where([data-ui="y2k"]) .ui-button:where([data-ui-variant="primary"]) {
2358
2374
  background: linear-gradient(180deg,#ffffff75,#ffffff14),var(--y2k-primary);
2359
2375
  color: var(--y2k-on-primary);
2360
2376
  }
2361
2377
 
2362
- .y2k-button-primary:hover {
2378
+ .y2k-button-primary:hover, :where([data-ui="y2k"]) .ui-button:where([data-ui-variant="primary"]):hover {
2363
2379
  background: linear-gradient(180deg,#ffffff80,#ffffff1a),var(--y2k-primary-hover);
2364
2380
  }
2365
2381
 
2366
- .y2k-button-secondary {
2382
+ .y2k-button-secondary, :where([data-ui="y2k"]) .ui-button:where([data-ui-variant="secondary"]) {
2367
2383
  background: linear-gradient(180deg,#ffffff75,#ffffff14),var(--y2k-secondary);
2368
2384
  color: var(--y2k-on-secondary);
2369
2385
  }
2370
2386
 
2371
- .y2k-button-secondary:hover {
2387
+ .y2k-button-secondary:hover, :where([data-ui="y2k"]) .ui-button:where([data-ui-variant="secondary"]):hover {
2372
2388
  background: var(--y2k-secondary-hover);
2373
2389
  }
2374
2390
 
2375
- .y2k-button-danger {
2391
+ .y2k-button-danger, :where([data-ui="y2k"]) .ui-button:where([data-ui-variant="danger"]) {
2376
2392
  background: var(--y2k-danger);
2377
2393
  color: var(--y2k-on-danger);
2378
2394
  }
2379
2395
 
2380
- .y2k-icon-button {
2396
+ .y2k-icon-button, :where([data-ui="y2k"]) .ui-icon-button {
2381
2397
  width: 2.85rem;
2382
2398
  padding: 0;
2383
2399
  }
2384
2400
 
2385
- .y2k-field {
2401
+ .y2k-field, :where([data-ui="y2k"]) .ui-field {
2386
2402
  gap: var(--y2k-space-2);
2387
2403
  flex-direction: column;
2388
2404
  display: flex;
2389
2405
  }
2390
2406
 
2391
- .y2k-label {
2407
+ .y2k-label, :where([data-ui="y2k"]) .ui-label {
2392
2408
  letter-spacing: .04em;
2393
2409
  font-weight: 900;
2394
2410
  }
2395
2411
 
2396
- .y2k-input, .y2k-textarea, .y2k-select {
2412
+ .y2k-input, .y2k-textarea, .y2k-select, :where([data-ui="y2k"]) .ui-input, :where([data-ui="y2k"]) .ui-textarea, :where([data-ui="y2k"]) .ui-select {
2397
2413
  background: linear-gradient(180deg,#ffffff38,#0000000d),var(--y2k-surface-soft);
2398
2414
  width: 100%;
2399
2415
  min-height: 2.9rem;
@@ -2406,22 +2422,22 @@
2406
2422
  box-shadow: inset 0 6px 14px #0000001f;
2407
2423
  }
2408
2424
 
2409
- .y2k-textarea {
2425
+ .y2k-textarea, :where([data-ui="y2k"]) .ui-textarea {
2410
2426
  resize: vertical;
2411
2427
  min-height: 8rem;
2412
2428
  }
2413
2429
 
2414
- .y2k-input:focus, .y2k-textarea:focus, .y2k-select:focus {
2430
+ .y2k-input:focus, .y2k-textarea:focus, .y2k-select:focus, :where([data-ui="y2k"]) .ui-input:focus, :where([data-ui="y2k"]) .ui-textarea:focus, :where([data-ui="y2k"]) .ui-select:focus {
2415
2431
  border-color: var(--y2k-focus);
2416
2432
  box-shadow: inset 0 6px 14px #0000001f,0 0 0 3px rgb(var(--y2k-focus-rgb)/.25),0 0 24px rgb(var(--y2k-focus-rgb)/.22);
2417
2433
  }
2418
2434
 
2419
- .y2k-help-text {
2435
+ .y2k-help-text, :where([data-ui="y2k"]) .ui-help-text {
2420
2436
  color: var(--y2k-text-muted);
2421
2437
  font-size: .9rem;
2422
2438
  }
2423
2439
 
2424
- .y2k-badge {
2440
+ .y2k-badge, :where([data-ui="y2k"]) .ui-badge {
2425
2441
  background: linear-gradient(180deg,#fff6,#ffffff14),var(--y2k-surface-strong);
2426
2442
  min-height: 1.8rem;
2427
2443
  color: var(--y2k-text);
@@ -2435,32 +2451,32 @@
2435
2451
  display: inline-flex;
2436
2452
  }
2437
2453
 
2438
- .y2k-badge-primary {
2454
+ .y2k-badge-primary, :where([data-ui="y2k"]) .ui-badge:where([data-ui-variant="primary"]) {
2439
2455
  background: var(--y2k-primary);
2440
2456
  color: var(--y2k-on-primary);
2441
2457
  }
2442
2458
 
2443
- .y2k-badge-secondary {
2459
+ .y2k-badge-secondary, :where([data-ui="y2k"]) .ui-badge:where([data-ui-variant="secondary"]) {
2444
2460
  background: var(--y2k-secondary);
2445
2461
  color: var(--y2k-on-secondary);
2446
2462
  }
2447
2463
 
2448
- .y2k-badge-success {
2464
+ .y2k-badge-success, :where([data-ui="y2k"]) .ui-badge:where([data-ui-variant="success"]) {
2449
2465
  background: var(--y2k-success);
2450
2466
  color: var(--y2k-on-success);
2451
2467
  }
2452
2468
 
2453
- .y2k-badge-warning {
2469
+ .y2k-badge-warning, :where([data-ui="y2k"]) .ui-badge:where([data-ui-variant="warning"]) {
2454
2470
  background: var(--y2k-warning);
2455
2471
  color: var(--y2k-on-warning);
2456
2472
  }
2457
2473
 
2458
- .y2k-badge-danger {
2474
+ .y2k-badge-danger, :where([data-ui="y2k"]) .ui-badge:where([data-ui-variant="danger"]) {
2459
2475
  background: var(--y2k-danger);
2460
2476
  color: var(--y2k-on-danger);
2461
2477
  }
2462
2478
 
2463
- .y2k-nav {
2479
+ .y2k-nav, :where([data-ui="y2k"]) .ui-nav {
2464
2480
  gap: var(--y2k-space-2);
2465
2481
  padding: var(--y2k-space-2);
2466
2482
  background: linear-gradient(180deg,#ffffff61,#ffffff14),var(--y2k-surface);
@@ -2471,7 +2487,7 @@
2471
2487
  display: flex;
2472
2488
  }
2473
2489
 
2474
- .y2k-nav-link {
2490
+ .y2k-nav-link, :where([data-ui="y2k"]) .ui-nav-link {
2475
2491
  min-height: 2.5rem;
2476
2492
  color: var(--y2k-text-muted);
2477
2493
  border-radius: var(--y2k-radius-pill);
@@ -2482,12 +2498,12 @@
2482
2498
  display: inline-flex;
2483
2499
  }
2484
2500
 
2485
- .y2k-nav-link:hover {
2501
+ .y2k-nav-link:hover, :where([data-ui="y2k"]) .ui-nav-link:hover {
2486
2502
  color: var(--y2k-text);
2487
2503
  background: #ffffff29;
2488
2504
  }
2489
2505
 
2490
- .y2k-nav-link.is-active, .y2k-nav-link[aria-current="page"] {
2506
+ .y2k-nav-link.is-active, .y2k-nav-link[aria-current="page"], :where([data-ui="y2k"]) .ui-nav-link.is-active, :where([data-ui="y2k"]) .ui-nav-link[aria-current="page"] {
2491
2507
  background: var(--y2k-primary);
2492
2508
  color: var(--y2k-on-primary);
2493
2509
  box-shadow: 0 0 20px var(--y2k-glow-primary);
@@ -2518,7 +2534,7 @@
2518
2534
  flex: none;
2519
2535
  }
2520
2536
 
2521
- .y2k-progress {
2537
+ .y2k-progress, :where([data-ui="y2k"]) .ui-progress {
2522
2538
  background: var(--y2k-surface-soft);
2523
2539
  border-radius: var(--y2k-radius-pill);
2524
2540
  width: 100%;
@@ -2527,14 +2543,14 @@
2527
2543
  box-shadow: inset 0 6px 14px #0000001f;
2528
2544
  }
2529
2545
 
2530
- .y2k-progress-bar {
2546
+ .y2k-progress-bar, :where([data-ui="y2k"]) .ui-progress-bar {
2531
2547
  height: 100%;
2532
2548
  width: var(--y2k-progress-value, 50%);
2533
2549
  background: linear-gradient(90deg,var(--y2k-primary),var(--y2k-accent),var(--y2k-secondary));
2534
2550
  border-radius: inherit;
2535
2551
  }
2536
2552
 
2537
- .y2k-alert {
2553
+ .y2k-alert, :where([data-ui="y2k"]) .ui-alert {
2538
2554
  padding: var(--y2k-space-4);
2539
2555
  background: var(--y2k-surface);
2540
2556
  border-radius: var(--y2k-radius-xl);
@@ -2542,49 +2558,49 @@
2542
2558
  border: 1px solid #ffffff61;
2543
2559
  }
2544
2560
 
2545
- .y2k-alert-title {
2561
+ .y2k-alert-title, :where([data-ui="y2k"]) .ui-alert-title {
2546
2562
  margin: 0;
2547
2563
  font-weight: 900;
2548
2564
  }
2549
2565
 
2550
- .y2k-alert-body {
2566
+ .y2k-alert-body, :where([data-ui="y2k"]) .ui-alert-body {
2551
2567
  color: var(--y2k-text-muted);
2552
2568
  margin: .5rem 0 0;
2553
2569
  }
2554
2570
 
2555
- .y2k-alert-success {
2571
+ .y2k-alert-success, :where([data-ui="y2k"]) .ui-alert:where([data-ui-variant="success"]) {
2556
2572
  box-shadow: var(--y2k-shadow-md),0 0 22px rgb(var(--y2k-success-rgb)/.2);
2557
2573
  }
2558
2574
 
2559
- .y2k-alert-warning {
2575
+ .y2k-alert-warning, :where([data-ui="y2k"]) .ui-alert:where([data-ui-variant="warning"]) {
2560
2576
  box-shadow: var(--y2k-shadow-md),0 0 22px rgb(var(--y2k-warning-rgb)/.2);
2561
2577
  }
2562
2578
 
2563
- .y2k-alert-danger {
2579
+ .y2k-alert-danger, :where([data-ui="y2k"]) .ui-alert:where([data-ui-variant="danger"]) {
2564
2580
  box-shadow: var(--y2k-shadow-md),0 0 22px rgb(var(--y2k-danger-rgb)/.2);
2565
2581
  }
2566
2582
 
2567
- .y2k-table-wrap {
2583
+ .y2k-table-wrap, :where([data-ui="y2k"]) .ui-table-wrap {
2568
2584
  overflow: auto;
2569
2585
  }
2570
2586
 
2571
- .y2k-table {
2587
+ .y2k-table, :where([data-ui="y2k"]) .ui-table {
2572
2588
  border-collapse: collapse;
2573
2589
  width: 100%;
2574
2590
  }
2575
2591
 
2576
- .y2k-table th, .y2k-table td {
2592
+ .y2k-table th, .y2k-table td, :where([data-ui="y2k"]) .ui-table th, :where([data-ui="y2k"]) .ui-table td {
2577
2593
  border-bottom: 1px solid rgb(var(--y2k-border-rgb)/.34);
2578
2594
  text-align: left;
2579
2595
  padding: .9rem 1rem;
2580
2596
  }
2581
2597
 
2582
- .y2k-table th {
2598
+ .y2k-table th, :where([data-ui="y2k"]) .ui-table th {
2583
2599
  background: #ffffff29;
2584
2600
  font-weight: 900;
2585
2601
  }
2586
2602
 
2587
- .y2k-table td {
2603
+ .y2k-table td, :where([data-ui="y2k"]) .ui-table td {
2588
2604
  color: var(--y2k-text-muted);
2589
2605
  }
2590
2606
 
@@ -2624,15 +2640,15 @@
2624
2640
  }
2625
2641
  }
2626
2642
 
2627
- .y2k-card, .y2k-panel {
2643
+ .y2k-card, .y2k-panel, :where([data-ui="y2k"]) .ui-card {
2628
2644
  background: var(--y2k-card-bg);
2629
2645
  }
2630
2646
 
2631
- .y2k-toolbar, .y2k-table-wrap, .y2k-button:not(.y2k-button-primary):not(.y2k-button-secondary):not(.y2k-button-danger):not(.y2k-button-ghost), .y2k-icon-button {
2647
+ .y2k-toolbar, .y2k-table-wrap, .y2k-button:not(.y2k-button-primary):not(.y2k-button-secondary):not(.y2k-button-danger):not(.y2k-button-ghost), .y2k-icon-button, :where([data-ui="y2k"]) .ui-toolbar, :where([data-ui="y2k"]) .ui-table-wrap, :where([data-ui="y2k"]) .ui-button:not(.ui-button:where([data-ui-variant="primary"])):not(.ui-button:where([data-ui-variant="secondary"])):not(.ui-button:where([data-ui-variant="danger"])):not(.ui-button:where([data-ui-variant="ghost"])), :where([data-ui="y2k"]) .ui-icon-button {
2632
2648
  background: var(--y2k-control-bg);
2633
2649
  }
2634
2650
 
2635
- .y2k-button, .y2k-icon-button, .y2k-badge, .y2k-nav-link {
2651
+ .y2k-button, .y2k-icon-button, .y2k-badge, .y2k-nav-link, :where([data-ui="y2k"]) .ui-button, :where([data-ui="y2k"]) .ui-icon-button, :where([data-ui="y2k"]) .ui-badge, :where([data-ui="y2k"]) .ui-nav-link {
2636
2652
  font-family: var(--y2k-font-control);
2637
2653
  }
2638
2654
 
@@ -2662,12 +2678,12 @@
2662
2678
  inline-size: 3rem;
2663
2679
  }
2664
2680
 
2665
- .y2k-button[aria-busy="true"], .y2k-icon-button[aria-busy="true"], [data-ui="y2k"] :where(button[aria-busy="true"], input[type="button"][aria-busy="true"], input[type="submit"][aria-busy="true"], input[type="reset"][aria-busy="true"]) {
2681
+ .y2k-button[aria-busy="true"], .y2k-icon-button[aria-busy="true"], [data-ui="y2k"] :where(button[aria-busy="true"], input[type="button"][aria-busy="true"], input[type="submit"][aria-busy="true"], input[type="reset"][aria-busy="true"]), :where([data-ui="y2k"]) .ui-button[aria-busy="true"], :where([data-ui="y2k"]) .ui-icon-button[aria-busy="true"] {
2666
2682
  cursor: progress;
2667
2683
  gap: .55rem;
2668
2684
  }
2669
2685
 
2670
- .y2k-button[aria-busy="true"]:after, .y2k-icon-button[aria-busy="true"]:after, [data-ui="y2k"] :where(button[aria-busy="true"], input[type="button"][aria-busy="true"], input[type="submit"][aria-busy="true"], input[type="reset"][aria-busy="true"]):after {
2686
+ .y2k-button[aria-busy="true"]:after, .y2k-icon-button[aria-busy="true"]:after, [data-ui="y2k"] :where(button[aria-busy="true"], input[type="button"][aria-busy="true"], input[type="submit"][aria-busy="true"], input[type="reset"][aria-busy="true"]):after, :where([data-ui="y2k"]) .ui-button[aria-busy="true"]:after, :where([data-ui="y2k"]) .ui-icon-button[aria-busy="true"]:after {
2671
2687
  content: "";
2672
2688
  border: .16em solid rgb(var(--y2k-primary-text-rgb)/.42);
2673
2689
  border-block-start-color: currentColor;
@@ -0,0 +1,20 @@
1
+ # Deprecated Interactive Surface Bridge Migration
2
+
3
+ The canonical integration for new applications is `ui-style-kit-css/visual.css`, `ui-style-kit-css/interactive-surface-theme.css`, `interactive-surface-css/state-core.css`, and `layout-style-css` in that order.
4
+
5
+ `interactive-surface-bridge` and `with-bridge` remain public v2 compatibility exports. They are deprecated because they include stateful bridge behavior that is no longer part of the canonical token-and-paint boundary. They are retained unchanged in v2 and will not be redirected to the token-only bridge.
6
+
7
+ The shared semantic path is separate from migration: a third-party token producer may load before `interactive-surface-css/standalone-preset.css`, but it does not reproduce UI Style Kit's specialized variant and level mappings. Existing bridge consumers should follow the canonical imports above when migrating.
8
+
9
+ ## Retained deprecated imports
10
+
11
+ Existing integrations may continue to use either exported stateful path while scheduling their migration:
12
+
13
+ ```js
14
+ import "ui-style-kit-css/interactive-surface-bridge";
15
+ import "ui-style-kit-css/interactive-surface-bridge.css";
16
+ import "ui-style-kit-css/with-bridge";
17
+ import "ui-style-kit-css/with-bridge.css";
18
+ ```
19
+
20
+ Do not combine a deprecated bridge import with `interactive-surface-theme.css`; select the legacy stateful path during migration or the canonical token-only path for new integration work.
package/docs/ECOSYSTEM.md CHANGED
@@ -2,15 +2,46 @@
2
2
 
3
3
  UI Style Kit CSS is the visual layer in the three-library CSS ecosystem. It can run alone, but it also has stable integration points for Interactive Surface CSS and Layout Style CSS.
4
4
 
5
+ `ecosystem-compatibility.json` is the authoritative source for supported ranges, validated combinations, canonical imports, and deprecated bridge metadata. UI Style Kit owns this file temporarily until a dedicated ecosystem fixture repository is introduced.
6
+
7
+ Its companion source records pin the exact published merge revisions used by integration and release verification. Update those immutable pins whenever a later companion release changes the validated contract.
8
+
9
+ ## Remote Validation Sequence
10
+
11
+ The pinned Interactive Surface and Layout commits are published merge objects. Before a UI branch or pull request is expected to validate, verify each pinned SHA remains fetchable from its GitHub repository. The CI and publish workflows perform the same remote-object preflight, so they intentionally fail rather than silently substituting a mutable branch or stale registry artifact when either companion revision is unavailable.
12
+
5
13
  ## Aligned Versions
6
14
 
7
15
  | Library | Current aligned version | Owns |
8
16
  |---|---:|---|
9
- | `ui-style-kit-css@2.1.0` | staged source target | visual identity, color themes, UI paint, native HTML styling, content wrapping, and bridge tokens |
10
- | `interactive-surface-css@1.5.0` | published release | interaction-state primitives, surface behavior, state layers, and input affordances |
11
- | `layout-style-css@2.1.0` | staged source target | structural wrappers, grids, sections, app shells, and layout recipes |
17
+ | `ui-style-kit-css@2.2.0` | current package version | visual identity, color themes, UI paint, native HTML styling, content wrapping, and bridge tokens |
18
+ | `interactive-surface-css@1.6.0` | published release | interaction-state primitives, surface behavior, state layers, and input affordances |
19
+ | `layout-style-css@3.0.1` | published release | structural wrappers, grids, sections, app shells, and layout recipes |
20
+
21
+ The current combination is `ui-style-kit-css@2.2.0`, `interactive-surface-css@1.6.0`, and `layout-style-css@3.0.1`. UI Style Kit `2.2.0` is the current package version, and the release pipeline treats it as the active candidate only while that exact npm version is absent. Interactive Surface `1.6.0` and Layout Style `3.0.1` are published releases. The validated minimum remains `ui-style-kit-css@2.1.0`, `interactive-surface-css@1.5.0`, and `layout-style-css@3.0.0`.
22
+
23
+ ## Layout-to-visual pairing matrix
24
+
25
+ Pairings are recommendations, never dependencies. `data-ly-layout`, `data-ui`, `data-theme`, and `data-mode` remain independently selectable; `layout-style-css/personalities.json` publishes the machine-readable source.
26
+
27
+ | Layout personality | Visual guidance |
28
+ | --- | --- |
29
+ | Minimal SaaS, Bento, Maximalist, Bauhaus, Tactile, Neumorphism, Retrofuturism, Brutalism, Cyberpunk, Y2K, Retro Glass | Native UI Style Kit match with the same identifier |
30
+ | F-pattern, Z-pattern, Split Screen, Mondrian | Any UI Style Kit visual preset; these are structure-only layouts |
31
+ | Synthwave | Recommend `cyberpunk` or `retrofuturism`; Layout's rendered demo verifies each preset while keeping the synthwave layout selected |
32
+
33
+ ## Shared semantic theming
34
+
35
+ UI Style Kit's complete, visual, and focused visual entrypoints produce the 12 package-neutral `--ui-*` control tokens under `[data-ui][data-theme][data-mode]`. A third-party theme may produce the same contract under its own scope; consumers do not need UI Style Kit-specific `--usk-*` values. Package-specific values remain first in consumer fallback chains, shared semantic values come second, and legacy values or literals remain last.
36
+
37
+ A third-party producer can theme Interactive Surface's complete standalone entry point without a package-specific adapter:
38
+
39
+ ```js
40
+ import "third-party-theme/tokens.css";
41
+ import "interactive-surface-css/standalone-preset.css";
42
+ ```
12
43
 
13
- UI Style Kit `2.1.0` and Layout Style `2.1.0` remain staged source targets until approved release steps complete. Interactive Surface `1.5.0` is the released companion state engine for this upgrade path.
44
+ UI Style Kit can use the same portable path by loading `ui-style-kit-css/visual.css` before `interactive-surface-css/standalone-preset.css`. That composition provides the semantic control baseline. Use the canonical `interactive-surface-theme.css` plus `state-core.css` path when an application needs UI Style Kit's specialized variant, level, icon-role, and state-opacity mappings.
14
45
 
15
46
  ## Adoption Paths
16
47
 
@@ -6,11 +6,32 @@
6
6
  npm run release:verify
7
7
  ```
8
8
 
9
- `npm run release:verify` is the non-publishing release gate. It runs `npm run check`, `npm run test:e2e`, `npm run test:axe`, `npm run test:visual`, `npm run test:matrix`, `npm run check:ecosystem:packs`, `npm audit --audit-level=moderate`, and `npm run pack:dry-run`.
9
+ `npm run release:verify` is the non-publishing release gate. It runs `npm run check`, `npm run test:e2e`, `npm run test:axe`, `npm run test:visual`, `npm run test:matrix`, the explicit UI-candidate release preflight, `npm audit --audit-level=moderate`, and `npm run pack:dry-run`.
10
10
 
11
- `npm run check` rebuilds dist CSS, runs stylelint, executes package, class API, shared theme-color, and vendor-prefix unit checks, validates core text/link contrast pairs and filled component `on-*` contrast pairs, and confirms package metadata. Browser gates cover regular demo flows, representative Axe scans, curated visual smoke checks, and the sharded 990-combination matrix. `npm run check:ecosystem:packs` verifies standalone, pairwise, and all-three packed package compatibility for the canonical visual/theme/state/layout imports and the deprecated bridge imports. `npm run pack:dry-run` shows the exact files that would publish.
11
+ `npm run release:preflight` validates the shared manifests and compatibility contract, queries npm for every exact minimum/current version, resolves every export from the candidate tarball, checks maintained documentation against installed packages, and reuses the current/minimum clean-install browser matrix. Normal UI preflight remains strict and queries `ui-style-kit-css@2.2.0` alongside every other documented exact version. The release workflows pass `--candidate-package ui-style-kit-css`, which excludes only that exact current version while it is absent from npm and still requires every published minimum and companion version. The gate performs no publish, tag, release, or deployment mutation and is therefore safe to execute on pull requests.
12
12
 
13
- By default, `npm run check:ecosystem:packs` packs this repository, packs the sibling `../Layout-Style-CSS` checkout, and packs the published `interactive-surface-css@1.5.0` artifact. Use `-- --layout-repo <path>` or `-- --interactive-spec <specifier>` when validating a different local Layout Style checkout or a different Interactive Surface package source.
13
+ `npm run check` rebuilds dist CSS, runs stylelint, executes package, class API, shared theme-color, and vendor-prefix unit checks, validates core text/link contrast pairs and filled component `on-*` contrast pairs, and confirms package metadata. Browser gates cover regular demo flows, representative Axe scans, curated visual smoke checks, and the sharded 990-combination matrix. `npm run check:ecosystem:packs` verifies standalone, pairwise, and all-three packed package compatibility for the canonical visual/theme/state/layout imports and the deprecated bridge imports in both supported matrices. `npm run pack:dry-run` shows the exact files that would publish.
14
+
15
+ `npm run check:ecosystem:current` packs this repository and the sibling `../Layout-Style-CSS` and `../Interactive-Surface-CSS` checkouts. It extracts imports from the explicitly maintained current documentation in all three repositories and resolves every documented specifier from the installed tarballs. Deprecated UI bridge guides are validated as a separate supported-compatibility class; changelogs and Layout migration guides are reviewed historical material rather than current setup. Use `-- --ui-spec <specifier>`, `-- --layout-repo <path>`, `-- --layout-spec <specifier>`, `-- --interactive-spec <specifier>`, `-- --interactive-repo <path>`, `-- --layout-docs-repo <path>`, or `-- --interactive-docs-repo <path>` when validating different package or documentation sources.
16
+
17
+ `npm run check:ecosystem:minimum` downloads and repacks the declared minimum published runtime versions: `ui-style-kit-css@2.1.0`, `interactive-surface-css@1.5.0`, and `layout-style-css@3.0.0`. Those tarballs predate the additive shared-manifest policy introduced on the coordinated branches, so the minimum matrix validates their exact installed versions and published CSS entry points; current packed heads retain the stricter manifest-schema and current-documentation checks. `npm run check:ecosystem:packs` runs current first and minimum second.
18
+
19
+ The current matrix checks `ui-style-kit-css@2.2.0` as the active candidate only while its exact npm version is absent, `interactive-surface-css@1.6.0` as a published release, and `layout-style-css@3.0.1` as a published release. UI Style Kit `2.2.0` remains the current package version. The minimum published matrix remains `ui-style-kit-css@2.1.0`, `interactive-surface-css@1.5.0`, and `layout-style-css@3.0.0`.
20
+
21
+ Both matrices install fresh tarball consumers for UI only, Interaction only, Layout only, every pair, and all three. Chromium then checks selected theme paint, native and prefixed components, interaction focus/disabled/loading/selected/persistent states, Layout wrappers/primitives/recipes/personalities, console cleanliness, and an empty external-request log. Three text-free baselines under `tests/snapshots/clean-install/` cover the highest-risk integrated combinations.
22
+
23
+ Snapshot verification decodes PNG pixels, requires exact dimensions, ignores pixelmatch-classified antialias noise, uses a `0.1` color threshold, and permits at most `0.25%` differing pixels. The committed fixtures render at 720-721 by 261 pixels and therefore allow 469-470 changed pixels while rejecting the tested 42% meaningful change. A mismatch retains both `SCENARIO-actual.png` and `SCENARIO-diff.png` in the reported safe temporary directory. CI only validates committed baselines and never passes the generation flag. To intentionally refresh them locally, run the current checker with `--update-snapshots`, inspect all three images, and rerun without that flag.
24
+
25
+ The PR integration and npm-publish workflows read the companion repository and immutable revision pins from `ecosystem-compatibility.json`, then pack those coordinated reviewed artifacts. Advance those pins whenever a later release changes a companion contract. The current values pin the published Interactive Surface CSS merge at `b50a60d8ffd804d8227b1a16903c394556b88511` and the published Layout Style CSS merge at `44c34693554879790c54a6205b37160ff63a1747`.
26
+
27
+ Use this exact bootstrap and merge sequence:
28
+
29
+ 1. Verify the published Interactive Surface CSS and Layout Style CSS merge commits remain remotely reachable.
30
+ 2. Update and review the final UI companion pins against those immutable merge commits.
31
+ 3. Push the final UI branch, rerun its explicit UI-candidate ecosystem preflight, and merge UI with a merge commit.
32
+ 4. Do not squash or rebase away reviewed release commits that remain part of the pinned verification history.
33
+
34
+ The workflows enforce immutable remote-object reachability and do not fall back to mutable branches or registry packages. The stable bootstrap ref lets companion workflows load the reviewed preflight implementation before the final UI commit references their heads.
14
35
 
15
36
  `npm run build` uses exactly pinned CSS Tree parsing and Lightning CSS formatting/minification. Generated minified bundles retain the release banner while preserving grammar-sensitive selector and `calc()` whitespace.
16
37
 
@@ -20,19 +41,19 @@ The npm artifact is library-focused: `dist/`, `styles/`, docs, and metadata. Dem
20
41
 
21
42
  No package, tag, or registry release occurs without explicit approval.
22
43
 
23
- For this ecosystem upgrade, use the approval-gated rollout order below:
44
+ The completed 2.0.4 correctness hotfix is historical context. Do not create replacement tags or registry releases merely to verify the coordinated compatibility contract.
24
45
 
25
- 1. Release `ui-style-kit-css@2.0.4` as the correctness hotfix from the merged hotfix content on `origin/main`. The 2.0.4 hotfix release line must pass `npm run release:verify` before any tag or publish step.
26
- 2. Confirm the already published `interactive-surface-css@1.5.0` companion state engine remains available from npm.
27
- 3. Release `ui-style-kit-css@2.1.0` after the hotfix is live.
28
- 4. Release `layout-style-css@2.1.0` after UI Style Kit 2.1 is live and Layout replaces its temporary GitHub UI fixture with the registry package.
29
- 5. Run the final all-three packed compatibility suite against the published packages.
46
+ Run the coordinated checked-out ecosystem proof from this repository:
47
+
48
+ ```bash
49
+ npm run check:ecosystem:packs -- --layout-repo ../Layout-Style-CSS --interactive-repo ../Interactive-Surface-CSS --layout-docs-repo ../Layout-Style-CSS --interactive-docs-repo ../Interactive-Surface-CSS
50
+ ```
30
51
 
31
52
  ```bash
32
53
  npm publish
33
54
  ```
34
55
 
35
- `prepublishOnly` runs `npm run release:verify`, so a direct `npm publish` still has the full release gate. For GitHub releases, create or dispatch a release for the matching package tag, such as `v2.1.0`. The release workflows verify that `package.json`, `package-lock.json`, `CHANGELOG.md`, and generated dist banners are aligned before publishing.
56
+ `prepublishOnly` runs `npm run release:verify`, so a direct `npm publish` still has the full release gate. For GitHub releases, create or dispatch a release for the matching package tag, such as `v2.2.0`. The release workflows verify that `package.json`, `package-lock.json`, `CHANGELOG.md`, and generated dist banners are aligned before publishing.
36
57
 
37
58
  ## Versioning
38
59
 
package/docs/TOKENS.md CHANGED
@@ -8,6 +8,46 @@ shared scheme channels -> prefixed aliases -> UI rules
8
8
 
9
9
  `styles/theme-colors.css` defines the active scheme and mode once as `--usk-*` RGB channels. Each UI style maps those shared channels to its public prefix, then component rules consume prefixed functional variables. `styles/native-elements.css` owns native HTML fallback selectors and consumes `--usk-native-*` tokens that each preset maps back to its own public variables.
10
10
 
11
+ ## Shared semantic token handshake
12
+
13
+ The existing `[data-ui][data-theme][data-mode]` native-token root publishes 12 fully typed `--ui-*` values. UI Style Kit is the primary producer, but the names are intentionally package-neutral so a third-party theme can produce the same contract. Consumer libraries treat these values as optional fallbacks: a package-specific override wins first, then the shared semantic value, then the consumer's legacy token and literal default.
14
+
15
+ | Shared token | CSS type | UI Style Kit source |
16
+ |---|---|---|
17
+ | `--ui-color-bg` | `<color>` | `rgb(var(--usk-bg-rgb))` |
18
+ | `--ui-color-surface` | `<color>` | `var(--usk-native-surface-strong)` |
19
+ | `--ui-color-text` | `<color>` | `var(--usk-native-text)` |
20
+ | `--ui-color-muted` | `<color>` | `var(--usk-native-text-muted)` |
21
+ | `--ui-color-primary` | `<color>` | `var(--usk-native-primary)` |
22
+ | `--ui-color-on-primary` | `<color>` | `var(--usk-native-on-primary)` |
23
+ | `--ui-color-border` | `<color>` | `var(--usk-native-border)` |
24
+ | `--ui-radius-control` | `<length>` | `var(--usk-native-radius)` |
25
+ | `--ui-shadow-control` | `<shadow-list>` | `var(--usk-native-shadow)` |
26
+ | `--ui-focus-color` | `<color>` | `var(--usk-native-focus)` |
27
+ | `--ui-motion-duration` | `<time>` | `var(--usk-motion-duration)` |
28
+ | `--ui-motion-easing` | `<easing-function>` | `var(--usk-motion-easing)` |
29
+
30
+ The two motion sources are scalar values (`140ms` and `cubic-bezier(0.2, 0, 0.2, 1)`), not values derived from a transition shorthand. That keeps them valid wherever a consumer needs one duration or one easing function.
31
+
32
+ A third-party theme can provide the same handshake without importing UI Style Kit:
33
+
34
+ ```css
35
+ [data-theme="partner"] {
36
+ --ui-color-surface: rgb(250 252 255);
37
+ --ui-color-text: rgb(18 28 45);
38
+ --ui-color-primary: rgb(20 92 180);
39
+ --ui-color-on-primary: white;
40
+ --ui-color-border: rgb(150 165 185);
41
+ --ui-radius-control: 0.75rem;
42
+ --ui-shadow-control: 0 8px 24px rgb(20 40 70 / 0.16);
43
+ --ui-focus-color: rgb(20 92 180);
44
+ --ui-motion-duration: 140ms;
45
+ --ui-motion-easing: cubic-bezier(0.2, 0, 0.2, 1);
46
+ }
47
+ ```
48
+
49
+ UI Style Kit entrypoints publish all 12 values. Standalone consumer packages must remain complete when none of them are present.
50
+
11
51
  ## Prefixes
12
52
 
13
53
  | UI style | Prefix |