@dixy-ui/themes 0.1.0-beta.2 → 0.1.0-beta.4

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 (94) hide show
  1. package/dist/ansi-panes.css +79 -5
  2. package/dist/arcade/ornament.d.ts +3 -0
  3. package/dist/arcade/ornament.js +8 -0
  4. package/dist/arcade-cabinet.css +1086 -0
  5. package/dist/art-deco.css +79 -5
  6. package/dist/atomic-lounge.css +83 -5
  7. package/dist/authoring.d.ts +8 -8
  8. package/dist/azulejo-tile.css +83 -5
  9. package/dist/blueprint.css +79 -5
  10. package/dist/brutalist-concrete.css +83 -5
  11. package/dist/bytes.json +97 -67
  12. package/dist/candy-clay.css +85 -5
  13. package/dist/catalog.d.ts +294 -42
  14. package/dist/catalog.js +301 -43
  15. package/dist/character.d.ts +1 -1
  16. package/dist/character.js +6 -0
  17. package/dist/chrome.js +13 -3
  18. package/dist/compile-css.js +23 -5
  19. package/dist/dispatch.css +731 -0
  20. package/dist/diwali-lights.css +83 -5
  21. package/dist/documents.d.ts +115 -7
  22. package/dist/documents.js +10 -2
  23. package/dist/foundations.d.ts +8 -0
  24. package/dist/foundations.js +10 -0
  25. package/dist/frame-styles.d.ts +3 -0
  26. package/dist/frame-styles.js +6 -0
  27. package/dist/freighter.css +145 -15
  28. package/dist/glass-ui.css +79 -5
  29. package/dist/holi-colours.css +83 -5
  30. package/dist/ledger.css +566 -0
  31. package/dist/living-forest.css +85 -5
  32. package/dist/mainframe.css +764 -0
  33. package/dist/manifests.d.ts +144 -144
  34. package/dist/material-light.css +83 -5
  35. package/dist/neon-night-market.css +83 -5
  36. package/dist/ocean-depths.css +85 -5
  37. package/dist/orbital-hud.css +145 -15
  38. package/dist/organic-paint-launch.d.ts +9 -0
  39. package/dist/organic-paint-launch.js +121 -46
  40. package/dist/organic-paint.d.ts +1 -1
  41. package/dist/organic-settings.d.ts +109 -25
  42. package/dist/organic-settings.js +49 -0
  43. package/dist/papel-picado.css +83 -5
  44. package/dist/phosphor-terminal.css +83 -5
  45. package/dist/prism-glass.css +79 -5
  46. package/dist/recipes.d.ts +162 -0
  47. package/dist/recipes.js +164 -0
  48. package/dist/resolve.d.ts +18 -2
  49. package/dist/retro-os.css +79 -5
  50. package/dist/riso-zine.css +79 -5
  51. package/dist/save-point.css +948 -0
  52. package/dist/savepoint/ornament.d.ts +3 -0
  53. package/dist/savepoint/ornament.js +8 -0
  54. package/dist/scrapbook.css +79 -5
  55. package/dist/signal.css +563 -0
  56. package/dist/skins/arcade-cabinet.d.ts +68 -0
  57. package/dist/skins/arcade-cabinet.js +68 -0
  58. package/dist/skins/dispatch.d.ts +57 -0
  59. package/dist/skins/dispatch.js +57 -0
  60. package/dist/skins/ledger.d.ts +57 -0
  61. package/dist/skins/ledger.js +57 -0
  62. package/dist/skins/mainframe.d.ts +57 -0
  63. package/dist/skins/mainframe.js +57 -0
  64. package/dist/skins/save-point.d.ts +68 -0
  65. package/dist/skins/save-point.js +68 -0
  66. package/dist/skins/signal.d.ts +57 -0
  67. package/dist/skins/signal.js +57 -0
  68. package/dist/skins/sunset-drive.d.ts +68 -0
  69. package/dist/skins/sunset-drive.js +68 -0
  70. package/dist/solar-sail.css +79 -5
  71. package/dist/starters-launch.d.ts +25 -1
  72. package/dist/starters-launch.js +343 -49
  73. package/dist/studio-hardware.css +83 -5
  74. package/dist/sumi-ink.css +79 -5
  75. package/dist/sunset/ornament.d.ts +3 -0
  76. package/dist/sunset/ornament.js +8 -0
  77. package/dist/sunset-drive.css +1024 -0
  78. package/dist/swiss-poster.css +149 -15
  79. package/dist/tactile-atelier.css +85 -5
  80. package/dist/theme-document.schema.json +34 -6
  81. package/dist/theme-fix.d.ts +11 -0
  82. package/dist/theme-fix.js +32 -0
  83. package/dist/theme-fixes.d.ts +2 -0
  84. package/dist/theme-fixes.js +1 -0
  85. package/dist/theme-schema.d.ts +6 -6
  86. package/dist/theme-schema.js +2 -0
  87. package/dist/tokyo-transit.css +83 -5
  88. package/dist/winamp-signal.css +83 -5
  89. package/dist/y2k-titanium.css +151 -15
  90. package/dist/yule-knit.css +79 -5
  91. package/package.json +50 -8
  92. package/dist/lunar-new-year.css +0 -811
  93. package/dist/skins/lunar-new-year.d.ts +0 -68
  94. package/dist/skins/lunar-new-year.js +0 -68
