@nxds/core 0.12.0 → 0.13.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.
@@ -1972,6 +1972,321 @@ function apcaLc(foreground, background) {
1972
1972
  );
1973
1973
  }
1974
1974
 
1975
+ // src/lib/contrast.ts
1976
+ var import_apca_w33 = require("apca-w3");
1977
+ var import_culori6 = require("culori");
1978
+
1979
+ // src/lib/semantic-palette-references.ts
1980
+ var STATUS_PALETTE_FAMILIES = {
1981
+ success: "green",
1982
+ warning: "orange",
1983
+ error: "red",
1984
+ information: "blue"
1985
+ };
1986
+ var CHART_PALETTE_REFERENCES = [
1987
+ { palette: "teal", light: "700", dark: "200" },
1988
+ { palette: "lime", light: "700", dark: "200" },
1989
+ { palette: "orange", light: "600", dark: "200" },
1990
+ { palette: "rose", light: "600", dark: "200" },
1991
+ { palette: "indigo", light: "600", dark: "200" }
1992
+ ];
1993
+ var SYNTAX_PALETTE_REFERENCES = {
1994
+ keyword: CHART_PALETTE_REFERENCES[3],
1995
+ string: CHART_PALETTE_REFERENCES[1],
1996
+ function: CHART_PALETTE_REFERENCES[4],
1997
+ type: CHART_PALETTE_REFERENCES[0],
1998
+ constant: CHART_PALETTE_REFERENCES[2]
1999
+ };
2000
+
2001
+ // src/lib/apca-pairs.ts
2002
+ var COLOR_FAMILIES = [
2003
+ "primary",
2004
+ "secondary",
2005
+ "success",
2006
+ "warning",
2007
+ "error",
2008
+ "information"
2009
+ ];
2010
+ var CATEGORICAL_INDICES = CHART_PALETTE_REFERENCES.map(
2011
+ (_, index) => index + 1
2012
+ );
2013
+ var CHART_STAGGER_LC = 4.5;
2014
+ var DIFF_SURFACES = ["success-subtle", "error-subtle"];
2015
+ var CODE_SURFACES = ["container", "container-hover", ...DIFF_SURFACES];
2016
+ var FOCUS_SURFACES = [
2017
+ "background",
2018
+ "container",
2019
+ "popover",
2020
+ "nav-background",
2021
+ "nav-item-hover",
2022
+ "nav-item-active",
2023
+ "nav-border"
2024
+ ];
2025
+ var text = (fg, bg, tier) => ({
2026
+ fg,
2027
+ bg,
2028
+ tier,
2029
+ kind: "text"
2030
+ });
2031
+ var label = (fg, bg, tier) => ({
2032
+ fg,
2033
+ bg,
2034
+ tier,
2035
+ kind: "label"
2036
+ });
2037
+ var ink = (fg, bg, tier) => ({
2038
+ fg,
2039
+ bg,
2040
+ tier,
2041
+ kind: "ink"
2042
+ });
2043
+ var APCA_PAIRS = [
2044
+ text("foreground", "background", "body"),
2045
+ text("foreground", "background-hover", "ui"),
2046
+ text("foreground", "muted", "ui"),
2047
+ text("muted-foreground", "muted", "ui"),
2048
+ text("muted-foreground-subtle", "muted", "incidental"),
2049
+ text("muted-foreground", "container", "ui"),
2050
+ text("muted-foreground-subtle", "container", "incidental"),
2051
+ text("foreground", "muted-extralight", "ui"),
2052
+ text("muted-foreground", "muted-extralight", "ui"),
2053
+ text("disabled-foreground", "disabled", "incidental"),
2054
+ text("container-foreground", "container", "body"),
2055
+ text("foreground", "container", "body"),
2056
+ text("popover-foreground", "popover", "body"),
2057
+ text("popover-foreground", "popover-hover", "ui"),
2058
+ text("foreground", "control-background", "ui"),
2059
+ text("foreground", "control-background-hover", "ui"),
2060
+ text("nav-foreground", "nav-background", "ui"),
2061
+ text("nav-muted-foreground", "nav-background", "incidental"),
2062
+ text("nav-foreground", "nav-item-hover", "ui"),
2063
+ text("nav-foreground", "nav-item-active", "ui"),
2064
+ ink("error-subtle-foreground", "background", "ui"),
2065
+ ink("error-subtle-foreground", "container", "ui"),
2066
+ ...COLOR_FAMILIES.flatMap((family) => [
2067
+ label(`${family}-foreground`, `${family}-background`, "ui"),
2068
+ label(`${family}-foreground`, `${family}-background-hover`, "ui"),
2069
+ label(`${family}-foreground`, `${family}-background-active`, "ui"),
2070
+ ink(`${family}-subtle-foreground`, `${family}-subtle`, "ui"),
2071
+ ink(`${family}-subtle-foreground`, `${family}-subtle-hover`, "ui"),
2072
+ ink(`${family}-subtle-foreground`, `${family}-subtle-active`, "ui")
2073
+ ]),
2074
+ ...CATEGORICAL_INDICES.flatMap(
2075
+ (index) => ["container", "container-hover", "background"].map((bg) => ({
2076
+ ...ink(`chart-categorical-${index}`, bg, "ui"),
2077
+ offset: (index - 1) * CHART_STAGGER_LC
2078
+ }))
2079
+ ),
2080
+ ...CODE_SURFACES.flatMap(
2081
+ (bg) => Object.keys(SYNTAX_PALETTE_REFERENCES).map(
2082
+ (role) => ink(`syntax-${role}`, bg, "ui")
2083
+ )
2084
+ ),
2085
+ // codeBlockTheme also colours code with the text tokens, which already read
2086
+ // on container and container-hover.
2087
+ ...DIFF_SURFACES.flatMap((bg) => [
2088
+ text("foreground", bg, "ui"),
2089
+ text("muted-foreground", bg, "ui"),
2090
+ text("muted-foreground-subtle", bg, "incidental")
2091
+ ]),
2092
+ // Focus is the primary accent (components.md § Focus States), so it shares
2093
+ // one solved color with primary-subtle-foreground.
2094
+ ...FOCUS_SURFACES.flatMap((surface) => [
2095
+ {
2096
+ ...ink("focus-default", surface, "incidental"),
2097
+ solveAs: "primary-subtle-foreground"
2098
+ },
2099
+ ink("focus-error", surface, "incidental")
2100
+ ]),
2101
+ ...[
2102
+ "background-active",
2103
+ "container-hover",
2104
+ "container-active",
2105
+ "popover",
2106
+ "popover-hover",
2107
+ "popover-active",
2108
+ "nav-background"
2109
+ ].flatMap((surface) => [
2110
+ text("foreground", surface, "ui"),
2111
+ text("muted-foreground", surface, "ui"),
2112
+ text("muted-foreground-subtle", surface, "incidental")
2113
+ ]),
2114
+ text("muted-foreground", "background", "ui"),
2115
+ text("muted-foreground-subtle", "background", "incidental"),
2116
+ text("container-foreground", "container-hover", "ui"),
2117
+ text("container-foreground", "container-active", "ui"),
2118
+ text("popover-foreground", "popover-active", "ui"),
2119
+ ...["background", "container", "popover"].flatMap((backdrop) => [
2120
+ { ...text("popover-foreground", "popover-alpha", "body"), backdrop },
2121
+ { ...text("foreground", "background-hover-alpha", "ui"), backdrop }
2122
+ ]),
2123
+ ...["#000000", "#ffffff"].map((backdrop) => ({
2124
+ ...text("popover-foreground", "popover-alpha", "body"),
2125
+ backdrop
2126
+ }))
2127
+ ];
2128
+
2129
+ // src/lib/perceptual-ramp.ts
2130
+ var import_culori5 = require("culori");
2131
+ var EMIT_GAMUT2 = "p3";
2132
+ var CUSP_FRACTION2 = 0.95;
2133
+ function isColor(value) {
2134
+ return (0, import_culori5.parse)(value) !== void 0;
2135
+ }
2136
+ function seedOklch(input) {
2137
+ const parsed = (0, import_culori5.parse)(input);
2138
+ if (!parsed)
2139
+ throw new Error(`perceptual-ramp: cannot parse color '${input}'`);
2140
+ const converted = (0, import_culori5.oklch)(parsed);
2141
+ if (!converted)
2142
+ throw new Error(`perceptual-ramp: cannot convert '${input}' to OKLCH`);
2143
+ return converted;
2144
+ }
2145
+ function pinnedOklch(seedHex, shade, options = {}) {
2146
+ const { capAtSeedChroma = true } = options;
2147
+ const seed = seedOklch(seedHex);
2148
+ const l = PERCEPTUAL_L_GRID[shade];
2149
+ const hue = seed.h ?? 0;
2150
+ const seedC = seed.c ?? 0;
2151
+ const cuspC = (0, import_culori5.clampChroma)({ mode: "oklch", l, c: 0.5, h: hue }, "oklch", EMIT_GAMUT2).c ?? 0;
2152
+ let chroma = cuspC * CUSP_FRACTION2;
2153
+ if (capAtSeedChroma) chroma = Math.min(chroma, seedC);
2154
+ const target = { mode: "oklch", l, c: chroma, h: hue };
2155
+ return formatOklch((0, import_culori5.clampChroma)(target, "oklch", EMIT_GAMUT2));
2156
+ }
2157
+ function rampFromSeed(seedHex, options = {}) {
2158
+ const ramp = {};
2159
+ for (const shade of SHADES)
2160
+ ramp[shade] = pinnedOklch(seedHex, shade, options);
2161
+ return ramp;
2162
+ }
2163
+
2164
+ // src/lib/contrast.ts
2165
+ var CONTRAST_MIN = 0;
2166
+ var CONTRAST_MAX = 100;
2167
+ function normalizeContrast(value, fallback = 50) {
2168
+ return typeof value === "number" && Number.isFinite(value) ? Math.round(Math.max(CONTRAST_MIN, Math.min(CONTRAST_MAX, value))) : fallback;
2169
+ }
2170
+ function contrastTarget(tier, contrast) {
2171
+ return TIER_THRESHOLDS[tier] + 15 * contrast / 100;
2172
+ }
2173
+ var BISECT_STEPS = 12;
2174
+ function bisect(fail, pass, passes) {
2175
+ for (let i = 0; i < BISECT_STEPS; i++) {
2176
+ const middle = (fail + pass) / 2;
2177
+ if (passes(middle)) pass = middle;
2178
+ else fail = middle;
2179
+ }
2180
+ return pass;
2181
+ }
2182
+ var token = (map, name) => {
2183
+ const value = map[`--nx-color-${name}`];
2184
+ if (value === void 0) throw new Error(`contrast: missing ${name}`);
2185
+ return value;
2186
+ };
2187
+ function pairBackground(map, pair) {
2188
+ const backdrop = pair.backdrop ? resolveToSrgbInts(
2189
+ pair.backdrop.startsWith("#") ? pair.backdrop : token(map, pair.backdrop)
2190
+ ) : void 0;
2191
+ return resolveToSrgbInts(token(map, pair.bg), backdrop);
2192
+ }
2193
+ function contrastForPair(map, pair) {
2194
+ const background = pairBackground(map, pair);
2195
+ return Math.abs(
2196
+ (0, import_apca_w33.APCAcontrast)(
2197
+ (0, import_apca_w33.sRGBtoY)(resolveToSrgbInts(token(map, pair.fg), background)),
2198
+ (0, import_apca_w33.sRGBtoY)(background)
2199
+ )
2200
+ );
2201
+ }
2202
+ var luminance = (color) => (0, import_apca_w33.sRGBtoY)(resolveToSrgbInts(color));
2203
+ var score = (foregroundY, backgroundY) => Math.abs((0, import_apca_w33.APCAcontrast)(foregroundY, backgroundY));
2204
+ function constraintsFor(map, pairs, contrast, endpointY) {
2205
+ const constraints = [];
2206
+ for (const pair of pairs) {
2207
+ const backgroundY = (0, import_apca_w33.sRGBtoY)(pairBackground(map, pair));
2208
+ const reachable = score(endpointY, backgroundY);
2209
+ if (reachable < TIER_THRESHOLDS[pair.tier]) return void 0;
2210
+ const target = contrastTarget(pair.tier, contrast) + (pair.offset ?? 0);
2211
+ constraints.push({ backgroundY, target: Math.min(target, reachable) });
2212
+ }
2213
+ return constraints;
2214
+ }
2215
+ var keepsTextSeed = (mode, kind) => mode === "light" && kind === "text";
2216
+ function solveForeground(seed, constraints, endpoint, keepSeed) {
2217
+ const passes = (color) => {
2218
+ const y = luminance(color);
2219
+ return constraints.every((c) => score(y, c.backgroundY) >= c.target);
2220
+ };
2221
+ if (keepSeed && passes(seed)) return seed;
2222
+ const parsed = seedOklch(seed);
2223
+ const at = (l) => formatOklch((0, import_culori6.clampChroma)({ ...parsed, l, alpha: 1 }, "oklch", "p3"));
2224
+ return at(
2225
+ bisect(keepSeed ? parsed.l : 1 - endpoint, endpoint, (l) => passes(at(l)))
2226
+ );
2227
+ }
2228
+ var SOLVE_GROUPS = /* @__PURE__ */ new Map();
2229
+ for (const pair of APCA_PAIRS) {
2230
+ const key = pair.solveAs ?? pair.fg;
2231
+ const group = SOLVE_GROUPS.get(key);
2232
+ if (!group) {
2233
+ SOLVE_GROUPS.set(key, { kind: pair.kind, pairs: [pair] });
2234
+ continue;
2235
+ }
2236
+ if (group.kind !== pair.kind)
2237
+ throw new Error(
2238
+ `contrast: ${pair.fg} is '${pair.kind}' but joins '${group.kind}' group ${key}`
2239
+ );
2240
+ group.pairs.push(pair);
2241
+ }
2242
+ function constrainFamilyFills(map, name, pairs) {
2243
+ const basePair = pairs[0];
2244
+ if (!basePair) throw new Error(`contrast: missing pairs for ${name}`);
2245
+ const baseY = luminance(token(map, basePair.bg));
2246
+ const endpoint = score(1, baseY) >= score(0, baseY) ? 1 : 0;
2247
+ map[`--nx-color-${name}`] = `oklch(${endpoint} 0 0)`;
2248
+ for (const pair of pairs) {
2249
+ const floor = TIER_THRESHOLDS[pair.tier];
2250
+ const value = token(map, pair.bg);
2251
+ if (score(endpoint, luminance(value)) >= floor) continue;
2252
+ const fill = seedOklch(value);
2253
+ const at = (l) => formatOklch((0, import_culori6.clampChroma)({ ...fill, l }, "oklch", "p3"));
2254
+ const readable = (l) => score(endpoint, luminance(at(l))) >= floor;
2255
+ map[`--nx-color-${pair.bg}`] = at(bisect(fill.l, 1 - endpoint, readable));
2256
+ }
2257
+ }
2258
+ function constrainColors(map, mode, contrast) {
2259
+ for (const [name, { kind, pairs }] of SOLVE_GROUPS)
2260
+ if (kind === "label") constrainFamilyFills(map, name, pairs);
2261
+ const endpoint = mode === "dark" ? 1 : 0;
2262
+ const endpointY = luminance(`oklch(${endpoint} 0 0)`);
2263
+ for (const [name, { kind, pairs }] of SOLVE_GROUPS) {
2264
+ if (kind === "label") continue;
2265
+ const constraints = constraintsFor(map, pairs, contrast, endpointY);
2266
+ if (constraints === void 0)
2267
+ throw new Error(`contrast: no readable ${name} in ${mode}`);
2268
+ const solved = solveForeground(
2269
+ token(map, name),
2270
+ constraints,
2271
+ endpoint,
2272
+ keepsTextSeed(mode, kind)
2273
+ );
2274
+ for (const fg of new Set(pairs.map((pair) => pair.fg).concat(name)))
2275
+ map[`--nx-color-${fg}`] = solved;
2276
+ }
2277
+ return map;
2278
+ }
2279
+
2280
+ // src/lib/runtime-layer.ts
2281
+ var RUNTIME_LAYER_ORDER = "@layer properties, theme, base, components, utilities, nx-runtime;";
2282
+ function inRuntimeLayer(css) {
2283
+ return `${RUNTIME_LAYER_ORDER}
2284
+ @layer nx-runtime {
2285
+ ${css}
2286
+ }
2287
+ `;
2288
+ }
2289
+
1975
2290
  // tokens/primitives/typography/typography-default.json
