@vectoriox/iox-ui 5.25.0 → 5.26.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.
@@ -1058,7 +1058,52 @@ const SPEC_AXES = {
1058
1058
  "light",
1059
1059
  "dark",
1060
1060
  "auto"
1061
- ]
1061
+ ],
1062
+ "tints": {
1063
+ "neutral": {
1064
+ "label": "Neutral"
1065
+ },
1066
+ "subtle": {
1067
+ "label": "Subtle",
1068
+ "paintChroma": 1,
1069
+ "ownScale": 1,
1070
+ "groundMaxL": 0.99,
1071
+ "chroma": {
1072
+ "bg": 0.008,
1073
+ "surface": 0.004,
1074
+ "surface-2": 0.014,
1075
+ "line": 0.012,
1076
+ "line-strong": 0.018,
1077
+ "text": 0.008,
1078
+ "text-muted": 0.022,
1079
+ "inverse-bg": 0.014,
1080
+ "inverse-surface": 0.018,
1081
+ "inverse-text": 0.005,
1082
+ "inverse-muted": 0.02,
1083
+ "inverse-line": 0.016
1084
+ }
1085
+ },
1086
+ "rich": {
1087
+ "label": "Rich",
1088
+ "paintChroma": 1.35,
1089
+ "ownScale": 1.6,
1090
+ "groundMaxL": 0.975,
1091
+ "chroma": {
1092
+ "bg": 0.02,
1093
+ "surface": 0.008,
1094
+ "surface-2": 0.03,
1095
+ "line": 0.024,
1096
+ "line-strong": 0.032,
1097
+ "text": 0.014,
1098
+ "text-muted": 0.04,
1099
+ "inverse-bg": 0.03,
1100
+ "inverse-surface": 0.036,
1101
+ "inverse-text": 0.01,
1102
+ "inverse-muted": 0.034,
1103
+ "inverse-line": 0.03
1104
+ }
1105
+ }
1106
+ }
1062
1107
  };
