silvery 0.18.2 → 0.19.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.
Files changed (156) hide show
  1. package/dist/{animation-DhINOJk8.mjs → animation-Cn64yepo.mjs} +1 -1
  2. package/dist/{animation-DhINOJk8.mjs.map → animation-Cn64yepo.mjs.map} +1 -1
  3. package/dist/{ansi-C6Qs1Wn2.mjs → ansi-CLOitHKx.mjs} +1 -1
  4. package/dist/ansi-CLOitHKx.mjs.map +1 -0
  5. package/dist/{ansi-CsjnZtAw.d.mts → ansi-Cc33mW54.d.mts} +1 -1
  6. package/dist/{ansi-CsjnZtAw.d.mts.map → ansi-Cc33mW54.d.mts.map} +1 -1
  7. package/dist/{chunk-BSw8zbkd.mjs → chunk-Vs_PY4HZ.mjs} +1 -1
  8. package/dist/cli-BKp0YtBD.mjs +4 -0
  9. package/dist/{context-BjWgrikx.mjs → context-BU5LkkIy.mjs} +8 -7
  10. package/dist/context-BU5LkkIy.mjs.map +1 -0
  11. package/dist/devtools-9QY4teqI.mjs +2 -0
  12. package/dist/{devtools-CeO9X_uv.mjs → devtools-DxkSLXDA.mjs} +4 -5
  13. package/dist/devtools-DxkSLXDA.mjs.map +1 -0
  14. package/dist/{eta-BnQSZcWf.mjs → eta-Bb3RH3wh.mjs} +1 -1
  15. package/dist/{eta-BnQSZcWf.mjs.map → eta-Bb3RH3wh.mjs.map} +1 -1
  16. package/dist/{flexily-zero-adapter-BOM0cl8R.mjs → flexily-zero-adapter-BlQa46nr.mjs} +21 -64
  17. package/dist/flexily-zero-adapter-BlQa46nr.mjs.map +1 -0
  18. package/dist/{flexily-zero-adapter-V8R3HQtK.mjs → flexily-zero-adapter-CMxXhdOL.mjs} +1 -1
  19. package/dist/{image-B0zMbVUr.mjs → image-CTII5QWI.mjs} +3 -3
  20. package/dist/image-CTII5QWI.mjs.map +1 -0
  21. package/dist/{index-Bh3U1K09.d.mts → index-BXslOebb.d.mts} +547 -137
  22. package/dist/index-BXslOebb.d.mts.map +1 -0
  23. package/dist/{index-C4vrhbud.d.mts → index-BnA7mNpo.d.mts} +1 -1
  24. package/dist/{index-C4vrhbud.d.mts.map → index-BnA7mNpo.d.mts.map} +1 -1
  25. package/dist/index-D3saHouR.d.mts +1392 -0
  26. package/dist/index-D3saHouR.d.mts.map +1 -0
  27. package/dist/index.d.mts +5 -33
  28. package/dist/index.d.mts.map +1 -1
  29. package/dist/index.mjs +13 -13
  30. package/dist/{layout-engine--drvrWjD.mjs → layout-engine-B6Cdz1yZ.mjs} +1 -1
  31. package/dist/{layout-engine-Dr3cY5U4.mjs → layout-engine-ClUgv6jB.mjs} +3 -3
  32. package/dist/{layout-engine-Dr3cY5U4.mjs.map → layout-engine-ClUgv6jB.mjs.map} +1 -1
  33. package/dist/{multi-progress-CcdqJFlf.mjs → multi-progress-Bq9Oi_WI.mjs} +3 -3
  34. package/dist/{multi-progress-CcdqJFlf.mjs.map → multi-progress-Bq9Oi_WI.mjs.map} +1 -1
  35. package/dist/{multi-progress-DQ-uUzLf.d.mts → multi-progress-DAQC7eap.d.mts} +2 -2
  36. package/dist/{multi-progress-DQ-uUzLf.d.mts.map → multi-progress-DAQC7eap.d.mts.map} +1 -1
  37. package/dist/{node-CP5WChgr.mjs → node-BeWlnCPY.mjs} +4 -4
  38. package/dist/node-BeWlnCPY.mjs.map +1 -0
  39. package/dist/{progress-bar-IrUjkLfU.mjs → progress-bar-CXE5Qfkd.mjs} +4 -4
  40. package/dist/progress-bar-CXE5Qfkd.mjs.map +1 -0
  41. package/dist/reconciler-Cwgm8hRR.mjs +8459 -0
  42. package/dist/reconciler-Cwgm8hRR.mjs.map +1 -0
  43. package/dist/{render-string-DVfgc8xr.mjs → render-string-Cbuf63Ya.mjs} +936 -136
  44. package/dist/render-string-Cbuf63Ya.mjs.map +1 -0
  45. package/dist/{render-string-BwLG7rIX.mjs → render-string-Tv-jqM16.mjs} +1 -1
  46. package/dist/runtime.d.mts +2 -2
  47. package/dist/runtime.mjs +3 -3
  48. package/dist/{spinner-BRkaJI0N.d.mts → spinner-CGo34vyR.d.mts} +2 -2
  49. package/dist/{spinner-BRkaJI0N.d.mts.map → spinner-CGo34vyR.d.mts.map} +1 -1
  50. package/dist/{spinner-BmldKx0M.mjs → spinner-CeOmcuw_.mjs} +3 -3
  51. package/dist/spinner-CeOmcuw_.mjs.map +1 -0
  52. package/dist/src-B5GjfG7g.mjs +4305 -0
  53. package/dist/src-B5GjfG7g.mjs.map +1 -0
  54. package/dist/{src-CJPXf3fC.mjs → src-C2uvC-r0.mjs} +7535 -6467
  55. package/dist/src-C2uvC-r0.mjs.map +1 -0
  56. package/dist/{src-D8kLrQBT.mjs → src-CChwjk0Z.mjs} +8 -86
  57. package/dist/src-CChwjk0Z.mjs.map +1 -0
  58. package/dist/{src-D_BS-as7.mjs → src-NCKb8kE5.mjs} +777 -776
  59. package/dist/src-NCKb8kE5.mjs.map +1 -0
  60. package/dist/theme.d.mts +2 -130
  61. package/dist/theme.mjs +3 -8
  62. package/dist/{types-B4A8Ebba.d.mts → types-BH_v3iMT.d.mts} +1 -1
  63. package/dist/{types-B4A8Ebba.d.mts.map → types-BH_v3iMT.d.mts.map} +1 -1
  64. package/dist/{types-e4dpfbSa.mjs → types-Bk2yw9Qj.mjs} +3 -3
  65. package/dist/types-Bk2yw9Qj.mjs.map +1 -0
  66. package/dist/ui/animation.d.mts +1 -1
  67. package/dist/ui/animation.mjs +1 -1
  68. package/dist/ui/ansi.d.mts +1 -1
  69. package/dist/ui/ansi.mjs +1 -1
  70. package/dist/ui/cli.d.mts +3 -3
  71. package/dist/ui/cli.mjs +5 -5
  72. package/dist/ui/display.d.mts +1 -1
  73. package/dist/ui/display.mjs.map +1 -1
  74. package/dist/ui/image.d.mts +1 -1
  75. package/dist/ui/image.mjs +1 -1
  76. package/dist/ui/input.d.mts +1 -1
  77. package/dist/ui/input.d.mts.map +1 -1
  78. package/dist/ui/input.mjs +2 -4
  79. package/dist/ui/input.mjs.map +1 -1
  80. package/dist/ui/progress.d.mts +3 -3
  81. package/dist/ui/progress.d.mts.map +1 -1
  82. package/dist/ui/progress.mjs +3 -3
  83. package/dist/ui/progress.mjs.map +1 -1
  84. package/dist/ui/react.d.mts +1 -1
  85. package/dist/ui/react.d.mts.map +1 -1
  86. package/dist/ui/react.mjs +2 -2
  87. package/dist/ui/react.mjs.map +1 -1
  88. package/dist/ui/utils.mjs +1 -1
  89. package/dist/ui/wrappers.d.mts +2 -2
  90. package/dist/ui/wrappers.mjs +1 -1
  91. package/dist/ui.d.mts +5 -5
  92. package/dist/ui.mjs +6 -6
  93. package/dist/{useLatest-6xqnGIU6.d.mts → useLatest-Bg2x4bfP.d.mts} +1 -1
  94. package/dist/{useLatest-6xqnGIU6.d.mts.map → useLatest-Bg2x4bfP.d.mts.map} +1 -1
  95. package/dist/{with-text-input-lUh9gYAG.d.mts → with-text-input-CRfoiFFG.d.mts} +3 -3
  96. package/dist/with-text-input-CRfoiFFG.d.mts.map +1 -0
  97. package/dist/{wrappers-JrEYTuKA.mjs → wrappers-UTADQkSY.mjs} +4 -4
  98. package/dist/wrappers-UTADQkSY.mjs.map +1 -0
  99. package/dist/{yoga-adapter-Bc8XT9cN.mjs → yoga-adapter-8oRGRw8V.mjs} +2 -2
  100. package/dist/{yoga-adapter-Bc8XT9cN.mjs.map → yoga-adapter-8oRGRw8V.mjs.map} +1 -1
  101. package/dist/yoga-adapter-D_CcxSt5.mjs +2 -0
  102. package/package.json +54 -45
  103. package/dist/UPNG-DvKjM6wE.mjs +0 -5076
  104. package/dist/UPNG-DvKjM6wE.mjs.map +0 -1
  105. package/dist/__vite-browser-external-2447137e-DPKHHqQK.mjs +0 -6
  106. package/dist/__vite-browser-external-2447137e-DPKHHqQK.mjs.map +0 -1
  107. package/dist/ansi-C6Qs1Wn2.mjs.map +0 -1
  108. package/dist/apng-CvSlLBtc.mjs +0 -3
  109. package/dist/apng-DFFVOItr.mjs +0 -70
  110. package/dist/apng-DFFVOItr.mjs.map +0 -1
  111. package/dist/assets/resvgjs.darwin-arm64-BtufyGW1.node +0 -0
  112. package/dist/backend-DU0Y938U.mjs +0 -13396
  113. package/dist/backend-DU0Y938U.mjs.map +0 -1
  114. package/dist/backends-BihMKFY_.mjs +0 -1181
  115. package/dist/backends-BihMKFY_.mjs.map +0 -1
  116. package/dist/backends-Dk_5G_gC.mjs +0 -3
  117. package/dist/cli-GwJ0S2In.mjs +0 -4
  118. package/dist/context-BjWgrikx.mjs.map +0 -1
  119. package/dist/derive-O_Kb1Bk_.d.mts +0 -28
  120. package/dist/derive-O_Kb1Bk_.d.mts.map +0 -1
  121. package/dist/devtools-CeO9X_uv.mjs.map +0 -1
  122. package/dist/devtools-nX4tj6OH.mjs +0 -2
  123. package/dist/flexily-zero-adapter-BOM0cl8R.mjs.map +0 -1
  124. package/dist/gif-B9Uq4qZA.mjs +0 -73
  125. package/dist/gif-B9Uq4qZA.mjs.map +0 -1
  126. package/dist/gif-BdrLRBmM.mjs +0 -3
  127. package/dist/gifenc-DfhOb4xr.mjs +0 -730
  128. package/dist/gifenc-DfhOb4xr.mjs.map +0 -1
  129. package/dist/image-B0zMbVUr.mjs.map +0 -1
  130. package/dist/index-Bh3U1K09.d.mts.map +0 -1
  131. package/dist/index-dehZ18K-.d.mts +0 -679
  132. package/dist/index-dehZ18K-.d.mts.map +0 -1
  133. package/dist/key-mapping-7k2ufK2b.mjs +0 -3
  134. package/dist/key-mapping-WLUmxjx1.mjs +0 -132
  135. package/dist/key-mapping-WLUmxjx1.mjs.map +0 -1
  136. package/dist/node-CP5WChgr.mjs.map +0 -1
  137. package/dist/progress-bar-IrUjkLfU.mjs.map +0 -1
  138. package/dist/reconciler-B8uxQxaU.mjs +0 -16482
  139. package/dist/reconciler-B8uxQxaU.mjs.map +0 -1
  140. package/dist/render-string-DVfgc8xr.mjs.map +0 -1
  141. package/dist/resvg-js-Cwipz-_J.mjs +0 -203
  142. package/dist/resvg-js-Cwipz-_J.mjs.map +0 -1
  143. package/dist/spinner-BmldKx0M.mjs.map +0 -1
  144. package/dist/src-C0sOQW-t.mjs +0 -3866
  145. package/dist/src-C0sOQW-t.mjs.map +0 -1
  146. package/dist/src-CJPXf3fC.mjs.map +0 -1
  147. package/dist/src-D8kLrQBT.mjs.map +0 -1
  148. package/dist/src-D_BS-as7.mjs.map +0 -1
  149. package/dist/theme.d.mts.map +0 -1
  150. package/dist/theme.mjs.map +0 -1
  151. package/dist/types-e4dpfbSa.mjs.map +0 -1
  152. package/dist/with-text-input-lUh9gYAG.d.mts.map +0 -1
  153. package/dist/wrapper-CE6GQ27z.mjs +0 -3527
  154. package/dist/wrapper-CE6GQ27z.mjs.map +0 -1
  155. package/dist/wrappers-JrEYTuKA.mjs.map +0 -1
  156. package/dist/yoga-adapter-B8LZpQcE.mjs +0 -2