package/dist/catalog.js CHANGED
@@ -1161,49 +1161,6 @@ export const skinCatalog = [
1161
1161
  },
1162
1162
  rendererSymbol: "DiwaliOrnament",
1163
1163
  },
1164
- {
1165
- id: "dixy/lunar-new-year",
1166
- slug: "lunar-new-year",
1167
- symbol: "lunarNewYear",
1168
- name: "Lunar New Year",
1169
- description: "Fortune at the door.",
1170
- detail: "Paper-cut scallops, lanterns, red and gold.",
1171
- swatches: ["#c8102e", "#f5c542", "#fff4e6"],
1172
- voice: {
1173
- eyebrow: "新年快乐 · SPRING FESTIVAL",
1174
- headline: "Fortune at the door.",
1175
- body: "Sweep out the old year and hang the lanterns high.",
1176
- primary: "Welcome",
1177
- secondary: "Visit family",
1178
- },
1179
- appearance: "light",
1180
- bodyFont: "inter",
1181
- headingFont: "playfair",
1182
- border: 1,
1183
- depth: "raised",
1184
- defaults: {
1185
- componentFinish: "inherit",
1186
- customAccent: false,
1187
- lightness: 0.54,
1188
- chroma: 0.2,
1189
- hue: 305,
1190
- density: "default",
1191
- ornament: "balanced",
1192
- relief: 1,
1193
- effects: "static",
1194
- accentColor: "red",
1195
- neutralColor: "sand",
1196
- radius: "sm",
1197
- shape: "rounded",
1198
- appearance: "light",
1199
- bodyFont: "inter",
1200
- headingFont: "playfair",
1201
- border: 1,
1202
- depth: "raised",
1203
- material: "paper",
1204
- },
1205
- rendererSymbol: "LunarOrnament",
1206
- },
1207
1164
  {
1208
1165
  id: "dixy/papel-picado",
1209
1166
  slug: "papel-picado",
@@ -1376,4 +1333,305 @@ export const skinCatalog = [
1376
1333
  },
1377
1334
  rendererSymbol: "GlassOrnament",
1378
1335
  },