1063
1108
  const SPEC_SPRINGS = {
1064
1109
  "lively": {
@@ -1130,7 +1175,11 @@ const SPEC_SCHEMES = {
1130
1175
  "accent": "var(--iox-inverse-accent)",
1131
1176
  "accent-ink": "var(--iox-inverse-accent-ink)",
1132
1177
  "accent-hover": "var(--iox-inverse-accent)",
1133
- "accent-text": "var(--iox-inverse-accent)"
1178
+ "accent-text": "var(--iox-inverse-accent)",
1179
+ "danger": "{{~danger}}",
1180
+ "danger-bg": "{{~danger-bg}}",
1181
+ "success": "{{~success}}",
1182
+ "success-bg": "{{~success-bg}}"
1134
1183
  }
1135
1184
  },
1136
1185
  "accent": {
@@ -1138,10 +1187,10 @@ const SPEC_SCHEMES = {
1138
1187
  "set": {
1139
1188
  "section-bg": "{{accent}}",
1140
1189
  "bg": "{{accent}}",
1141
- "surface": "color-mix(in srgb, {{accent-ink}} 10%, {{accent}})",
1142
- "surface-2": "color-mix(in srgb, {{accent-ink}} 10%, {{accent}})",
1143
- "surface-glass": "color-mix(in srgb, {{accent-ink}} 10%, {{accent}})",
1144
- "surface-glass-strong": "color-mix(in srgb, {{accent-ink}} 10%, {{accent}})",
1190
+ "surface": "{{accent-hover}}",
1191
+ "surface-2": "{{accent-hover}}",
1192
+ "surface-glass": "{{accent-hover}}",
1193
+ "surface-glass-strong": "{{accent-hover}}",
1145
1194
  "text": "{{accent-ink}}",
1146
1195
  "text-muted": "{{accent-ink}}",
1147
1196
  "line": "color-mix(in srgb, {{accent-ink}} 28%, transparent)",
@@ -1150,7 +1199,11 @@ const SPEC_SCHEMES = {
1150
1199
  "accent": "{{accent-ink}}",
1151
1200
  "accent-ink": "{{accent}}",
1152
1201
  "accent-text": "{{accent-ink}}",
1153
- "accent-hover": "color-mix(in srgb, {{accent-ink}} 85%, {{accent}})"
1202
+ "accent-hover": "{{accent-ink}}",
1203
+ "danger": "{{accent-ink}}",
1204
+ "danger-bg": "{{accent-hover}}",
1205
+ "success": "{{accent-ink}}",
1206
+ "success-bg": "{{accent-hover}}"
1154
1207
  }
1155
1208
  }
1156
1209
  };
@@ -1743,7 +1796,7 @@ const SPEC_FIELD_CLASS_BASELINE = {
1743
1796
  "transition": "border-color var(--iox-dur-base) var(--iox-ease-standard), box-shadow var(--iox-dur-base) var(--iox-ease-standard)"
1744
1797
  },
1745
1798
  ".iox-es-field .iox-field__control:focus-visible": {
1746
- "border-color": "var(--iox-accent)",
1799
+ "border-color": "var(--iox-accent-text)",
1747
1800
  "box-shadow": "var(--iox-field-focus)",
1748
1801
  "outline": "none"
1749
1802
  },
@@ -1763,8 +1816,225 @@ const SPEC_FIELD_CLASS_BASELINE = {
1763
1816
  },
1764
1817
  ".iox-es-field.iox-invalid .iox-field__control": {
1765
1818
  "border-color": "var(--iox-danger)"
1819
+ },
1820
+ ".iox-es-field .iox-field__control::placeholder": {
1821
+ "color": "var(--iox-text-muted)",
1822
+ "opacity": "1"
1823
+ },
1824
+ ".iox-es-field .iox-field__control:where([type='checkbox'], [type='radio'], [type='range'])": {
1825
+ "border": "none",
1826
+ "padding": "0",
1827
+ "background": "transparent",
1828
+ "accent-color": "var(--iox-accent-text)"
1829
+ },
1830
+ ".iox-es-field .iox-field__control--switch": {
1831
+ "background": "var(--iox-text-muted)",
1832
+ "transition": "background var(--iox-dur-fast) var(--iox-ease-standard)"
1833
+ },
1834
+ ".iox-es-field .iox-field__control--switch::before": {
1835
+ "background": "var(--iox-bg)",
1836
+ "transition": "transform var(--iox-dur-fast) var(--iox-ease-standard)"
1837
+ },
1838
+ ".iox-es-field .iox-field__control--switch:checked": {
1839
+ "background": "var(--iox-accent-text)"
1766
1840
  }
1767
1841
  };
1842
+ const SPEC_INK_SCOPES = [
1843
+ {
1844
+ "styles": [
1845
+ "button-primary",
1846
+ "button-secondary",
1847
+ "button-ghost"
1848
+ ],
1849
+ "set": {
1850
+ "icon-color": "currentColor",
1851
+ "heading-color": "currentColor",
1852
+ "eyebrow-color": "currentColor",
1853
+ "link-color": "currentColor",
1854
+ "link-hover-color": "currentColor",
1855
+ "text-muted": "currentColor"
1856
+ }
1857
+ }
1858
+ ];
1859
+ const SPEC_CONTRAST_AUDIT = {
1860
+ "pairs": [
1861
+ {
1862
+ "fg": "text",
1863
+ "bg": "bg",
1864
+ "min": 4.5
1865
+ },
1866
+ {
1867
+ "fg": "text",
1868
+ "bg": "surface",
1869
+ "min": 4.5
1870
+ },
1871
+ {
1872
+ "fg": "text-muted",
1873
+ "bg": "bg",
1874
+ "min": 4.5
1875
+ },
1876
+ {
1877
+ "fg": "text-muted",
1878
+ "bg": "surface",
1879
+ "min": 4.5
1880
+ },
1881
+ {
1882
+ "fg": "accent-ink",
1883
+ "bg": "accent",
1884
+ "min": 4.5
1885
+ },
1886
+ {
1887
+ "fg": "accent-text",
1888
+ "bg": "bg",
1889
+ "min": 4.5
1890
+ },
1891
+ {
1892
+ "fg": "inverse-text",
1893
+ "bg": "inverse-bg",
1894
+ "min": 4.5
1895
+ },
1896
+ {
1897
+ "fg": "inverse-muted",
1898
+ "bg": "inverse-bg",
1899
+ "min": 4.5
1900
+ },
1901
+ {
1902
+ "fg": "inverse-accent-ink",
1903
+ "bg": "inverse-accent",
1904
+ "min": 4.5
1905
+ },
1906
+ {
1907
+ "fg": "inverse-accent",
1908
+ "bg": "inverse-bg",
1909
+ "min": 4.5
1910
+ },
1911
+ {
1912
+ "fg": "success",
1913
+ "bg": "success-bg",
1914
+ "min": 4.5
1915
+ },
1916
+ {
1917
+ "fg": "danger",
1918
+ "bg": "danger-bg",
1919
+ "min": 4.5
1920
+ },
1921
+ {
1922
+ "fg": "accent-ink",
1923
+ "bg": "accent-hover",
1924
+ "min": 4.5
1925
+ },
1926
+ {
1927
+ "fg": "text-muted",
1928
+ "bg": "surface-2",
1929
+ "min": 4.5
1930
+ },
1931
+ {
1932
+ "fg": "text",
1933
+ "bg": "surface-2",
1934
+ "min": 4.5
1935
+ },
1936
+ {
1937
+ "fg": "accent-text",
1938
+ "bg": "surface",
1939
+ "min": 4.5
1940
+ },
1941
+ {
1942
+ "fg": "accent-text",
1943
+ "bg": "surface-2",
1944
+ "min": 4.5
1945
+ },
1946
+ {
1947
+ "fg": "inverse-text",
1948
+ "bg": "inverse-surface",
1949
+ "min": 4.5
1950
+ },
1951
+ {
1952
+ "fg": "inverse-muted",
1953
+ "bg": "inverse-surface",
1954
+ "min": 4.5
1955
+ },
1956
+ {
1957
+ "fg": "inverse-accent",
1958
+ "bg": "inverse-surface",
1959
+ "min": 4.5
1960
+ },
1961
+ {
1962
+ "fg": "line-strong",
1963
+ "bg": "bg",
1964
+ "min": 3
1965
+ },
1966
+ {
1967
+ "fg": "line-strong",
1968
+ "bg": "surface",
1969
+ "min": 3
1970
+ },
1971
+ {
1972
+ "fg": "line-strong",
1973
+ "bg": "surface-2",
1974
+ "min": 3
1975
+ }
1976
+ ],
1977
+ "formParts": [
1978
+ {
1979
+ "part": "input text",
1980
+ "fg": "var(--iox-field-ink)",
1981
+ "on": "var(--iox-field-bg)",
1982
+ "min": 4.5
1983
+ },
1984
+ {
1985
+ "part": "placeholder",
1986
+ "fg": "var(--iox-text-muted)",
1987
+ "on": "var(--iox-field-bg)",
1988
+ "min": 4.5
1989
+ },
1990
+ {
1991
+ "part": "label",
1992
+ "fg": "var(--iox-text)",
1993
+ "min": 4.5
1994
+ },
1995
+ {
1996
+ "part": "help",
1997
+ "fg": "var(--iox-text-muted)",
1998
+ "min": 4.5
1999
+ },
2000
+ {
2001
+ "part": "error",
2002
+ "fg": "var(--iox-danger)",
2003
+ "min": 4.5
2004
+ },
2005
+ {
2006
+ "part": "boundary",
2007
+ "fg": [
2008
+ "var(--iox-field-border)",
2009
+ "var(--iox-field-bg)"
2010
+ ],
2011
+ "any": true,
2012
+ "min": 3
2013
+ },
2014
+ {
2015
+ "part": "focus edge",
2016
+ "fg": "var(--iox-accent-text)",
2017
+ "min": 3
2018
+ },
2019
+ {
2020
+ "part": "switch off",
2021
+ "fg": "var(--iox-text-muted)",
2022
+ "thumb": "var(--iox-bg)",
2023
+ "min": 3
2024
+ },
2025
+ {
2026
+ "part": "switch on",
2027
+ "fg": "var(--iox-accent-text)",
2028
+ "thumb": "var(--iox-bg)",
2029
+ "min": 3
2030
+ },
2031
+ {
2032
+ "part": "checkbox · radio · range",
2033
+ "fg": "var(--iox-accent-text)",
2034
+ "min": 3
2035
+ }
2036
+ ]
2037
+ };
1768
2038
  const SPEC_LEGACY_ALIASES = {
1769
2039
  "radius-control": "var(--iox-button-radius)",
1770
2040
  "radius-surface": "var(--iox-card-radius)",
@@ -1789,7 +2059,8 @@ const SPEC_FLAVOR_PACKS = [
1789
2059
  "density": "regular",
1790
2060
  "motion": "standard",
1791
2061
  "pillButtons": false,
1792
- "mode": "light"
2062
+ "mode": "light",
2063
+ "tint": "subtle"
1793
2064
  },
1794
2065
  "seed": "#2F5BEA",
1795
2066
  "seeds": [
@@ -1854,14 +2125,97 @@ const SPEC_FLAVOR_PACKS = [
1854
2125
  ]
1855
2126
  }
1856
2127
  ],
2128
+ "palette": {
2129
+ "light": {
2130
+ "bg": "#FFFFFF",
2131
+ "page-bg": "var(--iox-bg)",
2132
+ "section-bg": "transparent",
2133
+ "surface": "#FFFFFF",
2134
+ "surface-2": "#F6F7F9",
2135
+ "surface-glass": "var(--iox-surface)",
2136
+ "surface-glass-strong": "var(--iox-surface)",
2137
+ "glass-border": "var(--iox-line)",
2138
+ "text": "#0F1115",
2139
+ "text-muted": "#5B616E",
2140
+ "line": "#E6E8EC",
2141
+ "line-strong": "#8B8F97",
2142
+ "accent": "#2F5BEA",
2143
+ "accent-ink": "#FFFFFF",
2144
+ "accent-hover": "#2449C4",
2145
+ "accent-text": "#2F5BEA",
2146
+ "inverse-bg": "#0F1115",
2147
+ "inverse-surface": "#1A1D23",
2148
+ "inverse-text": "#F2F3F5",
2149
+ "inverse-muted": "#A3A9B4",
2150
+ "inverse-line": "#2A2E36",
2151
+ "inverse-accent": "#8EA9FF",
2152
+ "inverse-accent-ink": "#0F1115",
2153
+ "success": "#1B6B3D",
2154
+ "success-bg": "#E7F4EC",
2155
+ "danger": "#B3261E",
2156
+ "danger-bg": "#FBE9E7",
2157
+ "scrim": "rgba(15, 17, 21, 0.45)"
2158
+ },
2159
+ "dark": {
2160
+ "bg": "#0E0F12",
2161
+ "surface": "#16181D",
2162
+ "surface-2": "#1C1F25",
2163
+ "text": "#F2F3F5",
2164
+ "text-muted": "#9AA0AC",
2165
+ "line": "#262A31",
2166
+ "line-strong": "#646A74",
2167
+ "accent": "#7A9BFF",
2168
+ "accent-ink": "#0E0F12",
2169
+ "accent-hover": "#9AB3FF",
2170
+ "accent-text": "#8EA9FF",
2171
+ "inverse-bg": "#F6F7F9",
2172
+ "inverse-surface": "#FFFFFF",
2173
+ "inverse-text": "#0F1115",
2174
+ "inverse-muted": "#5B616E",
2175
+ "inverse-line": "#E6E8EC",
2176
+ "inverse-accent": "#2F5BEA",
2177
+ "inverse-accent-ink": "#FFFFFF",
2178
+ "success": "#5FD08E",
2179
+ "success-bg": "#13291C",
2180
+ "danger": "#FF8A80",
2181
+ "danger-bg": "#3A1715",
2182
+ "scrim": "rgba(0, 0, 0, 0.6)"
2183
+ }
2184
+ },
2185
+ "tint": {
2186
+ "scale": 1,
2187
+ "roles": [
2188
+ "bg",
2189
+ "surface",
2190
+ "surface-2",
2191
+ "line",
2192
+ "line-strong",
2193
+ "text",
2194
+ "text-muted",
2195
+ "inverse-bg",
2196
+ "inverse-surface",
2197
+ "inverse-text",
2198
+ "inverse-muted",
2199
+ "inverse-line"
2200
+ ]
2201
+ },
2202
+ "legacy": {
2203
+ "line-strong": {
2204
+ "value": "#C9CED6",
2205
+ "dark": "#3A3F49"
2206
+ },
2207
+ "focus-ring": {
2208
+ "value": "0 0 0 3px color-mix(in srgb, var(--iox-accent) 35%, transparent)"
2209
+ }
2210
+ },
1857
2211
  "tokens": [
1858
2212
  {
1859
2213
  "name": "bg",
1860
2214
  "tier": "semantic",
1861
2215
  "type": "color",
1862
2216
  "group": "colour",
1863
- "value": "#FFFFFF",
1864
- "dark": "#0E0F12"
2217
+ "value": "#FAFCFF",
2218
+ "dark": "#0D0F13"
1865
2219
  },
1866
2220
  {
1867
2221
  "name": "page-bg",
@@ -1890,8 +2244,8 @@ const SPEC_FLAVOR_PACKS = [
1890
2244
  "tier": "semantic",
1891
2245
  "type": "color",
1892
2246
  "group": "colour",
1893
- "value": "#F6F7F9",
1894
- "dark": "#1C1F25"
2247
+ "value": "#F3F7FF",
2248
+ "dark": "#1C1F26"
1895
2249
  },
1896
2250
  {
1897
2251
  "name": "surface-glass",
@@ -1920,7 +2274,7 @@ const SPEC_FLAVOR_PACKS = [
1920
2274
  "type": "color",
1921
2275
  "group": "colour",
1922
2276
  "value": "#0F1115",
1923
- "dark": "#F2F3F5"
2277
+ "dark": "#F0F3F9"
1924
2278
  },
1925
2279
  {
1926
2280
  "name": "text-muted",
@@ -1928,14 +2282,14 @@ const SPEC_FLAVOR_PACKS = [
1928
2282
  "type": "color",
1929
2283
  "group": "colour",
1930
2284
  "value": "#5B616E",
1931
- "dark": "#9AA0AC"
2285
+ "dark": "#99A0AE"
1932
2286
  },
1933
2287
  {
1934
2288
  "name": "line",
1935
2289
  "tier": "semantic",
1936
2290
  "type": "color",
1937
2291
  "group": "colour",
1938
- "value": "#E6E8EC",
2292
+ "value": "#E4E8F0",
1939
2293
  "dark": "#262A31"
1940
2294
  },
1941
2295
  {
@@ -1943,8 +2297,8 @@ const SPEC_FLAVOR_PACKS = [
1943
2297
  "tier": "semantic",
1944
2298
  "type": "color",
1945
2299
  "group": "colour",
1946
- "value": "#C9CED6",
1947
- "dark": "#3A3F49"
2300
+ "value": "#898F9A",
2301
+ "dark": "#646A74"
1948
2302
  },
1949
2303
  {
1950
2304
  "name": "accent",
@@ -1983,15 +2337,15 @@ const SPEC_FLAVOR_PACKS = [
1983
2337
  "tier": "semantic",
1984
2338
  "type": "color",
1985
2339
  "group": "colour",
1986
- "value": "#0F1115",
1987
- "dark": "#F6F7F9"
2340
+ "value": "#0E1117",
2341
+ "dark": "#F3F7FF"
1988
2342
  },
1989
2343
  {
1990
2344
  "name": "inverse-surface",
1991
2345
  "tier": "semantic",
1992
2346
  "type": "color",
1993
2347
  "group": "colour",
1994
- "value": "#1A1D23",
2348
+ "value": "#191D26",
1995
2349
  "dark": "#FFFFFF"
1996
2350
  },
1997
2351
  {
@@ -1999,7 +2353,7 @@ const SPEC_FLAVOR_PACKS = [
1999
2353
  "tier": "semantic",
2000
2354
  "type": "color",
2001
2355
  "group": "colour",
2002
- "value": "#F2F3F5",
2356
+ "value": "#F1F3F7",
2003
2357
  "dark": "#0F1115"
2004
2358
  },
2005
2359
  {
@@ -2007,7 +2361,7 @@ const SPEC_FLAVOR_PACKS = [
2007
2361
  "tier": "semantic",
2008
2362
  "type": "color",
2009
2363
  "group": "colour",
2010
- "value": "#A3A9B4",
2364
+ "value": "#A2A9B6",
2011
2365
  "dark": "#5B616E"
2012
2366
  },
2013
2367
  {
@@ -2016,7 +2370,7 @@ const SPEC_FLAVOR_PACKS = [
2016
2370
  "type": "color",
2017
2371
  "group": "colour",
2018
2372
  "value": "#2A2E36",
2019
- "dark": "#E6E8EC"
2373
+ "dark": "#E3E8F3"
2020
2374
  },
2021
2375
  {
2022
2376
  "name": "inverse-accent",
@@ -2334,7 +2688,7 @@ const SPEC_FLAVOR_PACKS = [
2334
2688
  "tier": "semantic",
2335
2689
  "type": "shadow",
2336
2690
  "group": "depth",
2337
- "value": "0 0 0 3px color-mix(in srgb, var(--iox-accent) 35%, transparent)"
2691
+ "value": "0 0 0 2px var(--iox-bg), 0 0 0 4px var(--iox-accent-text)"
2338
2692
  },
2339
2693
  {
2340
2694
  "name": "space-section",
@@ -3027,7 +3381,8 @@ const SPEC_FLAVOR_PACKS = [
3027
3381
  "density": "airy",
3028
3382
  "motion": "calm",
3029
3383
  "pillButtons": false,
3030
- "mode": "light"
3384
+ "mode": "light",
3385
+ "tint": "subtle"
3031
3386
  },
3032
3387
  "seed": "#7A5B36",
3033
3388
  "seeds": [
@@ -3093,13 +3448,96 @@ const SPEC_FLAVOR_PACKS = [
3093
3448
  ]
3094
3449
  }
3095
3450
  ],
3451
+ "palette": {
3452
+ "light": {
3453
+ "bg": "#F7F3EC",
3454
+ "page-bg": "var(--iox-bg)",
3455
+ "section-bg": "transparent",
3456
+ "surface": "#FBF8F3",
3457
+ "surface-2": "#EFE9DF",
3458
+ "surface-glass": "var(--iox-surface)",
3459
+ "surface-glass-strong": "var(--iox-surface)",
3460
+ "glass-border": "var(--iox-line)",
3461
+ "text": "#1F1B16",
3462
+ "text-muted": "#665D54",
3463
+ "line": "#DDD4C7",
3464
+ "line-strong": "#908574",
3465
+ "accent": "#7A5B36",
3466
+ "accent-ink": "#FBF8F3",
3467
+ "accent-hover": "#5E4527",
3468
+ "accent-text": "#7A5B36",
3469
+ "inverse-bg": "#1F1B16",
3470
+ "inverse-surface": "#2A251F",
3471
+ "inverse-text": "#EFE8DC",
3472
+ "inverse-muted": "#B3A897",
3473
+ "inverse-line": "#3A332B",
3474
+ "inverse-accent": "#C9A878",
3475
+ "inverse-accent-ink": "#1F1B16",
3476
+ "success": "#3F6B3A",
3477
+ "success-bg": "#E9EEDF",
3478
+ "danger": "#9A3324",
3479
+ "danger-bg": "#F5E3DC",
3480
+ "scrim": "rgba(31, 27, 22, 0.5)"
3481
+ },
3482
+ "dark": {
3483
+ "bg": "#14110E",
3484
+ "surface": "#1A1612",
3485
+ "surface-2": "#1D1915",
3486
+ "text": "#EFE8DC",
3487
+ "text-muted": "#A9A090",
3488
+ "line": "#2E2822",
3489
+ "line-strong": "#6D6459",
3490
+ "accent": "#C9A878",
3491
+ "accent-ink": "#14110E",
3492
+ "accent-hover": "#D8BD93",
3493
+ "accent-text": "#C9A878",
3494
+ "inverse-bg": "#EFE9DF",
3495
+ "inverse-surface": "#F7F3EC",
3496
+ "inverse-text": "#1F1B16",
3497
+ "inverse-muted": "#665D54",
3498
+ "inverse-line": "#DDD4C7",
3499
+ "inverse-accent": "#7A5B36",
3500
+ "inverse-accent-ink": "#FBF8F3",
3501
+ "success": "#A9C79A",
3502
+ "success-bg": "#1E2619",
3503
+ "danger": "#E8A08F",
3504
+ "danger-bg": "#2E1A15",
3505
+ "scrim": "rgba(0, 0, 0, 0.6)"
3506
+ }
3507
+ },
3508
+ "tint": {
3509
+ "scale": 1.2,
3510
+ "roles": [
3511
+ "bg",
3512
+ "surface",
3513
+ "surface-2",
3514
+ "line",
3515
+ "line-strong",
3516
+ "text",
3517
+ "text-muted",
3518
+ "inverse-bg",
3519
+ "inverse-surface",
3520
+ "inverse-text",
3521
+ "inverse-muted",
3522
+ "inverse-line"
3523
+ ]
3524
+ },
3525
+ "legacy": {
3526
+ "line-strong": {
3527
+ "value": "#B9AD9C",
3528
+ "dark": "#4A4137"
3529
+ },
3530
+ "focus-ring": {
3531
+ "value": "0 0 0 3px color-mix(in srgb, var(--iox-accent) 35%, transparent)"
3532
+ }
3533
+ },
3096
3534
  "tokens": [
3097
3535
  {
3098
3536
  "name": "bg",
3099
3537
  "tier": "semantic",
3100
3538
  "type": "color",
3101
3539
  "group": "colour",
3102
- "value": "#F7F3EC",
3540
+ "value": "#F6F3ED",
3103
3541
  "dark": "#14110E"
3104
3542
  },
3105
3543
  {
@@ -3121,16 +3559,16 @@ const SPEC_FLAVOR_PACKS = [
3121
3559
  "tier": "semantic",
3122
3560
  "type": "color",
3123
3561
  "group": "colour",
3124
- "value": "#FBF8F3",
3125
- "dark": "#1A1612"
3562
+ "value": "#FBF8F4",
3563
+ "dark": "#191613"
3126
3564
  },
3127
3565
  {
3128
3566
  "name": "surface-2",
3129
3567
  "tier": "semantic",
3130
3568
  "type": "color",
3131
3569
  "group": "colour",
3132
- "value": "#EFE9DF",
3133
- "dark": "#1D1915"
3570
+ "value": "#EFE9E0",
3571
+ "dark": "#1E1913"
3134
3572
  },
3135
3573
  {
3136
3574
  "name": "surface-glass",
@@ -3158,32 +3596,32 @@ const SPEC_FLAVOR_PACKS = [
3158
3596
  "tier": "semantic",
3159
3597
  "type": "color",
3160
3598
  "group": "colour",
3161
- "value": "#1F1B16",
3162
- "dark": "#EFE8DC"
3599
+ "value": "#1E1B17",
3600
+ "dark": "#EEE8DE"
3163
3601
  },
3164
3602
  {
3165
3603
  "name": "text-muted",
3166
3604
  "tier": "semantic",
3167
3605
  "type": "color",
3168
3606
  "group": "colour",
3169
- "value": "#665D54",
3170
- "dark": "#A9A090"
3607
+ "value": "#675D52",
3608
+ "dark": "#A8A092"
3171
3609
  },
3172
3610
  {
3173
3611
  "name": "line",
3174
3612
  "tier": "semantic",
3175
3613
  "type": "color",
3176
3614
  "group": "colour",
3177
- "value": "#DDD4C7",
3178
- "dark": "#2E2822"
3615
+ "value": "#DCD4C9",
3616
+ "dark": "#2D2823"
3179
3617
  },
3180
3618
  {
3181
3619
  "name": "line-strong",
3182
3620
  "tier": "semantic",
3183
3621
  "type": "color",
3184
3622
  "group": "colour",
3185
- "value": "#B9AD9C",
3186
- "dark": "#4A4137"
3623
+ "value": "#8E8577",
3624
+ "dark": "#6C645B"
3187
3625
  },
3188
3626
  {
3189
3627
  "name": "accent",
@@ -3222,40 +3660,40 @@ const SPEC_FLAVOR_PACKS = [
3222
3660
  "tier": "semantic",
3223
3661
  "type": "color",
3224
3662
  "group": "colour",
3225
- "value": "#1F1B16",
3226
- "dark": "#EFE9DF"
3663
+ "value": "#201B15",
3664
+ "dark": "#EFE9E0"
3227
3665
  },
3228
3666
  {
3229
3667
  "name": "inverse-surface",
3230
3668
  "tier": "semantic",
3231
3669
  "type": "color",
3232
3670
  "group": "colour",
3233
- "value": "#2A251F",
3234
- "dark": "#F7F3EC"
3671
+ "value": "#2B251C",
3672
+ "dark": "#FAF3E6"
3235
3673
  },
3236
3674
  {
3237
3675
  "name": "inverse-text",
3238
3676
  "tier": "semantic",
3239
3677
  "type": "color",
3240
3678
  "group": "colour",
3241
- "value": "#EFE8DC",
3242
- "dark": "#1F1B16"
3679
+ "value": "#EEE8DE",
3680
+ "dark": "#1E1B17"
3243
3681
  },
3244
3682
  {
3245
3683
  "name": "inverse-muted",
3246
3684
  "tier": "semantic",
3247
3685
  "type": "color",
3248
3686
  "group": "colour",
3249
- "value": "#B3A897",
3250
- "dark": "#665D54"
3687
+ "value": "#B1A89A",
3688
+ "dark": "#675D53"
3251
3689
  },
3252
3690
  {
3253
3691
  "name": "inverse-line",
3254
3692
  "tier": "semantic",
3255
3693
  "type": "color",
3256
3694
  "group": "colour",
3257
- "value": "#3A332B",
3258
- "dark": "#DDD4C7"
3695
+ "value": "#3A332C",
3696
+ "dark": "#DCD4C9"
3259
3697
  },
3260
3698
  {
3261
3699
  "name": "inverse-accent",
@@ -3571,7 +4009,7 @@ const SPEC_FLAVOR_PACKS = [
3571
4009
  "tier": "semantic",
3572
4010
  "type": "shadow",
3573
4011
  "group": "depth",
3574
- "value": "0 0 0 3px color-mix(in srgb, var(--iox-accent) 35%, transparent)"
4012
+ "value": "0 0 0 2px var(--iox-bg), 0 0 0 4px var(--iox-accent-text)"
3575
4013
  },
3576
4014
  {
3577
4015
  "name": "space-section",
@@ -4286,7 +4724,8 @@ const SPEC_FLAVOR_PACKS = [
4286
4724
  "density": "regular",
4287
4725
  "motion": "standard",
4288
4726
  "pillButtons": false,
4289
- "mode": "dark"
4727
+ "mode": "dark",
4728
+ "tint": "subtle"
4290
4729
  },
4291
4730
  "seed": "#6E5BFF",
4292
4731
  "seeds": [
@@ -4354,14 +4793,97 @@ const SPEC_FLAVOR_PACKS = [
4354
4793
  ]
4355
4794
  }
4356
4795
  ],
4796
+ "palette": {
4797
+ "light": {
4798
+ "bg": "#FBFBFC",
4799
+ "page-bg": "radial-gradient(60% 50% at 50% 0%, color-mix(in srgb, var(--iox-accent) 10%, transparent), transparent 70%), var(--iox-bg)",
4800
+ "section-bg": "transparent",
4801
+ "surface": "#FFFFFF",
4802
+ "surface-2": "#F3F3F6",
4803
+ "surface-glass": "var(--iox-surface)",
4804
+ "surface-glass-strong": "var(--iox-surface)",
4805
+ "glass-border": "var(--iox-line)",
4806
+ "text": "#0B0B0F",
4807
+ "text-muted": "#5E6270",
4808
+ "line": "#E4E4EA",
4809
+ "line-strong": "#878690",
4810
+ "accent": "#5B47F0",
4811
+ "accent-ink": "#FFFFFF",
4812
+ "accent-hover": "#4A36DE",
4813
+ "accent-text": "#5B47F0",
4814
+ "inverse-bg": "#08090A",
4815
+ "inverse-surface": "#111214",
4816
+ "inverse-text": "#F7F8F8",
4817
+ "inverse-muted": "#8F949D",
4818
+ "inverse-line": "rgba(255, 255, 255, 0.08)",
4819
+ "inverse-accent": "#A69BFF",
4820
+ "inverse-accent-ink": "#08090A",
4821
+ "success": "#1B6B3D",
4822
+ "success-bg": "#E7F4EC",
4823
+ "danger": "#B3261E",
4824
+ "danger-bg": "#FBE9E7",
4825
+ "scrim": "rgba(8, 9, 10, 0.55)"
4826
+ },
4827
+ "dark": {
4828
+ "bg": "#08090A",
4829
+ "page-bg": "radial-gradient(60% 50% at 50% 0%, color-mix(in srgb, var(--iox-accent) 22%, transparent), transparent 70%), var(--iox-bg)",
4830
+ "surface": "#111214",
4831
+ "surface-2": "#18191C",
4832
+ "text": "#F7F8F8",
4833
+ "text-muted": "#8F949D",
4834
+ "line": "rgba(255, 255, 255, 0.08)",
4835
+ "line-strong": "rgba(255, 255, 255, 0.34)",
4836
+ "accent": "#6E5BFF",
4837
+ "accent-hover": "#5B47F0",
4838
+ "accent-text": "#A69BFF",
4839
+ "inverse-bg": "#F7F8F8",
4840
+ "inverse-surface": "#FFFFFF",
4841
+ "inverse-text": "#0B0B0F",
4842
+ "inverse-muted": "#5E6270",
4843
+ "inverse-line": "#E4E4EA",
4844
+ "inverse-accent": "#5B47F0",
4845
+ "inverse-accent-ink": "#FFFFFF",
4846
+ "success": "#4ADE80",
4847
+ "success-bg": "#0F2418",
4848
+ "danger": "#FF7B72",
4849
+ "danger-bg": "#2D1213",
4850
+ "scrim": "rgba(0, 0, 0, 0.7)"
4851
+ }
4852
+ },
4853
+ "tint": {
4854
+ "scale": 1,
4855
+ "roles": [
4856
+ "bg",
4857
+ "surface",
4858
+ "surface-2",
4859
+ "line",
4860
+ "line-strong",
4861
+ "text",
4862
+ "text-muted",
4863
+ "inverse-bg",
4864
+ "inverse-surface",
4865
+ "inverse-text",
4866
+ "inverse-muted",
4867
+ "inverse-line"
4868
+ ]
4869
+ },
4870
+ "legacy": {
4871
+ "line-strong": {
4872
+ "value": "#C9C9D3",
4873
+ "dark": "rgba(255, 255, 255, 0.16)"
4874
+ },
4875
+ "focus-ring": {
4876
+ "value": "0 0 0 3px color-mix(in srgb, var(--iox-accent) 35%, transparent)"
4877
+ }
4878
+ },
4357
4879
  "tokens": [
4358
4880
  {
4359
4881
  "name": "bg",
4360
4882
  "tier": "semantic",
4361
4883
  "type": "color",
4362
4884
  "group": "colour",
4363
- "value": "#FBFBFC",
4364
- "dark": "#08090A"
4885
+ "value": "#FAFBFF",
4886
+ "dark": "#08090C"
4365
4887
  },
4366
4888
  {
4367
4889
  "name": "page-bg",
@@ -4384,15 +4906,15 @@ const SPEC_FLAVOR_PACKS = [
4384
4906
  "type": "color",
4385
4907
  "group": "colour",
4386
4908
  "value": "#FFFFFF",
4387
- "dark": "#111214"
4909
+ "dark": "#121214"
4388
4910
  },
4389
4911
  {
4390
4912
  "name": "surface-2",
4391
4913
  "tier": "semantic",
4392
4914
  "type": "color",
4393
4915
  "group": "colour",
4394
- "value": "#F3F3F6",
4395
- "dark": "#18191C"
4916
+ "value": "#F2F3FD",
4917
+ "dark": "#181820"
4396
4918
  },
4397
4919
  {
4398
4920
  "name": "surface-glass",
@@ -4421,7 +4943,7 @@ const SPEC_FLAVOR_PACKS = [
4421
4943
  "type": "color",
4422
4944
  "group": "colour",
4423
4945
  "value": "#0B0B0F",
4424
- "dark": "#F7F8F8"
4946
+ "dark": "#F7F7FD"
4425
4947
  },
4426
4948
  {
4427
4949
  "name": "text-muted",
@@ -4429,14 +4951,14 @@ const SPEC_FLAVOR_PACKS = [
4429
4951
  "type": "color",
4430
4952
  "group": "colour",
4431
4953
  "value": "#5E6270",
4432
- "dark": "#8F949D"
4954
+ "dark": "#8D94A2"
4433
4955
  },
4434
4956
  {
4435
4957
  "name": "line",
4436
4958
  "tier": "semantic",
4437
4959
  "type": "color",
4438
4960
  "group": "colour",
4439
- "value": "#E4E4EA",
4961
+ "value": "#E3E4ED",
4440
4962
  "dark": "rgba(255, 255, 255, 0.08)"
4441
4963
  },
4442
4964
  {
@@ -4444,8 +4966,8 @@ const SPEC_FLAVOR_PACKS = [
4444
4966
  "tier": "semantic",
4445
4967
  "type": "color",
4446
4968
  "group": "colour",
4447
- "value": "#C9C9D3",
4448
- "dark": "rgba(255, 255, 255, 0.16)"
4969
+ "value": "#878692",
4970
+ "dark": "rgba(255, 255, 255, 0.34)"
4449
4971
  },
4450
4972
  {
4451
4973
  "name": "accent",
@@ -4483,15 +5005,15 @@ const SPEC_FLAVOR_PACKS = [
4483
5005
  "tier": "semantic",
4484
5006
  "type": "color",
4485
5007
  "group": "colour",
4486
- "value": "#08090A",
4487
- "dark": "#F7F8F8"
5008
+ "value": "#08080F",
5009
+ "dark": "#F6F7FF"
4488
5010
  },
4489
5011
  {
4490
5012
  "name": "inverse-surface",
4491
5013
  "tier": "semantic",
4492
5014
  "type": "color",
4493
5015
  "group": "colour",
4494
- "value": "#111214",
5016
+ "value": "#11111A",
4495
5017
  "dark": "#FFFFFF"
4496
5018
  },
4497
5019
  {
@@ -4499,7 +5021,7 @@ const SPEC_FLAVOR_PACKS = [
4499
5021
  "tier": "semantic",
4500
5022
  "type": "color",
4501
5023
  "group": "colour",
4502
- "value": "#F7F8F8",
5024
+ "value": "#F7F7FB",
4503
5025
  "dark": "#0B0B0F"
4504
5026
  },
4505
5027
  {
@@ -4507,7 +5029,7 @@ const SPEC_FLAVOR_PACKS = [
4507
5029
  "tier": "semantic",
4508
5030
  "type": "color",
4509
5031
  "group": "colour",
4510
- "value": "#8F949D",
5032
+ "value": "#8D94A1",
4511
5033
  "dark": "#5E6270"
4512
5034
  },
4513
5035
  {
@@ -4516,7 +5038,7 @@ const SPEC_FLAVOR_PACKS = [
4516
5038
  "type": "color",
4517
5039
  "group": "colour",
4518
5040
  "value": "rgba(255, 255, 255, 0.08)",
4519
- "dark": "#E4E4EA"
5041
+ "dark": "#E3E4F0"
4520
5042
  },
4521
5043
  {
4522
5044
  "name": "inverse-accent",
@@ -4835,7 +5357,7 @@ const SPEC_FLAVOR_PACKS = [
4835
5357
  "tier": "semantic",
4836
5358
  "type": "shadow",
4837
5359
  "group": "depth",
4838
- "value": "0 0 0 3px color-mix(in srgb, var(--iox-accent) 35%, transparent)"
5360
+ "value": "0 0 0 2px var(--iox-bg), 0 0 0 4px var(--iox-accent-text)"
4839
5361
  },
4840
5362
  {
4841
5363
  "name": "space-section",
@@ -5536,7 +6058,8 @@ const SPEC_FLAVOR_PACKS = [
5536
6058
  "density": "regular",
5537
6059
  "motion": "lively",
5538
6060
  "pillButtons": true,
5539
- "mode": "light"
6061
+ "mode": "light",
6062
+ "tint": "subtle"
5540
6063
  },
5541
6064
  "seed": "#0A66E8",
5542
6065
  "seeds": [
@@ -5601,14 +6124,108 @@ const SPEC_FLAVOR_PACKS = [
5601
6124
  ]
5602
6125
  }
5603
6126
  ],
6127
+ "palette": {
6128
+ "light": {
6129
+ "bg": "#EEF1F6",
6130
+ "page-bg": "radial-gradient(40% 50% at 12% 8%, #C9D8FF 0%, transparent 70%), radial-gradient(45% 55% at 88% 18%, #F5D0E6 0%, transparent 70%), radial-gradient(55% 60% at 50% 100%, #D7F2EA 0%, transparent 70%), var(--iox-bg)",
6131
+ "section-bg": "transparent",
6132
+ "surface": "#FFFFFF",
6133
+ "surface-2": "#F5F7FA",
6134
+ "surface-glass": "rgba(255, 255, 255, 0.55)",
6135
+ "surface-glass-strong": "rgba(255, 255, 255, 0.78)",
6136
+ "glass-border": "rgba(255, 255, 255, 0.6)",
6137
+ "text": "#0B0C0F",
6138
+ "text-muted": "#545966",
6139
+ "line": "rgba(15, 23, 42, 0.10)",
6140
+ "line-strong": "rgba(15, 23, 42, 0.49)",
6141
+ "accent": "#0A66E8",
6142
+ "accent-ink": "#FFFFFF",
6143
+ "accent-hover": "#0855C4",
6144
+ "accent-text": "#0658CC",
6145
+ "inverse-bg": "#0B0C10",
6146
+ "inverse-surface": "#1A1B20",
6147
+ "inverse-text": "#F5F6F8",
6148
+ "inverse-muted": "#A3A8B3",
6149
+ "inverse-line": "rgba(255, 255, 255, 0.12)",
6150
+ "inverse-accent": "#4C9AFF",
6151
+ "inverse-accent-ink": "#0B0C10",
6152
+ "success": "#1B6B3D",
6153
+ "success-bg": "#E3F5EA",
6154
+ "danger": "#B3261E",
6155
+ "danger-bg": "#FCE8E6",
6156
+ "scrim": "rgba(15, 23, 42, 0.30)"
6157
+ },
6158
+ "dark": {
6159
+ "bg": "#0B0C10",
6160
+ "page-bg": "radial-gradient(40% 50% at 12% 8%, #1B2A5C 0%, transparent 70%), radial-gradient(45% 55% at 88% 18%, #3D1F3A 0%, transparent 70%), radial-gradient(55% 60% at 50% 100%, #0F3A33 0%, transparent 70%), var(--iox-bg)",
6161
+ "surface": "#1A1B20",
6162
+ "surface-2": "#22232A",
6163
+ "surface-glass": "rgba(28, 28, 32, 0.55)",
6164
+ "surface-glass-strong": "rgba(28, 28, 32, 0.80)",
6165
+ "glass-border": "rgba(255, 255, 255, 0.12)",
6166
+ "text": "#F5F6F8",
6167
+ "text-muted": "#A3A8B3",
6168
+ "line": "rgba(255, 255, 255, 0.10)",
6169
+ "line-strong": "rgba(255, 255, 255, 0.37)",
6170
+ "accent": "#4C9AFF",
6171
+ "accent-ink": "#0B0C10",
6172
+ "accent-hover": "#6DADFF",
6173
+ "accent-text": "#6DADFF",
6174
+ "inverse-bg": "#F5F7FA",
6175
+ "inverse-surface": "#FFFFFF",
6176
+ "inverse-text": "#0B0C0F",
6177
+ "inverse-muted": "#545966",
6178
+ "inverse-line": "rgba(15, 23, 42, 0.10)",
6179
+ "inverse-accent": "#0A66E8",
6180
+ "inverse-accent-ink": "#FFFFFF",
6181
+ "success": "#5FD08E",
6182
+ "success-bg": "#12291C",
6183
+ "danger": "#FF8A80",
6184
+ "danger-bg": "#3A1715",
6185
+ "scrim": "rgba(0, 0, 0, 0.5)"
6186
+ }
6187
+ },
6188
+ "tint": {
6189
+ "scale": 1.2,
6190
+ "roles": [
6191
+ "bg",
6192
+ "surface",
6193
+ "surface-2",
6194
+ "line",
6195
+ "line-strong",
6196
+ "text",
6197
+ "text-muted",
6198
+ "inverse-bg",
6199
+ "inverse-surface",
6200
+ "inverse-text",
6201
+ "inverse-muted",
6202
+ "inverse-line"
6203
+ ],
6204
+ "paints": [
6205
+ "page-bg"
6206
+ ]
6207
+ },
6208
+ "legacy": {
6209
+ "line-strong": {
6210
+ "value": "rgba(15, 23, 42, 0.18)",
6211
+ "dark": "rgba(255, 255, 255, 0.18)"
6212
+ },
6213
+ "accent-text": {
6214
+ "value": "#0A5BCF",
6215
+ "dark": "#6DADFF"
6216
+ },
6217
+ "focus-ring": {
6218
+ "value": "0 0 0 3px color-mix(in srgb, var(--iox-accent) 35%, transparent)"
6219
+ }
6220
+ },
5604
6221
  "tokens": [
5605
6222
  {
5606
6223
  "name": "bg",
5607
6224
  "tier": "semantic",
5608
6225
  "type": "color",
5609
6226
  "group": "colour",
5610
- "value": "#EEF1F6",
5611
- "dark": "#0B0C10"
6227
+ "value": "#EDF1F8",
6228
+ "dark": "#0A0C10"
5612
6229
  },
5613
6230
  {
5614
6231
  "name": "page-bg",
@@ -5631,15 +6248,15 @@ const SPEC_FLAVOR_PACKS = [
5631
6248
  "type": "color",
5632
6249
  "group": "colour",
5633
6250
  "value": "#FFFFFF",
5634
- "dark": "#1A1B20"
6251
+ "dark": "#191B20"
5635
6252
  },
5636
6253
  {
5637
6254
  "name": "surface-2",
5638
6255
  "tier": "semantic",
5639
6256
  "type": "color",
5640
6257
  "group": "colour",
5641
- "value": "#F5F7FA",
5642
- "dark": "#22232A"
6258
+ "value": "#F2F7FF",
6259
+ "dark": "#22232C"
5643
6260
  },
5644
6261
  {
5645
6262
  "name": "surface-glass",
@@ -5670,16 +6287,16 @@ const SPEC_FLAVOR_PACKS = [
5670
6287
  "tier": "semantic",
5671
6288
  "type": "color",
5672
6289
  "group": "colour",
5673
- "value": "#0B0C0F",
5674
- "dark": "#F5F6F8"
6290
+ "value": "#0A0C10",
6291
+ "dark": "#F2F6FD"
5675
6292
  },
5676
6293
  {
5677
6294
  "name": "text-muted",
5678
6295
  "tier": "semantic",
5679
6296
  "type": "color",
5680
6297
  "group": "colour",
5681
- "value": "#545966",
5682
- "dark": "#A3A8B3"
6298
+ "value": "#535969",
6299
+ "dark": "#A0A8B9"
5683
6300
  },
5684
6301
  {
5685
6302
  "name": "line",
@@ -5694,8 +6311,8 @@ const SPEC_FLAVOR_PACKS = [
5694
6311
  "tier": "semantic",
5695
6312
  "type": "color",
5696
6313
  "group": "colour",
5697
- "value": "rgba(15, 23, 42, 0.18)",
5698
- "dark": "rgba(255, 255, 255, 0.18)"
6314
+ "value": "rgba(15, 23, 42, 0.49)",
6315
+ "dark": "rgba(255, 255, 255, 0.37)"
5699
6316
  },
5700
6317
  {
5701
6318
  "name": "accent",
@@ -5726,7 +6343,7 @@ const SPEC_FLAVOR_PACKS = [
5726
6343
  "tier": "semantic",
5727
6344
  "type": "color",
5728
6345
  "group": "colour",
5729
- "value": "#0A5BCF",
6346
+ "value": "#0658CC",
5730
6347
  "dark": "#6DADFF"
5731
6348
  },
5732
6349
  {
@@ -5734,15 +6351,15 @@ const SPEC_FLAVOR_PACKS = [
5734
6351
  "tier": "semantic",
5735
6352
  "type": "color",
5736
6353
  "group": "colour",
5737
- "value": "#0B0C10",
5738
- "dark": "#F5F7FA"
6354
+ "value": "#080C13",
6355
+ "dark": "#F2F7FF"
5739
6356
  },
5740
6357
  {
5741
6358
  "name": "inverse-surface",
5742
6359
  "tier": "semantic",
5743
6360
  "type": "color",
5744
6361
  "group": "colour",
5745
- "value": "#1A1B20",
6362
+ "value": "#151C26",
5746
6363
  "dark": "#FFFFFF"
5747
6364
  },
5748
6365
  {
@@ -5750,16 +6367,16 @@ const SPEC_FLAVOR_PACKS = [
5750
6367
  "tier": "semantic",
5751
6368
  "type": "color",
5752
6369
  "group": "colour",
5753
- "value": "#F5F6F8",
5754
- "dark": "#0B0C0F"
6370
+ "value": "#F4F6FA",
6371
+ "dark": "#0A0C0F"
5755
6372
  },
5756
6373
  {
5757
6374
  "name": "inverse-muted",
5758
6375
  "tier": "semantic",
5759
6376
  "type": "color",
5760
6377
  "group": "colour",
5761
- "value": "#A3A8B3",
5762
- "dark": "#545966"
6378
+ "value": "#A1A8B8",
6379
+ "dark": "#545967"
5763
6380
  },
5764
6381
  {
5765
6382
  "name": "inverse-line",
@@ -6087,7 +6704,7 @@ const SPEC_FLAVOR_PACKS = [
6087
6704
  "tier": "semantic",
6088
6705
  "type": "shadow",
6089
6706
  "group": "depth",
6090
- "value": "0 0 0 3px color-mix(in srgb, var(--iox-accent) 35%, transparent)"
6707
+ "value": "0 0 0 2px var(--iox-bg), 0 0 0 4px var(--iox-accent-text)"
6091
6708
  },
6092
6709
  {
6093
6710
  "name": "space-section",
@@ -6806,7 +7423,8 @@ const SPEC_FLAVOR_PACKS = [
6806
7423
  "density": "regular",
6807
7424
  "motion": "lively",
6808
7425
  "pillButtons": true,
6809
- "mode": "light"
7426
+ "mode": "light",
7427
+ "tint": "subtle"
6810
7428
  },
6811
7429
  "seed": "#6750A4",
6812
7430
  "seeds": [
@@ -6871,13 +7489,95 @@ const SPEC_FLAVOR_PACKS = [
6871
7489
  ]
6872
7490
  }
6873
7491
  ],
7492
+ "palette": {
7493
+ "light": {
7494
+ "bg": "#FFFBFE",
7495
+ "page-bg": "var(--iox-bg)",
7496
+ "section-bg": "transparent",
7497
+ "surface": "#FFFFFF",
7498
+ "surface-2": "#F3EDF7",
7499
+ "surface-glass": "var(--iox-surface)",
7500
+ "surface-glass-strong": "var(--iox-surface)",
7501
+ "glass-border": "var(--iox-line)",
7502
+ "text": "#1D1B20",
7503
+ "text-muted": "#49454F",
7504
+ "line": "#CAC4D0",
7505
+ "line-strong": "#79747E",
7506
+ "accent": "#6750A4",
7507
+ "accent-ink": "#FFFFFF",
7508
+ "accent-hover": "#5A4491",
7509
+ "accent-text": "#6750A4",
7510
+ "inverse-bg": "#322F35",
7511
+ "inverse-surface": "#3D3A41",
7512
+ "inverse-text": "#F5EFF7",
7513
+ "inverse-muted": "#CAC4D0",
7514
+ "inverse-line": "#49454F",
7515
+ "inverse-accent": "#D0BCFF",
7516
+ "inverse-accent-ink": "#381E72",
7517
+ "success": "#1F6B3A",
7518
+ "success-bg": "#DDF3E3",
7519
+ "danger": "#B3261E",
7520
+ "danger-bg": "#F9DEDC",
7521
+ "scrim": "rgba(29, 27, 32, 0.4)"
7522
+ },
7523
+ "dark": {
7524
+ "bg": "#141218",
7525
+ "surface": "#1D1B20",
7526
+ "surface-2": "#2B2930",
7527
+ "text": "#E6E0E9",
7528
+ "text-muted": "#CAC4D0",
7529
+ "line": "#49454F",
7530
+ "line-strong": "#938F99",
7531
+ "accent": "#D0BCFF",
7532
+ "accent-ink": "#381E72",
7533
+ "accent-hover": "#DCCBFF",
7534
+ "accent-text": "#D0BCFF",
7535
+ "inverse-bg": "#E6E0E9",
7536
+ "inverse-surface": "#F3EDF7",
7537
+ "inverse-text": "#322F35",
7538
+ "inverse-muted": "#49454F",
7539
+ "inverse-line": "#CAC4D0",
7540
+ "inverse-accent": "#6750A4",
7541
+ "inverse-accent-ink": "#FFFFFF",
7542
+ "success": "#8FD9A4",
7543
+ "success-bg": "#123620",
7544
+ "danger": "#F2B8B5",
7545
+ "danger-bg": "#601410",
7546
+ "scrim": "rgba(0, 0, 0, 0.55)"
7547
+ }
7548
+ },
7549
+ "tint": {
7550
+ "scale": 1.5,
7551
+ "roles": [
7552
+ "bg",
7553
+ "surface",
7554
+ "surface-2",
7555
+ "line",
7556
+ "line-strong",
7557
+ "text",
7558
+ "text-muted",
7559
+ "inverse-bg",
7560
+ "inverse-surface",
7561
+ "inverse-text",
7562
+ "inverse-muted",
7563
+ "inverse-line"
7564
+ ]
7565
+ },
7566
+ "legacy": {
7567
+ "focus-ring": {
7568
+ "value": "0 0 0 3px color-mix(in srgb, var(--iox-accent) 35%, transparent)"
7569
+ },
7570
+ "field-border": {
7571
+ "value": "transparent"
7572
+ }
7573
+ },
6874
7574
  "tokens": [
6875
7575
  {
6876
7576
  "name": "bg",
6877
7577
  "tier": "semantic",
6878
7578
  "type": "color",
6879
7579
  "group": "colour",
6880
- "value": "#FFFBFE",
7580
+ "value": "#FCFBFF",
6881
7581
  "dark": "#141218"
6882
7582
  },
6883
7583
  {
@@ -6900,15 +7600,15 @@ const SPEC_FLAVOR_PACKS = [
6900
7600
  "type": "color",
6901
7601
  "group": "colour",
6902
7602
  "value": "#FFFFFF",
6903
- "dark": "#1D1B20"
7603
+ "dark": "#1C1B20"
6904
7604
  },
6905
7605
  {
6906
7606
  "name": "surface-2",
6907
7607
  "tier": "semantic",
6908
7608
  "type": "color",
6909
7609
  "group": "colour",
6910
- "value": "#F3EDF7",
6911
- "dark": "#2B2930"
7610
+ "value": "#F4ECFA",
7611
+ "dark": "#2C2834"
6912
7612
  },
6913
7613
  {
6914
7614
  "name": "surface-glass",
@@ -6936,7 +7636,7 @@ const SPEC_FLAVOR_PACKS = [
6936
7636
  "tier": "semantic",
6937
7637
  "type": "color",
6938
7638
  "group": "colour",
6939
- "value": "#1D1B20",
7639
+ "value": "#1C1B21",
6940
7640
  "dark": "#E6E0E9"
6941
7641
  },
6942
7642
  {
@@ -6944,8 +7644,8 @@ const SPEC_FLAVOR_PACKS = [
6944
7644
  "tier": "semantic",
6945
7645
  "type": "color",
6946
7646
  "group": "colour",
6947
- "value": "#49454F",
6948
- "dark": "#CAC4D0"
7647
+ "value": "#4B4356",
7648
+ "dark": "#CDC2D8"
6949
7649
  },
6950
7650
  {
6951
7651
  "name": "line",
@@ -6960,8 +7660,8 @@ const SPEC_FLAVOR_PACKS = [
6960
7660
  "tier": "semantic",
6961
7661
  "type": "color",
6962
7662
  "group": "colour",
6963
- "value": "#79747E",
6964
- "dark": "#938F99"
7663
+ "value": "#7B7283",
7664
+ "dark": "#958D9F"
6965
7665
  },
6966
7666
  {
6967
7667
  "name": "accent",
@@ -7000,16 +7700,16 @@ const SPEC_FLAVOR_PACKS = [
7000
7700
  "tier": "semantic",
7001
7701
  "type": "color",
7002
7702
  "group": "colour",
7003
- "value": "#322F35",
7004
- "dark": "#E6E0E9"
7703
+ "value": "#332E39",
7704
+ "dark": "#E8DFED"
7005
7705
  },
7006
7706
  {
7007
7707
  "name": "inverse-surface",
7008
7708
  "tier": "semantic",
7009
7709
  "type": "color",
7010
7710
  "group": "colour",
7011
- "value": "#3D3A41",
7012
- "dark": "#F3EDF7"
7711
+ "value": "#3F3847",
7712
+ "dark": "#F6EBFD"
7013
7713
  },
7014
7714
  {
7015
7715
  "name": "inverse-text",
@@ -7024,16 +7724,16 @@ const SPEC_FLAVOR_PACKS = [
7024
7724
  "tier": "semantic",
7025
7725
  "type": "color",
7026
7726
  "group": "colour",
7027
- "value": "#CAC4D0",
7028
- "dark": "#49454F"
7727
+ "value": "#CCC2D6",
7728
+ "dark": "#4A4355"
7029
7729
  },
7030
7730
  {
7031
7731
  "name": "inverse-line",
7032
7732
  "tier": "semantic",
7033
7733
  "type": "color",
7034
7734
  "group": "colour",
7035
- "value": "#49454F",
7036
- "dark": "#CAC4D0"
7735
+ "value": "#4A4452",
7736
+ "dark": "#CBC3D3"
7037
7737
  },
7038
7738
  {
7039
7739
  "name": "inverse-accent",
@@ -7351,7 +8051,7 @@ const SPEC_FLAVOR_PACKS = [
7351
8051
  "tier": "semantic",
7352
8052
  "type": "shadow",
7353
8053
  "group": "depth",
7354
- "value": "0 0 0 3px color-mix(in srgb, var(--iox-accent) 35%, transparent)"
8054
+ "value": "0 0 0 2px var(--iox-bg), 0 0 0 4px var(--iox-accent-text)"
7355
8055
  },
7356
8056
  {
7357
8057
  "name": "space-section",
@@ -7881,8 +8581,7 @@ const SPEC_FLAVOR_PACKS = [
7881
8581
  "tier": "component",
7882
8582
  "type": "color",
7883
8583
  "group": "components",
7884
- "value": "transparent",
7885
- "overridden": true
8584
+ "value": "var(--iox-line-strong)"
7886
8585
  },
7887
8586
  {
7888
8587
  "name": "field-border-width",
@@ -8057,7 +8756,8 @@ const SPEC_FLAVOR_PACKS = [
8057
8756
  "density": "compact",
8058
8757
  "motion": "snappy",
8059
8758
  "pillButtons": false,
8060
- "mode": "light"
8759
+ "mode": "light",
8760
+ "tint": "subtle"
8061
8761
  },
8062
8762
  "seed": "#FF5C39",
8063
8763
  "seeds": [
@@ -8126,6 +8826,77 @@ const SPEC_FLAVOR_PACKS = [
8126
8826
  ]
8127
8827
  }
8128
8828
  ],
8829
+ "palette": {
8830
+ "light": {
8831
+ "bg": "#FFF8E7",
8832
+ "page-bg": "var(--iox-bg)",
8833
+ "section-bg": "transparent",
8834
+ "surface": "#FFFFFF",
8835
+ "surface-2": "#FFD23F",
8836
+ "surface-glass": "var(--iox-surface)",
8837
+ "surface-glass-strong": "var(--iox-surface)",
8838
+ "glass-border": "var(--iox-line)",
8839
+ "text": "#0A0A0A",
8840
+ "text-muted": "#3D3D3D",
8841
+ "line": "#0A0A0A",
8842
+ "line-strong": "#0A0A0A",
8843
+ "accent": "#FF5C39",
8844
+ "accent-ink": "#0A0A0A",
8845
+ "accent-hover": "#FF7A5C",
8846
+ "accent-text": "#AD3112",
8847
+ "inverse-bg": "#0A0A0A",
8848
+ "inverse-surface": "#1E1E1E",
8849
+ "inverse-text": "#FFF8E7",
8850
+ "inverse-muted": "#C9C3B4",
8851
+ "inverse-line": "#FFF8E7",
8852
+ "inverse-accent": "#FFD23F",
8853
+ "inverse-accent-ink": "#0A0A0A",
8854
+ "success": "#0B6B3A",
8855
+ "success-bg": "#C9F2D9",
8856
+ "danger": "#B3261E",
8857
+ "danger-bg": "#FFD9D2",
8858
+ "scrim": "rgba(10, 10, 10, 0.5)"
8859
+ },
8860
+ "dark": {
8861
+ "bg": "#121212",
8862
+ "surface": "#1E1E1E",
8863
+ "surface-2": "#2A2A2A",
8864
+ "text": "#F5F5F0",
8865
+ "text-muted": "#BDBDB5",
8866
+ "line": "#F5F5F0",
8867
+ "line-strong": "#F5F5F0",
8868
+ "accent": "#FF7A5C",
8869
+ "accent-hover": "#FF9478",
8870
+ "accent-text": "#FF8A6E",
8871
+ "inverse-bg": "#FFF8E7",
8872
+ "inverse-surface": "#FFFFFF",
8873
+ "inverse-text": "#0A0A0A",
8874
+ "inverse-muted": "#3D3D3D",
8875
+ "inverse-line": "#0A0A0A",
8876
+ "inverse-accent": "#B5381B",
8877
+ "inverse-accent-ink": "#FFFFFF",
8878
+ "success": "#5FD08E",
8879
+ "success-bg": "#0F2A1A",
8880
+ "danger": "#FF8A80",
8881
+ "danger-bg": "#3A1715",
8882
+ "scrim": "rgba(0, 0, 0, 0.6)"
8883
+ }
8884
+ },
8885
+ "tint": {
8886
+ "scale": 2.4,
8887
+ "roles": [
8888
+ "bg",
8889
+ "surface",
8890
+ "inverse-text",
8891
+ "inverse-line"
8892
+ ]
8893
+ },
8894
+ "legacy": {
8895
+ "accent-text": {
8896
+ "value": "#B5381B",
8897
+ "dark": "#FF8A6E"
8898
+ }
8899
+ },
8129
8900
  "tokens": [
8130
8901
  {
8131
8902
  "name": "bg",
@@ -8133,7 +8904,7 @@ const SPEC_FLAVOR_PACKS = [
8133
8904
  "type": "color",
8134
8905
  "group": "colour",
8135
8906
  "value": "#FFF8E7",
8136
- "dark": "#121212"
8907
+ "dark": "#1A0F0C"
8137
8908
  },
8138
8909
  {
8139
8910
  "name": "page-bg",
@@ -8155,7 +8926,7 @@ const SPEC_FLAVOR_PACKS = [
8155
8926
  "type": "color",
8156
8927
  "group": "colour",
8157
8928
  "value": "#FFFFFF",
8158
- "dark": "#1E1E1E"
8929
+ "dark": "#221D1B"
8159
8930
  },
8160
8931
  {
8161
8932
  "name": "surface-2",
@@ -8246,7 +9017,7 @@ const SPEC_FLAVOR_PACKS = [
8246
9017
  "tier": "semantic",
8247
9018
  "type": "color",
8248
9019
  "group": "colour",
8249
- "value": "#B5381B",
9020
+ "value": "#AD3112",
8250
9021
  "dark": "#FF8A6E"
8251
9022
  },
8252
9023
  {
@@ -8271,7 +9042,7 @@ const SPEC_FLAVOR_PACKS = [
8271
9042
  "type": "color",
8272
9043
  "group": "colour",
8273
9044
  "value": "#FFF8E7",
8274
- "dark": "#0A0A0A"
9045
+ "dark": "#0F0807"
8275
9046
  },
8276
9047
  {
8277
9048
  "name": "inverse-muted",
@@ -8287,7 +9058,7 @@ const SPEC_FLAVOR_PACKS = [
8287
9058
  "type": "color",
8288
9059
  "group": "colour",
8289
9060
  "value": "#FFF8E7",
8290
- "dark": "#0A0A0A"
9061
+ "dark": "#170402"
8291
9062
  },
8292
9063
  {
8293
9064
  "name": "inverse-accent",
@@ -9309,64 +10080,100 @@ const SPEC_FLAVOR_PACKS = [
9309
10080
  ];
9310
10081
  const SPEC_CONTRAST = {
9311
10082
  "crisp": {
9312
- "light:text/bg": 18.9,
10083
+ "light:text/bg": 18.39,
9313
10084
  "light:text/surface": 18.9,
9314
- "light:text-muted/bg": 6.21,
10085
+ "light:text-muted/bg": 6.05,
9315
10086
  "light:text-muted/surface": 6.21,
9316
10087
  "light:accent-ink/accent": 5.52,
9317
- "light:accent-text/bg": 5.52,
9318
- "light:inverse-text/inverse-bg": 17.02,
10088
+ "light:accent-text/bg": 5.37,
10089
+ "light:inverse-text/inverse-bg": 17.01,
9319
10090
  "light:inverse-muted/inverse-bg": 8,
9320
10091
  "light:inverse-accent-ink/inverse-accent": 8.34,
9321
10092
  "light:inverse-accent/inverse-bg": 8.34,
9322
10093
  "light:success/success-bg": 5.77,
9323
10094
  "light:danger/danger-bg": 5.58,
9324
10095
  "light:accent-ink/accent-hover": 7.43,
9325
- "light:text-muted/surface-2": 5.8,
10096
+ "light:text-muted/surface-2": 5.79,
10097
+ "light:text/surface-2": 17.6,
10098
+ "light:accent-text/surface": 5.52,
10099
+ "light:accent-text/surface-2": 5.14,
10100
+ "light:inverse-text/inverse-surface": 15.18,
10101
+ "light:inverse-muted/inverse-surface": 7.14,
10102
+ "light:inverse-accent/inverse-surface": 7.44,
10103
+ "light:line-strong/bg": 3.16,
10104
+ "light:line-strong/surface": 3.25,
10105
+ "light:line-strong/surface-2": 3.03,
9326
10106
  "dark:text/bg": 17.26,
9327
- "dark:text/surface": 15.99,
10107
+ "dark:text/surface": 15.98,
9328
10108
  "dark:text-muted/bg": 7.3,
9329
10109
  "dark:text-muted/surface": 6.76,
9330
10110
  "dark:accent-ink/accent": 7.26,
9331
- "dark:accent-text/bg": 8.46,
9332
- "dark:inverse-text/inverse-bg": 17.63,
9333
- "dark:inverse-muted/inverse-bg": 5.8,
10111
+ "dark:accent-text/bg": 8.47,
10112
+ "dark:inverse-text/inverse-bg": 17.6,
10113
+ "dark:inverse-muted/inverse-bg": 5.79,
9334
10114
  "dark:inverse-accent-ink/inverse-accent": 5.52,
9335
- "dark:inverse-accent/inverse-bg": 5.15,
10115
+ "dark:inverse-accent/inverse-bg": 5.14,
9336
10116
  "dark:success/success-bg": 8,
9337
10117
  "dark:danger/danger-bg": 7,
9338
10118
  "dark:accent-ink/accent-hover": 9.37,
9339
- "dark:text-muted/surface-2": 6.29
10119
+ "dark:text-muted/surface-2": 6.28,
10120
+ "dark:text/surface-2": 14.84,
10121
+ "dark:accent-text/surface": 7.84,
10122
+ "dark:accent-text/surface-2": 7.28,
10123
+ "dark:inverse-text/inverse-surface": 18.9,
10124
+ "dark:inverse-muted/inverse-surface": 6.21,
10125
+ "dark:inverse-accent/inverse-surface": 5.52,
10126
+ "dark:line-strong/bg": 3.52,
10127
+ "dark:line-strong/surface": 3.26,
10128
+ "dark:line-strong/surface-2": 3.03
9340
10129
  },
9341
10130
  "linen": {
9342
- "light:text/bg": 15.48,
9343
- "light:text/surface": 16.16,
9344
- "light:text-muted/bg": 5.83,
10131
+ "light:text/bg": 15.49,
10132
+ "light:text/surface": 16.2,
10133
+ "light:text-muted/bg": 5.81,
9345
10134
  "light:text-muted/surface": 6.08,
9346
10135
  "light:accent-ink/accent": 5.87,
9347
- "light:accent-text/bg": 5.62,
9348
- "light:inverse-text/inverse-bg": 14.06,
9349
- "light:inverse-muted/inverse-bg": 7.31,
10136
+ "light:accent-text/bg": 5.61,
10137
+ "light:inverse-text/inverse-bg": 14.02,
10138
+ "light:inverse-muted/inverse-bg": 7.27,
9350
10139
  "light:inverse-accent-ink/inverse-accent": 7.63,
9351
- "light:inverse-accent/inverse-bg": 7.63,
10140
+ "light:inverse-accent/inverse-bg": 7.61,
9352
10141
  "light:success/success-bg": 5.26,
9353
10142
  "light:danger/danger-bg": 5.88,
9354
10143
  "light:accent-ink/accent-hover": 8.41,
9355
- "light:text-muted/surface-2": 5.34,
9356
- "dark:text/bg": 15.45,
9357
- "dark:text/surface": 14.77,
9358
- "dark:text-muted/bg": 7.27,
9359
- "dark:text-muted/surface": 6.95,
10144
+ "light:text-muted/surface-2": 5.33,
10145
+ "light:text/surface-2": 14.21,
10146
+ "light:accent-text/surface": 5.87,
10147
+ "light:accent-text/surface-2": 5.15,
10148
+ "light:inverse-text/inverse-surface": 12.45,
10149
+ "light:inverse-muted/inverse-surface": 6.46,
10150
+ "light:inverse-accent/inverse-surface": 6.76,
10151
+ "light:line-strong/bg": 3.29,
10152
+ "light:line-strong/surface": 3.44,
10153
+ "light:line-strong/surface-2": 3.02,
10154
+ "dark:text/bg": 15.44,
10155
+ "dark:text/surface": 14.79,
10156
+ "dark:text-muted/bg": 7.26,
10157
+ "dark:text-muted/surface": 6.96,
9360
10158
  "dark:accent-ink/accent": 8.38,
9361
10159
  "dark:accent-text/bg": 8.38,
9362
- "dark:inverse-text/inverse-bg": 14.18,
9363
- "dark:inverse-muted/inverse-bg": 5.34,
10160
+ "dark:inverse-text/inverse-bg": 14.21,
10161
+ "dark:inverse-muted/inverse-bg": 5.33,
9364
10162
  "dark:inverse-accent-ink/inverse-accent": 5.87,
9365
10163
  "dark:inverse-accent/inverse-bg": 5.15,
9366
10164
  "dark:success/success-bg": 8.41,
9367
10165
  "dark:danger/danger-bg": 7.73,
9368
10166
  "dark:accent-ink/accent-hover": 10.41,
9369
- "dark:text-muted/surface-2": 6.75
10167
+ "dark:text-muted/surface-2": 6.74,
10168
+ "dark:text/surface-2": 14.32,
10169
+ "dark:accent-text/surface": 8.03,
10170
+ "dark:accent-text/surface-2": 7.77,
10171
+ "dark:inverse-text/inverse-surface": 15.54,
10172
+ "dark:inverse-muted/inverse-surface": 5.82,
10173
+ "dark:inverse-accent/inverse-surface": 5.63,
10174
+ "dark:line-strong/bg": 3.24,
10175
+ "dark:line-strong/surface": 3.1,
10176
+ "dark:line-strong/surface-2": 3
9370
10177
  },
9371
10178
  "midnight": {
9372
10179
  "light:text/bg": 19,
@@ -9375,88 +10182,133 @@ const SPEC_CONTRAST = {
9375
10182
  "light:text-muted/surface": 6.07,
9376
10183
  "light:accent-ink/accent": 5.83,
9377
10184
  "light:accent-text/bg": 5.63,
9378
- "light:inverse-text/inverse-bg": 18.73,
10185
+ "light:inverse-text/inverse-bg": 18.68,
9379
10186
  "light:inverse-muted/inverse-bg": 6.54,
9380
10187
  "light:inverse-accent-ink/inverse-accent": 8.31,
9381
- "light:inverse-accent/inverse-bg": 8.31,
10188
+ "light:inverse-accent/inverse-bg": 8.32,
9382
10189
  "light:success/success-bg": 5.77,
9383
10190
  "light:danger/danger-bg": 5.58,
9384
10191
  "light:accent-ink/accent-hover": 7.31,
9385
- "light:text-muted/surface-2": 5.49,
9386
- "dark:text/bg": 18.73,
9387
- "dark:text/surface": 17.62,
9388
- "dark:text-muted/bg": 6.54,
9389
- "dark:text-muted/surface": 6.15,
10192
+ "light:text-muted/surface-2": 5.5,
10193
+ "light:text/surface-2": 17.79,
10194
+ "light:accent-text/surface": 5.83,
10195
+ "light:accent-text/surface-2": 5.28,
10196
+ "light:inverse-text/inverse-surface": 17.56,
10197
+ "light:inverse-muted/inverse-surface": 6.15,
10198
+ "light:inverse-accent/inverse-surface": 7.82,
10199
+ "light:line-strong/bg": 3.47,
10200
+ "light:line-strong/surface": 3.59,
10201
+ "light:line-strong/surface-2": 3.25,
10202
+ "dark:text/bg": 18.66,
10203
+ "dark:text/surface": 17.53,
10204
+ "dark:text-muted/bg": 6.53,
10205
+ "dark:text-muted/surface": 6.14,
9390
10206
  "dark:accent-ink/accent": 4.56,
9391
- "dark:accent-text/bg": 8.31,
9392
- "dark:inverse-text/inverse-bg": 18.46,
9393
- "dark:inverse-muted/inverse-bg": 5.71,
10207
+ "dark:accent-text/bg": 8.3,
10208
+ "dark:inverse-text/inverse-bg": 18.4,
10209
+ "dark:inverse-muted/inverse-bg": 5.69,
9394
10210
  "dark:inverse-accent-ink/inverse-accent": 5.83,
9395
- "dark:inverse-accent/inverse-bg": 5.48,
10211
+ "dark:inverse-accent/inverse-bg": 5.46,
9396
10212
  "dark:success/success-bg": 9.37,
9397
10213
  "dark:danger/danger-bg": 6.9,
9398
10214
  "dark:accent-ink/accent-hover": 5.83,
9399
- "dark:text-muted/surface-2": 5.77
10215
+ "dark:text-muted/surface-2": 5.79,
10216
+ "dark:text/surface-2": 16.53,
10217
+ "dark:accent-text/surface": 7.8,
10218
+ "dark:accent-text/surface-2": 7.35,
10219
+ "dark:inverse-text/inverse-surface": 19.64,
10220
+ "dark:inverse-muted/inverse-surface": 6.07,
10221
+ "dark:inverse-accent/inverse-surface": 5.83
9400
10222
  },
9401
10223
  "glass": {
9402
- "light:text/bg": 17.27,
9403
- "light:text/surface": 19.56,
9404
- "light:text-muted/bg": 6.19,
9405
- "light:text-muted/surface": 7.01,
10224
+ "light:text/bg": 17.28,
10225
+ "light:text/surface": 19.57,
10226
+ "light:text-muted/bg": 6.18,
10227
+ "light:text-muted/surface": 7,
9406
10228
  "light:accent-ink/accent": 5.15,
9407
- "light:accent-text/bg": 5.44,
9408
- "light:inverse-text/inverse-bg": 18.08,
9409
- "light:inverse-muted/inverse-bg": 8.2,
10229
+ "light:accent-text/bg": 5.66,
10230
+ "light:inverse-text/inverse-bg": 18.1,
10231
+ "light:inverse-muted/inverse-bg": 8.21,
9410
10232
  "light:inverse-accent-ink/inverse-accent": 6.86,
9411
- "light:inverse-accent/inverse-bg": 6.86,
10233
+ "light:inverse-accent/inverse-bg": 6.88,
9412
10234
  "light:success/success-bg": 5.76,
9413
10235
  "light:danger/danger-bg": 5.55,
9414
10236
  "light:accent-ink/accent-hover": 6.76,
9415
- "light:text-muted/surface-2": 6.53,
9416
- "dark:text/bg": 18.08,
10237
+ "light:text-muted/surface-2": 6.51,
10238
+ "light:text/surface-2": 18.2,
10239
+ "light:accent-text/surface": 6.41,
10240
+ "light:accent-text/surface-2": 5.96,
10241
+ "light:inverse-text/inverse-surface": 15.83,
10242
+ "light:inverse-muted/inverse-surface": 7.18,
10243
+ "light:inverse-accent/inverse-surface": 6.01,
10244
+ "dark:text/bg": 18.06,
9417
10245
  "dark:text/surface": 15.9,
9418
10246
  "dark:text-muted/bg": 8.2,
9419
- "dark:text-muted/surface": 7.21,
10247
+ "dark:text-muted/surface": 7.22,
9420
10248
  "dark:accent-ink/accent": 6.86,
9421
- "dark:accent-text/bg": 8.44,
9422
- "dark:inverse-text/inverse-bg": 18.22,
9423
- "dark:inverse-muted/inverse-bg": 6.53,
10249
+ "dark:accent-text/bg": 8.45,
10250
+ "dark:inverse-text/inverse-bg": 18.21,
10251
+ "dark:inverse-muted/inverse-bg": 6.5,
9424
10252
  "dark:inverse-accent-ink/inverse-accent": 5.15,
9425
- "dark:inverse-accent/inverse-bg": 4.8,
10253
+ "dark:inverse-accent/inverse-bg": 4.79,
9426
10254
  "dark:success/success-bg": 8.02,
9427
10255
  "dark:danger/danger-bg": 7,
9428
10256
  "dark:accent-ink/accent-hover": 8.44,
9429
- "dark:text-muted/surface-2": 6.56
10257
+ "dark:text-muted/surface-2": 6.54,
10258
+ "dark:text/surface-2": 14.41,
10259
+ "dark:accent-text/surface": 7.44,
10260
+ "dark:accent-text/surface-2": 6.75,
10261
+ "dark:inverse-text/inverse-surface": 19.58,
10262
+ "dark:inverse-muted/inverse-surface": 7,
10263
+ "dark:inverse-accent/inverse-surface": 5.15
9430
10264
  },
9431
10265
  "bloom": {
9432
- "light:text/bg": 16.65,
9433
- "light:text/surface": 17.07,
10266
+ "light:text/bg": 16.6,
10267
+ "light:text/surface": 17.1,
9434
10268
  "light:text-muted/bg": 9.11,
9435
- "light:text-muted/surface": 9.34,
10269
+ "light:text-muted/surface": 9.39,
9436
10270
  "light:accent-ink/accent": 6.44,
9437
- "light:accent-text/bg": 6.28,
9438
- "light:inverse-text/inverse-bg": 11.65,
9439
- "light:inverse-muted/inverse-bg": 7.73,
10271
+ "light:accent-text/bg": 6.25,
10272
+ "light:inverse-text/inverse-bg": 11.68,
10273
+ "light:inverse-muted/inverse-bg": 7.7,
9440
10274
  "light:inverse-accent-ink/inverse-accent": 7.71,
9441
- "light:inverse-accent/inverse-bg": 7.73,
10275
+ "light:inverse-accent/inverse-bg": 7.74,
9442
10276
  "light:success/success-bg": 5.59,
9443
10277
  "light:danger/danger-bg": 5.14,
9444
10278
  "light:accent-ink/accent-hover": 7.86,
9445
- "light:text-muted/surface-2": 8.13,
10279
+ "light:text-muted/surface-2": 8.15,
10280
+ "light:text/surface-2": 14.84,
10281
+ "light:accent-text/surface": 6.44,
10282
+ "light:accent-text/surface-2": 5.59,
10283
+ "light:inverse-text/inverse-surface": 9.94,
10284
+ "light:inverse-muted/inverse-surface": 6.56,
10285
+ "light:inverse-accent/inverse-surface": 6.59,
10286
+ "light:line-strong/bg": 4.45,
10287
+ "light:line-strong/surface": 4.59,
10288
+ "light:line-strong/surface-2": 3.98,
9446
10289
  "dark:text/bg": 14.35,
9447
- "dark:text/surface": 13.17,
9448
- "dark:text-muted/bg": 10.91,
9449
- "dark:text-muted/surface": 10.02,
10290
+ "dark:text/surface": 13.21,
10291
+ "dark:text-muted/bg": 10.89,
10292
+ "dark:text-muted/surface": 10.03,
9450
10293
  "dark:accent-ink/accent": 7.71,
9451
10294
  "dark:accent-text/bg": 10.91,
9452
10295
  "dark:inverse-text/inverse-bg": 10.17,
9453
- "dark:inverse-muted/inverse-bg": 7.21,
10296
+ "dark:inverse-muted/inverse-bg": 7.28,
9454
10297
  "dark:inverse-accent-ink/inverse-accent": 6.44,
9455
10298
  "dark:inverse-accent/inverse-bg": 4.97,
9456
10299
  "dark:success/success-bg": 8.02,
9457
10300
  "dark:danger/danger-bg": 7.66,
9458
10301
  "dark:accent-ink/accent-hover": 8.79,
9459
- "dark:text-muted/surface-2": 8.42
10302
+ "dark:text-muted/surface-2": 8.43,
10303
+ "dark:text/surface-2": 11.1,
10304
+ "dark:accent-text/surface": 10.04,
10305
+ "dark:accent-text/surface-2": 8.44,
10306
+ "dark:inverse-text/inverse-surface": 11.43,
10307
+ "dark:inverse-muted/inverse-surface": 8.19,
10308
+ "dark:inverse-accent/inverse-surface": 5.59,
10309
+ "dark:line-strong/bg": 5.83,
10310
+ "dark:line-strong/surface": 5.37,
10311
+ "dark:line-strong/surface-2": 4.51
9460
10312
  },
9461
10313
  "pop": {
9462
10314
  "light:text/bg": 18.7,
@@ -9464,7 +10316,7 @@ const SPEC_CONTRAST = {
9464
10316
  "light:text-muted/bg": 10.26,
9465
10317
  "light:text-muted/surface": 10.86,
9466
10318
  "light:accent-ink/accent": 6.45,
9467
- "light:accent-text/bg": 5.59,
10319
+ "light:accent-text/bg": 6.15,
9468
10320
  "light:inverse-text/inverse-bg": 18.7,
9469
10321
  "light:inverse-muted/inverse-bg": 11.26,
9470
10322
  "light:inverse-accent-ink/inverse-accent": 13.71,
@@ -9473,20 +10325,38 @@ const SPEC_CONTRAST = {
9473
10325
  "light:danger/danger-bg": 5.01,
9474
10326
  "light:accent-ink/accent-hover": 7.72,
9475
10327
  "light:text-muted/surface-2": 7.52,
9476
- "dark:text/bg": 17.13,
10328
+ "light:text/surface-2": 13.71,
10329
+ "light:accent-text/surface": 6.51,
10330
+ "light:accent-text/surface-2": 4.51,
10331
+ "light:inverse-text/inverse-surface": 15.74,
10332
+ "light:inverse-muted/inverse-surface": 9.49,
10333
+ "light:inverse-accent/inverse-surface": 11.54,
10334
+ "light:line-strong/bg": 18.7,
10335
+ "light:line-strong/surface": 19.8,
10336
+ "light:line-strong/surface-2": 13.71,
10337
+ "dark:text/bg": 17.18,
9477
10338
  "dark:text/surface": 15.24,
9478
- "dark:text-muted/bg": 9.91,
10339
+ "dark:text-muted/bg": 9.94,
9479
10340
  "dark:text-muted/surface": 8.82,
9480
10341
  "dark:accent-ink/accent": 7.72,
9481
- "dark:accent-text/bg": 8.13,
9482
- "dark:inverse-text/inverse-bg": 18.7,
10342
+ "dark:accent-text/bg": 8.15,
10343
+ "dark:inverse-text/inverse-bg": 18.74,
9483
10344
  "dark:inverse-muted/inverse-bg": 10.26,
9484
10345
  "dark:inverse-accent-ink/inverse-accent": 5.92,
9485
10346
  "dark:inverse-accent/inverse-bg": 5.59,
9486
10347
  "dark:success/success-bg": 7.98,
9487
10348
  "dark:danger/danger-bg": 7,
9488
10349
  "dark:accent-ink/accent-hover": 9.2,
9489
- "dark:text-muted/surface-2": 7.59
10350
+ "dark:text-muted/surface-2": 7.59,
10351
+ "dark:text/surface-2": 13.12,
10352
+ "dark:accent-text/surface": 7.23,
10353
+ "dark:accent-text/surface-2": 6.23,
10354
+ "dark:inverse-text/inverse-surface": 19.85,
10355
+ "dark:inverse-muted/inverse-surface": 10.86,
10356
+ "dark:inverse-accent/inverse-surface": 5.92,
10357
+ "dark:line-strong/bg": 17.18,
10358
+ "dark:line-strong/surface": 15.24,
10359
+ "dark:line-strong/surface-2": 13.12
9490
10360
  }
9491
10361
  };
9492
10362
  const SPEC_TIER_IDS = ["semantic", "component"];
@@ -9494,6 +10364,9 @@ const SPEC_TIER_IDS = ["semantic", "component"];
9494
10364
  const DESIGN_TOKEN_TYPES = SPEC_TOKEN_TYPES;
9495
10365
  const DESIGN_TOKEN_TIERS = SPEC_TIER_IDS;
9496
10366
  const DESIGN_TOKEN_GROUPS = ['colour', 'type', 'shape', 'depth', 'space', 'motion', 'components'];
10367
+ const TINT_IDS = Object.keys(SPEC_AXES.tints);
10368
+ /** What a studio that stored its look BEFORE the tint existed wears: exactly the look's own palette. */
10369
+ const PRE_TINT_DEFAULT = 'neutral';
9497
10370
  /** The spec's flavors, typed. Assignment here is the compile-time proof that the generated
9498
10371
  * data fits `FlavorPackV2`. */
9499
10372
  const SPEC_FLAVORS = SPEC_FLAVOR_PACKS;
@@ -9615,7 +10488,7 @@ const REDUCED_MOTION_OVERRIDES = SPEC_A11Y.reducedMotion;
9615
10488
  /** What `prefers-reduced-transparency: reduce` makes solid — the contract's `a11y.reducedTransparency`. */
9616
10489
  const REDUCED_TRANSPARENCY_OVERRIDES = SPEC_A11Y.reducedTransparency;
9617
10490
  const ROOT = ':root';
9618
- const DEFAULT_SCHEME = 'default';
10491
+ const DEFAULT_SCHEME$1 = 'default';
9619
10492
  const REFERENCE = 'var(';
9620
10493
  const MEDIA_DARK = '(prefers-color-scheme: dark)';
9621
10494
  const ACCESSIBILITY_MEDIA = [
@@ -9637,7 +10510,7 @@ const media = (query, rules) => {
9637
10510
  };
9638
10511
  const schemeSelector = (id, scope) => scope ? `${scope} .iox-scheme-${id}` : `.iox-scheme-${id}`;
9639
10512
  const nonDefaultSchemes = () => Object.entries(SPEC_SCHEMES)
9640
- .filter(([id]) => id !== DEFAULT_SCHEME)
10513
+ .filter(([id]) => id !== DEFAULT_SCHEME$1)
9641
10514
  .map(([id, scheme]) => [id, scheme.set]);
9642
10515
  /** `{ 'iox-brand': '#2f6f62', … }` — the builder registry's input shape for base values. */
9643
10516
  function tokensToVarMap(tokens) {
@@ -9656,8 +10529,8 @@ function tokensToDarkVarMap(tokens) {
9656
10529
  }
9657
10530
  return map;
9658
10531
  }
9659
- const TOKEN_REF = /var\(\s*--iox-([\w-]+)\s*(?:,([^()]*))?\)/g;
9660
- const PLACEHOLDER = /\{\{\s*([\w-]+)\s*\}\}/g;
10532
+ const TOKEN_REF$1 = /var\(\s*--iox-([\w-]+)\s*(?:,([^()]*))?\)/g;
10533
+ const PLACEHOLDER = /\{\{\s*(~?)([\w-]+)\s*\}\}/g;
9661
10534
  const LIGHT = 'light';
9662
10535
  const DARK = 'dark';
9663
10536
  const modeValue = (t, mode) => (mode === DARK ? darkOf(t) ?? t.value : t.value);
@@ -9683,7 +10556,7 @@ function resolveTokenValues(tokens, mode = LIGHT) {
9683
10556
  if (value === undefined || trail.has(name))
9684
10557
  return null;
9685
10558
  const next = new Set(trail).add(name);
9686
- return value.replace(TOKEN_REF, (ref, inner, fallback) => resolve(inner, next) ?? (fallback !== undefined ? fallback.trim() : ref));
10559
+ return value.replace(TOKEN_REF$1, (ref, inner, fallback) => resolve(inner, next) ?? (fallback !== undefined ? fallback.trim() : ref));
9687
10560
  };
9688
10561
  for (const name of raw.keys()) {
9689
10562
  const value = resolve(name, new Set());
@@ -9692,6 +10565,22 @@ function resolveTokenValues(tokens, mode = LIGHT) {
9692
10565
  }
9693
10566
  return out;
9694
10567
  }
10568
+ /**
10569
+ * Every token's value INSIDE a section wearing `schemeId`, in one mode — what CSS computes there: the
10570
+ * scheme's overrides (`{{token}}` / `{{~token}}` placeholders substituted from the root), every other
10571
+ * row as declared, and `var()` references resolved within the section (the §3c re-declaration rule
10572
+ * makes that the section's own resolution). `default` (or an unknown id) is the root.
10573
+ */
10574
+ function resolveSchemeTokenValues(tokens, mode, schemeId) {
10575
+ const rows = usableTokens(tokens);
10576
+ const set = schemeId === DEFAULT_SCHEME$1 ? undefined : SPEC_SCHEMES[schemeId]?.set;
10577
+ if (!set)
10578
+ return resolveTokenValues(rows, mode);
10579
+ const root = resolveTokenValues(rows, mode);
10580
+ const other = resolveTokenValues(rows, mode === DARK ? LIGHT : DARK);
10581
+ const overrides = new Map(schemeEntries(set, root, other));
10582
+ return resolveTokenValues(rows.map(t => ({ name: t.name, value: overrides.get(t.name) ?? modeValue(t, mode) })), LIGHT);
10583
+ }
9695
10584
  /**
9696
10585
  * `value` with every `var(--iox-…)` replaced by that token's resolved root value in `mode` — what
9697
10586
  * the Style panel's Detach writes, so the node keeps exactly what it showed as a literal. An unknown
@@ -9699,21 +10588,24 @@ function resolveTokenValues(tokens, mode = LIGHT) {
9699
10588
  */
9700
10589
  function resolveTokenReferences(value, tokens, mode = LIGHT) {
9701
10590
  const resolved = resolveTokenValues(tokens, mode);
9702
- return value.replace(TOKEN_REF, (ref, name, fallback) => resolved[name] ?? (fallback !== undefined ? fallback.trim() : ref));
10591
+ return value.replace(TOKEN_REF$1, (ref, name, fallback) => resolved[name] ?? (fallback !== undefined ? fallback.trim() : ref));
9703
10592
  }
9704
- /** A scheme value with its `{{token}}` placeholders replaced by resolved root values — or null
9705
- * when a placeholder names a token the set does not have (the declaration is then omitted). */
9706
- function substitute(template, resolved) {
10593
+ /** A scheme value with its placeholders replaced — `{{token}}` by the root's resolved value in this
10594
+ * mode, `{{~token}}` by its value in the OTHER mode (an inverse section is the other mode's ground,
10595
+ * DS9) — or null when a placeholder names a token the set does not have (the declaration is then
10596
+ * omitted). */
10597
+ function substitute(template, resolved, opposite) {
9707
10598
  let missing = false;
9708
- const value = template.replace(PLACEHOLDER, (_, name) => {
9709
- if (!(name in resolved))
10599
+ const value = template.replace(PLACEHOLDER, (_, tilde, name) => {
10600
+ const from = tilde ? opposite : resolved;
10601
+ if (!(name in from))
9710
10602
  missing = true;
9711
- return resolved[name] ?? '';
10603
+ return from[name] ?? '';
9712
10604
  });
9713
10605
  return missing ? null : value;
9714
10606
  }
9715
- const schemeEntries = (set, resolved) => Object.entries(set)
9716
- .map(([name, template]) => [name, substitute(template, resolved)])
10607
+ const schemeEntries = (set, resolved, opposite) => Object.entries(set)
10608
+ .map(([name, template]) => [name, substitute(template, resolved, opposite)])
9717
10609
  .filter((e) => e[1] !== null);
9718
10610
  const hasPlaceholder = (value) => value.includes('{{');
9719
10611
  /**
@@ -9729,13 +10621,14 @@ const hasPlaceholder = (value) => value.includes('{{');
9729
10621
  * and CSS makes both invalid. The contract writes `{{accent}}` instead — the token's ROOT value,
9730
10622
  * resolved here at compile time (and again from dark values for the dark twin).
9731
10623
  */
9732
- function compileSchemeCss(tokens, scope) {
10624
+ function compileSchemeCss(tokens, scope, opposite) {
9733
10625
  const rows = usableTokens(tokens);
9734
10626
  if (!rows.length)
9735
10627
  return '';
9736
10628
  const resolved = resolveTokenValues(rows, LIGHT);
10629
+ const other = opposite ?? resolveTokenValues(rows, DARK);
9737
10630
  return nonDefaultSchemes().map(([id, set]) => rule(schemeSelector(id, scope), [
9738
- ...schemeEntries(set, resolved),
10631
+ ...schemeEntries(set, resolved, other),
9739
10632
  ...rows.filter(t => !(t.name in set) && t.value.includes(REFERENCE))
9740
10633
  .map((t) => [t.name, t.value]),
9741
10634
  ])).filter(Boolean).join('\n');
@@ -9751,9 +10644,9 @@ function darkSchemeRules(rows, scope) {
9751
10644
  });
9752
10645
  return nonDefaultSchemes().map(([id, set]) => {
9753
10646
  const swapped = Object.fromEntries(Object.entries(set).filter(([, v]) => hasPlaceholder(v)));
9754
- const lightSwap = new Map(schemeEntries(swapped, light));
10647
+ const lightSwap = new Map(schemeEntries(swapped, light, dark));
9755
10648
  return rule(schemeSelector(id, scope), [
9756
- ...schemeEntries(swapped, dark).filter(([name, value]) => lightSwap.get(name) !== value),
10649
+ ...schemeEntries(swapped, dark, light).filter(([name, value]) => lightSwap.get(name) !== value),
9757
10650
  ...redeclared.filter(t => !(t.name in set)).map((t) => [t.name, darkOf(t)]),
9758
10651
  ], ' ');
9759
10652
  });
@@ -9763,15 +10656,18 @@ function presentOverrides(rows, overrides, onlyWithDark) {
9763
10656
  }
9764
10657
  /** The token CSS as the two halves a renderer places around its node rules. */
9765
10658
  function compileTokenCssBlocks(tokens, opts = {}) {
9766
- const rows = rowsForMode(usableTokens(tokens), opts.mode);
10659
+ const all = usableTokens(tokens);
10660
+ const rows = rowsForMode(all, opts.mode);
9767
10661
  const root = opts.scope ?? ROOT;
10662
+ // A forced mode flattens the rows to ONE mode; a `{{~token}}` still reads the other mode's value.
10663
+ const opposite = resolveTokenValues(all, opts.mode === DARK ? LIGHT : DARK);
9768
10664
  const present = new Set(rows.map(t => t.name));
9769
10665
  const unset = opts.isolate
9770
10666
  ? [...specTokenNames()].filter(name => !present.has(name)).map((name) => [name, 'initial'])
9771
10667
  : [];
9772
10668
  const base = [
9773
10669
  rule(root, [...unset, ...rows.map((t) => [t.name, t.value])]),
9774
- compileSchemeCss(rows, opts.scope),
10670
+ compileSchemeCss(rows, opts.scope, opposite),
9775
10671
  ...ACCESSIBILITY_MEDIA.map(({ query, overrides }) => media(query, [rule(root, presentOverrides(rows, overrides, false), ' ')])),
9776
10672
  ].filter(Boolean).join('\n');
9777
10673
  const darkRows = rows.map((t) => [t.name, darkOf(t)])
@@ -10280,12 +11176,12 @@ const COLOR_SCHEME_TRAIT = 'colorScheme';
10280
11176
  const COLOR_SCHEME_TYPES = ['Section', 'Container', 'LinkedContainer'];
10281
11177
  /** Every scheme in contract order, with the contract's label (Default · Subtle · Inverse · Brand). */
10282
11178
  const COLOR_SCHEMES = Object.keys(SPEC_SCHEMES).map(id => ({ id, label: SPEC_SCHEMES[id].label }));
10283
- const SCHEME_IDS = new Set(Object.keys(SPEC_SCHEMES));
11179
+ const SCHEME_IDS$1 = new Set(Object.keys(SPEC_SCHEMES));
10284
11180
  const SCHEME_PREFIX = 'iox-scheme-';
10285
11181
  const MARKER_PREFIX = `${ELEMENT_STYLE_MARKER_CLASS}-`;
10286
11182
  /** `iox-scheme-<id>` for a known NON-default scheme, else null — an unknown id never reaches a class attribute. */
10287
11183
  function colorSchemeClass(id) {
10288
- return typeof id === 'string' && id !== ColorScheme.Default && SCHEME_IDS.has(id) ? `${SCHEME_PREFIX}${id}` : null;
11184
+ return typeof id === 'string' && id !== ColorScheme.Default && SCHEME_IDS$1.has(id) ? `${SCHEME_PREFIX}${id}` : null;
10289
11185
  }
10290
11186
  /** A node's `colorScheme`, from `props` (serialized) or its trait (builder). */
10291
11187
  function colorSchemeOf(node) {
@@ -10410,7 +11306,8 @@ function oklabToRgb(c) {
10410
11306
  b: linearToSrgb(-0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s),
10411
11307
  };
10412
11308
  }
10413
- const inGamut = (c) => [c.r, c.g, c.b].every(v => v >= -1e-6 && v <= 1 + 1e-6);
11309
+ const inSrgbGamut = (c) => [c.r, c.g, c.b].every(v => v >= -1e-6 && v <= 1 + 1e-6);
11310
+ const inGamut = inSrgbGamut;
10414
11311
  /** The OKLab colour at (L, hue, chroma), chroma reduced until it fits sRGB. */
10415
11312
  function atLightness(L, hueA, hueB, chroma) {
10416
11313
  const len = Math.hypot(hueA, hueB) || 1;
@@ -10476,7 +11373,7 @@ const RAMP_STEPS = [
10476
11373
  { step: 900, L: 0.27, chromaScale: 0.62 },
10477
11374
  ];
10478
11375
  const BLACK = { r: 0, g: 0, b: 0 };
10479
- const WHITE = { r: 1, g: 1, b: 1 };
11376
+ const WHITE$1 = { r: 1, g: 1, b: 1 };
10480
11377
  /** Snap to the 8-bit hex the token will actually carry — contrast is judged on WHAT SHIPS.
10481
11378
  * (The first version searched in float space and hex rounding landed 6.9596 where 7 was owed.) */
10482
11379
  const quant = (c) => parseHexColor(toHexColor(c));
@@ -10529,12 +11426,12 @@ function deriveBrandTokens(seed, pack) {
10529
11426
  // 2 — brandInk on brand-500, nudging 500 (within its neighbours) when neither ink clears 4.5
10530
11427
  let five = ramp.find(r => r.step === 500);
10531
11428
  five.rgb = quant(five.rgb);
10532
- const inkFor = (bg) => (wcagContrastRatio(WHITE, bg) >= wcagContrastRatio(BLACK, bg) ? WHITE : BLACK);
11429
+ const inkFor = (bg) => (wcagContrastRatio(WHITE$1, bg) >= wcagContrastRatio(BLACK, bg) ? WHITE$1 : BLACK);
10533
11430
  for (let i = 0; i < 40 && wcagContrastRatio(inkFor(five.rgb), five.rgb) < 4.5; i++) {
10534
11431
  const L = rgbToOklab(five.rgb).L;
10535
11432
  // Mid tones can fail both inks — walk toward whichever side is already winning, but
10536
11433
  // never past the neighbouring steps: the ramp's monotonic lightness is a guarantee.
10537
- const towardDark = wcagContrastRatio(WHITE, five.rgb) >= wcagContrastRatio(BLACK, five.rgb);
11434
+ const towardDark = wcagContrastRatio(WHITE$1, five.rgb) >= wcagContrastRatio(BLACK, five.rgb);
10538
11435
  const next = Math.min(0.695, Math.max(0.545, L + (towardDark ? -0.012 : 0.012)));
10539
11436
  if (next === L)
10540
11437
  break;
@@ -10573,10 +11470,12 @@ const WCAG_AA_TEXT = 4.5;
10573
11470
  const ACCENT_TOKEN_NAMES = [
10574
11471
  'accent', 'accent-ink', 'accent-hover', 'accent-text', 'inverse-accent', 'inverse-accent-ink',
10575
11472
  ];
11473
+ const groundList = (g) => (g === undefined || g === null ? [] : typeof g === 'string' ? [g] : [...g]);
11474
+ const hasGround = (g) => groundList(g).length > 0;
10576
11475
  const RAMP_ORDER = RAMP_STEPS.map(s => s.step);
10577
- const WHITE_HEX = toHexColor(WHITE);
11476
+ const WHITE_HEX = toHexColor(WHITE$1);
10578
11477
  const BLACK_HEX = toHexColor(BLACK);
10579
- const passesText = (fg, bg) => wcagContrastRatio(fg, bg) >= WCAG_AA_TEXT;
11478
+ const passesText = (fg, bg) => groundList(bg).every(g => wcagContrastRatio(fg, g) >= WCAG_AA_TEXT);
10580
11479
  const bestInkHex = (bg) => (wcagContrastRatio(WHITE_HEX, bg) >= wcagContrastRatio(BLACK_HEX, bg) ? WHITE_HEX : BLACK_HEX);
10581
11480
  /**
10582
11481
  * The quartet a seed different from the pack's own becomes, built ON `deriveBrandTokens` (its
@@ -10613,7 +11512,7 @@ function deriveAccentTokens(seed, against, pack = {}) {
10613
11512
  hover: hoverFor(500, ink),
10614
11513
  text: firstOn([500, 600, 700, 800, 900], against.bg),
10615
11514
  };
10616
- const dark = against.bgDark ? (() => {
11515
+ const dark = hasGround(against.bgDark) ? (() => {
10617
11516
  const darkStep = [300, 200, 400].find(n => passesText(bestInkHex(step(n)), step(n))) ?? 300;
10618
11517
  const darkInk = bestInkHex(step(darkStep));
10619
11518
  return {
@@ -10624,7 +11523,8 @@ function deriveAccentTokens(seed, against, pack = {}) {
10624
11523
  };
10625
11524
  })() : null;
10626
11525
  const inverseOn = (inverseBg) => {
10627
- const toward = wcagContrastRatio(step(RAMP_ORDER[0]), inverseBg) >= wcagContrastRatio(step(RAMP_ORDER[RAMP_ORDER.length - 1]), inverseBg)
11526
+ const ground = groundList(inverseBg)[0];
11527
+ const toward = wcagContrastRatio(step(RAMP_ORDER[0]), ground) >= wcagContrastRatio(step(RAMP_ORDER[RAMP_ORDER.length - 1]), ground)
10628
11528
  ? -1 : 1;
10629
11529
  const walk = RAMP_ORDER.filter(n => (toward < 0 ? n <= 500 : n >= 500));
10630
11530
  if (toward < 0)
@@ -10639,8 +11539,8 @@ function deriveAccentTokens(seed, against, pack = {}) {
10639
11539
  const fill = step(walk[walk.length - 1]);
10640
11540
  return { accent: fill, ink: passesText(inkOn(fill), fill) ? inkOn(fill) : bestInkHex(fill) };
10641
11541
  };
10642
- const inverse = against.inverseBg ? inverseOn(against.inverseBg) : null;
10643
- const inverseDark = against.inverseBg && against.inverseBgDark ? inverseOn(against.inverseBgDark) : null;
11542
+ const inverse = hasGround(against.inverseBg) ? inverseOn(against.inverseBg) : null;
11543
+ const inverseDark = hasGround(against.inverseBg) && hasGround(against.inverseBgDark) ? inverseOn(against.inverseBgDark) : null;
10644
11544
  const row = (name, value, darkValue) => ({
10645
11545
  name, value, type: 'color', group: 'colour', tier: 'semantic',
10646
11546
  ...(darkValue ? { values: { dark: darkValue } } : {}),
@@ -10657,6 +11557,487 @@ function deriveAccentTokens(seed, against, pack = {}) {
10657
11557
  ];
10658
11558
  }
10659
11559
 
11560
+ const TRANSPARENT = { r: 0, g: 0, b: 0, a: 0 };
11561
+ const NAMED = {
11562
+ transparent: TRANSPARENT,
11563
+ white: { r: 1, g: 1, b: 1, a: 1 },
11564
+ black: { r: 0, g: 0, b: 0, a: 1 },
11565
+ };
11566
+ const CURRENT_COLOR = new Set(['currentcolor', 'inherit']);
11567
+ const RGB_FN = /^rgba?\(([^)]*)\)$/i;
11568
+ const COLOR_MIX = /^color-mix\(\s*in srgb\s*,(.*)\)$/i;
11569
+ const MIX_STOP = /^(.*?)(?:\s+(\d+(?:\.\d+)?)%)?$/;
11570
+ const GRADIENT = /^(?:radial|linear|conic)-gradient\((.*)\)$/i;
11571
+ const STOP_POSITION = /\s+-?\d+(?:\.\d+)?%(\s+-?\d+(?:\.\d+)?%)?$/;
11572
+ const SHADOW_LAYER = /^(-?[\d.]+px|0)\s+(-?[\d.]+px|0)\s+(-?[\d.]+px|0)\s+(-?[\d.]+px|0)\s+(.+)$/;
11573
+ /** Split on top-level commas (never inside parentheses). */
11574
+ function splitTopLevel(value, separator = ',') {
11575
+ const out = [];
11576
+ let depth = 0;
11577
+ let current = '';
11578
+ for (const ch of String(value ?? '')) {
11579
+ if (ch === '(')
11580
+ depth++;
11581
+ if (ch === ')')
11582
+ depth--;
11583
+ if (ch === separator && depth === 0) {
11584
+ out.push(current.trim());
11585
+ current = '';
11586
+ continue;
11587
+ }
11588
+ current += ch;
11589
+ }
11590
+ if (current.trim())
11591
+ out.push(current.trim());
11592
+ return out;
11593
+ }
11594
+ /** `top` composited over an opaque `under`. */
11595
+ function compositeOver(top, under) {
11596
+ const a = top.a;
11597
+ return { r: top.r * a + under.r * (1 - a), g: top.g * a + under.g * (1 - a), b: top.b * a + under.b * (1 - a), a: 1 };
11598
+ }
11599
+ /** The 8-bit colour a screen shows — contrast is judged on WHAT SHIPS, as the derivation's grounds are. */
11600
+ const quantizeRgb = (c) => parseHexColor(toHexColor(c));
11601
+ /** One CSS colour → RGBA, or null when it is not a colour this evaluator reads. `ink` = currentColor. */
11602
+ function parseCssColour(value, ink) {
11603
+ const v = String(value ?? '').trim();
11604
+ const low = v.toLowerCase();
11605
+ if (low in NAMED)
11606
+ return NAMED[low];
11607
+ if (CURRENT_COLOR.has(low))
11608
+ return ink ?? null;
11609
+ const hex = parseHexColor(v);
11610
+ if (hex)
11611
+ return { ...hex, a: 1 };
11612
+ const rgb = RGB_FN.exec(v);
11613
+ if (rgb) {
11614
+ const p = rgb[1].split(/[\s,/]+/).filter(Boolean).map(Number);
11615
+ return { r: p[0] / 255, g: p[1] / 255, b: p[2] / 255, a: p[3] ?? 1 };
11616
+ }
11617
+ const mix = COLOR_MIX.exec(v);
11618
+ if (mix)
11619
+ return mixColours(splitTopLevel(mix[1]), ink);
11620
+ return null;
11621
+ }
11622
+ function mixColours(parts, ink) {
11623
+ const stop = (s) => {
11624
+ const m = MIX_STOP.exec(s.trim());
11625
+ return { c: parseCssColour(m[1], ink), p: m[2] !== undefined ? Number(m[2]) / 100 : null };
11626
+ };
11627
+ const [x, y] = parts.map(stop);
11628
+ if (!x?.c || !y?.c)
11629
+ return null;
11630
+ const px = x.p ?? (y.p !== null ? 1 - y.p : 0.5);
11631
+ const py = y.p ?? 1 - px;
11632
+ const a = x.c.a * px + y.c.a * py;
11633
+ if (a <= 0)
11634
+ return TRANSPARENT;
11635
+ const channel = (k) => (x.c[k] * x.c.a * px + y.c[k] * y.c.a * py) / a;
11636
+ return { r: channel('r'), g: channel('g'), b: channel('b'), a };
11637
+ }
11638
+ /**
11639
+ * A paint → every colour a reader can meet ON it: a plain colour is one; a gradient layer list is each
11640
+ * stop over the final plain layer, and that layer itself. The worst case is the one a check reads.
11641
+ */
11642
+ function paintColours(value, ink) {
11643
+ const layers = splitTopLevel(String(value ?? ''));
11644
+ if (!layers.length)
11645
+ return [];
11646
+ const last = parseCssColour(layers[layers.length - 1], ink);
11647
+ if (layers.length === 1)
11648
+ return last ? [last] : [];
11649
+ if (!last)
11650
+ return [];
11651
+ const ground = { ...last, a: 1 };
11652
+ const out = [ground];
11653
+ for (const layer of layers.slice(0, -1)) {
11654
+ const g = GRADIENT.exec(layer);
11655
+ if (!g)
11656
+ continue;
11657
+ for (const part of splitTopLevel(g[1])) {
11658
+ const colour = parseCssColour(part.replace(STOP_POSITION, ''), ink);
11659
+ if (colour)
11660
+ out.push(compositeOver(colour, ground));
11661
+ }
11662
+ }
11663
+ return out;
11664
+ }
11665
+ /** The outermost ring of a box-shadow list (`0 0 0 4px <colour>`) — a focus indicator's colour. */
11666
+ function ringColour(shadow, ink) {
11667
+ const layers = splitTopLevel(String(shadow ?? ''))
11668
+ .map(l => SHADOW_LAYER.exec(l.trim()))
11669
+ .filter((m) => !!m)
11670
+ .map(m => ({ spread: parseFloat(m[4]) || 0, colour: m[5] }));
11671
+ if (!layers.length)
11672
+ return null;
11673
+ const outer = layers.reduce((a, b) => (b.spread >= a.spread ? b : a));
11674
+ return parseCssColour(outer.colour, ink);
11675
+ }
11676
+
11677
+ /**
11678
+ * The whole colour system follows the brand (design-system DS9 — Doron, 2026-10-19: "I would imagine
11679
+ * that once I change the colour of the brand, the whole colour system changes, but it doesn't").
11680
+ *
11681
+ * One brand colour in → every colour token of the look out, light and dark:
11682
+ * - **Background tint** (`DesignChoices.tint`): Neutral is the look's own palette, untouched; Subtle and
11683
+ * Rich give every neutral role the flavor lists the BRAND's hue — the role keeps its own OKLab
11684
+ * lightness (so the look's light/dark structure and contrast survive) at the level's chroma (or its
11685
+ * own, when the flavor coloured it more), scaled by how chromatic the brand is: a grey brand tints
11686
+ * nothing. Material 3's neutral tonal palettes and Radix's tinted greys, as one table in the contract.
11687
+ * A pure-white page is capped just under white (the level's `groundMaxL`) so it can carry the tint; the flavor's paints rotate
11688
+ * with the brand (Glass's mesh); Midnight's glow already reads the accent.
11689
+ * - **Accents**: the flavor's own quartet at its own seed, else derived from the brand ramp — and
11690
+ * `accent-text` is the first step that reads on EVERY ground (bg, surface, surface-2, the page's paint).
11691
+ * - **Held pairs**: every text and line role is pushed until it clears its pair again on its grounds.
11692
+ * A no-op for the hand-tuned palette at its own seed — the generator's gate proves it.
11693
+ *
11694
+ * Port of iox-ai-guidance `design-system/colour.mjs` `flavorColours`; held equal to it by
11695
+ * `flavor-fixtures.v1.json` (brand-neutrals.spec.ts). Change the maths THERE first.
11696
+ */
11697
+ /** A seed below this OKLCH chroma tints at a proportionally lower strength. */
11698
+ const TINT_FULL_CHROMA = 0.08;
11699
+ /** A neutral at least this chromatic was coloured on purpose: it keeps its hue offset from the flavor's seed. */
11700
+ const TINT_OWN_HUE_CHROMA = 0.01;
11701
+ /** A brand below this chroma has no reliable hue: paints and coloured neutrals are not turned toward it. */
11702
+ const TINT_TURN_CHROMA = 0.02;
11703
+ /** WCAG 1.4.11 — non-text contrast: UI boundaries, glyphs, focus indicators. */
11704
+ const WCAG_AA_UI = 3;
11705
+ const PAGE = 'page';
11706
+ const GROUND_ROLES = new Set(['bg']);
11707
+ const TEXT_GROUNDS = ['bg', 'surface', 'surface-2', PAGE];
11708
+ const INVERSE_GROUNDS = ['inverse-bg', 'inverse-surface'];
11709
+ const MODES$1 = ['light', 'dark'];
11710
+ /** The roles a derivation holds to their pair, on the grounds named (`page` = the page paint's colours). */
11711
+ const HELD_CONTRAST = [
11712
+ ['text', TEXT_GROUNDS, WCAG_AA_TEXT],
11713
+ ['text-muted', TEXT_GROUNDS, WCAG_AA_TEXT],
11714
+ ['line-strong', TEXT_GROUNDS, WCAG_AA_UI],
11715
+ ['danger', TEXT_GROUNDS, WCAG_AA_TEXT],
11716
+ ['success', TEXT_GROUNDS, WCAG_AA_TEXT],
11717
+ ['inverse-text', INVERSE_GROUNDS, WCAG_AA_TEXT],
11718
+ ['inverse-muted', INVERSE_GROUNDS, WCAG_AA_TEXT],
11719
+ ];
11720
+ const TINT_LEVELS = SPEC_AXES.tints;
11721
+ const upper = (hex) => hex.toUpperCase();
11722
+ const passesAll = (fg, bgs, min) => bgs.every(bg => wcagContrastRatio(fg, bg) >= min);
11723
+ /** The lightest/darkest version of `fg` (its own hue and chroma) that clears `min` on every ground. */
11724
+ function ensureContrast(fg, bgs, min) {
11725
+ if (!parseHexColor(fg) || bgs.some(b => !parseHexColor(b)) || passesAll(fg, bgs, min))
11726
+ return fg;
11727
+ const lab = rgbToOklab(parseHexColor(fg));
11728
+ const meanBgL = bgs.reduce((sum, b) => sum + rgbToOklab(parseHexColor(b)).L, 0) / bgs.length;
11729
+ const darker = lab.L <= meanBgL;
11730
+ const chroma = Math.hypot(lab.a, lab.b);
11731
+ const ua = chroma > 1e-6 ? lab.a : 0;
11732
+ const ub = chroma > 1e-6 ? lab.b : 1e-6;
11733
+ let lo = darker ? 0 : lab.L;
11734
+ let hi = darker ? lab.L : 1;
11735
+ let best = darker ? '#000000' : '#ffffff';
11736
+ for (let i = 0; i < 30; i++) {
11737
+ const mid = (lo + hi) / 2;
11738
+ const candidate = toHexColor(atLightness(mid, ua, ub, chroma));
11739
+ if (passesAll(candidate, bgs, min)) {
11740
+ best = candidate;
11741
+ if (darker)
11742
+ lo = mid;
11743
+ else
11744
+ hi = mid;
11745
+ }
11746
+ else if (darker)
11747
+ hi = mid;
11748
+ else
11749
+ lo = mid;
11750
+ }
11751
+ return best;
11752
+ }
11753
+ const RGBA = /^rgba\(\s*(\d+),\s*(\d+),\s*(\d+),\s*([\d.]+)\s*\)$/i;
11754
+ const ALPHA_STEP = 0.01;
11755
+ /** A translucent `fg` (rgba) made just opaque enough to clear `min` on every ground, in 0.01 steps. */
11756
+ function ensureAlpha(fg, bgs, min) {
11757
+ const m = RGBA.exec(String(fg ?? '').trim());
11758
+ if (!m)
11759
+ return fg;
11760
+ const [r, g, b] = [m[1], m[2], m[3]].map(Number);
11761
+ const passes = (a) => bgs.every(bg => {
11762
+ const ground = parseHexColor(bg);
11763
+ return wcagContrastRatio(quantizeRgb(compositeOver({ r: r / 255, g: g / 255, b: b / 255, a }, ground)), ground) >= min;
11764
+ });
11765
+ let alpha = Number(m[4]);
11766
+ if (passes(alpha))
11767
+ return fg;
11768
+ while (alpha < 1 && !passes(alpha))
11769
+ alpha = Math.min(1, Math.round((alpha + ALPHA_STEP) * 100) / 100);
11770
+ return `rgba(${r}, ${g}, ${b}, ${alpha})`;
11771
+ }
11772
+ /** The colour at (L, hue angle) with the most chroma ≤ `chroma` that fits sRGB (a tint never overshoots its
11773
+ * level, and a stronger level never lands under a weaker one — `atLightness`'s ×0.82 steps can). */
11774
+ function atLightnessMaxChroma(L, hue, chroma) {
11775
+ const ua = Math.cos(hue);
11776
+ const ub = Math.sin(hue);
11777
+ const at = (c) => oklabToRgb({ L, a: ua * c, b: ub * c });
11778
+ if (inSrgbGamut(at(chroma)))
11779
+ return at(chroma);
11780
+ let lo = 0;
11781
+ let hi = chroma;
11782
+ for (let i = 0; i < 24; i++) {
11783
+ const mid = (lo + hi) / 2;
11784
+ if (inSrgbGamut(at(mid)))
11785
+ lo = mid;
11786
+ else
11787
+ hi = mid;
11788
+ }
11789
+ return at(lo);
11790
+ }
11791
+ /** The seed's OKLab hue angle and chroma — a grey seed keeps a stable (arbitrary) axis. */
11792
+ function seedHue(seed) {
11793
+ const lab = rgbToOklab(parseHexColor(seed));
11794
+ const chroma = Math.hypot(lab.a, lab.b);
11795
+ const ua = chroma > 1e-6 ? lab.a : 0.0;
11796
+ const ub = chroma > 1e-6 ? lab.b : 1e-6;
11797
+ return { hue: Math.atan2(ub, ua), chroma };
11798
+ }
11799
+ const HEX_IN = /#[0-9a-f]{6}\b/gi;
11800
+ /** Every hex colour inside a paint (a gradient's stops) turned by `angle` radians of OKLab hue. */
11801
+ function rotatePaint(paint, angle, chromaScale) {
11802
+ return String(paint).replace(HEX_IN, hex => {
11803
+ const lab = rgbToOklab(parseHexColor(hex));
11804
+ const a = lab.a * Math.cos(angle) - lab.b * Math.sin(angle);
11805
+ const b = lab.a * Math.sin(angle) + lab.b * Math.cos(angle);
11806
+ return upper(toHexColor(atLightness(lab.L, a, b, Math.hypot(a, b) * chromaScale)));
11807
+ });
11808
+ }
11809
+ /** The opaque colours a palette's named grounds show; `page` = every colour of the page's own paint. */
11810
+ function groundsOf(p, names) {
11811
+ const out = [];
11812
+ for (const name of names) {
11813
+ if (name === PAGE) {
11814
+ const resolved = resolveTokenValues(Object.entries(p).map(([n, value]) => ({ name: n, value })))['page-bg'];
11815
+ for (const c of paintColours(resolved))
11816
+ if (c.a >= 1)
11817
+ out.push(toHexColor(c));
11818
+ }
11819
+ else if (parseHexColor(p[name]))
11820
+ out.push(p[name]);
11821
+ }
11822
+ return [...new Set(out.map(upper))];
11823
+ }
11824
+ function holdContrast(p) {
11825
+ for (const [fg, names, min] of HELD_CONTRAST) {
11826
+ if (parseHexColor(p[fg]))
11827
+ p[fg] = upper(ensureContrast(p[fg], groundsOf(p, names), min));
11828
+ else if (RGBA.test(String(p[fg] ?? '').trim()))
11829
+ p[fg] = ensureAlpha(p[fg], groundsOf(p, names), min);
11830
+ }
11831
+ }
11832
+ function tintPalette(p, flavor, level, seed) {
11833
+ const { hue: brandHue, chroma } = seedHue(seed);
11834
+ const strength = Math.min(1, chroma / TINT_FULL_CHROMA);
11835
+ const turn = chroma >= TINT_TURN_CHROMA ? brandHue - seedHue(flavor.seed).hue : 0;
11836
+ for (const role of flavor.tint.roles) {
11837
+ const rgb = parseHexColor(p[role]);
11838
+ if (!rgb)
11839
+ continue;
11840
+ const lab = rgbToOklab(rgb);
11841
+ const L = GROUND_ROLES.has(role) ? Math.min(lab.L, level.groundMaxL ?? 1) : lab.L;
11842
+ const own = Math.hypot(lab.a, lab.b);
11843
+ const hue = own >= TINT_OWN_HUE_CHROMA ? Math.atan2(lab.b, lab.a) + turn : brandHue;
11844
+ const c = Math.max(own * (level.ownScale ?? 1), (level.chroma?.[role] ?? 0) * flavor.tint.scale) * strength;
11845
+ p[role] = upper(toHexColor(atLightnessMaxChroma(L, hue, c)));
11846
+ }
11847
+ for (const name of flavor.tint.paints ?? [])
11848
+ p[name] = rotatePaint(p[name], turn, level.paintChroma ?? 1);
11849
+ }
11850
+ /**
11851
+ * The colour tokens of a flavor for a brand `seed` and a background `tint`, light and dark.
11852
+ * Neutral at the flavor's own seed returns its palette exactly.
11853
+ */
11854
+ function flavorColours(flavor, choices) {
11855
+ const seed = choices.seed || flavor.seed;
11856
+ const level = TINT_LEVELS[choices.tint ?? PRE_TINT_DEFAULT];
11857
+ const palette = {
11858
+ light: { ...flavor.palette.light },
11859
+ dark: { ...flavor.palette.light, ...flavor.palette.dark },
11860
+ };
11861
+ if (level?.chroma)
11862
+ for (const mode of MODES$1)
11863
+ tintPalette(palette[mode], flavor, level, seed);
11864
+ if (seed.toLowerCase() !== flavor.seed.toLowerCase()) {
11865
+ // Twice: the page paint may read the accent (Midnight's glow), so its grounds are known only once
11866
+ // the fill is — and the fill never depends on the grounds.
11867
+ for (let pass = 0; pass < 2; pass++) {
11868
+ const derived = deriveAccentTokens(seed, {
11869
+ bg: groundsOf(palette.light, TEXT_GROUNDS), bgDark: groundsOf(palette.dark, TEXT_GROUNDS),
11870
+ inverseBg: groundsOf(palette.light, INVERSE_GROUNDS), inverseBgDark: groundsOf(palette.dark, INVERSE_GROUNDS),
11871
+ });
11872
+ for (const t of derived) {
11873
+ palette.light[t.name] = upper(t.value);
11874
+ if (t.values?.dark)
11875
+ palette.dark[t.name] = upper(t.values.dark);
11876
+ }
11877
+ }
11878
+ }
11879
+ for (const mode of MODES$1) {
11880
+ const p = palette[mode];
11881
+ p['accent-text'] = upper(ensureContrast(p['accent-text'], groundsOf(p, TEXT_GROUNDS), WCAG_AA_TEXT));
11882
+ p['inverse-accent'] = upper(ensureContrast(p['inverse-accent'], groundsOf(p, INVERSE_GROUNDS), WCAG_AA_TEXT));
11883
+ holdContrast(p);
11884
+ }
11885
+ const out = {};
11886
+ for (const name of Object.keys(flavor.palette.light))
11887
+ out[name] = [palette.light[name], palette.dark[name]];
11888
+ return out;
11889
+ }
11890
+ /** The grounds the PRE-DS9 accent derivation read: `bg` alone (light/dark), `inverse-bg` alone. */
11891
+ function preTintAccentGrounds(palette) {
11892
+ const dark = { ...palette.light, ...palette.dark };
11893
+ return { bg: palette.light['bg'] ?? '', bgDark: dark['bg'], inverseBg: palette.light['inverse-bg'], inverseBgDark: dark['inverse-bg'] };
11894
+ }
11895
+
11896
+ const FORM_PARTS = SPEC_CONTRAST_AUDIT.formParts;
11897
+ const INK_SCOPES = SPEC_INK_SCOPES;
11898
+ const SCHEME_IDS = Object.keys(SPEC_SCHEMES);
11899
+ const CONTAINER_GROUPS = new Set(['Layout', 'Overlays']);
11900
+ const NOT_CONTENT = new Set(['rule', 'media']);
11901
+ const SECTION_STYLE = 'section';
11902
+ const ICON_STYLE = 'icon';
11903
+ const BUTTON_GROUP = 'Buttons';
11904
+ const GLYPH_GROUP = 'Media';
11905
+ const FORMS_GROUP = 'Forms';
11906
+ const DEFAULT_SCHEME = 'default';
11907
+ const SECTION = 'section';
11908
+ const FIELD = 'field';
11909
+ const WHITE = { r: 1, g: 1, b: 1, a: 1 };
11910
+ const SINGLE_REF = /^var\(--iox-([\w-]+)\)$/;
11911
+ const TOKEN_REF = /var\(\s*--iox-([\w-]+)\s*(?:,([^()]*))?\)/g;
11912
+ /** A style value with its var() references resolved against `values` (already-resolved tokens). */
11913
+ function resolveIn(values, v) {
11914
+ const single = SINGLE_REF.exec(String(v ?? '').trim());
11915
+ if (single)
11916
+ return values[single[1]] ?? v;
11917
+ return String(v ?? '').replace(TOKEN_REF, (ref, name, fallback) => values[name] ?? (fallback !== undefined ? fallback.trim() : ref));
11918
+ }
11919
+ const overAll = (tops, unders) => unders.flatMap(u => tops.map(t => compositeOver(t, u)));
11920
+ const opaque = (paints) => paints.some(c => c.a > 0);
11921
+ const ownStyle = (e) => (e.base ?? {});
11922
+ function inkScoped(values, styleId) {
11923
+ const scope = INK_SCOPES.find(s => s.styles.includes(styleId));
11924
+ return scope ? { ...values, ...scope.set } : values;
11925
+ }
11926
+ /** Every pair a reader meets, for one set of token rows in one mode. */
11927
+ function auditDesignContrast(rows, mode) {
11928
+ const findings = [];
11929
+ const styles = ELEMENT_STYLES;
11930
+ const byId = new Map(styles.map(e => [e.id, e]));
11931
+ const containers = [
11932
+ null,
11933
+ ...styles.filter(e => CONTAINER_GROUPS.has(e.group) && ownStyle(e)['backgroundColor'] && e.id !== SECTION_STYLE),
11934
+ ];
11935
+ const content = styles.filter(e => !CONTAINER_GROUPS.has(e.group) && (ownStyle(e)['color'] || ownStyle(e)['backgroundColor'])
11936
+ && e.group !== FORMS_GROUP && !NOT_CONTENT.has(e.id));
11937
+ const notices = styles.filter(e => e.group === FORMS_GROUP && ownStyle(e)['color']);
11938
+ const section = ownStyle(byId.get(SECTION_STYLE));
11939
+ const iconColour = ownStyle(byId.get(ICON_STYLE))['color'];
11940
+ for (const schemeId of SCHEME_IDS) {
11941
+ const values = resolveSchemeTokenValues(rows, mode, schemeId);
11942
+ const pageInk = parseCssColour(values['text']);
11943
+ const page = paintColours(values['page-bg'], pageInk);
11944
+ const sectionPaint = paintColours(values['section-bg'], pageInk);
11945
+ const ground = opaque(sectionPaint)
11946
+ ? sectionPaint.map(c => (c.a < 1 ? compositeOver(c, page[0] ?? WHITE) : c))
11947
+ : page;
11948
+ const sectionInk = parseCssColour(resolveIn(values, section['color']), pageInk);
11949
+ for (const box of containers) {
11950
+ const boxStyle = box ? ownStyle(box) : null;
11951
+ const bgs = boxStyle ? overAll(paintColours(resolveIn(values, boxStyle['backgroundColor']), sectionInk), ground) : ground;
11952
+ const boxInk = boxStyle?.['color'] && boxStyle['color'] !== 'inherit'
11953
+ ? parseCssColour(resolveIn(values, boxStyle['color']), sectionInk) : sectionInk;
11954
+ const where = { scheme: schemeId, container: box?.id ?? SECTION };
11955
+ const record = (element, part, fg, bg, ratio, min) => findings.push({ ...where, element, part, fg, bg, ratio: Math.round(ratio * 100) / 100, min, pass: ratio >= min - 1e-9 });
11956
+ const check = (element, part, fg, under, min) => {
11957
+ if (!fg)
11958
+ return;
11959
+ for (const g of under) {
11960
+ const bg = quantizeRgb(g);
11961
+ const f = quantizeRgb(fg.a < 1 ? compositeOver(fg, bg) : fg);
11962
+ record(element, part, toHexColor(f), toHexColor(bg), wcagContrastRatio(f, bg), min);
11963
+ }
11964
+ };
11965
+ check(box?.id ?? SECTION, 'text', boxInk, bgs, WCAG_AA_TEXT);
11966
+ for (const e of content) {
11967
+ const states = [['base', ownStyle(e)], ...(e.hover ? [['hover', { ...ownStyle(e), ...e.hover }]] : [])];
11968
+ const glyph = e.group === GLYPH_GROUP;
11969
+ for (const [state, s] of states) {
11970
+ const fill = s['backgroundColor'] ? paintColours(resolveIn(values, s['backgroundColor']), boxInk) : [];
11971
+ const under = fill.length && opaque(fill) ? overAll(fill, bgs) : bgs;
11972
+ const ink = s['color'] ? parseCssColour(resolveIn(values, s['color']), boxInk) : boxInk;
11973
+ check(e.id, state === 'base' ? (glyph ? 'glyph' : 'text') : `${state} text`, ink, under, glyph ? WCAG_AA_UI : WCAG_AA_TEXT);
11974
+ if (state === 'base' && e.group === BUTTON_GROUP) {
11975
+ check(e.id, 'icon', parseCssColour(resolveIn(inkScoped(values, e.id), iconColour), ink), under, WCAG_AA_UI);
11976
+ const focus = e.focus?.['boxShadow'];
11977
+ if (focus)
11978
+ check(e.id, 'focus ring', ringColour(resolveIn(values, focus), ink), bgs, WCAG_AA_UI);
11979
+ }
11980
+ }
11981
+ }
11982
+ for (const part of FORM_PARTS) {
11983
+ const fieldBg = paintColours(resolveIn(values, part.on ?? 'transparent'), boxInk);
11984
+ const under = part.on && opaque(fieldBg) ? overAll(fieldBg, bgs) : bgs;
11985
+ if (part.any) {
11986
+ for (const g of under) {
11987
+ const bg = quantizeRgb(g);
11988
+ const ratio = Math.max(...part.fg.map(fg => {
11989
+ const c = parseCssColour(resolveIn(values, fg), boxInk);
11990
+ return c ? wcagContrastRatio(quantizeRgb(c.a < 1 ? compositeOver(c, bg) : c), bg) : 1;
11991
+ }));
11992
+ record(FIELD, part.part, '', toHexColor(bg), ratio, part.min);
11993
+ }
11994
+ continue;
11995
+ }
11996
+ const paint = parseCssColour(resolveIn(values, part.fg), boxInk);
11997
+ check(FIELD, part.part, paint, under, part.min);
11998
+ if (part.thumb && paint) {
11999
+ check(FIELD, `${part.part} thumb`, parseCssColour(resolveIn(values, part.thumb), boxInk), bgs.map(b => compositeOver(paint, b)), part.min);
12000
+ }
12001
+ }
12002
+ if (box === null && schemeId === DEFAULT_SCHEME) {
12003
+ for (const n of notices) {
12004
+ const fill = paintColours(resolveIn(values, ownStyle(n)['backgroundColor']), boxInk);
12005
+ check(n.id, 'text', parseCssColour(resolveIn(values, ownStyle(n)['color']), boxInk), overAll(fill, bgs), WCAG_AA_TEXT);
12006
+ }
12007
+ }
12008
+ }
12009
+ }
12010
+ return findings;
12011
+ }
12012
+ /** The pairs the Design ▸ Colour tab lists for the CURRENT brand (Board 6 + DS9): what a filled button
12013
+ * shows, and the link on every section scheme — each the worst case on the section itself. */
12014
+ var ColourCheckId;
12015
+ (function (ColourCheckId) {
12016
+ ColourCheckId["ButtonLabel"] = "button-label";
12017
+ ColourCheckId["ButtonIcon"] = "button-icon";
12018
+ ColourCheckId["Link"] = "link";
12019
+ })(ColourCheckId || (ColourCheckId = {}));
12020
+ const COLOUR_TAB_CHECKS = [
12021
+ { id: ColourCheckId.ButtonLabel, element: 'button-primary', part: 'text', schemes: [DEFAULT_SCHEME] },
12022
+ { id: ColourCheckId.ButtonIcon, element: 'button-primary', part: 'icon', schemes: [DEFAULT_SCHEME] },
12023
+ { id: ColourCheckId.Link, element: 'link', part: 'text', schemes: SCHEME_IDS },
12024
+ ];
12025
+ /** The Colour tab's brand rows, from one audit of the rows the canvas wears. */
12026
+ function colourTabChecks(rows, mode) {
12027
+ const findings = auditDesignContrast(rows, mode).filter(f => f.container === SECTION);
12028
+ const out = [];
12029
+ for (const check of COLOUR_TAB_CHECKS) {
12030
+ for (const scheme of check.schemes) {
12031
+ const hits = findings.filter(f => f.scheme === scheme && f.element === check.element && f.part === check.part);
12032
+ if (!hits.length)
12033
+ continue;
12034
+ const worst = hits.reduce((a, b) => (b.ratio < a.ratio ? b : a));
12035
+ out.push({ id: check.id, scheme, fg: worst.fg, bg: worst.bg, ratio: worst.ratio, min: worst.min, passes: worst.pass });
12036
+ }
12037
+ }
12038
+ return out;
12039
+ }
12040
+
10660
12041
  /**
10661
12042
  * Fonts (design-system plan §5b, D7): ONE Google catalog for both renderers, and ONE face builder
10662
12043
  * for the families a studio uploads.
@@ -11162,7 +12543,8 @@ function missingFontRoles(tokens, uploaded) {
11162
12543
  *
11163
12544
  * Layering, each step over the last (the boards' `tokenMap`, with the product's colour math):
11164
12545
  * pack tokens → chosen font pair → shape · density · motion axes → pill-button rule →
11165
- * the author's own font roles → a seed ≠ the pack's own re-derives the accent quartet.
12546
+ * the author's own font roles → every COLOUR token from the brand seed and the background tint
12547
+ * (`flavorColours`, DS9: tinted neutrals, the accent quartet, the held contrast pairs).
11166
12548
  *
11167
12549
  * `mode` does not change rows — every row keeps its light value and its dark override; mode is
11168
12550
  * how the stylesheet is compiled.
@@ -11231,13 +12613,43 @@ function buildFlavorTokens(pack, choices) {
11231
12613
  if (typeof family === 'string' && family.trim() !== '')
11232
12614
  set(role, userFontStack(family, byName.get(role)?.value), USER_TOKEN_SOURCE);
11233
12615
  }
12616
+ setColours(byName, flavorColours(pack, { seed: choices.seed, tint: choices.tint ?? pack.defaults.tint }));
12617
+ return rows;
12618
+ }
12619
+ /** Colour rows take their light value and the dark one only where it differs (the contract's own rule). */
12620
+ function setColours(byName, colours) {
12621
+ for (const [name, [light, dark]] of Object.entries(colours)) {
12622
+ const row = byName.get(name);
12623
+ if (!row)
12624
+ continue;
12625
+ row.value = light;
12626
+ if (dark !== undefined && dark !== light)
12627
+ row.values = { dark };
12628
+ else
12629
+ delete row.values;
12630
+ }
12631
+ }
12632
+ /**
12633
+ * What the contract wrote for `choices` BEFORE DS9 — the baseline a studio that applied its look before
12634
+ * the tint existed is judged against (`designBaseline`, `designTokenRepairs`): the look's own palette, the
12635
+ * rows DS9 changed at their old values (`pack.legacy`), and a seed ≠ the pack's own re-deriving the accent
12636
+ * set against `bg` alone, as `deriveAccentTokens` was called then. No held pairs, no tint.
12637
+ */
12638
+ function legacyFlavorTokens(pack, choices) {
12639
+ const rows = buildFlavorTokens(pack, { ...choices, seed: pack.seed, tint: 'neutral' });
12640
+ const byName = new Map(rows.map(r => [r.name, r]));
12641
+ for (const [name, old] of Object.entries(pack.legacy ?? {})) {
12642
+ const row = byName.get(name);
12643
+ if (!row)
12644
+ continue;
12645
+ row.value = old.value;
12646
+ if (old.dark !== undefined)
12647
+ row.values = { dark: old.dark };
12648
+ else
12649
+ delete row.values;
12650
+ }
11234
12651
  if (choices.seed && choices.seed.toLowerCase() !== pack.seed.toLowerCase()) {
11235
- const bg = byName.get('bg');
11236
- const inverseBg = byName.get('inverse-bg');
11237
- for (const accent of deriveAccentTokens(choices.seed, {
11238
- bg: bg?.value ?? '', bgDark: bg?.values?.dark,
11239
- inverseBg: inverseBg?.value, inverseBgDark: inverseBg?.values?.dark,
11240
- })) {
12652
+ for (const accent of deriveAccentTokens(choices.seed, preTintAccentGrounds(pack.palette))) {
11241
12653
  const row = byName.get(accent.name);
11242
12654
  if (!row)
11243
12655
  continue;
@@ -11475,6 +12887,7 @@ var DesignConfigKey;
11475
12887
  DesignConfigKey["Motion"] = "motion";
11476
12888
  DesignConfigKey["PillButtons"] = "pillButtons";
11477
12889
  DesignConfigKey["Mode"] = "mode";
12890
+ DesignConfigKey["Tint"] = "tint";
11478
12891
  DesignConfigKey["Fonts"] = "fonts";
11479
12892
  DesignConfigKey["Revert"] = "revert";
11480
12893
  })(DesignConfigKey || (DesignConfigKey = {}));
@@ -11551,6 +12964,7 @@ function resolveDesignChoices(partial) {
11551
12964
  motion: keyOf(SPEC_AXES.motions, asString(partial?.motion)) ?? pack.defaults.motion,
11552
12965
  pillButtons: asBoolean(partial?.pillButtons) ?? pack.defaults.pillButtons,
11553
12966
  mode: (MODES.includes(asString(partial?.mode) ?? '') ? asString(partial?.mode) : pack.defaults.mode),
12967
+ tint: keyOf(SPEC_AXES.tints, asString(partial?.tint)) ?? pack.defaults.tint,
11554
12968
  ...(fonts ? { fonts } : {}),
11555
12969
  };
11556
12970
  }
@@ -11569,9 +12983,14 @@ function choicesForPack(flavorId, applied) {
11569
12983
  return resolveDesignChoices(applied);
11570
12984
  return resolveDesignChoices({ flavorId: pack.id, fonts: applied?.fonts });
11571
12985
  }
11572
- /** A stored `settings.design` config → the resolved design. No row (or no config) → Crisp's defaults. */
12986
+ /**
12987
+ * A stored `settings.design` config → the resolved design. No row (or no config) → Crisp's defaults. A
12988
+ * row stored before DS9 has no `tint`: it was applied with the look's own palette, so it reads `neutral`
12989
+ * (never the pack's new default — the studio's rows hold the palette, and nothing may repaint them unasked).
12990
+ */
11573
12991
  function readDesignConfig(config, hasRow = !!config) {
11574
12992
  const map = configMap(config);
12993
+ const storedTint = asString(map.get(DesignConfigKey.Tint)) ?? (hasRow ? PRE_TINT_DEFAULT : null);
11575
12994
  const storedFlavorId = asString(map.get(DesignConfigKey.FlavorId));
11576
12995
  const storedSeed = asString(map.get(DesignConfigKey.BrandSeed));
11577
12996
  const choices = resolveDesignChoices({
@@ -11583,6 +13002,7 @@ function readDesignConfig(config, hasRow = !!config) {
11583
13002
  motion: map.get(DesignConfigKey.Motion),
11584
13003
  pillButtons: asBoolean(map.get(DesignConfigKey.PillButtons)) ?? undefined,
11585
13004
  mode: map.get(DesignConfigKey.Mode),
13005
+ tint: (storedTint ?? undefined),
11586
13006
  fonts: map.get(DesignConfigKey.Fonts),
11587
13007
  });
11588
13008
  return {
@@ -11611,6 +13031,7 @@ function designConfigEntries(choices, flavorVersion, revert) {
11611
13031
  { key: DesignConfigKey.Motion, value: c.motion },
11612
13032
  { key: DesignConfigKey.PillButtons, value: String(c.pillButtons) },
11613
13033
  { key: DesignConfigKey.Mode, value: c.mode },
13034
+ { key: DesignConfigKey.Tint, value: c.tint },
11614
13035
  ...(c.fonts ? [{ key: DesignConfigKey.Fonts, value: JSON.stringify(c.fonts) }] : []),
11615
13036
  ...(revert ? [{ key: DesignConfigKey.Revert, value: JSON.stringify(revert) }] : []),
11616
13037
  ];
@@ -11621,7 +13042,7 @@ function sameDesignChoices(a, b) {
11621
13042
  const y = resolveDesignChoices(b);
11622
13043
  return x.flavorId === y.flavorId && x.seed.toLowerCase() === y.seed.toLowerCase() && x.pairId === y.pairId
11623
13044
  && x.shape === y.shape && x.density === y.density && x.motion === y.motion
11624
- && x.pillButtons === y.pillButtons && x.mode === y.mode
13045
+ && x.pillButtons === y.pillButtons && x.mode === y.mode && x.tint === y.tint
11625
13046
  && JSON.stringify(x.fonts ?? {}) === JSON.stringify(y.fonts ?? {});
11626
13047
  }
11627
13048
 
@@ -11639,6 +13060,12 @@ function designTokenRows(choices) {
11639
13060
  const pack = flavorPackById(choices.flavorId);
11640
13061
  return pack ? buildFlavorTokens(pack, { ...choices, flavorId: pack.id }) : [];
11641
13062
  }
13063
+ /** What a design wrote BEFORE DS9 (the look's own palette, the rows DS9 changed at their old values, the
13064
+ * accent derived against `bg` alone) — empty for an unknown pack. */
13065
+ function legacyDesignTokenRows(choices) {
13066
+ const pack = flavorPackById(choices.flavorId);
13067
+ return pack ? legacyFlavorTokens(pack, { ...choices, flavorId: pack.id }) : [];
13068
+ }
11642
13069
  /** What the F1/F2 Swiss seeding wrote: the four Swiss rows + the brand set derived from its seed. */
11643
13070
  function swissExpectations(seed) {
11644
13071
  const rows = SWISS_FLAVOR.tokens.map(t => ({ name: t.name, value: t.value, values: t.values }));
@@ -11650,17 +13077,20 @@ function swissExpectations(seed) {
11650
13077
  }
11651
13078
  return expectations(rows);
11652
13079
  }
11653
- /** What a v2 pack writes at its OWN defaults, by pack id — computed once per id per caller. */
13080
+ /** What a v2 pack writes at its OWN defaults, by pack id — today and before DS9 (a studio seeded then holds
13081
+ * the old defaults) — computed once per id per caller. */
11654
13082
  function packDefaultsLookup() {
11655
13083
  const cache = new Map();
11656
13084
  return packId => {
11657
13085
  if (!cache.has(packId)) {
11658
13086
  const pack = isRetiredFlavorId(packId) ? undefined : flavorPackById(packId);
11659
- cache.set(packId, pack && pack.id === packId ? expectations(designTokenRows(packDesignChoices(pack.id))) : undefined);
13087
+ const choices = pack && pack.id === packId ? packDesignChoices(pack.id) : null;
13088
+ cache.set(packId, choices ? [expectations(designTokenRows(choices)), expectations(legacyDesignTokenRows(choices))] : []);
11660
13089
  }
11661
13090
  return cache.get(packId);
11662
13091
  };
11663
13092
  }
13093
+ const present = (list) => list.filter((e) => !!e);
11664
13094
  /**
11665
13095
  * What the PREVIOUS design wrote, as a baseline keyed by the row's own stamp: a row Swiss stamped is
11666
13096
  * judged against what Swiss wrote, every other row against `buildFlavorTokens` of the stored choices
@@ -11676,15 +13106,17 @@ function packDefaultsLookup() {
11676
13106
  */
11677
13107
  function designBaseline(previous) {
11678
13108
  const retired = isRetiredFlavorId(previous.storedFlavorId);
11679
- const current = expectations(designTokenRows(retired ? packDesignChoices(previous.choices.flavorId) : previous.choices));
13109
+ const wrote = retired ? packDesignChoices(previous.choices.flavorId) : previous.choices;
13110
+ const current = expectations(designTokenRows(wrote));
13111
+ const beforeTint = expectations(legacyDesignTokenRows(wrote));
11680
13112
  const swiss = swissExpectations(retired ? previous.storedSeed : null);
11681
13113
  const packDefaults = packDefaultsLookup();
11682
13114
  return (row) => {
11683
13115
  const stampedBy = SEED_STAMP.exec(row.source ?? '')?.[1];
11684
13116
  if (stampedBy === SWISS_FLAVOR.id)
11685
13117
  return swiss.get(row.name);
11686
- const ownDefault = stampedBy ? packDefaults(stampedBy)?.get(row.name) : undefined;
11687
- return [current.get(row.name), ownDefault].filter((e) => !!e);
13118
+ const ownDefaults = stampedBy ? packDefaults(stampedBy).map(m => m.get(row.name)) : [];
13119
+ return present([current.get(row.name), beforeTint.get(row.name), ...ownDefaults]);
11688
13120
  };
11689
13121
  }
11690
13122
  /**
@@ -11719,15 +13151,18 @@ function missingDesignRows(existing, choices) {
11719
13151
  /**
11720
13152
  * The builder-load REPAIR (DS4.1): rows the design writes that are the machine's and nobody touched,
11721
13153
  * yet hold something other than the design's value, are rewritten — so an org heals on its next load
11722
- * with no author action. Two shapes:
13154
+ * with no author action. Three shapes:
11723
13155
  * - stamped by the current pack, light value exactly the pack's, dark half not: iox-cms dropped
11724
13156
  * `values.dark` on every write from F0 to DS4 (`values` was an implicit relation), and a revert could
11725
13157
  * leave the previous apply's dark behind;
11726
13158
  * - stamped by a v2 pack and still holding what THAT pack writes at its own defaults (its dark half
11727
13159
  * possibly lost the same way) while the stored design says otherwise: an apply that judged the row
11728
13160
  * edited (before 5.24.0, a lost dark half did) left it on the default — the six brand rows of a studio
11729
- * whose brand colour never reached its accent.
11730
- * No author edit produces either shape — the Tokens panel edited the light value only, and since DS8 an
13161
+ * whose brand colour never reached its accent;
13162
+ * - stamped by the current pack and still holding what the design wrote BEFORE DS9
13163
+ * (`legacyDesignTokenRows`): the contrast fixes — a 3:1 `line-strong`, a 3:1 focus ring, an
13164
+ * `accent-text` that reads on every ground — reach a studio that applied its look before them.
13165
+ * No author edit produces any of these shapes — the Tokens panel edited the light value only, and since DS8 an
11731
13166
  * edit makes the row `source: user`, which this never touches.
11732
13167
  */
11733
13168
  function designTokenRepairs(existing, choices) {
@@ -11736,6 +13171,7 @@ function designTokenRepairs(existing, choices) {
11736
13171
  return [];
11737
13172
  const stamp = flavorSourceStamp(pack.id);
11738
13173
  const desired = new Map(designTokenRows(choices).map(r => [r.name, r]));
13174
+ const beforeTint = expectations(legacyDesignTokenRows(choices));
11739
13175
  const packDefaults = packDefaultsLookup();
11740
13176
  const out = [];
11741
13177
  for (const row of existing ?? []) {
@@ -11746,8 +13182,11 @@ function designTokenRepairs(existing, choices) {
11746
13182
  continue;
11747
13183
  const stampedBy = SEED_STAMP.exec(row.source ?? '')?.[1];
11748
13184
  const darkOnly = row.source === stamp && row.value === want.value;
11749
- const ownDefault = stampedBy ? packDefaults(stampedBy)?.get(row.name) : undefined;
11750
- if (!darkOnly && !(ownDefault && untouchedSeedRow(row, [ownDefault])))
13185
+ const machineWrote = present([
13186
+ ...(stampedBy ? packDefaults(stampedBy).map(m => m.get(row.name)) : []),
13187
+ ...(stampedBy === pack.id ? [beforeTint.get(row.name)] : []),
13188
+ ]);
13189
+ if (!darkOnly && !untouchedSeedRow(row, machineWrote))
11751
13190
  continue;
11752
13191
  out.push({ id: row._id, data: { value: want.value, values: want.values ?? {}, source: stamp, ...(want.group ? { group: want.group } : {}), ...(want.tier ? { tier: want.tier } : {}) } });
11753
13192
  }
@@ -11837,5 +13276,5 @@ function planFontFamilyRemoval(existing, previous, family) {
11837
13276
  * Generated bundle index. Do not edit.
11838
13277
  */
11839
13278
 
11840
- export { ACCENT_TOKEN_NAMES, AdoptOutcome, AdoptSkipReason, BUTTON_VARIANT_TO_STYLE, COLOR_SCHEMES, COLOR_SCHEME_TRAIT, COLOR_SCHEME_TYPES, ColorScheme, DEFAULT_FLAVOR_ID, DESIGN_TOKEN_GROUPS, DESIGN_TOKEN_TIERS, DESIGN_TOKEN_TYPES, DesignConfigKey, ELEMENT_STYLES, ELEMENT_STYLE_MARKER_CLASS, ELEMENT_STYLE_STATES, EMPTY_IMAGE_ATTRIBUTE, EMPTY_IMAGE_SRC, ElementStyleState, FLAVOR_SPEC_VERSION, FONT_CATALOG, FONT_FAMILY_TOKENS, FONT_FILE_ACCEPT, FONT_FILE_EXTENSIONS, FONT_FILE_FORMATS, FONT_STYLES, FONT_WEIGHTS, FontUploadError, GOOGLE_FONTS_CSS_ORIGIN, GOOGLE_FONTS_FILE_ORIGIN, MAX_FONT_FILE_BYTES, NEW_NODE_STYLE_DEFAULTS, OwnedTraitLink, PALETTE_PRESETS, PRE_DS2_FLAVOR_DEFAULTS, REDUCED_MOTION_OVERRIDES, REDUCED_TRANSPARENCY_OVERRIDES, REVERT_WINDOW_MS, SPEC_A11Y, SPEC_AXES, SPEC_BUTTON_VARIANT_TO_STYLE, SPEC_CONTRAST, SPEC_DEFAULT_ELEMENT_STYLE, SPEC_ELEMENT_STYLES, SPEC_FIELD_CLASS_BASELINE, SPEC_FLAVORS, SPEC_FLAVOR_PACKS, SPEC_FONTS, SPEC_FONT_ROLES, SPEC_LEGACY_ALIASES, SPEC_PALETTE_PRESETS, SPEC_SCHEMES, SPEC_SPRINGS, SPEC_TIERS, SPEC_TIER_IDS, SPEC_TOKEN_TYPES, SUPERSEDED_STYLE_VALUES, SWISS_FLAVOR, USER_TOKEN_SOURCE, WCAG_AA_TEXT, adoptElementStyles, adoptionStyleFor, apcaLc, applyElementStyle, applyHeadingLevelRule, buildFlavorTokens, buildFontFaceCss, catalogFontId, checkFontWeight, choicesForPack, colorSchemeClass, colorSchemeOf, compareFontWeights, compileSchemeCss, compileTokenCss, compileTokenCssBlocks, cssString, defaultDesignChoices, defaultElementStyleFor, deriveAccentTokens, deriveBrandTokens, designBaseline, designConfigEntries, designModeOf, designTokenRepairs, designTokenRows, elementStyleById, elementStyleClass, elementStylesFor, emptyImageLabelSrc, emptyImagePlaceholder, emptyImageSrc, flavorPackById, flavorSeedWrites, flavorSourceStamp, fontFamilyKey, fontFileName, fontFileStem, fontFormatOf, fontPreloads, fontRoleReferences, fontStackWithout, fontWeightCovers, fontWeightRange, fontWeightValue, fontsForTokens, formatFontFamilies, formatFontFamily, formatFontWeight, googleFontHref, groupFontFamilies, hasElementStyleMarker, isDesignTokenGroup, isDesignTokenTier, isDesignTokenType, isFontWeightRange, isRetiredFlavorId, legacyRuleTokenReferences, matchFontWeight, missingDesignRows, missingFontRoles, nodeDesignClasses, normalizeFontStyle, normalizeFontWeight, normalizeFontWeightValue, oklabToRgb, ownedTraitStatus, ownedTraitsOf, packDesignChoices, parseFontFamilies, parseFontWeight, parseHexColor, planDesignApply, planDesignRevert, planFlavorRevert, planFlavorSeed, planFontFamilyRemoval, planSwissMigration, previewElementStyleAdoption, previewFontWeight, readDesignConfig, readOwnedTrait, relativeLuminance, resolveDesignChoices, resolveTokenReferences, resolveTokenValues, revertAvailable, rgbToOklab, sameDesignChoices, specTokenNames, springToLinear, stackNamesFamily, styleKeyToKebab, switchElementStyle, syncNodeDesignClasses, toHexColor, tokenReferences, tokensToDarkVarMap, tokensToVarMap, unknownTokenReferences, untouchedSeedRow, userFontStack, validateFlavorPack, wcagContrastRatio, writeOwnedTrait };
13279
+ export { ACCENT_TOKEN_NAMES, AdoptOutcome, AdoptSkipReason, BUTTON_VARIANT_TO_STYLE, COLOR_SCHEMES, COLOR_SCHEME_TRAIT, COLOR_SCHEME_TYPES, ColorScheme, ColourCheckId, DEFAULT_FLAVOR_ID, DESIGN_TOKEN_GROUPS, DESIGN_TOKEN_TIERS, DESIGN_TOKEN_TYPES, DesignConfigKey, ELEMENT_STYLES, ELEMENT_STYLE_MARKER_CLASS, ELEMENT_STYLE_STATES, EMPTY_IMAGE_ATTRIBUTE, EMPTY_IMAGE_SRC, ElementStyleState, FLAVOR_SPEC_VERSION, FONT_CATALOG, FONT_FAMILY_TOKENS, FONT_FILE_ACCEPT, FONT_FILE_EXTENSIONS, FONT_FILE_FORMATS, FONT_STYLES, FONT_WEIGHTS, FontUploadError, GOOGLE_FONTS_CSS_ORIGIN, GOOGLE_FONTS_FILE_ORIGIN, HELD_CONTRAST, MAX_FONT_FILE_BYTES, NEW_NODE_STYLE_DEFAULTS, OwnedTraitLink, PALETTE_PRESETS, PRE_DS2_FLAVOR_DEFAULTS, PRE_TINT_DEFAULT, REDUCED_MOTION_OVERRIDES, REDUCED_TRANSPARENCY_OVERRIDES, REVERT_WINDOW_MS, SPEC_A11Y, SPEC_AXES, SPEC_BUTTON_VARIANT_TO_STYLE, SPEC_CONTRAST, SPEC_CONTRAST_AUDIT, SPEC_DEFAULT_ELEMENT_STYLE, SPEC_ELEMENT_STYLES, SPEC_FIELD_CLASS_BASELINE, SPEC_FLAVORS, SPEC_FLAVOR_PACKS, SPEC_FONTS, SPEC_FONT_ROLES, SPEC_INK_SCOPES, SPEC_LEGACY_ALIASES, SPEC_PALETTE_PRESETS, SPEC_SCHEMES, SPEC_SPRINGS, SPEC_TIERS, SPEC_TIER_IDS, SPEC_TOKEN_TYPES, SUPERSEDED_STYLE_VALUES, SWISS_FLAVOR, TINT_FULL_CHROMA, TINT_IDS, TINT_LEVELS, TINT_OWN_HUE_CHROMA, TINT_TURN_CHROMA, USER_TOKEN_SOURCE, WCAG_AA_TEXT, WCAG_AA_UI, adoptElementStyles, adoptionStyleFor, apcaLc, applyElementStyle, applyHeadingLevelRule, atLightness, atLightnessMaxChroma, auditDesignContrast, buildFlavorTokens, buildFontFaceCss, catalogFontId, checkFontWeight, choicesForPack, colorSchemeClass, colorSchemeOf, colourTabChecks, compareFontWeights, compileSchemeCss, compileTokenCss, compileTokenCssBlocks, compositeOver, cssString, defaultDesignChoices, defaultElementStyleFor, deriveAccentTokens, deriveBrandTokens, designBaseline, designConfigEntries, designModeOf, designTokenRepairs, designTokenRows, elementStyleById, elementStyleClass, elementStylesFor, emptyImageLabelSrc, emptyImagePlaceholder, emptyImageSrc, ensureAlpha, ensureContrast, flavorColours, flavorPackById, flavorSeedWrites, flavorSourceStamp, fontFamilyKey, fontFileName, fontFileStem, fontFormatOf, fontPreloads, fontRoleReferences, fontStackWithout, fontWeightCovers, fontWeightRange, fontWeightValue, fontsForTokens, formatFontFamilies, formatFontFamily, formatFontWeight, googleFontHref, groupFontFamilies, hasElementStyleMarker, inSrgbGamut, isDesignTokenGroup, isDesignTokenTier, isDesignTokenType, isFontWeightRange, isRetiredFlavorId, legacyDesignTokenRows, legacyFlavorTokens, legacyRuleTokenReferences, matchFontWeight, missingDesignRows, missingFontRoles, nodeDesignClasses, normalizeFontStyle, normalizeFontWeight, normalizeFontWeightValue, oklabToRgb, ownedTraitStatus, ownedTraitsOf, packDesignChoices, paintColours, parseCssColour, parseFontFamilies, parseFontWeight, parseHexColor, planDesignApply, planDesignRevert, planFlavorRevert, planFlavorSeed, planFontFamilyRemoval, planSwissMigration, preTintAccentGrounds, previewElementStyleAdoption, previewFontWeight, quantizeRgb, readDesignConfig, readOwnedTrait, relativeLuminance, resolveDesignChoices, resolveSchemeTokenValues, resolveTokenReferences, resolveTokenValues, revertAvailable, rgbToOklab, ringColour, sameDesignChoices, specTokenNames, splitTopLevel, springToLinear, stackNamesFamily, styleKeyToKebab, switchElementStyle, syncNodeDesignClasses, toHexColor, tokenReferences, tokensToDarkVarMap, tokensToVarMap, unknownTokenReferences, untouchedSeedRow, userFontStack, validateFlavorPack, wcagContrastRatio, writeOwnedTrait };
11841
13280
  //# sourceMappingURL=vectoriox-iox-ui-design-core.mjs.map