@@ -1,5 +1,6 @@
1
- import { i as __require, n as __esmMin } from "./chunk-BSw8zbkd.mjs";
1
+ import { i as __require, n as __esmMin } from "./chunk-Vs_PY4HZ.mjs";
2
2
  import "string-width";
3
+ import { blend, brighten, checkContrast, colorDistance, complement, contrastFg, darken, deltaE, ensureContrast, hexToOklch, hexToRgb as hexToRgb$1, oklchToHex } from "@silvery/color";
3
4
  //#region packages/ansi/src/detection.ts
4
5
  /**
5
6
  * Detect if terminal supports cursor control (repositioning).
@@ -289,7 +290,148 @@ function bgFromRgb(r, g, b, level) {
289
290
  const idx = nearestAnsi16(r, g, b);
290
291
  return idx < 8 ? `${40 + idx}` : `${92 + idx}`;
291
292
  }
292
- var MODIFIERS, FG_COLORS, BG_COLORS, ANSI_16_COLORS;
293
+ /**
294
+ * Convert a 256-palette index back to its canonical xterm hex value.
295
+ *
296
+ * Mirrors `rgbToAnsi256`:
297
+ * - 16–231: 6×6×6 color cube. Index = 16 + 36·r + 6·g + b (each channel 0..5).
298
+ * - 232–255: 24-step grayscale ramp.
299
+ * - 0–15: ANSI 16 slots (reuses ANSI16_SLOT_HEX for exact parity with
300
+ * `nearestAnsi16`).
301
+ */
302
+ function ansi256ToHex(idx) {
303
+ if (idx < 0 || idx > 255 || !Number.isInteger(idx)) return "#000000";
304
+ if (idx < 16) {
305
+ const [r, g, b] = ANSI_16_COLORS[idx];
306
+ return rgbToHexHash(r, g, b);
307
+ }
308
+ if (idx < 232) {
309
+ const levels = [
310
+ 0,
311
+ 95,
312
+ 135,
313
+ 175,
314
+ 215,
315
+ 255
316
+ ];
317
+ const i = idx - 16;
318
+ const r = levels[Math.floor(i / 36)];
319
+ const g = levels[Math.floor(i % 36 / 6)];
320
+ const b = levels[i % 6];
321
+ return rgbToHexHash(r, g, b);
322
+ }
323
+ const gray = 8 + (idx - 232) * 10;
324
+ return rgbToHexHash(gray, gray, gray);
325
+ }
326
+ function rgbToHexHash(r, g, b) {
327
+ const h = (n) => n.toString(16).padStart(2, "0");
328
+ return `#${h(r)}${h(g)}${h(b)}`;
329
+ }
330
+ function parseHexLocal(hex) {
331
+ if (typeof hex !== "string") return null;
332
+ let s = hex.trim();
333
+ if (s.startsWith("#")) s = s.slice(1);
334
+ if (s.length === 3) s = s.split("").map((c) => c + c).join("");
335
+ if (s.length !== 6) return null;
336
+ const r = parseInt(s.slice(0, 2), 16);
337
+ const g = parseInt(s.slice(2, 4), 16);
338
+ const b = parseInt(s.slice(4, 6), 16);
339
+ if (Number.isNaN(r) || Number.isNaN(g) || Number.isNaN(b)) return null;
340
+ return [
341
+ r,
342
+ g,
343
+ b
344
+ ];
345
+ }
346
+ /**
347
+ * Hex-in / hex-out quantization for previews.
348
+ *
349
+ * Takes any hex color and returns the hex a real terminal at that tier would
350
+ * actually emit. Used by the Sterling storybook to make the `1/2/3/4` tier
351
+ * toggle visibly different in-process — the output phase already does this
352
+ * when writing to a real TTY, but preview surfaces (theme swatches, rendered
353
+ * components inside a storybook app) bypass output-phase quantization. Apply
354
+ * `quantizeHex` at render time to mimic tier-specific terminal output.
355
+ *
356
+ * - `truecolor`: returns the input unchanged (normalized to `#rrggbb`).
357
+ * - `256`: snaps to the nearest xterm-256 slot, then returns that slot's hex.
358
+ * - `ansi16`: snaps to one of the 16 standard slots (canonical xterm RGB).
359
+ * - `mono`: luminance threshold (>= 0.5 → `#ffffff`, else `#000000`).
360
+ *
361
+ * Returns the input unchanged if it cannot be parsed as a hex color.
362
+ */
363
+ function quantizeHex(hex, tier) {
364
+ const rgb = parseHexLocal(hex);
365
+ if (!rgb) return hex;
366
+ const [r, g, b] = rgb;
367
+ if (tier === "truecolor") return rgbToHexHash(r, g, b);
368
+ if (tier === "256") return ansi256ToHex(rgbToAnsi256(r, g, b));
369
+ if (tier === "ansi16") {
370
+ const [cr, cg, cb] = ANSI_16_COLORS[nearestAnsi16(r, g, b)];
371
+ return rgbToHexHash(cr, cg, cb);
372
+ }
373
+ return (.2126 * r + .7152 * g + .0722 * b) / 255 >= .5 ? "#ffffff" : "#000000";
374
+ }
375
+ function isHexLeaf$1(value) {
376
+ return typeof value === "string" && HEX_LEAF_RE$1.test(value);
377
+ }
378
+ /**
379
+ * Pre-quantize every hex leaf in a Theme (or any object tree) to the
380
+ * requested color tier.
381
+ *
382
+ * Walks the input recursively — each string leaf matching `#rgb` / `#rrggbb`
383
+ * is passed through {@link quantizeHex}; all other values (numbers, booleans,
384
+ * non-hex strings like `"Nord"`, null/undefined, arrays of non-hex values)
385
+ * pass through unchanged. Arrays and nested objects are rebuilt with
386
+ * quantized leaves.
387
+ *
388
+ * Works on both the legacy ANSI Theme (flat hex tokens + `palette` array)
389
+ * and the Sterling Theme (nested roles + flat tokens) — the structural rule
390
+ * "any leaf that looks like a hex is a color value" holds for both.
391
+ *
392
+ * @example Pre-cache tier variants
393
+ * ```ts
394
+ * import { pickColorLevel } from "silvery"
395
+ *
396
+ * const themes = {
397
+ * truecolor: theme,
398
+ * ansi16: pickColorLevel(theme, "ansi16"),
399
+ * mono: pickColorLevel(theme, "mono"),
400
+ * }
401
+ * ```
402
+ *
403
+ * @example Storybook — show multiple tiers simultaneously
404
+ * ```tsx
405
+ * <ThemeProvider theme={pickColorLevel(theme, "ansi16")}>
406
+ * <AlertPreview />
407
+ * </ThemeProvider>
408
+ * ```
409
+ *
410
+ * Notes:
411
+ * - `truecolor` is a no-op — returns the input unchanged (identity).
412
+ * - The result is structurally identical to the input (same keys, same
413
+ * nesting); only hex leaves are remapped.
414
+ * - Idempotent per tier: `pickColorLevel(pickColorLevel(t, "ansi16"), "ansi16")`
415
+ * yields the same hex values as `pickColorLevel(t, "ansi16")`.
416
+ * - Does not freeze the returned object. Callers that want immutability
417
+ * should `Object.freeze()` (or deep-freeze) the result themselves.
418
+ */
419
+ function pickColorLevel(theme, tier) {
420
+ if (tier === "truecolor") return theme;
421
+ return pickColorLevelWalk(theme, tier);
422
+ }
423
+ function pickColorLevelWalk(obj, tier) {
424
+ if (obj == null) return obj;
425
+ if (isHexLeaf$1(obj)) return quantizeHex(obj, tier);
426
+ if (Array.isArray(obj)) return obj.map((v) => pickColorLevelWalk(v, tier));
427
+ if (typeof obj === "object") {
428
+ const out = {};
429
+ for (const [k, v] of Object.entries(obj)) out[k] = pickColorLevelWalk(v, tier);
430
+ return out;
431
+ }
432
+ return obj;
433
+ }
434
+ var MODIFIERS, FG_COLORS, BG_COLORS, ANSI_16_COLORS, ANSI16_SLOT_HEX, HEX_LEAF_RE$1;
293
435
  var init_color_maps = __esmMin((() => {
294
436
  MODIFIERS = {
295
437
  reset: [0, 0],
@@ -424,6 +566,95 @@ var init_color_maps = __esmMin((() => {
424
566
  255
425
567
  ]
426
568
  ];
569
+ ANSI16_SLOT_HEX = {
570
+ black: "#000000",
571
+ red: "#800000",
572
+ green: "#008000",
573
+ yellow: "#808000",
574
+ blue: "#000080",
575
+ magenta: "#800080",
576
+ cyan: "#008080",
577
+ white: "#c0c0c0",
578
+ blackBright: "#808080",
579
+ gray: "#808080",
580
+ grey: "#808080",
581
+ redBright: "#ff0000",
582
+ greenBright: "#00ff00",
583
+ yellowBright: "#ffff00",
584
+ blueBright: "#0000ff",
585
+ magentaBright: "#ff00ff",
586
+ cyanBright: "#00ffff",
587
+ whiteBright: "#ffffff"
588
+ };
589
+ HEX_LEAF_RE$1 = /^#[0-9a-fA-F]{3}([0-9a-fA-F]{3})?$/;
590
+ }));
591
+ //#endregion
592
+ //#region packages/ansi/src/flatten.ts
593
+ function isHexLeaf(value) {
594
+ return typeof value === "string" && HEX_LEAF_RE.test(value);
595
+ }
596
+ /**
597
+ * Populate flat hyphen-keys onto `theme` in-place by walking hex leaves and
598
+ * asking `rule` where each leaf should also live at the root.
599
+ *
600
+ * Both the nested and flat forms reference the SAME string (not copies) —
601
+ * `bakeFlat({...}).accent.bg === bakeFlat({...})["bg-accent"]`.
602
+ *
603
+ * `rule` defaults to {@link defaultFlattenRule} (channel-role-state).
604
+ * Rules returning `null` for a path skip that leaf — useful for suppressing
605
+ * metadata or implementing partial projections.
606
+ *
607
+ * The returned object is deep-frozen. The input object is mutated in place
608
+ * and returned; callers that want an unfrozen copy should `structuredClone`
609
+ * before calling.
610
+ *
611
+ * @param theme nested POJO of hex-string leaves (plus optional metadata)
612
+ * @param rule how to compute flat keys from nested paths
613
+ * @returns the same object, with flat keys added and frozen
614
+ */
615
+ function bakeFlat(theme, rule = defaultFlattenRule) {
616
+ const root = theme;
617
+ if (Object.isFrozen(root)) return theme;
618
+ walk(root, [], root, rule);
619
+ freezeDeep(root);
620
+ return theme;
621
+ }
622
+ function walk(node, path, root, rule) {
623
+ for (const key of Object.keys(node)) {
624
+ if (node === root && key.includes("-")) continue;
625
+ const value = node[key];
626
+ const subpath = [...path, key];
627
+ if (isHexLeaf(value)) {
628
+ const flatKey = rule(subpath);
629
+ if (flatKey !== null) root[flatKey] = value;
630
+ continue;
631
+ }
632
+ if (value && typeof value === "object" && !Array.isArray(value)) walk(value, subpath, root, rule);
633
+ }
634
+ }
635
+ function freezeDeep(o) {
636
+ if (o === null || typeof o !== "object") return;
637
+ if (Object.isFrozen(o)) return;
638
+ Object.freeze(o);
639
+ for (const k of Object.keys(o)) freezeDeep(o[k]);
640
+ }
641
+ var defaultFlattenRule, HEX_LEAF_RE;
642
+ var init_flatten = __esmMin((() => {
643
+ defaultFlattenRule = (path) => {
644
+ if (path.length < 2) return null;
645
+ const role = path[0];
646
+ const last = path[path.length - 1];
647
+ const mid = path.slice(1, -1);
648
+ if (last === "fgOn") return `fg-on-${role}`;
649
+ if (last === "fg" || last === "bg" || last === "border") {
650
+ const state = mid.length > 0 ? mid.join("-") : void 0;
651
+ return state ? `${last}-${role}-${state}` : `${last}-${role}`;
652
+ }
653
+ if (role === "surface") return `bg-surface-${last}`;
654
+ if (role === "border") return `border-${last}`;
655
+ return null;
656
+ };
657
+ HEX_LEAF_RE = /^#[0-9a-fA-F]{3}([0-9a-fA-F]{3})?([0-9a-fA-F]{2})?$/;
427
658
  }));
428
659
  //#endregion
429
660
  //#region packages/ansi/src/terminal-control.ts
@@ -486,447 +717,123 @@ var init_terminal_control = __esmMin((() => {
486
717
  `${ESC$3}`;
487
718
  }));
488
719
  //#endregion
489
- //#region packages/color/src/oklch.ts
490
- function parseHex(hex) {
491
- if (hex[0] !== "#") return null;
492
- const h = hex.slice(1);
493
- if (h.length === 3) {
494
- const r = parseInt(h[0] + h[0], 16);
495
- const g = parseInt(h[1] + h[1], 16);
496
- const b = parseInt(h[2] + h[2], 16);
497
- if (Number.isNaN(r) || Number.isNaN(g) || Number.isNaN(b)) return null;
498
- return [
499
- r,
500
- g,
501
- b
502
- ];
503
- }
504
- if (h.length === 6) {
505
- const r = parseInt(h.slice(0, 2), 16);
506
- const g = parseInt(h.slice(2, 4), 16);
507
- const b = parseInt(h.slice(4, 6), 16);
508
- if (Number.isNaN(r) || Number.isNaN(g) || Number.isNaN(b)) return null;
509
- return [
510
- r,
511
- g,
512
- b
513
- ];
514
- }
515
- return null;
516
- }
517
- /** sRGB channel (0–255) → linear RGB (0–1). Inverse gamma. */
518
- function srgbToLinear(c) {
519
- const s = c / 255;
520
- return s <= .04045 ? s / 12.92 : ((s + .055) / 1.055) ** 2.4;
521
- }
522
- /** Linear RGB (0–1) → sRGB channel (0–255). Forward gamma. */
523
- function linearToSrgb(c) {
524
- const clamped = Math.max(0, Math.min(1, c));
525
- return clamped <= .0031308 ? 12.92 * clamped * 255 : (1.055 * clamped ** (1 / 2.4) - .055) * 255;
526
- }
527
- /** Linear RGB → OKLab (Ottosson 2020 matrix). */
528
- function linearRgbToOklab(r, g, b) {
529
- const l = .4122214708 * r + .5363325363 * g + .0514459929 * b;
530
- const m = .2119034982 * r + .6806995451 * g + .1073969566 * b;
531
- const s = .0883024619 * r + .2817188376 * g + .6299787005 * b;
532
- const lCbrt = Math.cbrt(l);
533
- const mCbrt = Math.cbrt(m);
534
- const sCbrt = Math.cbrt(s);
535
- return [
536
- .2104542553 * lCbrt + .793617785 * mCbrt - .0040720468 * sCbrt,
537
- 1.9779984951 * lCbrt - 2.428592205 * mCbrt + .4505937099 * sCbrt,
538
- .0259040371 * lCbrt + .7827717662 * mCbrt - .808675766 * sCbrt
539
- ];
540
- }
541
- /** OKLab → linear RGB (inverse of the above). */
542
- function oklabToLinearRgb(L, a, bb) {
543
- const lCbrt = L + .3963377774 * a + .2158037573 * bb;
544
- const mCbrt = L - .1055613458 * a - .0638541728 * bb;
545
- const sCbrt = L - .0894841775 * a - 1.291485548 * bb;
546
- const l = lCbrt ** 3;
547
- const m = mCbrt ** 3;
548
- const s = sCbrt ** 3;
549
- return [
550
- 4.0767416621 * l - 3.3077115913 * m + .2309699292 * s,
551
- -1.2684380046 * l + 2.6097574011 * m - .3413193965 * s,
552
- -.0041960863 * l - .7034186147 * m + 1.707614701 * s
553
- ];
554
- }
555
- /** Hex (`#RRGGBB`) → OKLCH. Returns `null` for invalid hex. */
556
- function hexToOklch(hex) {
557
- const rgb = parseHex(hex);
558
- if (!rgb) return null;
559
- const [r, g, b] = rgb;
560
- const [lr, lg, lb] = [
561
- srgbToLinear(r),
562
- srgbToLinear(g),
563
- srgbToLinear(b)
564
- ];
565
- const [L, a, bb] = linearRgbToOklab(lr, lg, lb);
566
- const C = Math.sqrt(a * a + bb * bb);
567
- let H = Math.atan2(bb, a) * 180 / Math.PI;
568
- if (H < 0) H += 360;
569
- return {
570
- L,
571
- C,
572
- H
573
- };
574
- }
575
- /** Check whether linear RGB is inside sRGB gamut (each channel in [0, 1]). */
576
- function inGamut(r, g, b) {
577
- const e = 1e-5;
578
- return r >= -e && r <= 1 + e && g >= -e && g <= 1 + e && b >= -e && b <= 1 + e;
579
- }
720
+ //#region packages/ansi/src/kitty-graphics.ts
580
721
  /**
581
- * OKLCH hex. Gamut-maps out-of-sRGB colors by reducing chroma until in-gamut
582
- * (preserves L and H the perceptual anchors). This is the CSS Color 4
583
- * recommended approach for rendering OKLCH on sRGB displays.
722
+ * Derive a stable placement ID for a given (x, y) cell. Max column = 9999,
723
+ * which comfortably exceeds any realistic terminal width.
584
724
  */
585
- function oklchToHex(c) {
586
- const L = Math.max(0, Math.min(1, c.L));
587
- const Crad = (c.H % 360 + 360) % 360 * Math.PI / 180;
588
- let lo = 0;
589
- let hi = Math.max(0, c.C);
590
- let [rHi, gHi, bHi] = oklabToLinearRgb(L, hi * Math.cos(Crad), hi * Math.sin(Crad));
591
- if (inGamut(rHi, gHi, bHi)) return rgbToHexInternal(linearToSrgb(rHi), linearToSrgb(gHi), linearToSrgb(bHi));
592
- for (let i = 0; i < 20; i++) {
593
- const mid = (lo + hi) / 2;
594
- const [rr, gg, bbLin] = oklabToLinearRgb(L, mid * Math.cos(Crad), mid * Math.sin(Crad));
595
- if (inGamut(rr, gg, bbLin)) lo = mid;
596
- else hi = mid;
597
- }
598
- const a = lo * Math.cos(Crad);
599
- const bb = lo * Math.sin(Crad);
600
- [rHi, gHi, bHi] = oklabToLinearRgb(L, a, bb);
601
- return rgbToHexInternal(linearToSrgb(rHi), linearToSrgb(gHi), linearToSrgb(bHi));
602
- }
603
- function rgbToHexInternal(r, g, b) {
604
- const clamp = (n) => Math.max(0, Math.min(255, Math.round(n)));
605
- return `#${clamp(r).toString(16).padStart(2, "0")}${clamp(g).toString(16).padStart(2, "0")}${clamp(b).toString(16).padStart(2, "0")}`.toUpperCase();
725
+ function backdropPlacementId(x, y) {
726
+ return x * BACKDROP_PLACEMENT_X_STRIDE + y + 1;
606
727
  }
607
728
  /**
608
- * Linear interpolate in OKLab (rectangular a, b, L interpolated directly).
609
- *
610
- * CSS Color Module 4's default interpolation space. Avoids the hue-arc
611
- * weirdness of `lerpOklch` when one endpoint is near-neutral (its H is
612
- * effectively undefined). Produces the expected "tinted surface" when blending
613
- * `bg` with an accent color.
729
+ * Encode a Uint8Array as base64. Kitty expects standard base64 (with `+`/`/`
730
+ * and `=` padding). We use Buffer when available (Node/Bun), fall back to
731
+ * btoa for browser/canvas adapters (the canvas target may never actually
732
+ * need to emit Kitty escapes this is just defensive).
614
733
  */
615
- function lerpOklabHex(aHex, bHex, t) {
616
- const aOk = hexToOklch(aHex);
617
- const bOk = hexToOklch(bHex);
618
- if (!aOk || !bOk) return null;
619
- const aRad = aOk.H * Math.PI / 180;
620
- const bRad = bOk.H * Math.PI / 180;
621
- const aA = aOk.C * Math.cos(aRad);
622
- const aB = aOk.C * Math.sin(aRad);
623
- const bA = bOk.C * Math.cos(bRad);
624
- const bB = bOk.C * Math.sin(bRad);
625
- const L = aOk.L + (bOk.L - aOk.L) * t;
626
- const A = aA + (bA - aA) * t;
627
- const B = aB + (bB - aB) * t;
628
- const C = Math.sqrt(A * A + B * B);
629
- let H = Math.atan2(B, A) * 180 / Math.PI;
630
- if (H < 0) H += 360;
631
- return oklchToHex({
632
- L,
633
- C,
634
- H
635
- });
734
+ function base64Encode(bytes) {
735
+ if (typeof Buffer !== "undefined") return Buffer.from(bytes).toString("base64");
736
+ let binary = "";
737
+ for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);
738
+ const g = globalThis;
739
+ if (typeof g.btoa === "function") return g.btoa(binary);
740
+ throw new Error("base64 encoding unavailable in this environment");
636
741
  }
637
742
  /**
638
- * ΔE in OKLCH (≈ ΔE₀₀ quality in practice OKLCH was designed to make Euclidean
639
- * distance perceptually meaningful). Hue is weighted by chroma so near-neutral
640
- * colors don't produce spurious large ΔH contributions.
641
- */
642
- function deltaE(a, b) {
643
- const dL = a.L - b.L;
644
- const dC = a.C - b.C;
645
- const dh = ((a.H - b.H + 540) % 360 - 180) * (Math.PI / 180);
646
- (a.C + b.C) / 2;
647
- const dH = 2 * Math.sqrt(a.C * b.C) * Math.sin(dh / 2);
648
- return Math.sqrt(dL * dL + dC * dC + dH * dH);
649
- }
650
- var init_oklch = __esmMin((() => {}));
651
- //#endregion
652
- //#region packages/color/src/color.ts
653
- /** Parse #rrggbb or #rgb to [r, g, b]. Returns null for invalid input. */
654
- function hexToRgb(hex) {
655
- if (hex[0] !== "#") return null;
656
- const h = hex.slice(1);
657
- if (h.length === 3) return [
658
- parseInt(h[0] + h[0], 16),
659
- parseInt(h[1] + h[1], 16),
660
- parseInt(h[2] + h[2], 16)
661
- ];
662
- if (h.length === 6) return [
663
- parseInt(h.slice(0, 2), 16),
664
- parseInt(h.slice(2, 4), 16),
665
- parseInt(h.slice(4, 6), 16)
666
- ];
667
- return null;
668
- }
669
- /** Convert [r, g, b] (0-255) to hex string. */
670
- function rgbToHex(r, g, b) {
671
- const clamp = (n) => Math.max(0, Math.min(255, Math.round(n)));
672
- return `#${clamp(r).toString(16).padStart(2, "0")}${clamp(g).toString(16).padStart(2, "0")}${clamp(b).toString(16).padStart(2, "0")}`.toUpperCase();
673
- }
674
- /**
675
- * Blend two hex colors in OKLab space. t=0 returns a, t=1 returns b.
676
- * Perceptually-uniform midpoints (unlike naive RGB blending which produces
677
- * muddy halfway colors).
743
+ * Build a tiny RGBA pixel grid for the scrim overlay.
678
744
  *
679
- * Interpolation is done in OKLab (rectangular a/b), not OKLCH (polar). This
680
- * matches CSS Color Module 4's default interpolation space and avoids hue-arc
681
- * weirdness when one endpoint is near-neutral (its hue is effectively
682
- * undefined). For explicit hue-rotation blending, use `lerpOklch` directly.
745
+ * Kitty's graphics protocol paints images at native pixel resolution scaled
746
+ * to `c` x `r` cells. A 2x2 RGBA image scaled to a single cell (~10x20 px
747
+ * depending on font) gives us a smooth fill. We intentionally keep the
748
+ * image tiny to minimize base64 payload size on the upload frame.
683
749
  *
684
- * For non-hex inputs (ANSI names), returns `a` unchanged.
685
- */
686
- function blend(a, b, t) {
687
- return lerpOklabHex(a, b, t) ?? a;
688
- }
689
- /**
690
- * Brighten a hex color by raising OKLCH lightness. amount=0.1 adds 0.1 to L
691
- * (perceptually linear — 10% brighter looks 10% brighter regardless of hue).
750
+ * Pixel color: `(r, g, b, a)` where `r/g/b` is the scrim tint and `a` is the
751
+ * alpha (0-255). For a dark backdrop we use near-black at ~50% alpha, which
752
+ * darkens the emoji underneath without completely hiding it.
692
753
  *
693
- * For non-hex inputs, returns the color unchanged.
754
+ * Width/height = 2 pixels — 16 bytes total, ~24 bytes base64. Upload is ~60
755
+ * bytes including control chars. One-time cost per modal session.
694
756
  */
695
- function brighten(color, amount) {
696
- const o = hexToOklch(color);
697
- if (!o) return color;
698
- return oklchToHex({
699
- L: Math.min(1, o.L + amount),
700
- C: o.C,
701
- H: o.H
702
- });
757
+ function buildScrimPixels(tint, alpha) {
758
+ const a = Math.max(0, Math.min(255, Math.round(alpha)));
759
+ const r = Math.max(0, Math.min(255, Math.round(tint.r)));
760
+ const g = Math.max(0, Math.min(255, Math.round(tint.g)));
761
+ const b = Math.max(0, Math.min(255, Math.round(tint.b)));
762
+ const bytes = new Uint8Array(16);
763
+ for (let i = 0; i < 4; i++) {
764
+ bytes[i * 4 + 0] = r;
765
+ bytes[i * 4 + 1] = g;
766
+ bytes[i * 4 + 2] = b;
767
+ bytes[i * 4 + 3] = a;
768
+ }
769
+ return bytes;
703
770
  }
704
771
  /**
705
- * Darken a hex color by lowering OKLCH lightness. amount=0.1 subtracts 0.1 from L.
772
+ * APC wrapper: `\x1b_G<control>[;<payload>]\x1b\\`.
706
773
  *
707
- * For non-hex inputs, returns the color unchanged.
774
+ * The protocol allows chunking large payloads via `m=1` but our scrim is
775
+ * tiny — always fits in one chunk.
708
776
  */
709
- function darken(color, amount) {
710
- const o = hexToOklch(color);
711
- if (!o) return color;
712
- return oklchToHex({
713
- L: Math.max(0, o.L - amount),
714
- C: o.C,
715
- H: o.H
716
- });
777
+ function apc(control, payload) {
778
+ if (payload === void 0 || payload === "") return `\x1b_G${control}\x1b\\`;
779
+ return `\x1b_G${control};${payload}\x1b\\`;
717
780
  }
718
781
  /**
719
- * Desaturate a hex color by lowering OKLCH chroma. amount=0.4 reduces C by 40%
720
- * (relative consistent with the original HSL-based contract). For a flat
721
- * subtraction, use `saturate(color, -amount)`.
782
+ * Emit a one-shot image upload. Terminal stores the RGBA pixels under
783
+ * `i=<imageId>` and keeps them until explicitly freed. Subsequent placements
784
+ * reference the image by ID without re-sending pixel data.
722
785
  *
723
- * For non-hex inputs, returns the color unchanged.
786
+ * `q=2` suppresses the terminal's OK/error reply — otherwise we'd see stray
787
+ * APC sequences back on stdin.
724
788
  */
725
- function desaturate(color, amount) {
726
- const o = hexToOklch(color);
727
- if (!o) return color;
728
- return oklchToHex({
729
- L: o.L,
730
- C: Math.max(0, o.C * (1 - amount)),
731
- H: o.H
732
- });
789
+ function kittyUploadScrimImage(pixels, width, height, imageId = BACKDROP_SCRIM_IMAGE_ID) {
790
+ const payload = base64Encode(pixels);
791
+ return apc(`a=t,f=32,s=${width},v=${height},i=${imageId},q=2`, payload);
733
792
  }
734
793
  /**
735
- * Get the complementary color (180° hue rotation) in OKLCH. Preserves L + C,
736
- * so the complement has the same perceived brightness and colorfulness.
794
+ * Emit a cell placement. Places `imageId` at the current cursor position
795
+ * covering `c` cols and `r` rows with z-index `z`. `C=1` prevents the cursor
796
+ * from advancing after placement (critical — otherwise every placement
797
+ * shifts the cursor, breaking the caller's positioning).
737
798
  *
738
- * For non-hex inputs, returns the color unchanged.
739
- */
740
- function complement(color) {
741
- const o = hexToOklch(color);
742
- if (!o) return color;
743
- return oklchToHex({
744
- L: o.L,
745
- C: o.C,
746
- H: (o.H + 180) % 360
747
- });
748
- }
749
- /** Perceptual color distance (ΔE) between two hex colors, in OKLCH. */
750
- function colorDistance(a, b) {
751
- const oa = hexToOklch(a);
752
- const ob = hexToOklch(b);
753
- if (!oa || !ob) return null;
754
- return deltaE(oa, ob);
755
- }
756
- /**
757
- * Linearize an sRGB channel value (0-255) for WCAG 2.1 luminance.
758
- * Kept for WCAG contrast checking — OKLCH uses its own linearization.
759
- */
760
- function channelLuminance(c) {
761
- const s = c / 255;
762
- return s <= .03928 ? s / 12.92 : Math.pow((s + .055) / 1.055, 2.4);
763
- }
764
- /**
765
- * Compute relative luminance of a hex color per WCAG 2.1.
766
- * Returns a value between 0 (darkest) and 1 (lightest), or null for invalid input.
767
- */
768
- function relativeLuminance(hex) {
769
- const rgb = hexToRgb(hex);
770
- if (!rgb) return null;
771
- return .2126 * channelLuminance(rgb[0]) + .7152 * channelLuminance(rgb[1]) + .0722 * channelLuminance(rgb[2]);
772
- }
773
- /**
774
- * Pick black or white text for readability on the given background.
775
- * Uses WCAG 2.1 relative luminance.
799
+ * Placement ID (`p=<pid>`) is stable per cell so incremental frames can
800
+ * replace placements without accumulating duplicates.
776
801
  */
777
- function contrastFg(bg) {
778
- const luminance = relativeLuminance(bg);
779
- if (luminance === null) return "#FFFFFF";
780
- return luminance > .179 ? "#000000" : "#FFFFFF";
781
- }
782
- function rgbToHsl(r, g, b) {
783
- r /= 255;
784
- g /= 255;
785
- b /= 255;
786
- const max = Math.max(r, g, b), min = Math.min(r, g, b);
787
- const l = (max + min) / 2;
788
- if (max === min) return [
789
- 0,
790
- 0,
791
- l
792
- ];
793
- const d = max - min;
794
- const s = l > .5 ? d / (2 - max - min) : d / (max + min);
795
- let h = 0;
796
- if (max === r) h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
797
- else if (max === g) h = ((b - r) / d + 2) / 6;
798
- else h = ((r - g) / d + 4) / 6;
799
- return [
800
- h * 360,
801
- s,
802
- l
803
- ];
804
- }
805
- function hslToHex(h, s, l) {
806
- h = (h % 360 + 360) % 360;
807
- const a = s * Math.min(l, 1 - l);
808
- const f = (n) => {
809
- const k = (n + h / 30) % 12;
810
- return l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
811
- };
812
- return rgbToHex(f(0) * 255, f(8) * 255, f(4) * 255);
813
- }
814
- function hexToHsl(hex) {
815
- const rgb = hexToRgb(hex);
816
- if (!rgb) return null;
817
- return rgbToHsl(rgb[0], rgb[1], rgb[2]);
802
+ function kittyPlaceAt(opts) {
803
+ const imageId = opts.imageId ?? 48879;
804
+ const cols = opts.cols ?? 1;
805
+ const rows = opts.rows ?? 1;
806
+ const z = opts.z ?? 1;
807
+ return apc(`a=p,i=${imageId},p=${opts.placementId},c=${cols},r=${rows},z=${z},C=1,q=2`);
818
808
  }
819
- var init_color = __esmMin((() => {
820
- init_oklch();
821
- }));
822
- //#endregion
823
- //#region packages/color/src/contrast.ts
824
809
  /**
825
- * Check contrast ratio between foreground and background colors.
826
- *
827
- * Uses the WCAG 2.1 relative luminance formula to compute the contrast
828
- * ratio and check AA (>= 4.5:1) and AAA (>= 7:1) compliance for normal text.
829
- *
830
- * @param fg - Foreground hex color (e.g. "#FFFFFF")
831
- * @param bg - Background hex color (e.g. "#000000")
832
- * @returns Contrast ratio and AA/AAA pass/fail, or null if colors are not valid hex
833
- *
834
- * @example
835
- * ```typescript
836
- * const result = checkContrast("#FFFFFF", "#000000")
837
- * // { ratio: 21, aa: true, aaa: true }
838
- *
839
- * const poor = checkContrast("#777777", "#888888")
840
- * // { ratio: ~1.3, aa: false, aaa: false }
841
- * ```
810
+ * Delete ALL placements of our scrim image without freeing the image.
811
+ * Used when the modal closes — we leave the image cached in case another
812
+ * modal opens, but remove every overlay cell at once.
842
813
  */
843
- function checkContrast(fg, bg) {
844
- const fgLum = relativeLuminance(fg);
845
- const bgLum = relativeLuminance(bg);
846
- if (fgLum === null || bgLum === null) return null;
847
- const lighter = Math.max(fgLum, bgLum);
848
- const darker = Math.min(fgLum, bgLum);
849
- const ratio = (lighter + .05) / (darker + .05);
850
- return {
851
- ratio,
852
- aa: ratio >= 4.5,
853
- aaa: ratio >= 7
854
- };
814
+ function kittyDeleteAllScrimPlacements(imageId = BACKDROP_SCRIM_IMAGE_ID) {
815
+ return apc(`a=d,d=i,i=${imageId},q=2`);
855
816
  }
856
817
  /**
857
- * Adjust a color's OKLCH lightness until it meets a minimum WCAG contrast ratio
858
- * against a reference color. Preserves hue and chroma — only lightness shifts,
859
- * and only as much as needed.
860
- *
861
- * Returns the original color unchanged if it already meets the target.
818
+ * Absolute cursor position (CUP). 1-based row/col per VT100.
862
819
  *
863
- * For impossible targets (e.g. 21:1 against mid-gray), returns the
864
- * best achievable color (near-black or near-white in the same hue).
865
- *
866
- * @param color - The color to adjust (hex)
867
- * @param against - The reference background color (hex)
868
- * @param minRatio - Minimum contrast ratio to achieve (e.g. 4.5 for AA)
869
- * @returns Adjusted hex color meeting the target, or original if already OK
870
- *
871
- * @example
872
- * ```typescript
873
- * // Yellow on white — too low contrast, gets darkened (perceptually; same hue preserved)
874
- * ensureContrast("#FFAB91", "#FFFFFF", 4.5)
875
- *
876
- * // Blue on dark bg — already fine, returned unchanged
877
- * ensureContrast("#5C9FFF", "#1A1A2E", 4.5) // → "#5C9FFF"
878
- * ```
820
+ * Used to position the cursor before emitting a placement so the placement
821
+ * lands in the right cell. Kept small and local — the rest of the pipeline
822
+ * uses more elaborate cursor tracking, but for out-of-band overlay emission
823
+ * we just want a deterministic "jump here, place, done."
879
824
  */
880
- function ensureContrast(color, against, minRatio) {
881
- const current = checkContrast(color, against);
882
- if (!current) return color;
883
- if (current.ratio >= minRatio) return color;
884
- const o = hexToOklch(color);
885
- if (!o) return color;
886
- const lightBg = contrastFg(against) === "#000000";
887
- let lo, hi;
888
- if (lightBg) {
889
- lo = 0;
890
- hi = o.L;
891
- } else {
892
- lo = o.L;
893
- hi = 1;
894
- }
895
- for (let i = 0; i < 24; i++) {
896
- const mid = (lo + hi) / 2;
897
- const r = checkContrast(oklchToHex({
898
- L: mid,
899
- C: o.C,
900
- H: o.H
901
- }), against);
902
- if (!r) break;
903
- if (lightBg) if (r.ratio >= minRatio) lo = mid;
904
- else hi = mid;
905
- else if (r.ratio >= minRatio) hi = mid;
906
- else lo = mid;
907
- }
908
- return oklchToHex({
909
- L: lightBg ? lo : hi,
910
- C: o.C,
911
- H: o.H
912
- });
825
+ function cupTo(col, row) {
826
+ return `\x1b[${row + 1};${col + 1}H`;
913
827
  }
914
- var init_contrast = __esmMin((() => {
915
- init_oklch();
916
- init_color();
917
- }));
918
- //#endregion
919
- //#region packages/color/src/index.ts
920
- var init_src$1 = __esmMin((() => {
921
- init_color();
922
- init_oklch();
923
- init_contrast();
828
+ var BACKDROP_SCRIM_IMAGE_ID, BACKDROP_PLACEMENT_X_STRIDE;
829
+ var init_kitty_graphics = __esmMin((() => {
830
+ BACKDROP_SCRIM_IMAGE_ID = 48879;
831
+ BACKDROP_PLACEMENT_X_STRIDE = 1e4;
924
832
  }));
925
833
  //#endregion
926
834
  //#region packages/ansi/src/style/colors.ts
927
835
  var THEME_TOKEN_DEFAULTS;
928
836
  var init_colors = __esmMin((() => {
929
- init_src$1();
930
837
  init_color_maps();
931
838
  THEME_TOKEN_DEFAULTS = {
932
839
  primary: 33,
@@ -959,7 +866,26 @@ function resolveThemeColor(name, theme) {
959
866
  if (!theme) return void 0;
960
867
  return resolveToken(name, theme);
961
868
  }
962
- /** Internal: resolve a token name (with or without $ prefix) against a theme. */
869
+ /** Internal: resolve a token name (with or without $ prefix) against a theme.
870
+ *
871
+ * Resolution order:
872
+ * 1. Direct key lookup — finds Sterling flat keys (`bg-accent`,
873
+ * `fg-on-error`, `border-focus`, …) and legacy kebab keys
874
+ * (`primary-hover`, `fg-hover`, `bg-surface-hover`) and plain names
875
+ * (`bg`, `primary`, `muted`).
876
+ * 2. No-hyphen fallback — `$surface-bg` → `theme.surfacebg`,
877
+ * `$focus-border` → `theme.focusborder`.
878
+ *
879
+ * The old `LEGACY_ALIASES` table (e.g. `fgmuted` → `muted`, `bgsurface` →
880
+ * `surfacebg`) was removed in 0.18.1 once every shipped default Theme ships
881
+ * with Sterling flat tokens baked in — `theme["fg-muted"]` and
882
+ * `theme["bg-surface-subtle"]` are direct fields now, so no alias fallback
883
+ * is required for canonical Sterling tokens. Tokens that existed only as
884
+ * aliases (e.g. `$bg-surface`, `$fg-on-primary`, `$border-input`,
885
+ * `$fg-disabled`) no longer resolve — callers should use the canonical
886
+ * Sterling equivalents (`$bg-surface-default`, `$fg-on-accent`,
887
+ * `$border-default`, `$fg-muted`).
888
+ */
963
889
  function resolveToken(name, theme) {
964
890
  if (!theme) return void 0;
965
891
  const token = name.startsWith("$") ? name.slice(1) : name;
@@ -967,14 +893,13 @@ function resolveToken(name, theme) {
967
893
  const idx = parseInt(token.slice(5), 10);
968
894
  if (idx >= 0 && idx < 16 && theme.palette && idx < theme.palette.length) return theme.palette[idx];
969
895
  }
970
- const key = token.replace(/-/g, "");
971
896
  const themeObj = theme;
972
- const direct = themeObj[key];
897
+ const direct = themeObj[token];
973
898
  if (typeof direct === "string") return direct;
974
- const aliased = PRIMER_ALIASES[key];
975
- if (aliased) {
976
- const val = themeObj[aliased];
977
- if (typeof val === "string") return val;
899
+ const noHyphen = token.replace(/-/g, "");
900
+ if (noHyphen !== token) {
901
+ const stripped = themeObj[noHyphen];
902
+ if (typeof stripped === "string") return stripped;
978
903
  }
979
904
  }
980
905
  /** Convert chalk numeric level (0-3) to ColorLevel. */
@@ -1066,7 +991,7 @@ function createChainWithRef(state, ref) {
1066
991
  const level = ref.level;
1067
992
  if (prop === "hex" || prop === "bgHex") return (color) => {
1068
993
  if (level === null) return createChainWithRef(state, ref);
1069
- const rgb = hexToRgb(color);
994
+ const rgb = hexToRgb$1(color);
1070
995
  if (!rgb) return createChainWithRef(state, ref);
1071
996
  const code = prop === "hex" ? fgFromRgb(rgb[0], rgb[1], rgb[2], level) : bgFromRgb(rgb[0], rgb[1], rgb[2], level);
1072
997
  const close = prop === "hex" ? "39" : "49";
@@ -1124,7 +1049,7 @@ function createChainWithRef(state, ref) {
1124
1049
  if (level === null) return createChainWithRef(state, ref);
1125
1050
  const hex = resolveToken(prop, ref.theme);
1126
1051
  if (hex) {
1127
- const rgb = hexToRgb(hex);
1052
+ const rgb = hexToRgb$1(hex);
1128
1053
  if (rgb) {
1129
1054
  const code = fgFromRgb(rgb[0], rgb[1], rgb[2], level);
1130
1055
  if (prop === "link") return createChainWithRef({
@@ -1188,44 +1113,10 @@ function createChainWithRef(state, ref) {
1188
1113
  proxyRef.proxy = proxy;
1189
1114
  return proxy;
1190
1115
  }
1191
- var PRIMER_ALIASES, ESC$2, KNOWN_METHODS, THEME_TOKENS;
1116
+ var ESC$2, KNOWN_METHODS, THEME_TOKENS;
1192
1117
  var init_style = __esmMin((() => {
1193
1118
  init_detection();
1194
1119
  init_colors();
1195
- PRIMER_ALIASES = {
1196
- fgmuted: "muted",
1197
- fgdisabled: "disabledfg",
1198
- fgcursor: "cursor",
1199
- fgselected: "selection",
1200
- fginverse: "inverse",
1201
- fgonsurface: "surface",
1202
- fgonpopover: "popover",
1203
- fgonprimary: "primaryfg",
1204
- fgonsecondary: "secondaryfg",
1205
- fgonaccent: "accentfg",
1206
- fgonerror: "errorfg",
1207
- fgonwarning: "warningfg",
1208
- fgonsuccess: "successfg",
1209
- fgoninfo: "infofg",
1210
- bgmuted: "mutedbg",
1211
- bgsurface: "surfacebg",
1212
- bgpopover: "popoverbg",
1213
- bginverse: "inversebg",
1214
- bgselected: "selectionbg",
1215
- bgcursor: "cursorbg",
1216
- borderfocus: "focusborder",
1217
- borderinput: "inputborder",
1218
- brandhover: "brandHover",
1219
- brandactive: "brandActive",
1220
- brandred: "brandRed",
1221
- brandorange: "brandOrange",
1222
- brandyellow: "brandYellow",
1223
- brandgreen: "brandGreen",
1224
- brandteal: "brandTeal",
1225
- brandblue: "brandBlue",
1226
- brandpurple: "brandPurple",
1227
- brandpink: "brandPink"
1228
- };
1229
1120
  ESC$2 = "\x1B[";
1230
1121
  KNOWN_METHODS = new Set([
1231
1122
  "hex",
@@ -1326,6 +1217,31 @@ var init_mixed_proxy = __esmMin((() => {
1326
1217
  }));
1327
1218
  //#endregion
1328
1219
  //#region packages/ansi/src/theme/invariants.ts
1220
+ /**
1221
+ * Theme invariants — post-derivation visibility + optional WCAG checks.
1222
+ *
1223
+ * Two independent invariant groups:
1224
+ *
1225
+ * 1. **Visibility (always checked)** — selection and cursor must be
1226
+ * distinguishable from bg. These fail silently because ensureContrast
1227
+ * doesn't touch `bg-selected`/`bg-cursor`; you get "invisible selection"
1228
+ * bugs that only surface via user complaints.
1229
+ *
1230
+ * 2. **WCAG contrast (opt-in)** — `deriveTheme()` already runs `ensureContrast`
1231
+ * on every text/bg pair as it builds the Theme (lenient auto-adjust). A
1232
+ * second validation pass is redundant for normal use. Enable it explicitly
1233
+ * at build time to *verify* that shipped themes meet the targets, or when
1234
+ * loading a hand-authored Theme object that skipped `deriveTheme`.
1235
+ *
1236
+ * This is why `validateThemeInvariants` defaults to `{ wcag: false }` — the
1237
+ * existing derivation already handles contrast. Callers opt in via
1238
+ * `validateThemeInvariants(theme, { wcag: true })` for strict pre-ship audits.
1239
+ *
1240
+ * All token access is Sterling-shaped — flat hyphen keys (`bg-accent`,
1241
+ * `fg-on-error`, `border-focus`) exist on every Theme via the derive +
1242
+ * bakeFlat pipeline. No concat-kebab legacy names (`primaryfg`, `mutedbg`, …)
1243
+ * — those were removed in silvery 0.19.0 (Sterling interior migration).
1244
+ */
1329
1245
  function lightness(hex) {
1330
1246
  const o = hexToOklch(hex);
1331
1247
  return o ? o.L : null;
@@ -1357,43 +1273,51 @@ function validateThemeInvariants(theme, opts = {}) {
1357
1273
  const checkWcag = opts.wcag ?? false;
1358
1274
  const checkVisibility = opts.visibility ?? true;
1359
1275
  const violations = [];
1360
- if (checkWcag) for (const pair of CONTRAST_PAIRS) {
1361
- const fg = theme[pair.fg];
1362
- const bg = theme[pair.bg];
1363
- if (typeof fg !== "string" || typeof bg !== "string") continue;
1364
- const r = checkContrast(fg, bg);
1365
- if (r === null) continue;
1366
- if (r.ratio < pair.min) violations.push({
1367
- rule: pair.rule,
1368
- tokens: [String(pair.fg), String(pair.bg)],
1369
- actual: r.ratio,
1370
- required: pair.min,
1371
- message: `${pair.fg} (${fg}) on ${pair.bg} (${bg}) is ${r.ratio.toFixed(2)}:1, needs ${pair.min.toFixed(1)}:1`
1372
- });
1276
+ if (checkWcag) {
1277
+ const themeRecord = theme;
1278
+ for (const pair of CONTRAST_PAIRS) {
1279
+ const fg = themeRecord[pair.fg];
1280
+ const bg = themeRecord[pair.bg];
1281
+ if (typeof fg !== "string" || typeof bg !== "string") continue;
1282
+ const r = checkContrast(fg, bg);
1283
+ if (r === null) continue;
1284
+ if (r.ratio < pair.min) violations.push({
1285
+ rule: pair.rule,
1286
+ tokens: [pair.fg, pair.bg],
1287
+ actual: r.ratio,
1288
+ required: pair.min,
1289
+ message: `${pair.fg} (${fg}) on ${pair.bg} (${bg}) is ${r.ratio.toFixed(2)}:1, needs ${pair.min.toFixed(1)}:1`
1290
+ });
1291
+ }
1373
1292
  }
1374
1293
  if (checkVisibility) {
1294
+ const themeAny = theme;
1295
+ const selectionBg = themeAny["bg-selected"] ?? themeAny["selectionbg"] ?? "";
1296
+ const cursorBg = themeAny["bg-cursor"] ?? themeAny["cursorbg"] ?? "";
1297
+ const selectionKey = themeAny["bg-selected"] !== void 0 ? "bg-selected" : "selectionbg";
1298
+ const cursorKey = themeAny["bg-cursor"] !== void 0 ? "bg-cursor" : "cursorbg";
1375
1299
  const lBg = lightness(theme.bg);
1376
- const lSelBg = lightness(theme.selectionbg);
1300
+ const lSelBg = lightness(selectionBg);
1377
1301
  if (lBg !== null && lSelBg !== null) {
1378
1302
  const dL = Math.abs(lSelBg - lBg);
1379
1303
  if (dL < .08) violations.push({
1380
1304
  rule: "visibility:selection",
1381
- tokens: ["selectionbg", "bg"],
1305
+ tokens: [selectionKey, "bg"],
1382
1306
  actual: dL,
1383
1307
  required: SELECTION_DELTA_L,
1384
- message: `selectionbg (${theme.selectionbg}) differs from bg (${theme.bg}) by ΔL=${dL.toFixed(3)}, needs ≥ ${SELECTION_DELTA_L.toFixed(2)}`
1308
+ message: `${selectionKey} (${selectionBg}) differs from bg (${theme.bg}) by ΔL=${dL.toFixed(3)}, needs ≥ ${SELECTION_DELTA_L.toFixed(2)}`
1385
1309
  });
1386
1310
  }
1387
1311
  const oBg = hexToOklch(theme.bg);
1388
- const oCursorBg = hexToOklch(theme.cursorbg);
1312
+ const oCursorBg = hexToOklch(cursorBg);
1389
1313
  if (oBg && oCursorBg) {
1390
1314
  const de = deltaE(oBg, oCursorBg);
1391
1315
  if (de < .15) violations.push({
1392
1316
  rule: "visibility:cursor",
1393
- tokens: ["cursorbg", "bg"],
1317
+ tokens: [cursorKey, "bg"],
1394
1318
  actual: de,
1395
1319
  required: CURSOR_DELTA_E,
1396
- message: `cursorbg (${theme.cursorbg}) differs from bg (${theme.bg}) by ΔE=${de.toFixed(3)}, needs ≥ ${CURSOR_DELTA_E.toFixed(2)}`
1320
+ message: `${cursorKey} (${cursorBg}) differs from bg (${theme.bg}) by ΔE=${de.toFixed(3)}, needs ≥ ${CURSOR_DELTA_E.toFixed(2)}`
1397
1321
  });
1398
1322
  }
1399
1323
  }
@@ -1411,7 +1335,6 @@ function formatViolations(violations) {
1411
1335
  }
1412
1336
  var AA_RATIO, FAINT_RATIO, SELECTION_DELTA_L, CURSOR_DELTA_E, CONTRAST_PAIRS, ThemeInvariantError;
1413
1337
  var init_invariants = __esmMin((() => {
1414
- init_src$1();
1415
1338
  AA_RATIO = 4.5;
1416
1339
  FAINT_RATIO = 1.5;
1417
1340
  SELECTION_DELTA_L = .08;
@@ -1424,152 +1347,110 @@ var init_invariants = __esmMin((() => {
1424
1347
  min: AA_RATIO
1425
1348
  },
1426
1349
  {
1427
- rule: "contrast:fg/surfacebg",
1350
+ rule: "contrast:fg/bg-surface-subtle",
1428
1351
  fg: "fg",
1429
- bg: "surfacebg",
1352
+ bg: "bg-surface-subtle",
1430
1353
  min: AA_RATIO
1431
1354
  },
1432
1355
  {
1433
- rule: "contrast:fg/popoverbg",
1356
+ rule: "contrast:fg/bg-surface-overlay",
1434
1357
  fg: "fg",
1435
- bg: "popoverbg",
1358
+ bg: "bg-surface-overlay",
1436
1359
  min: AA_RATIO
1437
1360
  },
1438
1361
  {
1439
- rule: "contrast:muted/mutedbg",
1440
- fg: "muted",
1441
- bg: "mutedbg",
1362
+ rule: "contrast:fg-muted/bg-muted",
1363
+ fg: "fg-muted",
1364
+ bg: "bg-muted",
1442
1365
  min: 3
1443
1366
  },
1444
1367
  {
1445
- rule: "contrast:primary/bg",
1446
- fg: "primary",
1368
+ rule: "contrast:fg-accent/bg",
1369
+ fg: "fg-accent",
1447
1370
  bg: "bg",
1448
1371
  min: AA_RATIO
1449
1372
  },
1450
1373
  {
1451
- rule: "contrast:secondary/bg",
1452
- fg: "secondary",
1374
+ rule: "contrast:fg-error/bg",
1375
+ fg: "fg-error",
1453
1376
  bg: "bg",
1454
1377
  min: AA_RATIO
1455
1378
  },
1456
1379
  {
1457
- rule: "contrast:accent/bg",
1458
- fg: "accent",
1380
+ rule: "contrast:fg-warning/bg",
1381
+ fg: "fg-warning",
1459
1382
  bg: "bg",
1460
1383
  min: AA_RATIO
1461
1384
  },
1462
1385
  {
1463
- rule: "contrast:error/bg",
1464
- fg: "error",
1386
+ rule: "contrast:fg-success/bg",
1387
+ fg: "fg-success",
1465
1388
  bg: "bg",
1466
1389
  min: AA_RATIO
1467
1390
  },
1468
1391
  {
1469
- rule: "contrast:warning/bg",
1470
- fg: "warning",
1392
+ rule: "contrast:fg-info/bg",
1393
+ fg: "fg-info",
1471
1394
  bg: "bg",
1472
1395
  min: AA_RATIO
1473
1396
  },
1474
1397
  {
1475
- rule: "contrast:success/bg",
1476
- fg: "success",
1477
- bg: "bg",
1398
+ rule: "contrast:fg-on-accent/bg-accent",
1399
+ fg: "fg-on-accent",
1400
+ bg: "bg-accent",
1478
1401
  min: AA_RATIO
1479
1402
  },
1480
1403
  {
1481
- rule: "contrast:info/bg",
1482
- fg: "info",
1483
- bg: "bg",
1404
+ rule: "contrast:fg-on-error/bg-error",
1405
+ fg: "fg-on-error",
1406
+ bg: "bg-error",
1484
1407
  min: AA_RATIO
1485
1408
  },
1486
1409
  {
1487
- rule: "contrast:link/bg",
1488
- fg: "link",
1489
- bg: "bg",
1410
+ rule: "contrast:fg-on-warning/bg-warning",
1411
+ fg: "fg-on-warning",
1412
+ bg: "bg-warning",
1490
1413
  min: AA_RATIO
1491
1414
  },
1492
1415
  {
1493
- rule: "contrast:inverse/inversebg",
1494
- fg: "inverse",
1495
- bg: "inversebg",
1416
+ rule: "contrast:fg-on-success/bg-success",
1417
+ fg: "fg-on-success",
1418
+ bg: "bg-success",
1496
1419
  min: AA_RATIO
1497
1420
  },
1498
1421
  {
1499
- rule: "contrast:selection/selectionbg",
1500
- fg: "selection",
1501
- bg: "selectionbg",
1422
+ rule: "contrast:fg-on-info/bg-info",
1423
+ fg: "fg-on-info",
1424
+ bg: "bg-info",
1502
1425
  min: AA_RATIO
1503
1426
  },
1504
1427
  {
1505
- rule: "contrast:cursor/cursorbg",
1506
- fg: "cursor",
1507
- bg: "cursorbg",
1428
+ rule: "contrast:fg-on-selected/bg-selected",
1429
+ fg: "fg-on-selected",
1430
+ bg: "bg-selected",
1508
1431
  min: AA_RATIO
1509
1432
  },
1510
1433
  {
1511
- rule: "contrast:primaryfg/primary",
1512
- fg: "primaryfg",
1513
- bg: "primary",
1434
+ rule: "contrast:fg-cursor/bg-cursor",
1435
+ fg: "fg-cursor",
1436
+ bg: "bg-cursor",
1514
1437
  min: AA_RATIO
1515
1438
  },
1516
1439
  {
1517
- rule: "contrast:secondaryfg/secondary",
1518
- fg: "secondaryfg",
1519
- bg: "secondary",
1520
- min: AA_RATIO
1521
- },
1522
- {
1523
- rule: "contrast:accentfg/accent",
1524
- fg: "accentfg",
1525
- bg: "accent",
1526
- min: AA_RATIO
1527
- },
1528
- {
1529
- rule: "contrast:errorfg/error",
1530
- fg: "errorfg",
1531
- bg: "error",
1532
- min: AA_RATIO
1533
- },
1534
- {
1535
- rule: "contrast:warningfg/warning",
1536
- fg: "warningfg",
1537
- bg: "warning",
1538
- min: AA_RATIO
1539
- },
1540
- {
1541
- rule: "contrast:successfg/success",
1542
- fg: "successfg",
1543
- bg: "success",
1544
- min: AA_RATIO
1545
- },
1546
- {
1547
- rule: "contrast:infofg/info",
1548
- fg: "infofg",
1549
- bg: "info",
1550
- min: AA_RATIO
1551
- },
1552
- {
1553
- rule: "contrast:inputborder/bg",
1554
- fg: "inputborder",
1555
- bg: "bg",
1556
- min: 3
1557
- },
1558
- {
1559
- rule: "contrast:focusborder/bg",
1560
- fg: "focusborder",
1440
+ rule: "contrast:border-default/bg",
1441
+ fg: "border-default",
1561
1442
  bg: "bg",
1562
1443
  min: 3
1563
1444
  },
1564
1445
  {
1565
- rule: "contrast:disabledfg/bg",
1566
- fg: "disabledfg",
1446
+ rule: "contrast:border-focus/bg",
1447
+ fg: "border-focus",
1567
1448
  bg: "bg",
1568
1449
  min: 3
1569
1450
  },
1570
1451
  {
1571
- rule: "contrast:border/bg",
1572
- fg: "border",
1452
+ rule: "contrast:border-muted/bg",
1453
+ fg: "border-muted",
1573
1454
  bg: "bg",
1574
1455
  min: FAINT_RATIO
1575
1456
  }
@@ -1584,7 +1465,97 @@ var init_invariants = __esmMin((() => {
1584
1465
  };
1585
1466
  }));
1586
1467
  //#endregion
1468
+ //#region packages/ansi/src/theme/derived.ts
1469
+ /**
1470
+ * deriveFields — single helper that fills all derived theme sections.
1471
+ *
1472
+ * Eliminates 4-way duplication of brand, categorical ring, state-variant, and
1473
+ * variants population across:
1474
+ * - derive.ts (deriveTruecolorTheme + deriveAnsi16Theme)
1475
+ * - default-schemes.ts (ansi16DarkTheme + ansi16LightTheme)
1476
+ * - @silvery/theme/generate.ts (generateTheme)
1477
+ * - @silvery/theme/schemes/index.ts (ansi16DarkTheme + ansi16LightTheme)
1478
+ *
1479
+ * Canonical authority: derive.ts truecolor path. ANSI16 paths are aligned to
1480
+ * deriveAnsi16Theme output (which is itself the canonical ANSI16 reference).
1481
+ */
1482
+ /**
1483
+ * Derive the shared "delta" fields common to every theme object:
1484
+ * brand tokens, categorical ring, state variants, and typography variants.
1485
+ *
1486
+ * Pass a `shift` function for truecolor hover/active derivation (OKLCH
1487
+ * brighten/darken). Omit `shift` for ANSI16 — hover/active fall back to the
1488
+ * base color (no intermediate intensities available on 16-color terminals).
1489
+ *
1490
+ * @example
1491
+ * // Truecolor (dark theme)
1492
+ * import { brighten, darken } from "@silvery/color"
1493
+ * deriveFields({ shift: (hex, a) => brighten(hex, a), primary, ... })
1494
+ *
1495
+ * @example
1496
+ * // ANSI16 — no shift function
1497
+ * deriveFields({ primary, accent, fg, selectionbg, surfacebg, ring })
1498
+ */
1499
+ function deriveFields(input) {
1500
+ const { dark, shift, primary, accent, fg, selectionbg, surfacebg, ring } = input;
1501
+ const applyShift = dark !== void 0 ? (color, amount) => dark ? brighten(color, amount) : darken(color, amount) : shift ?? ((color, _amount) => color);
1502
+ return {
1503
+ brand: primary,
1504
+ "brand-hover": applyShift(primary, .04),
1505
+ "brand-active": applyShift(primary, .08),
1506
+ ...ring,
1507
+ "primary-hover": applyShift(primary, .04),
1508
+ "primary-active": applyShift(primary, .08),
1509
+ "accent-hover": applyShift(accent, .04),
1510
+ "accent-active": applyShift(accent, .08),
1511
+ "fg-hover": applyShift(fg, .04),
1512
+ "fg-active": applyShift(fg, .08),
1513
+ "bg-selected-hover": applyShift(selectionbg, .04),
1514
+ "bg-surface-hover": applyShift(surfacebg, .04),
1515
+ variants: DEFAULT_VARIANTS
1516
+ };
1517
+ }
1518
+ var DEFAULT_VARIANTS;
1519
+ var init_derived = __esmMin((() => {
1520
+ DEFAULT_VARIANTS = {
1521
+ h1: {
1522
+ color: "$primary",
1523
+ bold: true
1524
+ },
1525
+ h2: {
1526
+ color: "$accent",
1527
+ bold: true
1528
+ },
1529
+ h3: { bold: true },
1530
+ body: {},
1531
+ "body-muted": { color: "$muted" },
1532
+ "fine-print": {
1533
+ color: "$muted",
1534
+ dim: true
1535
+ },
1536
+ strong: { bold: true },
1537
+ em: { italic: true },
1538
+ link: {
1539
+ color: "$link",
1540
+ underlineStyle: "single"
1541
+ },
1542
+ key: {
1543
+ color: "$accent",
1544
+ bold: true
1545
+ },
1546
+ code: { backgroundColor: "$mutedbg" },
1547
+ kbd: {
1548
+ backgroundColor: "$mutedbg",
1549
+ color: "$accent",
1550
+ bold: true
1551
+ }
1552
+ };
1553
+ }));
1554
+ //#endregion
1587
1555
  //#region packages/ansi/src/theme/derive.ts
1556
+ /**
1557
+ * Theme derivation — transforms a ColorScheme into a Theme.
1558
+ */
1588
1559
  function deriveTheme(palette, mode = "truecolor", adjustments) {
1589
1560
  if (mode === "ansi16") return deriveAnsi16Theme(palette);
1590
1561
  return deriveTruecolorTheme(palette, adjustments);
@@ -1652,9 +1623,6 @@ function deriveTruecolorTheme(p, adjustments) {
1652
1623
  const success = ensure("success", p.green, bg, AA);
1653
1624
  const info = ensure("info", blend(fg, accent, .5), bg, AA);
1654
1625
  const link = ensure("link", dark ? p.brightBlue : p.blue, bg, AA);
1655
- const brand = primary;
1656
- const brandHover = dark ? brighten(primary, .04) : darken(primary, .04);
1657
- const brandActive = dark ? brighten(primary, .08) : darken(primary, .08);
1658
1626
  const red = ensure("red", p.red, bg, AA);
1659
1627
  const orange = ensure("orange", blend(p.red, p.yellow, .5), bg, AA);
1660
1628
  const yellow = ensure("yellow", p.yellow, bg, AA);
@@ -1672,6 +1640,24 @@ function deriveTruecolorTheme(p, adjustments) {
1672
1640
  const selection = ensure("selection", p.selectionForeground, selectionBg, AA);
1673
1641
  const cursorBgRepaired = repairCursorBg(p.cursorColor, bg);
1674
1642
  const cursor = ensure("cursor", p.cursorText, cursorBgRepaired, AA);
1643
+ const derived = deriveFields({
1644
+ dark,
1645
+ primary,
1646
+ accent,
1647
+ fg,
1648
+ selectionbg: selectionBg,
1649
+ surfacebg,
1650
+ ring: {
1651
+ red,
1652
+ orange,
1653
+ yellow,
1654
+ green,
1655
+ teal,
1656
+ blue,
1657
+ purple,
1658
+ pink
1659
+ }
1660
+ });
1675
1661
  return {
1676
1662
  name: p.name ?? (dark ? "derived-dark" : "derived-light"),
1677
1663
  bg,
@@ -1725,30 +1711,30 @@ function deriveTruecolorTheme(p, adjustments) {
1725
1711
  p.brightCyan,
1726
1712
  p.brightWhite
1727
1713
  ],
1728
- brand,
1729
- brandHover,
1730
- brandActive,
1731
- red,
1732
- orange,
1733
- yellow,
1734
- green,
1735
- teal,
1736
- blue,
1737
- purple,
1738
- pink,
1739
- brandRed: red,
1740
- brandOrange: orange,
1741
- brandYellow: yellow,
1742
- brandGreen: green,
1743
- brandTeal: teal,
1744
- brandBlue: blue,
1745
- brandPurple: purple,
1746
- brandPink: pink
1714
+ ...derived
1747
1715
  };
1748
1716
  }
1749
1717
  function deriveAnsi16Theme(p) {
1750
1718
  const dark = p.dark ?? true;
1751
1719
  const primaryColor = dark ? p.yellow : p.blue;
1720
+ const accentColor = p.cyan;
1721
+ const derived = deriveFields({
1722
+ primary: primaryColor,
1723
+ accent: accentColor,
1724
+ fg: p.foreground,
1725
+ selectionbg: p.selectionBackground,
1726
+ surfacebg: p.black,
1727
+ ring: {
1728
+ red: dark ? p.brightRed : p.red,
1729
+ orange: dark ? p.brightRed : p.red,
1730
+ yellow: p.yellow,
1731
+ green: dark ? p.brightGreen : p.green,
1732
+ teal: p.cyan,
1733
+ blue: dark ? p.brightBlue : p.blue,
1734
+ purple: p.magenta,
1735
+ pink: dark ? p.brightMagenta : p.magenta
1736
+ }
1737
+ });
1752
1738
  return {
1753
1739
  name: p.name ?? (dark ? "derived-ansi16-dark" : "derived-ansi16-light"),
1754
1740
  bg: p.background,
@@ -1769,7 +1755,7 @@ function deriveAnsi16Theme(p) {
1769
1755
  primaryfg: p.black,
1770
1756
  secondary: p.magenta,
1771
1757
  secondaryfg: p.black,
1772
- accent: p.cyan,
1758
+ accent: accentColor,
1773
1759
  accentfg: p.black,
1774
1760
  error: dark ? p.brightRed : p.red,
1775
1761
  errorfg: p.black,
@@ -1802,17 +1788,7 @@ function deriveAnsi16Theme(p) {
1802
1788
  p.brightCyan,
1803
1789
  p.brightWhite
1804
1790
  ],
1805
- brand: primaryColor,
1806
- brandHover: primaryColor,
1807
- brandActive: primaryColor,
1808
- brandRed: dark ? p.brightRed : p.red,
1809
- brandOrange: dark ? p.brightRed : p.red,
1810
- brandYellow: p.yellow,
1811
- brandGreen: dark ? p.brightGreen : p.green,
1812
- brandTeal: p.cyan,
1813
- brandBlue: dark ? p.brightBlue : p.blue,
1814
- brandPurple: p.magenta,
1815
- brandPink: dark ? p.brightMagenta : p.magenta
1791
+ ...derived
1816
1792
  };
1817
1793
  }
1818
1794
  /**
@@ -1859,8 +1835,8 @@ function repairCursorBg(cursorBg, bg) {
1859
1835
  }
1860
1836
  var AA, DIM, FAINT, CONTROL;
1861
1837
  var init_derive = __esmMin((() => {
1862
- init_src$1();
1863
1838
  init_invariants();
1839
+ init_derived();
1864
1840
  AA = 4.5;
1865
1841
  DIM = 3;
1866
1842
  FAINT = 1.5;
@@ -1883,10 +1859,16 @@ function deriveMonochromeTheme(theme) {
1883
1859
  * consumed by the render pipeline.
1884
1860
  *
1885
1861
  * Accepts strings like `"$primary"`, `"$fg-muted"`, `"$border-focus"`. Strips
1886
- * the `$` prefix and hyphens, tries direct Theme key lookup, then falls back
1887
- * to the Primer alias table. Returns `undefined` for non-token strings (hex,
1862
+ * the `$` prefix and looks the name up directly against `DEFAULT_MONO_ATTRS`,
1863
+ * which carries both legacy keys (`muted`, `surfacebg`, `focusborder`, …) AND
1864
+ * Sterling flat tokens (`fg-muted`, `bg-surface-default`, `border-focus`, …)
1865
+ * as first-class entries. Returns `undefined` for non-token strings (hex,
1888
1866
  * rgb(), named ANSI colors) — callers should treat this as "no attrs".
1889
1867
  *
1868
+ * A secondary no-hyphen fallback (`$surface-bg` → `surfacebg`) keeps the
1869
+ * legacy hyphenated-compound form working for callers that still emit that
1870
+ * shape.
1871
+ *
1890
1872
  * @param color The color string (e.g. `"$primary"`, `"#ff0000"`, `"red"`)
1891
1873
  * @param theme Active theme (reserved for per-theme overrides)
1892
1874
  * @returns Array of mono-attrs for the token, or `undefined` if not a
@@ -1894,17 +1876,17 @@ function deriveMonochromeTheme(theme) {
1894
1876
  */
1895
1877
  function monoAttrsForColorString(color, theme) {
1896
1878
  if (!color.startsWith("$")) return void 0;
1897
- const raw = color.slice(1).replace(/-/g, "");
1879
+ const name = color.slice(1);
1898
1880
  const attrs = deriveMonochromeTheme(theme);
1899
- const direct = attrs[raw];
1881
+ const direct = attrs[name];
1900
1882
  if (direct !== void 0) return direct;
1901
- const aliased = PRIMER_ALIASES_FOR_MONO[raw];
1902
- if (aliased) {
1903
- const v = attrs[aliased];
1904
- if (v !== void 0) return v;
1883
+ const noHyphen = name.replace(/-/g, "");
1884
+ if (noHyphen !== name) {
1885
+ const stripped = attrs[noHyphen];
1886
+ if (stripped !== void 0) return stripped;
1905
1887
  }
1906
1888
  }
1907
- var DEFAULT_MONO_ATTRS, PRIMER_ALIASES_FOR_MONO;
1889
+ var DEFAULT_MONO_ATTRS;
1908
1890
  var init_monochrome = __esmMin((() => {
1909
1891
  DEFAULT_MONO_ATTRS = {
1910
1892
  bg: [],
@@ -1938,31 +1920,47 @@ var init_monochrome = __esmMin((() => {
1938
1920
  inputborder: [],
1939
1921
  selection: [],
1940
1922
  selectionbg: ["inverse"],
1941
- cursor: []
1942
- };
1943
- PRIMER_ALIASES_FOR_MONO = {
1944
- fgmuted: "muted",
1945
- fgdisabled: "disabledfg",
1946
- fgcursor: "cursor",
1947
- fgselected: "selection",
1948
- fginverse: "inverse",
1949
- fgonsurface: "surface",
1950
- fgonpopover: "popover",
1951
- fgonprimary: "primaryfg",
1952
- fgonsecondary: "secondaryfg",
1953
- fgonaccent: "accentfg",
1954
- fgonerror: "errorfg",
1955
- fgonwarning: "warningfg",
1956
- fgonsuccess: "successfg",
1957
- fgoninfo: "infofg",
1958
- bgmuted: "mutedbg",
1959
- bgsurface: "surfacebg",
1960
- bgpopover: "popoverbg",
1961
- bginverse: "inversebg",
1962
- bgselected: "selectionbg",
1963
- bgcursor: "cursorbg",
1964
- borderfocus: "focusborder",
1965
- borderinput: "inputborder"
1923
+ cursor: [],
1924
+ "fg-muted": ["dim"],
1925
+ "bg-muted": [],
1926
+ "fg-accent": ["italic", "bold"],
1927
+ "bg-accent": [],
1928
+ "fg-on-accent": [],
1929
+ "border-accent": [],
1930
+ "fg-accent-hover": ["italic", "bold"],
1931
+ "bg-accent-hover": [],
1932
+ "fg-accent-active": ["italic", "bold"],
1933
+ "bg-accent-active": [],
1934
+ "fg-info": ["italic"],
1935
+ "bg-info": [],
1936
+ "fg-on-info": [],
1937
+ "bg-info-hover": [],
1938
+ "bg-info-active": [],
1939
+ "fg-success": ["bold"],
1940
+ "bg-success": [],
1941
+ "fg-on-success": [],
1942
+ "bg-success-hover": [],
1943
+ "bg-success-active": [],
1944
+ "fg-warning": ["bold"],
1945
+ "bg-warning": [],
1946
+ "fg-on-warning": [],
1947
+ "bg-warning-hover": [],
1948
+ "bg-warning-active": [],
1949
+ "fg-error": ["bold", "inverse"],
1950
+ "bg-error": [],
1951
+ "fg-on-error": ["inverse"],
1952
+ "bg-error-hover": [],
1953
+ "bg-error-active": [],
1954
+ "bg-surface-default": [],
1955
+ "bg-surface-subtle": [],
1956
+ "bg-surface-raised": [],
1957
+ "bg-surface-overlay": [],
1958
+ "bg-surface-hover": [],
1959
+ "border-default": [],
1960
+ "border-focus": ["bold"],
1961
+ "border-muted": [],
1962
+ "fg-cursor": [],
1963
+ "bg-cursor": []
1966
1964
  };
1967
1965
  }));
1968
1966
  //#endregion
@@ -2021,7 +2019,6 @@ function fingerprintMatch(probed, catalog, opts = {}) {
2021
2019
  }
2022
2020
  var FINGERPRINT_FIELDS;
2023
2021
  var init_fingerprint = __esmMin((() => {
2024
- init_src$1();
2025
2022
  FINGERPRINT_FIELDS = [
2026
2023
  "foreground",
2027
2024
  "background",
@@ -2074,154 +2071,9 @@ var init_types = __esmMin((() => {
2074
2071
  }));
2075
2072
  //#endregion
2076
2073
  //#region packages/ansi/src/theme/default-schemes.ts
2077
- var ansi16DarkTheme, ansi16LightTheme, defaultDarkScheme, defaultLightScheme;
2074
+ var defaultDarkScheme, defaultLightScheme, ansi16DarkTheme, ansi16LightTheme;
2078
2075
  var init_default_schemes = __esmMin((() => {
2079
- ansi16DarkTheme = {
2080
- name: "dark-ansi16",
2081
- bg: "",
2082
- fg: "whiteBright",
2083
- muted: "white",
2084
- mutedbg: "black",
2085
- surface: "whiteBright",
2086
- surfacebg: "black",
2087
- popover: "whiteBright",
2088
- popoverbg: "black",
2089
- inverse: "black",
2090
- inversebg: "whiteBright",
2091
- cursor: "black",
2092
- cursorbg: "yellow",
2093
- selection: "black",
2094
- selectionbg: "yellow",
2095
- primary: "yellow",
2096
- primaryfg: "black",
2097
- secondary: "white",
2098
- secondaryfg: "black",
2099
- accent: "blueBright",
2100
- accentfg: "black",
2101
- error: "redBright",
2102
- errorfg: "black",
2103
- warning: "yellow",
2104
- warningfg: "black",
2105
- success: "greenBright",
2106
- successfg: "black",
2107
- info: "cyan",
2108
- infofg: "black",
2109
- border: "gray",
2110
- inputborder: "gray",
2111
- focusborder: "blueBright",
2112
- link: "blueBright",
2113
- disabledfg: "gray",
2114
- palette: [
2115
- "black",
2116
- "red",
2117
- "green",
2118
- "yellow",
2119
- "blue",
2120
- "magenta",
2121
- "cyan",
2122
- "white",
2123
- "blackBright",
2124
- "redBright",
2125
- "greenBright",
2126
- "yellowBright",
2127
- "blueBright",
2128
- "magentaBright",
2129
- "cyanBright",
2130
- "whiteBright"
2131
- ],
2132
- brand: "yellow",
2133
- brandHover: "yellow",
2134
- brandActive: "yellow",
2135
- red: "redBright",
2136
- orange: "redBright",
2137
- yellow: "yellow",
2138
- green: "greenBright",
2139
- teal: "cyan",
2140
- blue: "blueBright",
2141
- purple: "magenta",
2142
- pink: "magentaBright",
2143
- brandRed: "redBright",
2144
- brandOrange: "redBright",
2145
- brandYellow: "yellow",
2146
- brandGreen: "greenBright",
2147
- brandTeal: "cyan",
2148
- brandBlue: "blueBright",
2149
- brandPurple: "magenta",
2150
- brandPink: "magentaBright"
2151
- };
2152
- ansi16LightTheme = {
2153
- name: "light-ansi16",
2154
- bg: "",
2155
- fg: "black",
2156
- muted: "blackBright",
2157
- mutedbg: "white",
2158
- surface: "black",
2159
- surfacebg: "white",
2160
- popover: "black",
2161
- popoverbg: "white",
2162
- inverse: "whiteBright",
2163
- inversebg: "black",
2164
- cursor: "black",
2165
- cursorbg: "blue",
2166
- selection: "black",
2167
- selectionbg: "cyan",
2168
- primary: "blue",
2169
- primaryfg: "black",
2170
- secondary: "blue",
2171
- secondaryfg: "black",
2172
- accent: "cyan",
2173
- accentfg: "black",
2174
- error: "red",
2175
- errorfg: "black",
2176
- warning: "yellow",
2177
- warningfg: "black",
2178
- success: "green",
2179
- successfg: "black",
2180
- info: "cyan",
2181
- infofg: "black",
2182
- border: "gray",
2183
- inputborder: "gray",
2184
- focusborder: "blue",
2185
- link: "blueBright",
2186
- disabledfg: "gray",
2187
- palette: [
2188
- "black",
2189
- "red",
2190
- "green",
2191
- "yellow",
2192
- "blue",
2193
- "magenta",
2194
- "cyan",
2195
- "white",
2196
- "blackBright",
2197
- "redBright",
2198
- "greenBright",
2199
- "yellowBright",
2200
- "blueBright",
2201
- "magentaBright",
2202
- "cyanBright",
2203
- "whiteBright"
2204
- ],
2205
- brand: "blue",
2206
- brandHover: "blue",
2207
- brandActive: "blue",
2208
- red: "red",
2209
- orange: "red",
2210
- yellow: "yellow",
2211
- green: "green",
2212
- teal: "cyan",
2213
- blue: "blue",
2214
- purple: "magenta",
2215
- pink: "magenta",
2216
- brandRed: "red",
2217
- brandOrange: "red",
2218
- brandYellow: "yellow",
2219
- brandGreen: "green",
2220
- brandTeal: "cyan",
2221
- brandBlue: "blue",
2222
- brandPurple: "magenta",
2223
- brandPink: "magenta"
2224
- };
2076
+ init_derive();
2225
2077
  defaultDarkScheme = {
2226
2078
  name: "default-dark",
2227
2079
  dark: true,
@@ -2274,6 +2126,8 @@ var init_default_schemes = __esmMin((() => {
2274
2126
  selectionBackground: "#ccd0da",
2275
2127
  selectionForeground: "#4c4f69"
2276
2128
  };
2129
+ ansi16DarkTheme = deriveAnsi16Theme(defaultDarkScheme);
2130
+ ansi16LightTheme = deriveAnsi16Theme(defaultLightScheme);
2277
2131
  }));
2278
2132
  //#endregion
2279
2133
  //#region packages/ansi/src/osc-palette.ts
@@ -2487,6 +2341,23 @@ async function detectTerminalScheme(timeoutMs = 150) {
2487
2341
  if (!wasRaw) stdin.setRawMode(false);
2488
2342
  }
2489
2343
  }
2344
+ async function detectTheme(opts = {}) {
2345
+ const colorLevel = opts.caps?.colorLevel;
2346
+ if (colorLevel === "none" || colorLevel === "basic") return opts.caps?.darkBackground ?? true ? ansi16DarkTheme : ansi16LightTheme;
2347
+ const detected = await detectTerminalScheme(opts.timeoutMs);
2348
+ const isDark = detected?.dark ?? opts.caps?.darkBackground ?? true;
2349
+ const fallback = opts.fallback ?? (isDark ? opts.fallbackDark ?? defaultDarkScheme : opts.fallbackLight ?? defaultLightScheme);
2350
+ if (!detected) return deriveTheme(fallback);
2351
+ return deriveTheme({
2352
+ ...fallback,
2353
+ ...stripNulls$1(detected.palette)
2354
+ });
2355
+ }
2356
+ function stripNulls$1(partial) {
2357
+ const result = {};
2358
+ for (const [k, v] of Object.entries(partial)) if (v != null) result[k] = v;
2359
+ return result;
2360
+ }
2490
2361
  function isDarkColor(hex) {
2491
2362
  const r = parseInt(hex.slice(1, 3), 16) / 255;
2492
2363
  const g = parseInt(hex.slice(3, 5), 16) / 255;
@@ -2494,6 +2365,8 @@ function isDarkColor(hex) {
2494
2365
  return .2126 * r + .7152 * g + .0722 * b <= .5;
2495
2366
  }
2496
2367
  var init_detect = __esmMin((() => {
2368
+ init_derive();
2369
+ init_default_schemes();
2497
2370
  init_osc_palette();
2498
2371
  init_osc_colors();
2499
2372
  }));
@@ -2629,6 +2502,25 @@ var init_orchestrator = __esmMin((() => {
2629
2502
  init_detect();
2630
2503
  init_fingerprint();
2631
2504
  init_default_schemes();
2505
+ }));
2506
+ //#endregion
2507
+ //#region packages/ansi/src/theme/tokens.ts
2508
+ var KNOWN_VARIANTS;
2509
+ var init_tokens = __esmMin((() => {
2510
+ KNOWN_VARIANTS = [
2511
+ "h1",
2512
+ "h2",
2513
+ "h3",
2514
+ "body",
2515
+ "body-muted",
2516
+ "fine-print",
2517
+ "strong",
2518
+ "em",
2519
+ "link",
2520
+ "key",
2521
+ "code",
2522
+ "kbd"
2523
+ ];
2632
2524
  })), CSI;
2633
2525
  var init_color_scheme = __esmMin((() => {
2634
2526
  CSI = `[`;
@@ -2636,24 +2528,133 @@ var init_color_scheme = __esmMin((() => {
2636
2528
  `${CSI}`;
2637
2529
  }));
2638
2530
  //#endregion
2531
+ //#region packages/ansi/src/theme/generators.ts
2532
+ var init_generators = __esmMin((() => {}));
2533
+ //#endregion
2534
+ //#region packages/ansi/src/theme/auto-generate.ts
2535
+ var init_auto_generate = __esmMin((() => {
2536
+ init_generators();
2537
+ init_derive();
2538
+ }));
2539
+ //#endregion
2540
+ //#region packages/ansi/src/theme/generate.ts
2541
+ /**
2542
+ * Generate a complete ANSI 16 theme from a primary color + dark/light preference.
2543
+ *
2544
+ * All token values are ANSI color names (e.g. "yellow", "blueBright").
2545
+ */
2546
+ function generateTheme(primary, dark) {
2547
+ const fg = dark ? "whiteBright" : "black";
2548
+ const accent = primary;
2549
+ const selectionbg = primary;
2550
+ const surfacebg = dark ? "black" : "white";
2551
+ const derived = deriveFields({
2552
+ primary,
2553
+ accent,
2554
+ fg,
2555
+ selectionbg,
2556
+ surfacebg,
2557
+ ring: {
2558
+ red: dark ? "redBright" : "red",
2559
+ orange: dark ? "redBright" : "red",
2560
+ yellow: "yellow",
2561
+ green: dark ? "greenBright" : "green",
2562
+ teal: "cyan",
2563
+ blue: dark ? "blueBright" : "blue",
2564
+ purple: "magenta",
2565
+ pink: dark ? "magentaBright" : "magenta"
2566
+ }
2567
+ });
2568
+ return {
2569
+ name: `${dark ? "dark" : "light"}-${primary}`,
2570
+ bg: "",
2571
+ fg,
2572
+ muted: dark ? "white" : "blackBright",
2573
+ mutedbg: dark ? "black" : "white",
2574
+ surface: dark ? "whiteBright" : "black",
2575
+ surfacebg,
2576
+ popover: dark ? "whiteBright" : "black",
2577
+ popoverbg: dark ? "blackBright" : "white",
2578
+ inverse: dark ? "black" : "whiteBright",
2579
+ inversebg: dark ? "whiteBright" : "black",
2580
+ cursor: "black",
2581
+ cursorbg: primary,
2582
+ selection: "black",
2583
+ selectionbg: primary,
2584
+ primary,
2585
+ primaryfg: "black",
2586
+ secondary: primary,
2587
+ secondaryfg: "black",
2588
+ accent: primary,
2589
+ accentfg: "black",
2590
+ error: dark ? "redBright" : "red",
2591
+ errorfg: "black",
2592
+ warning: primary,
2593
+ warningfg: "black",
2594
+ success: dark ? "greenBright" : "green",
2595
+ successfg: "black",
2596
+ info: dark ? "cyanBright" : "cyan",
2597
+ infofg: "black",
2598
+ border: "gray",
2599
+ inputborder: "gray",
2600
+ focusborder: dark ? "blueBright" : "blue",
2601
+ link: "blueBright",
2602
+ disabledfg: "gray",
2603
+ palette: [
2604
+ "black",
2605
+ "red",
2606
+ "green",
2607
+ "yellow",
2608
+ "blue",
2609
+ "magenta",
2610
+ "cyan",
2611
+ "white",
2612
+ "blackBright",
2613
+ "redBright",
2614
+ "greenBright",
2615
+ "yellowBright",
2616
+ "blueBright",
2617
+ "magentaBright",
2618
+ "cyanBright",
2619
+ "whiteBright"
2620
+ ],
2621
+ ...derived
2622
+ };
2623
+ }
2624
+ var init_generate = __esmMin((() => {
2625
+ init_derived();
2626
+ }));
2627
+ //#endregion
2639
2628
  //#region packages/ansi/src/index.ts
2640
2629
  var init_src = __esmMin((() => {
2641
2630
  init_detection();
2642
2631
  init_sgr_codes();
2643
2632
  init_utils();
2633
+ init_color_maps();
2634
+ init_flatten();
2644
2635
  init_terminal_control();
2636
+ init_kitty_graphics();
2645
2637
  init_style();
2646
2638
  init_mixed_proxy();
2639
+ init_colors();
2647
2640
  init_derive();
2641
+ init_derived();
2648
2642
  init_monochrome();
2643
+ init_fingerprint();
2649
2644
  init_orchestrator();
2645
+ init_invariants();
2650
2646
  init_default_schemes();
2651
2647
  init_types();
2648
+ init_tokens();
2652
2649
  init_detect();
2653
2650
  init_osc_palette();
2651
+ init_osc_colors();
2654
2652
  init_color_scheme();
2653
+ init_generators();
2654
+ init_auto_generate();
2655
+ init_generate();
2655
2656
  }));
2656
2657
  //#endregion
2657
- export { detectTerminalCaps as $, brighten as A, rgbToHsl as B, createMixedStyle as C, checkContrast as D, init_src$1 as E, hexToHsl as F, enableKittyKeyboard as G, oklchToHex as H, hexToRgb as I, fgColorCode as J, enableMouse as K, hslToHex as L, contrastFg as M, darken as N, ensureContrast as O, desaturate as P, detectInput as Q, relativeLuminance as R, deriveTheme as S, resolveThemeColor as T, disableKittyKeyboard as U, hexToOklch as V, disableMouse as W, detectColor as X, defaultCaps as Y, detectCursor as Z, setPaletteColor as _, queryBackgroundColor as a, COLOR_SCHEME_FIELDS as b, resetBackgroundColor as c, setBackgroundColor as d, detectUnicode as et, setCursorColor as f, queryPaletteColor as g, queryMultiplePaletteColors as h, detectColorScheme as i, complement as j, blend as k, resetCursorColor as l, parsePaletteResponse as m, detectScheme as n, queryCursorColor as o, setForegroundColor as p, bgColorCode as q, detectTerminalScheme as r, queryForegroundColor as s, init_src as t, resetForegroundColor as u, ansi16DarkTheme as v, createStyle as w, monoAttrsForColorString as x, ansi16LightTheme as y, rgbToHex as z };
2658
+ export { backdropPlacementId as A, bakeFlat as B, COLOR_SCHEME_FIELDS as C, createMixedStyle as D, deriveFields as E, kittyUploadScrimImage as F, bgColorCode as G, ANSI16_SLOT_HEX as H, disableKittyKeyboard as I, detectColor as J, fgColorCode as K, disableMouse as L, cupTo as M, kittyDeleteAllScrimPlacements as N, createStyle as O, kittyPlaceAt as P, detectUnicode as Q, enableKittyKeyboard as R, ansi16LightTheme as S, deriveTheme as T, pickColorLevel as U, defaultFlattenRule as V, quantizeHex as W, detectInput as X, detectCursor as Y, detectTerminalCaps as Z, parsePaletteResponse as _, detectTerminalScheme as a, setPaletteColor as b, queryBackgroundColor as c, resetBackgroundColor as d, resetCursorColor as f, setForegroundColor as g, setCursorColor as h, detectScheme as i, buildScrimPixels as j, resolveThemeColor as k, queryCursorColor as l, setBackgroundColor as m, generateTheme as n, detectTheme as o, resetForegroundColor as p, defaultCaps as q, KNOWN_VARIANTS as r, detectColorScheme as s, init_src as t, queryForegroundColor as u, queryMultiplePaletteColors as v, monoAttrsForColorString as w, ansi16DarkTheme as x, queryPaletteColor as y, enableMouse as z };
2658
2659
 
2659
- //# sourceMappingURL=src-D_BS-as7.mjs.map
2660
+ //# sourceMappingURL=src-NCKb8kE5.mjs.map