1976
2291
  var typography_default_default = {
1977
2292
  family: {
@@ -2110,6 +2425,13 @@ var typography_default_default = {
2110
2425
  unit: "px"
2111
2426
  },
2112
2427
  $type: "dimension"
2428
+ },
2429
+ code: {
2430
+ $value: {
2431
+ value: 12,
2432
+ unit: "px"
2433
+ },
2434
+ $type: "dimension"
2113
2435
  }
2114
2436
  },
2115
2437
  weight: {
@@ -2231,384 +2553,93 @@ var typography_default_default = {
2231
2553
  "7xl": {
2232
2554
  $value: {
2233
2555
  value: 72,
2234
- unit: "px"
2235
- },
2236
- $type: "dimension"
2237
- },
2238
- "8xl": {
2239
- $value: {
2240
- value: 96,
2241
- unit: "px"
2242
- },
2243
- $type: "dimension"
2244
- },
2245
- "9xl": {
2246
- $value: {
2247
- value: 128,
2248
- unit: "px"
2249
- },
2250
- $type: "dimension"
2251
- }
2252
- },
2253
- letterspacing: {
2254
- tighter: {
2255
- $value: {
2256
- value: -0.800000011920929,
2257
- unit: "px"
2258
- },
2259
- $type: "dimension"
2260
- },
2261
- tight: {
2262
- $value: {
2263
- value: -0.4000000059604645,
2264
- unit: "px"
2265
- },
2266
- $type: "dimension"
2267
- },
2268
- normal: {
2269
- $value: {
2270
- value: 0,
2271
- unit: "px"
2272
- },
2273
- $type: "dimension"
2274
- },
2275
- wide: {
2276
- $value: {
2277
- value: 0.4000000059604645,
2278
- unit: "px"
2279
- },
2280
- $type: "dimension"
2281
- },
2282
- wider: {
2283
- $value: {
2284
- value: 0.800000011920929,
2285
- unit: "px"
2286
- },
2287
- $type: "dimension"
2288
- },
2289
- widest: {
2290
- $value: {
2291
- value: 1.600000023841858,
2292
- unit: "px"
2293
- },
2294
- $type: "dimension"
2295
- }
2296
- }
2297
- };
2298
-
2299
- // src/lib/contrast.ts
2300
- var import_apca_w33 = require("apca-w3");
2301
- var import_culori6 = require("culori");
2302
-
2303
- // src/lib/semantic-palette-references.ts
2304
- var STATUS_PALETTE_FAMILIES = {
2305
- success: "green",
2306
- warning: "orange",
2307
- error: "red",
2308
- information: "blue"
2309
- };
2310
- var CHART_PALETTE_REFERENCES = [
2311
- { palette: "teal", light: "700", dark: "200" },
2312
- { palette: "lime", light: "700", dark: "200" },
2313
- { palette: "orange", light: "600", dark: "200" },
2314
- { palette: "rose", light: "600", dark: "200" },
2315
- { palette: "indigo", light: "600", dark: "200" }
2316
- ];
2317
- var SYNTAX_PALETTE_REFERENCES = {
2318
- keyword: CHART_PALETTE_REFERENCES[3],
2319
- string: CHART_PALETTE_REFERENCES[1],
2320
- function: CHART_PALETTE_REFERENCES[4],
2321
- type: CHART_PALETTE_REFERENCES[0],
2322
- constant: CHART_PALETTE_REFERENCES[2]
2323
- };
2324
-
2325
- // src/lib/apca-pairs.ts
2326
- var COLOR_FAMILIES = [
2327
- "primary",
2328
- "secondary",
2329
- "success",
2330
- "warning",
2331
- "error",
2332
- "information"
2333
- ];
2334
- var CATEGORICAL_INDICES = CHART_PALETTE_REFERENCES.map(
2335
- (_, index) => index + 1
2336
- );
2337
- var CHART_STAGGER_LC = 4.5;
2338
- var DIFF_SURFACES = ["success-subtle", "error-subtle"];
2339
- var CODE_SURFACES = ["container", "container-hover", ...DIFF_SURFACES];
2340
- var FOCUS_SURFACES = [
2341
- "background",
2342
- "container",
2343
- "popover",
2344
- "nav-background",
2345
- "nav-item-hover",
2346
- "nav-item-active",
2347
- "nav-border"
2348
- ];
2349
- var text = (fg, bg, tier) => ({
2350
- fg,
2351
- bg,
2352
- tier,
2353
- kind: "text"
2354
- });
2355
- var label = (fg, bg, tier) => ({
2356
- fg,
2357
- bg,
2358
- tier,
2359
- kind: "label"
2360
- });
2361
- var ink = (fg, bg, tier) => ({
2362
- fg,
2363
- bg,
2364
- tier,
2365
- kind: "ink"
2366
- });
2367
- var APCA_PAIRS = [
2368
- text("foreground", "background", "body"),
2369
- text("foreground", "background-hover", "ui"),
2370
- text("foreground", "muted", "ui"),
2371
- text("muted-foreground", "muted", "ui"),
2372
- text("muted-foreground-subtle", "muted", "incidental"),
2373
- text("muted-foreground", "container", "ui"),
2374
- text("muted-foreground-subtle", "container", "incidental"),
2375
- text("foreground", "muted-extralight", "ui"),
2376
- text("muted-foreground", "muted-extralight", "ui"),
2377
- text("disabled-foreground", "disabled", "incidental"),
2378
- text("container-foreground", "container", "body"),
2379
- text("foreground", "container", "body"),
2380
- text("popover-foreground", "popover", "body"),
2381
- text("popover-foreground", "popover-hover", "ui"),
2382
- text("foreground", "control-background", "ui"),
2383
- text("foreground", "control-background-hover", "ui"),
2384
- text("nav-foreground", "nav-background", "ui"),
2385
- text("nav-muted-foreground", "nav-background", "incidental"),
2386
- text("nav-foreground", "nav-item-hover", "ui"),
2387
- text("nav-foreground", "nav-item-active", "ui"),
2388
- ink("error-subtle-foreground", "background", "ui"),
2389
- ink("error-subtle-foreground", "container", "ui"),
2390
- ...COLOR_FAMILIES.flatMap((family) => [
2391
- label(`${family}-foreground`, `${family}-background`, "ui"),
2392
- label(`${family}-foreground`, `${family}-background-hover`, "ui"),
2393
- label(`${family}-foreground`, `${family}-background-active`, "ui"),
2394
- ink(`${family}-subtle-foreground`, `${family}-subtle`, "ui"),
2395
- ink(`${family}-subtle-foreground`, `${family}-subtle-hover`, "ui"),
2396
- ink(`${family}-subtle-foreground`, `${family}-subtle-active`, "ui")
2397
- ]),
2398
- ...CATEGORICAL_INDICES.flatMap(
2399
- (index) => ["container", "container-hover", "background"].map((bg) => ({
2400
- ...ink(`chart-categorical-${index}`, bg, "ui"),
2401
- offset: (index - 1) * CHART_STAGGER_LC
2402
- }))
2403
- ),
2404
- ...CODE_SURFACES.flatMap(
2405
- (bg) => Object.keys(SYNTAX_PALETTE_REFERENCES).map(
2406
- (role) => ink(`syntax-${role}`, bg, "ui")
2407
- )
2408
- ),
2409
- // codeBlockTheme also colours code with the text tokens, which already read
2410
- // on container and container-hover.
2411
- ...DIFF_SURFACES.flatMap((bg) => [
2412
- text("foreground", bg, "ui"),
2413
- text("muted-foreground", bg, "ui"),
2414
- text("muted-foreground-subtle", bg, "incidental")
2415
- ]),
2416
- // Focus is the primary accent (components.md § Focus States), so it shares
2417
- // one solved color with primary-subtle-foreground.
2418
- ...FOCUS_SURFACES.flatMap((surface) => [
2419
- {
2420
- ...ink("focus-default", surface, "incidental"),
2421
- solveAs: "primary-subtle-foreground"
2556
+ unit: "px"
2557
+ },
2558
+ $type: "dimension"
2422
2559
  },
2423
- ink("focus-error", surface, "incidental")
2424
- ]),
2425
- ...[
2426
- "background-active",
2427
- "container-hover",
2428
- "container-active",
2429
- "popover",
2430
- "popover-hover",
2431
- "popover-active",
2432
- "nav-background"
2433
- ].flatMap((surface) => [
2434
- text("foreground", surface, "ui"),
2435
- text("muted-foreground", surface, "ui"),
2436
- text("muted-foreground-subtle", surface, "incidental")
2437
- ]),
2438
- text("muted-foreground", "background", "ui"),
2439
- text("muted-foreground-subtle", "background", "incidental"),
2440
- text("container-foreground", "container-hover", "ui"),
2441
- text("container-foreground", "container-active", "ui"),
2442
- text("popover-foreground", "popover-active", "ui"),
2443
- ...["background", "container", "popover"].flatMap((backdrop) => [
2444
- { ...text("popover-foreground", "popover-alpha", "body"), backdrop },
2445
- { ...text("foreground", "background-hover-alpha", "ui"), backdrop }
2446
- ]),
2447
- ...["#000000", "#ffffff"].map((backdrop) => ({
2448
- ...text("popover-foreground", "popover-alpha", "body"),
2449
- backdrop
2450
- }))
2451
- ];
2452
-
2453
- // src/lib/perceptual-ramp.ts
2454
- var import_culori5 = require("culori");
2455
- var EMIT_GAMUT2 = "p3";
2456
- var CUSP_FRACTION2 = 0.95;
2457
- function isColor(value) {
2458
- return (0, import_culori5.parse)(value) !== void 0;
2459
- }
2460
- function seedOklch(input) {
2461
- const parsed = (0, import_culori5.parse)(input);
2462
- if (!parsed)
2463
- throw new Error(`perceptual-ramp: cannot parse color '${input}'`);
2464
- const converted = (0, import_culori5.oklch)(parsed);
2465
- if (!converted)
2466
- throw new Error(`perceptual-ramp: cannot convert '${input}' to OKLCH`);
2467
- return converted;
2468
- }
2469
- function pinnedOklch(seedHex, shade, options = {}) {
2470
- const { capAtSeedChroma = true } = options;
2471
- const seed = seedOklch(seedHex);
2472
- const l = PERCEPTUAL_L_GRID[shade];
2473
- const hue = seed.h ?? 0;
2474
- const seedC = seed.c ?? 0;
2475
- const cuspC = (0, import_culori5.clampChroma)({ mode: "oklch", l, c: 0.5, h: hue }, "oklch", EMIT_GAMUT2).c ?? 0;
2476
- let chroma = cuspC * CUSP_FRACTION2;
2477
- if (capAtSeedChroma) chroma = Math.min(chroma, seedC);
2478
- const target = { mode: "oklch", l, c: chroma, h: hue };
2479
- return formatOklch((0, import_culori5.clampChroma)(target, "oklch", EMIT_GAMUT2));
2480
- }
2481
- function rampFromSeed(seedHex, options = {}) {
2482
- const ramp = {};
2483
- for (const shade of SHADES)
2484
- ramp[shade] = pinnedOklch(seedHex, shade, options);
2485
- return ramp;
2486
- }
2487
-
2488
- // src/lib/contrast.ts
2489
- var CONTRAST_MIN = 0;
2490
- var CONTRAST_MAX = 100;
2491
- function normalizeContrast(value, fallback = 50) {
2492
- return typeof value === "number" && Number.isFinite(value) ? Math.round(Math.max(CONTRAST_MIN, Math.min(CONTRAST_MAX, value))) : fallback;
2493
- }
2494
- function contrastTarget(tier, contrast) {
2495
- return TIER_THRESHOLDS[tier] + 15 * contrast / 100;
2496
- }
2497
- var BISECT_STEPS = 12;
2498
- function bisect(fail, pass, passes) {
2499
- for (let i = 0; i < BISECT_STEPS; i++) {
2500
- const middle = (fail + pass) / 2;
2501
- if (passes(middle)) pass = middle;
2502
- else fail = middle;
2560
+ "8xl": {
2561
+ $value: {
2562
+ value: 96,
2563
+ unit: "px"
2564
+ },
2565
+ $type: "dimension"
2566
+ },
2567
+ "9xl": {
2568
+ $value: {
2569
+ value: 128,
2570
+ unit: "px"
2571
+ },
2572
+ $type: "dimension"
2573
+ }
2574
+ },
2575
+ letterspacing: {
2576
+ tighter: {
2577
+ $value: {
2578
+ value: -0.800000011920929,
2579
+ unit: "px"
2580
+ },
2581
+ $type: "dimension"
2582
+ },
2583
+ tight: {
2584
+ $value: {
2585
+ value: -0.4000000059604645,
2586
+ unit: "px"
2587
+ },
2588
+ $type: "dimension"
2589
+ },
2590
+ normal: {
2591
+ $value: {
2592
+ value: 0,
2593
+ unit: "px"
2594
+ },
2595
+ $type: "dimension"
2596
+ },
2597
+ wide: {
2598
+ $value: {
2599
+ value: 0.4000000059604645,
2600
+ unit: "px"
2601
+ },
2602
+ $type: "dimension"
2603
+ },
2604
+ wider: {
2605
+ $value: {
2606
+ value: 0.800000011920929,
2607
+ unit: "px"
2608
+ },
2609
+ $type: "dimension"
2610
+ },
2611
+ widest: {
2612
+ $value: {
2613
+ value: 1.600000023841858,
2614
+ unit: "px"
2615
+ },
2616
+ $type: "dimension"
2617
+ }
2503
2618
  }
2504
- return pass;
2505
- }
2506
- var token = (map, name) => {
2507
- const value = map[`--nx-color-${name}`];
2508
- if (value === void 0) throw new Error(`contrast: missing ${name}`);
2509
- return value;
2510
2619
  };