1336
+ {
1337
+ id: "dixy/sunset-drive",
1338
+ slug: "sunset-drive",
1339
+ symbol: "sunsetDrive",
1340
+ name: "Sunset Drive",
1341
+ description: "Cruise the coast.",
1342
+ detail: "80s coastal neon: a striped sun, a horizon grid and pink light.",
1343
+ swatches: ["#ff4fa3", "#ffb347", "#1b0b30"],
1344
+ voice: {
1345
+ eyebrow: "COAST HIGHWAY · 1986",
1346
+ headline: "Cruise the coast.",
1347
+ body: "Pink skies, palm shadows and a long drive home.",
1348
+ primary: "Drive",
1349
+ secondary: "Park it",
1350
+ },
1351
+ appearance: "dark",
1352
+ bodyFont: "figtree",
1353
+ headingFont: "neon",
1354
+ border: 1,
1355
+ depth: "floating",
1356
+ defaults: {
1357
+ componentFinish: "inherit",
1358
+ customAccent: false,
1359
+ lightness: 0.54,
1360
+ chroma: 0.2,
1361
+ hue: 305,
1362
+ density: "default",
1363
+ ornament: "balanced",
1364
+ relief: 1,
1365
+ effects: "static",
1366
+ accentColor: "pink",
1367
+ neutralColor: "mauve",
1368
+ radius: "lg",
1369
+ shape: "pill",
1370
+ appearance: "dark",
1371
+ bodyFont: "figtree",
1372
+ headingFont: "neon",
1373
+ border: 1,
1374
+ depth: "floating",
1375
+ material: "glossy",
1376
+ },
1377
+ rendererSymbol: "SunsetOrnament",
1378
+ },
1379
+ {
1380
+ id: "dixy/save-point",
1381
+ slug: "save-point",
1382
+ symbol: "savePoint",
1383
+ name: "Save Point",
1384
+ description: "Rest here?",
1385
+ detail: "1994 menu windows: blue panels, white double borders, a blinking cursor.",
1386
+ swatches: ["#2b44b8", "#ffe066", "#05081c"],
1387
+ voice: {
1388
+ eyebrow: "CHAPTER 3 · SAVE POINT",
1389
+ headline: "Rest here?",
1390
+ body: "Your progress is safe. The party is ready when you are.",
1391
+ primary: "Save",
1392
+ secondary: "Continue",
1393
+ },
1394
+ appearance: "dark",
1395
+ bodyFont: "terminal",
1396
+ headingFont: "pixel",
1397
+ border: 2,
1398
+ depth: "raised",
1399
+ defaults: {
1400
+ componentFinish: "inherit",
1401
+ customAccent: false,
1402
+ lightness: 0.54,
1403
+ chroma: 0.2,
1404
+ hue: 305,
1405
+ density: "default",
1406
+ ornament: "balanced",
1407
+ relief: 1,
1408
+ effects: "static",
1409
+ accentColor: "yellow",
1410
+ neutralColor: "slate",
1411
+ radius: "sm",
1412
+ shape: "rounded",
1413
+ appearance: "dark",
1414
+ bodyFont: "terminal",
1415
+ headingFont: "pixel",
1416
+ border: 2,
1417
+ depth: "raised",
1418
+ material: "matte",
1419
+ },
1420
+ rendererSymbol: "SavePointOrnament",
1421
+ },
1422
+ {
1423
+ id: "dixy/arcade-cabinet",
1424
+ slug: "arcade-cabinet",
1425
+ symbol: "arcadeCabinet",
1426
+ name: "Arcade Cabinet",
1427
+ description: "Insert coin.",
1428
+ detail: "Scanlines, chunky pixels, hard red shadows and marquee bulbs.",
1429
+ swatches: ["#ff3b3b", "#ffd400", "#050505"],
1430
+ voice: {
1431
+ eyebrow: "1UP · HI 042000",
1432
+ headline: "Insert coin.",
1433
+ body: "Three lives. One high score. No continues.",
1434
+ primary: "Start",
1435
+ secondary: "Quit",
1436
+ },
1437
+ appearance: "dark",
1438
+ bodyFont: "terminal",
1439
+ headingFont: "pixel",
1440
+ border: 2,
1441
+ depth: "raised",
1442
+ defaults: {
1443
+ componentFinish: "inherit",
1444
+ customAccent: false,
1445
+ lightness: 0.54,
1446
+ chroma: 0.2,
1447
+ hue: 305,
1448
+ density: "default",
1449
+ ornament: "balanced",
1450
+ relief: 1,
1451
+ effects: "static",
1452
+ accentColor: "red",
1453
+ neutralColor: "neutral",
1454
+ radius: "none",
1455
+ shape: "square",
1456
+ appearance: "dark",
1457
+ bodyFont: "terminal",
1458
+ headingFont: "pixel",
1459
+ border: 2,
1460
+ depth: "raised",
1461
+ material: "matte",
1462
+ },
1463
+ rendererSymbol: "ArcadeOrnament",
1464
+ },
1465
+ {
1466
+ id: "dixy/ledger",
1467
+ slug: "ledger",
1468
+ symbol: "ledger",
1469
+ name: "Ledger",
1470
+ description: "Cash position",
1471
+ detail: "A quiet working theme: hairline rules, tabular figures, one green accent and faint ledger columns.",
1472
+ swatches: ["#0b6e4f", "#fbfbf9", "#16181d"],
1473
+ voice: {
1474
+ eyebrow: "Q3 · TREASURY",
1475
+ headline: "Cash position",
1476
+ body: "Balances reconcile nightly. Figures in USD thousands.",
1477
+ primary: "Export CSV",
1478
+ secondary: "Filters",
1479
+ },
1480
+ appearance: "light",
1481
+ bodyFont: "inter",
1482
+ headingFont: "plex",
1483
+ border: 1,
1484
+ depth: "raised",
1485
+ defaults: {
1486
+ componentFinish: "inherit",
1487
+ customAccent: false,
1488
+ lightness: 0.54,
1489
+ chroma: 0.2,
1490
+ hue: 305,
1491
+ density: "default",
1492
+ ornament: "balanced",
1493
+ relief: 1,
1494
+ effects: "static",
1495
+ accentColor: "jade",
1496
+ neutralColor: "gray",
1497
+ radius: "sm",
1498
+ shape: "rounded",
1499
+ appearance: "light",
1500
+ bodyFont: "inter",
1501
+ headingFont: "plex",
1502
+ border: 1,
1503
+ depth: "raised",
1504
+ material: "matte",
1505
+ },
1506
+ rendererSymbol: null,
1507
+ },
1508
+ {
1509
+ id: "dixy/mainframe",
1510
+ slug: "mainframe",
1511
+ symbol: "mainframe",
1512
+ name: "Mainframe",
1513
+ description: "Shipments",
1514
+ detail: "A square enterprise grid: flat grey layers instead of shadows, one blue, dense 40px rows.",
1515
+ swatches: ["#0f5fd9", "#f4f4f4", "#161616"],
1516
+ voice: {
1517
+ eyebrow: "OPERATIONS / SHIPMENTS",
1518
+ headline: "Shipments",
1519
+ body: "1,284 active across 38 carriers. Updated two minutes ago.",
1520
+ primary: "New shipment",
1521
+ secondary: "Export",
1522
+ },
1523
+ appearance: "light",
1524
+ bodyFont: "plexSans",
1525
+ headingFont: "plexSans",
1526
+ border: 1,
1527
+ depth: "none",
1528
+ defaults: {
1529
+ componentFinish: "inherit",
1530
+ customAccent: false,
1531
+ lightness: 0.54,
1532
+ chroma: 0.2,
1533
+ hue: 305,
1534
+ density: "default",
1535
+ ornament: "balanced",
1536
+ relief: 1,
1537
+ effects: "static",
1538
+ accentColor: "blue",
1539
+ neutralColor: "neutral",
1540
+ radius: "none",
1541
+ shape: "square",
1542
+ appearance: "light",
1543
+ bodyFont: "plexSans",
1544
+ headingFont: "plexSans",
1545
+ border: 1,
1546
+ depth: "none",
1547
+ material: "matte",
1548
+ },
1549
+ rendererSymbol: null,
1550
+ },
1551
+ {
1552
+ id: "dixy/dispatch",
1553
+ slug: "dispatch",
1554
+ symbol: "dispatch",
1555
+ name: "Dispatch",
1556
+ description: "Ready when you are",
1557
+ detail: "Black and white, bold type and pill controls. Colour is kept for status.",
1558
+ swatches: ["#000000", "#ffffff", "#eeeeee"],
1559
+ voice: {
1560
+ eyebrow: "LIVE · 842 IN TRANSIT",
1561
+ headline: "Ready when you are",
1562
+ body: "Every route, driver and delivery in one place. Colour only means something.",
1563
+ primary: "New shipment",
1564
+ secondary: "Export",
1565
+ },
1566
+ appearance: "light",
1567
+ bodyFont: "inter",
1568
+ headingFont: "inter",
1569
+ border: 1,
1570
+ depth: "raised",
1571
+ defaults: {
1572
+ componentFinish: "inherit",
1573
+ customAccent: false,
1574
+ lightness: 0.54,
1575
+ chroma: 0.2,
1576
+ hue: 305,
1577
+ density: "default",
1578
+ ornament: "balanced",
1579
+ relief: 1,
1580
+ effects: "static",
1581
+ accentColor: "neutral",
1582
+ neutralColor: "neutral",
1583
+ radius: "lg",
1584
+ shape: "pill",
1585
+ appearance: "light",
1586
+ bodyFont: "inter",
1587
+ headingFont: "inter",
1588
+ border: 1,
1589
+ depth: "raised",
1590
+ material: "matte",
1591
+ },
1592
+ rendererSymbol: null,
1593
+ },
1594
+ {
1595
+ id: "dixy/signal",
1596
+ slug: "signal",
1597
+ symbol: "signal",
1598
+ name: "Signal",
1599
+ description: "Make it easier to read",
1600
+ detail: "High contrast, accessibility first: 2px edges, 44px targets, a thick focus ring with a yellow halo, no textures or ornament.",
1601
+ swatches: ["#000000", "#ffffff", "#ffbf00"],
1602
+ voice: {
1603
+ eyebrow: "SETTINGS · DISPLAY",
1604
+ headline: "Make it easier to read",
1605
+ body: "Clear type, strong edges and focus you can always see.",
1606
+ primary: "Save changes",
1607
+ secondary: "Cancel",
1608
+ },
1609
+ appearance: "light",
1610
+ bodyFont: "atkinson",
1611
+ headingFont: "atkinson",
1612
+ border: 2,
1613
+ depth: "none",
1614
+ defaults: {
1615
+ componentFinish: "inherit",
1616
+ customAccent: false,
1617
+ lightness: 0.54,
1618
+ chroma: 0.2,
1619
+ hue: 305,
1620
+ density: "default",
1621
+ ornament: "balanced",
1622
+ relief: 1,
1623
+ effects: "static",
1624
+ accentColor: "blue",
1625
+ neutralColor: "neutral",
1626
+ radius: "sm",
1627
+ shape: "rounded",
1628
+ appearance: "light",
1629
+ bodyFont: "atkinson",
1630
+ headingFont: "atkinson",
1631
+ border: 2,
1632
+ depth: "none",
1633
+ material: "matte",
1634
+ },
1635
+ rendererSymbol: null,
1636
+ },
1379
1637
  ];