2511
- function pairBackground(map, pair) {
2512
- const backdrop = pair.backdrop ? resolveToSrgbInts(
2513
- pair.backdrop.startsWith("#") ? pair.backdrop : token(map, pair.backdrop)
2514
- ) : void 0;
2515
- return resolveToSrgbInts(token(map, pair.bg), backdrop);
2516
- }
2517
- function contrastForPair(map, pair) {
2518
- const background = pairBackground(map, pair);
2519
- return Math.abs(
2520
- (0, import_apca_w33.APCAcontrast)(
2521
- (0, import_apca_w33.sRGBtoY)(resolveToSrgbInts(token(map, pair.fg), background)),
2522
- (0, import_apca_w33.sRGBtoY)(background)
2523
- )
2524
- );
2525
- }
2526
- var luminance = (color) => (0, import_apca_w33.sRGBtoY)(resolveToSrgbInts(color));
2527
- var score = (foregroundY, backgroundY) => Math.abs((0, import_apca_w33.APCAcontrast)(foregroundY, backgroundY));
2528
- function constraintsFor(map, pairs, contrast, endpointY) {
2529
- const constraints = [];
2530
- for (const pair of pairs) {
2531
- const backgroundY = (0, import_apca_w33.sRGBtoY)(pairBackground(map, pair));
2532
- const reachable = score(endpointY, backgroundY);
2533
- if (reachable < TIER_THRESHOLDS[pair.tier]) return void 0;
2534
- const target = contrastTarget(pair.tier, contrast) + (pair.offset ?? 0);
2535
- constraints.push({ backgroundY, target: Math.min(target, reachable) });
2536
- }
2537
- return constraints;
2538
- }
2539
- var keepsTextSeed = (mode, kind) => mode === "light" && kind === "text";
2540
- function solveForeground(seed, constraints, endpoint, keepSeed) {
2541
- const passes = (color) => {
2542
- const y = luminance(color);
2543
- return constraints.every((c) => score(y, c.backgroundY) >= c.target);
2544
- };
2545
- if (keepSeed && passes(seed)) return seed;
2546
- const parsed = seedOklch(seed);
2547
- const at = (l) => formatOklch((0, import_culori6.clampChroma)({ ...parsed, l, alpha: 1 }, "oklch", "p3"));
2548
- return at(
2549
- bisect(keepSeed ? parsed.l : 1 - endpoint, endpoint, (l) => passes(at(l)))
2550
- );
2551
- }
2552
- var SOLVE_GROUPS = /* @__PURE__ */ new Map();
2553
- for (const pair of APCA_PAIRS) {
2554
- const key = pair.solveAs ?? pair.fg;
2555
- const group = SOLVE_GROUPS.get(key);
2556
- if (!group) {
2557
- SOLVE_GROUPS.set(key, { kind: pair.kind, pairs: [pair] });
2558
- continue;
2559
- }
2560
- if (group.kind !== pair.kind)
2561
- throw new Error(
2562
- `contrast: ${pair.fg} is '${pair.kind}' but joins '${group.kind}' group ${key}`
2563
- );
2564
- group.pairs.push(pair);
2565
- }
2566
- function constrainFamilyFills(map, name, pairs) {
2567
- const basePair = pairs[0];
2568
- if (!basePair) throw new Error(`contrast: missing pairs for ${name}`);
2569
- const baseY = luminance(token(map, basePair.bg));
2570
- const endpoint = score(1, baseY) >= score(0, baseY) ? 1 : 0;
2571
- map[`--nx-color-${name}`] = `oklch(${endpoint} 0 0)`;
2572
- for (const pair of pairs) {
2573
- const floor = TIER_THRESHOLDS[pair.tier];
2574
- const value = token(map, pair.bg);
2575
- if (score(endpoint, luminance(value)) >= floor) continue;
2576
- const fill = seedOklch(value);
2577
- const at = (l) => formatOklch((0, import_culori6.clampChroma)({ ...fill, l }, "oklch", "p3"));
2578
- const readable = (l) => score(endpoint, luminance(at(l))) >= floor;
2579
- map[`--nx-color-${pair.bg}`] = at(bisect(fill.l, 1 - endpoint, readable));
2580
- }
2581
- }
2582
- function constrainColors(map, mode, contrast) {
2583
- for (const [name, { kind, pairs }] of SOLVE_GROUPS)
2584
- if (kind === "label") constrainFamilyFills(map, name, pairs);
2585
- const endpoint = mode === "dark" ? 1 : 0;
2586
- const endpointY = luminance(`oklch(${endpoint} 0 0)`);
2587
- for (const [name, { kind, pairs }] of SOLVE_GROUPS) {
2588
- if (kind === "label") continue;
2589
- const constraints = constraintsFor(map, pairs, contrast, endpointY);
2590
- if (constraints === void 0)
2591
- throw new Error(`contrast: no readable ${name} in ${mode}`);
2592
- const solved = solveForeground(
2593
- token(map, name),
2594
- constraints,
2595
- endpoint,
2596
- keepsTextSeed(mode, kind)
2597
- );
2598
- for (const fg of new Set(pairs.map((pair) => pair.fg).concat(name)))
2599
- map[`--nx-color-${fg}`] = solved;
2600
- }
2601
- return map;
2602
- }
2603
2620
 