@@ -9,7 +9,7 @@ import { type ThemeChrome } from "./chrome.ts";
9
9
  export declare const controlStyles: readonly ["standard", "botanical", "pixel", "instrument", "hardware", "glass", "stitched", "pearl", "clay", "brass", "chrome", "halo"];
10
10
  export declare const motionStyles: readonly ["standard", "snappy", "stepped", "springy", "weighted", "drift"];
11
11
  export declare const stateStyles: readonly ["standard", "led", "marching", "inlay", "glow", "stamp"];
12
- export declare const focusStyles: readonly ["ring", "double", "dashed", "glow", "offset"];
12
+ export declare const focusStyles: readonly ["ring", "double", "dashed", "glow", "offset", "halo"];
13
13
  export declare const dividerStyles: readonly ["line", "dashed", "dotted", "double", "groove"];
14
14
  export declare const selectionStyles: readonly ["accent", "inverse", "highlighter"];
15
15
  export declare const scrollbarStyles: readonly ["native", "thin", "accent"];
package/dist/character.js CHANGED
@@ -43,6 +43,7 @@ export const focusStyles = [
43
43
  "dashed",
44
44
  "glow",
45
45
  "offset",
46
+ "halo",
46
47
  ];
47
48
  export const dividerStyles = [
48
49
  "line",
@@ -393,6 +394,11 @@ function detailCSS(c, S, theme) {
393
394
  rules.push(`${focus} { outline-width:2px; outline-offset:2px; box-shadow:0 0 0 6px ${mix("var(--dixy-color-border-focus)", 28)}; }`);
394
395
  if (d.focus === "offset")
395
396
  rules.push(`${focus} { outline-width:2px; outline-offset:5px; }`);
397
+ // High-contrast: a solid 3px ring plus a yellow halo outside it, visible on any surface.
398
+ // Skin and material rules set box-shadow at higher specificity (fields at 0,5,0), so the
399
+ // halo is important: a focus indicator has to win over decoration.
400
+ if (d.focus === "halo")
401
+ rules.push(`${focus} { --dixy-focus-halo:0 0 0 8px var(--dixy-color-yellow-9); outline-style:solid; outline-width:3px; outline-offset:2px; box-shadow:var(--dixy-focus-halo) !important; }`);
396
402
  const lines = {
397
403
  dashed: (a) => `repeating-linear-gradient(${a},${EDGE} 0 6px,transparent 6px 10px)`,
398
404
  dotted: (a) => `repeating-linear-gradient(${a},${EDGE} 0 2px,transparent 2px 5px)`,
package/dist/chrome.js CHANGED
@@ -187,9 +187,19 @@ function cornerCSS(style, frame) {
187
187
  return "";
188
188
  case "pixel":
189
189
  return `${frame} { border-radius:0; --dixy-chrome-bar-radius:0px; }`;
190
- case "notched":
191
- // Clip-path also clips outer shadows, so notched windows lean on inset relief.
192
- return `${frame} { border-radius:0; --dixy-chrome-bar-radius:0px; clip-path:polygon(10px 0,calc(100% - 10px) 0,100% 10px,100% calc(100% - 10px),calc(100% - 10px) 100%,10px 100%,0 calc(100% - 10px),0 10px); }`;
190
+ case "notched": {
191
+ // corner-shape draws the border along the bevel (and keeps outer
192
+ // shadows). Without it, clip-path cuts the corners off — border and
193
+ // all — so an overlay redraws the four diagonals in the edge colour.
194
+ const w = "var(--dixy-skin-frame-width,1px)";
195
+ const line = (to) => `linear-gradient(${to},transparent 50%,var(--dixy-skin-edge) 50% calc(50% + ${w}),transparent calc(50% + ${w}))`;
196
+ return `${frame} { border-radius:0; --dixy-chrome-bar-radius:0px; }
197
+ @supports (corner-shape:bevel) { ${frame} { border-radius:10px; corner-shape:bevel; } }
198
+ @supports not (corner-shape:bevel) {
199
+ ${frame} { clip-path:polygon(10px 0,calc(100% - 10px) 0,100% 10px,100% calc(100% - 10px),calc(100% - 10px) 100%,10px 100%,0 calc(100% - 10px),0 10px); }
200
+ ${frame}::after { content:""; position:absolute; inset:calc(${w} * -1); pointer-events:none; z-index:1; background:${line("to bottom right")} top left/10px 10px no-repeat,${line("to bottom left")} top right/10px 10px no-repeat,${line("to top right")} bottom left/10px 10px no-repeat,${line("to top left")} bottom right/10px 10px no-repeat; }
201
+ }`;
202
+ }
193
203
  case "round":
194
204
  return `${frame} { border-radius:16px; --dixy-chrome-bar-radius:13px; }`;
195
205
  }
@@ -54,6 +54,12 @@ export function compileThemeCSS(m) {
54
54
  ? `blur(${m.backdropBlur}px) saturate(${m.backdropSaturate}%)`
55
55
  : "";
56
56
  const borderStyle = m.frame === "rails" ? "ridge" : "solid";
57
+ // Overlays float over unrelated content, so a translucent material tint
58
+ // alone leaves them unreadable. Mix in the opaque raised surface: mostly
59
+ // opaque when the material blurs what is behind it, nearly solid when not.
60
+ // Fields get their own edge: WCAG 1.4.11 needs 3:1 around them, and the
61
+ // decorative material edge (white on glass) can be nearly invisible.
62
+ // Base 8/9 at 50% measured >= 3.35:1 on every built-in theme.
57
63
  // Character rules sit after material rules and carry the theme ancestor, so they win over paint defaults.
58
64
  const C = (parts, state = "") => `${theme} :is(${parts})[data-dixy-skin="${m.id}"]${state}`;
59
65
  return `
@@ -62,6 +68,7 @@ export function compileThemeCSS(m) {
62
68
  ${theme} {
63
69
  ${style}
64
70
  --dixy-skin-edge:${m.edge};
71
+ --dixy-skin-field-edge:color-mix(in oklab,var(--dixy-color-base-9) 50%,var(--dixy-color-base-8));
65
72
  ${ornamentVariables}
66
73
  ${colors("light")}
67
74
  ${m.inkTint ? `--dixy-color-text-primary:color-mix(in srgb,var(--dixy-color-base-12) ${100 - m.inkTint * 100}%,${m.tint[1]});` : ""}
@@ -89,7 +96,10 @@ export function compileThemeCSS(m) {
89
96
  --dixy-skin-mark-opacity:1;
90
97
  ${characterTokenCSS(m.character)}
91
98
  }
92
- ${theme}[data-appearance="dark"] { ${colors("dark")} --dixy-skin-selected:var(--dixy-skin-finish); ${m.inkTint ? `--dixy-color-text-primary:color-mix(in srgb,var(--dixy-color-base-12) ${100 - m.inkTint * 100}%,${m.tint[0]});` : ""} --dixy-skin-edge:${m.darkEdge}; ${m.darkCanvas ? `--dixy-skin-canvas:${m.darkCanvas};` : ""} --dixy-skin-surface:color-mix(in srgb,var(--dixy-color-background-surface-raised) ${m.darkSurfaceMix}%,${m.tint[1]}); --dixy-skin-ground:color-mix(in srgb,var(--dixy-color-background-canvas) 65%,${m.tint[1]}); }
99
+ ${theme}[data-appearance="dark"] { ${colors("dark")} ${m.inkTint ? `--dixy-color-text-primary:color-mix(in srgb,var(--dixy-color-base-12) ${100 - m.inkTint * 100}%,${m.tint[0]});` : ""} --dixy-skin-edge:${m.darkEdge}; ${m.darkShadow ? `--dixy-skin-authored-shadow:${m.darkShadow};` : ""} ${m.darkInset ? `--dixy-skin-inset:${m.darkInset};` : ""} ${m.darkCanvas ? `--dixy-skin-canvas:${m.darkCanvas};` : ""} --dixy-skin-surface:color-mix(in srgb,var(--dixy-color-background-surface-raised) ${m.darkSurfaceMix}%,${m.tint[1]}); --dixy-skin-ground:color-mix(in srgb,var(--dixy-color-background-canvas) 65%,${m.tint[1]}); }
100
+ ${m.deepSolid ? `${theme}:not([data-appearance="dark"]) { --dixy-color-brand-9:var(--dixy-color-brand-11); --dixy-color-brand-10:var(--dixy-color-brand-12); --dixy-color-brand-pressed:var(--dixy-color-brand-12); }` : ""}
101
+ ${m.controlHeights ? `${theme} { --dixy-size-control-sm:${m.controlHeights[0]}; --dixy-size-control-md:${m.controlHeights[1]}; --dixy-size-control-lg:${m.controlHeights[2]}; --dixy-height-sm:${m.controlHeights[0]}; --dixy-height-md:${m.controlHeights[1]}; --dixy-height-lg:${m.controlHeights[2]}; }` : ""}
102
+ ${m.monoAccent ? `${theme}[data-accent="neutral"] { --dixy-color-brand-9:var(--dixy-color-neutral-12); --dixy-color-brand-10:var(--dixy-color-neutral-11); --dixy-color-brand-11:var(--dixy-color-neutral-12); --dixy-color-brand-pressed:var(--dixy-color-neutral-11); --dixy-color-brand-on-solid:var(--dixy-color-neutral-1); --dixy-color-brand-focus:var(--dixy-color-blue-focus); }` : ""}
93
103
  ${theme}[data-relief="2"] { --dixy-skin-shadow:var(--dixy-skin-depth-shadow,var(--dixy-skin-authored-shadow)),0 10px 18px #0002; }
94
104
  ${theme}[data-relief="0"],${theme}[data-effects="reduced"] { --dixy-skin-shadow:none; --dixy-skin-inset:none; --dixy-skin-control-edge:none; --dixy-skin-panel-relief:none; --dixy-skin-control-relief:none; }
95
105
  ${theme}[data-effects="reduced"] { --dixy-skin-paint:none; --dixy-skin-finish:none; --dixy-skin-canvas:none; --dixy-skin-thumb:none; --dixy-skin-mark-opacity:0; }
@@ -104,16 +114,24 @@ export function compileThemeCSS(m) {
104
114
  ${S(".dixy-card,.dixy-dialog-popup")} { padding:var(--dixy-skin-card-inset); border:${frameWidth}px ${borderStyle} var(--dixy-skin-edge); }
105
115
  ${own(surfaces)} { background-image:var(--dixy-skin-paint); background-size:var(--dixy-skin-grain-size) var(--dixy-skin-grain-size),100% 100%,100% 100%,100% 100%; box-shadow:var(--dixy-skin-panel-relief); }
106
116
  ${own(surfaces, ':not([data-variant="solid"]):not([data-variant="soft"])')} { background-color:var(--dixy-skin-surface); }
117
+ ${own(overlays, ':not([data-variant="solid"]):not([data-variant="soft"])')} { background-color:color-mix(in srgb,var(--dixy-color-background-surface-raised) ${glass ? 72 : 94}%,var(--dixy-skin-surface)); }
107
118
  ${S(fields)} { border-radius:calc(var(--dixy-radius-control) * ${p.cornerScale}); }
108
- ${own(fields)} { border-width:var(--dixy-input-border-width); border-color:var(--dixy-skin-edge); background-image:var(--dixy-skin-paint); background-color:var(--dixy-color-background-canvas); background-size:var(--dixy-skin-grain-size) var(--dixy-skin-grain-size),100% 100%,100% 100%,100% 100%; box-shadow:var(--dixy-skin-inset); }
119
+ ${S(".dixy-textarea")} { border-radius:calc(min(var(--dixy-radius-control), var(--dixy-radius-card)) * ${p.cornerScale}); }
120
+ ${own(fields)} { border-width:var(--dixy-input-border-width); border-color:var(--dixy-skin-field-edge); background-image:var(--dixy-skin-paint); background-color:var(--dixy-color-background-canvas); background-size:var(--dixy-skin-grain-size) var(--dixy-skin-grain-size),100% 100%,100% 100%,100% 100%; box-shadow:var(--dixy-skin-inset); }
121
+ /* materials.css styles [data-dixy-visual] surfaces at 0,5,0. Match the
122
+ skin's paint to that so its image and grain size always land together;
123
+ otherwise the material image is tiled at the grain size (stripes). */
124
+ ${own(`${surfaces},${fields}`, "[data-dixy-visual][data-material]:not([data-disabled])")} { background-image:var(--dixy-skin-paint); }
109
125
  ${own(".dixy-button", actions)} { border-width:var(--dixy-button-border-width); border-color:var(--dixy-skin-edge); border-radius:calc(var(--dixy-shape-control) * ${p.cornerScale}); background-image:var(--dixy-skin-finish); box-shadow:var(--dixy-skin-control-relief); }
110
126
  ${m.tintActions ? `${own(".dixy-button", '[data-variant="solid"][data-color="accent"]:not([data-disabled])')} { background-color:var(--dixy-skin-surface); color:var(--dixy-color-text-action-primary); }` : ""}
111
127
  ${own(".dixy-button", actions + ":active")} { box-shadow:var(--dixy-skin-inset); }
112
128
  ${own(".dixy-tabs-list")} { background-color:var(--dixy-color-background-canvas); border:1px solid var(--dixy-skin-edge); box-shadow:var(--dixy-skin-inset); }
113
- ${own(".dixy-tabs-indicator")} { background-image:var(--dixy-skin-finish); box-shadow:var(--dixy-skin-control-relief); border:1px solid var(--dixy-skin-edge); }
114
- /* Toggle groups read like tabs: a sunken track, the selected toggle a raised thumb (slider-knob paint in light, the raised finish in dark so its label stays readable). */
129
+ /* Selected tabs and toggles are one flat colour, lifted by edge and relief only. A gradient behind the label (thumb art, sheen, material image) splits it across two colours. :not([data-variant="line"]) also outranks materials.css (0,3,0). */
130
+ ${own(".dixy-tabs-indicator")} { box-shadow:var(--dixy-skin-control-relief); border:1px solid var(--dixy-skin-edge); }
131
+ ${own(".dixy-tabs-indicator", ':not([data-variant="line"])')} { background-image:none; }
132
+ /* Toggle groups read like tabs: a sunken track, the selected toggle a raised, flat thumb. */
115
133
  ${theme} .dixy-toggle-group:is([data-attached],[data-segmented])${guard} { background-color:var(--dixy-color-background-canvas); border:1px solid var(--dixy-skin-edge); box-shadow:var(--dixy-skin-inset); }
116
- ${own(".dixy-toggle", ':not([data-variant="solid"])[data-pressed]:not([data-disabled])')} { background-color:var(--dixy-color-background-surface-raised); background-image:var(--dixy-skin-selected,var(--dixy-skin-thumb)); box-shadow:var(--dixy-skin-control-relief); border-color:var(--dixy-skin-edge); color:var(--dixy-color-text-primary); }
134
+ ${own(".dixy-toggle", ':not([data-variant="solid"])[data-pressed]:not([data-disabled])')} { background-color:var(--dixy-color-background-surface-raised); background-image:none; box-shadow:var(--dixy-skin-control-relief); border-color:var(--dixy-skin-edge); color:var(--dixy-color-text-primary); }
117
135
  ${own(tracks)} { border:1px solid var(--dixy-skin-edge); background-color:var(--dixy-color-background-surface); box-shadow:var(--dixy-skin-inset); }
118
136
  ${own(fills)} { background-image:var(--dixy-skin-finish); }
119
137
  ${own(".dixy-switch-root,.dixy-checkbox-root,.dixy-radio-root")}::before { box-shadow:var(--dixy-skin-inset); }