2604
- // src/lib/runtime-layer.ts
2605
- var RUNTIME_LAYER_ORDER = "@layer properties, theme, base, components, utilities, nx-runtime;";
2606
- function inRuntimeLayer(css) {
2607
- return `${RUNTIME_LAYER_ORDER}
2608
- @layer nx-runtime {
2609
- ${css}
2621
+ // src/lib/typography-scale.ts
2622
+ var TYPOGRAPHY_BASE_PX = 14;
2623
+ function formatPx(value) {
2624
+ return `${Number(value.toFixed(4))}px`;
2610
2625
  }
2611
- `;
2626
+ var CODE_SIZE = "code";
2627
+ function typographyScale(uiPx, codePx) {
2628
+ const scale = uiPx / TYPOGRAPHY_BASE_PX;
2629
+ return new Map([
2630
+ ...Object.entries(typography_default_default.size).map(
2631
+ ([name, token2]) => [
2632
+ `--nx-typography-size-${name}`,
2633
+ formatPx(name === CODE_SIZE ? codePx : token2.$value.value * scale)
2634
+ ]
2635
+ ),
2636
+ ...Object.entries(typography_default_default["line-height"]).map(
2637
+ ([name, token2]) => [
2638
+ `--nx-typography-line-height-${name}`,
2639
+ formatPx(token2.$value.value * scale)
2640
+ ]
2641
+ )
2642
+ ]);
2612
2643
  }
2613
2644
 
2614
2645
  // src/lib/appearance-model.ts
@@ -2683,7 +2714,7 @@ var DEFAULT_NXDS_APPEARANCE = {
2683
2714
  uiFont: '-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
2684
2715
  headingFont: null,
2685
2716
  codeFont: 'ui-monospace, "SF Mono", Menlo, monospace',
2686
- uiFontSize: 14,
2717
+ uiFontSize: TYPOGRAPHY_BASE_PX,
2687
2718
  codeFontSize: 12,
2688
2719
  reduceMotion: false,
2689
2720
  pointerCursors: false,
@@ -2718,18 +2749,8 @@ var fontFamilyOr = (value, fallback) => typeof value === "string" && value.lengt
2718
2749
  var boolOr = (value, fallback) => typeof value === "boolean" ? value : fallback;
2719
2750
  var enumOr = (value, values, fallback) => typeof value === "string" && values.has(value) ? value : fallback;
2720
2751
  var clampFontSize = (value, fallback) => typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.min(FONT_SIZE_PX_MAX, Math.max(FONT_SIZE_PX_MIN, value)) : fallback;
2721
- function formatPx(value) {
2722
- return `${Number(value.toFixed(4))}px`;
2723
- }
2724
- function typographyScaleVariables(uiPx) {
2725
- const scale = uiPx / DEFAULT_NXDS_APPEARANCE.prefs.uiFontSize;
2726
- const sizeVars = Object.entries(typography_default_default.size).map(
2727
- ([name, token2]) => ` --nx-typography-size-${name}: ${formatPx(token2.$value.value * scale)};`
2728
- );
2729
- const lineHeightVars = Object.entries(typography_default_default["line-height"]).map(
2730
- ([name, token2]) => ` --nx-typography-line-height-${name}: ${formatPx(token2.$value.value * scale)};`
2731
- );
2732
- return [...sizeVars, ...lineHeightVars].join("\n");
2752
+ function typographyScaleVariables(uiPx, codePx) {
2753
+ return [...typographyScale(uiPx, codePx)].map(([name, value]) => ` ${name}: ${value};`).join("\n");
2733
2754
  }
2734
2755
  var PUBLIC_MODE_RENAME = {
2735
2756
  density: {
@@ -2817,9 +2838,8 @@ function appearancePrefsToCss(prefs) {
2817
2838
  --nx-typography-family-font-sans: ${prefs.uiFont};
2818
2839
  --nx-typography-family-font-heading: ${prefs.headingFont ?? "var(--nx-typography-family-font-sans)"};
2819
2840
  --nx-typography-family-font-mono: ${prefs.codeFont};
2820
- ${typographyScaleVariables(uiPx)}
2821
- }`),
2822
- `.nx\\:font-mono, .nx\\:typography-code-block, .nx\\:typography-code-inline { font-size: ${codePx}px; }`
2841
+ ${typographyScaleVariables(uiPx, codePx)}
2842
+ }`)
2823
2843
  ];
2824
2844
  if (prefs.fontSmoothing) {
2825
2845
  blocks.push(