uivisor 0.2.0 → 0.2.2

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 (2) hide show
  1. package/dist/overlay/index.js +368 -1050
  2. package/package.json +1 -1
@@ -255,8 +255,8 @@ function suggestUtility(property, value) {
255
255
  return `${sp}-[${n}px]`;
256
256
  }
257
257
  if (property === "line-height") {
258
- const t = value.trim();
259
- const unitless = /^(\d*\.?\d+)$/.exec(t);
258
+ const t2 = value.trim();
259
+ const unitless = /^(\d*\.?\d+)$/.exec(t2);
260
260
  if (unitless) {
261
261
  const named = {
262
262
  "1": "leading-none",
@@ -266,16 +266,16 @@ function suggestUtility(property, value) {
266
266
  "1.625": "leading-relaxed",
267
267
  "2": "leading-loose"
268
268
  };
269
- return named[String(parseFloat(unitless[1]))] ?? `leading-[${t}]`;
269
+ return named[String(parseFloat(unitless[1]))] ?? `leading-[${t2}]`;
270
270
  }
271
- const n = px(t);
271
+ const n = px(t2);
272
272
  if (n != null) return `leading-[${n}px]`;
273
- return `leading-[${t}]`;
273
+ return `leading-[${t2}]`;
274
274
  }
275
275
  if (property === "letter-spacing") {
276
- const t = value.trim();
277
- if (t === "normal" || t === "0" || t === "0px" || t === "0em") return "tracking-normal";
278
- const em = /^(-?\d*\.?\d+)em$/.exec(t);
276
+ const t2 = value.trim();
277
+ if (t2 === "normal" || t2 === "0" || t2 === "0px" || t2 === "0em") return "tracking-normal";
278
+ const em = /^(-?\d*\.?\d+)em$/.exec(t2);
279
279
  if (em) {
280
280
  const named = {
281
281
  "-0.05": "tracking-tighter",
@@ -284,9 +284,9 @@ function suggestUtility(property, value) {
284
284
  "0.05": "tracking-wider",
285
285
  "0.1": "tracking-widest"
286
286
  };
287
- return named[String(parseFloat(em[1]))] ?? `tracking-[${t}]`;
287
+ return named[String(parseFloat(em[1]))] ?? `tracking-[${t2}]`;
288
288
  }
289
- return `tracking-[${t}]`;
289
+ return `tracking-[${t2}]`;
290
290
  }
291
291
  if (property === "color" || property === "background-color") {
292
292
  const hex = rgbToHex(value) ?? (value.startsWith("#") ? value : null);
@@ -340,11 +340,11 @@ function suggestUtility(property, value) {
340
340
  };
341
341
  if (SIZE_PREFIX[property]) {
342
342
  const pre = SIZE_PREFIX[property];
343
- const t = value.trim();
344
- if (t === "auto") return `${pre}-auto`;
345
- if (t === "100%") return `${pre}-full`;
346
- const n = px(t);
347
- if (n == null) return `${pre}-[${t}]`;
343
+ const t2 = value.trim();
344
+ if (t2 === "auto") return `${pre}-auto`;
345
+ if (t2 === "100%") return `${pre}-full`;
346
+ const n = px(t2);
347
+ if (n == null) return `${pre}-[${t2}]`;
348
348
  const scale = n / 4;
349
349
  if (Number.isInteger(scale) && scale >= 0 && scale <= 96) return `${pre}-${scale}`;
350
350
  return `${pre}-[${n}px]`;
@@ -424,6 +424,8 @@ var SECTIONS = [
424
424
  label: "Display",
425
425
  options: ["block", "inline-block", "inline", "flex", "inline-flex", "grid", "inline-grid", "none"]
426
426
  },
427
+ // Justify / Align are handled by the bigger visual button-rows injected right
428
+ // below Display (flexControlsHtml) — not duplicated here as plain selects.
427
429
  {
428
430
  kind: "select",
429
431
  css: "flex-direction",
@@ -431,20 +433,6 @@ var SECTIONS = [
431
433
  options: ["row", "row-reverse", "column", "column-reverse"],
432
434
  requires: "flexgrid"
433
435
  },
434
- {
435
- kind: "select",
436
- css: "justify-content",
437
- label: "Justify",
438
- options: ["normal", "flex-start", "center", "flex-end", "space-between", "space-around", "space-evenly"],
439
- requires: "flexgrid"
440
- },
441
- {
442
- kind: "select",
443
- css: "align-items",
444
- label: "Align",
445
- options: ["normal", "stretch", "flex-start", "center", "flex-end", "baseline"],
446
- requires: "flexgrid"
447
- },
448
436
  {
449
437
  kind: "select",
450
438
  css: "flex-wrap",
@@ -666,7 +654,7 @@ function buildDesignSystem(vars, rootPx = 16) {
666
654
  });
667
655
  }
668
656
  const byCategory = {};
669
- for (const t of tokens) (byCategory[t.category] ||= []).push(t);
657
+ for (const t2 of tokens) (byCategory[t2.category] ||= []).push(t2);
670
658
  for (const cat of Object.keys(byCategory)) {
671
659
  byCategory[cat].sort(
672
660
  (a, b) => a.px != null && b.px != null ? a.px - b.px : a.name.localeCompare(b.name)
@@ -679,22 +667,22 @@ function nearestToken(ds, category, target) {
679
667
  if (!list || !list.length) return null;
680
668
  if (target.value != null) {
681
669
  const norm = (s) => {
682
- const t = s.trim();
683
- return (rgbToHex(t) || t).replace(/\s+/g, "").toLowerCase();
670
+ const t2 = s.trim();
671
+ return (rgbToHex(t2) || t2).replace(/\s+/g, "").toLowerCase();
684
672
  };
685
673
  const want = norm(target.value);
686
- const hit = list.find((t) => norm(t.value) === want);
674
+ const hit = list.find((t2) => norm(t2.value) === want);
687
675
  if (hit) return { token: hit, exact: true };
688
676
  }
689
- if (target.px != null && list.some((t) => t.px != null)) {
677
+ if (target.px != null && list.some((t2) => t2.px != null)) {
690
678
  let best = list[0];
691
679
  let bestD = Infinity;
692
- for (const t of list) {
693
- if (t.px == null) continue;
694
- const d = Math.abs(t.px - target.px);
680
+ for (const t2 of list) {
681
+ if (t2.px == null) continue;
682
+ const d = Math.abs(t2.px - target.px);
695
683
  if (d < bestD) {
696
684
  bestD = d;
697
- best = t;
685
+ best = t2;
698
686
  }
699
687
  }
700
688
  return { token: best, exact: bestD < 0.5 };
@@ -737,609 +725,6 @@ function collectVarNames(rule, out) {
737
725
  if (inner) for (const r of Array.from(inner)) collectVarNames(r, out);
738
726
  }
739
727
 
740
- // src/overlay/cssData.ts
741
- var CSS_PROPERTY_DATA = [
742
- { "property": "display", "category": "Layout", "type": "enum", "keywords": ["block", "inline", "inline-block", "flex", "inline-flex", "grid", "inline-grid", "flow-root", "none", "contents", "table", "inline-table", "table-row-group", "table-header-group", "table-footer-group", "table-row", "table-cell", "table-column-group", "table-column", "table-caption", "list-item", "ruby"] },
743
- { "property": "position", "category": "Layout", "type": "enum", "keywords": ["static", "relative", "absolute", "fixed", "sticky"] },
744
- { "property": "top", "category": "Layout", "type": "length", "keywords": ["auto"], "units": ["px", "%", "em", "rem", "vh", "vw"], "box": "inset" },
745
- { "property": "right", "category": "Layout", "type": "length", "keywords": ["auto"], "units": ["px", "%", "em", "rem", "vh", "vw"], "box": "inset" },
746
- { "property": "bottom", "category": "Layout", "type": "length", "keywords": ["auto"], "units": ["px", "%", "em", "rem", "vh", "vw"], "box": "inset" },
747
- { "property": "left", "category": "Layout", "type": "length", "keywords": ["auto"], "units": ["px", "%", "em", "rem", "vh", "vw"], "box": "inset" },
748
- { "property": "inset", "category": "Layout", "type": "length", "keywords": ["auto"], "units": ["px", "%", "em", "rem", "vh", "vw"], "shorthand": true },
749
- { "property": "inset-block", "category": "Layout", "type": "length", "keywords": ["auto"], "units": ["px", "%", "em", "rem", "vh", "vw"], "shorthand": true },
750
- { "property": "inset-inline", "category": "Layout", "type": "length", "keywords": ["auto"], "units": ["px", "%", "em", "rem", "vh", "vw"], "shorthand": true },
751
- { "property": "inset-block-start", "category": "Layout", "type": "length", "keywords": ["auto"], "units": ["px", "%", "em", "rem", "vh", "vw"] },
752
- { "property": "inset-block-end", "category": "Layout", "type": "length", "keywords": ["auto"], "units": ["px", "%", "em", "rem", "vh", "vw"] },
753
- { "property": "inset-inline-start", "category": "Layout", "type": "length", "keywords": ["auto"], "units": ["px", "%", "em", "rem", "vh", "vw"] },
754
- { "property": "inset-inline-end", "category": "Layout", "type": "length", "keywords": ["auto"], "units": ["px", "%", "em", "rem", "vh", "vw"] },
755
- { "property": "float", "category": "Layout", "type": "enum", "keywords": ["left", "right", "none", "inline-start", "inline-end"] },
756
- { "property": "clear", "category": "Layout", "type": "enum", "keywords": ["none", "left", "right", "both", "inline-start", "inline-end"] },
757
- { "property": "visibility", "category": "Layout", "type": "enum", "keywords": ["visible", "hidden", "collapse"], "inherited": true },
758
- { "property": "z-index", "category": "Layout", "type": "integer", "keywords": ["auto"] },
759
- { "property": "box-sizing", "category": "Layout", "type": "enum", "keywords": ["content-box", "border-box"] },
760
- { "property": "overflow", "category": "Layout", "type": "enum", "keywords": ["visible", "hidden", "clip", "scroll", "auto"], "shorthand": true },
761
- { "property": "overflow-x", "category": "Layout", "type": "enum", "keywords": ["visible", "hidden", "clip", "scroll", "auto"] },
762
- { "property": "overflow-y", "category": "Layout", "type": "enum", "keywords": ["visible", "hidden", "clip", "scroll", "auto"] },
763
- { "property": "overflow-block", "category": "Layout", "type": "enum", "keywords": ["visible", "hidden", "clip", "scroll", "auto"] },
764
- { "property": "overflow-inline", "category": "Layout", "type": "enum", "keywords": ["visible", "hidden", "clip", "scroll", "auto"] },
765
- { "property": "overflow-clip-margin", "category": "Layout", "type": "length", "keywords": ["content-box", "padding-box", "border-box"], "units": ["px", "em", "rem"] },
766
- { "property": "isolation", "category": "Layout", "type": "enum", "keywords": ["auto", "isolate"] },
767
- { "property": "contain", "category": "Layout", "type": "enum", "keywords": ["none", "strict", "content", "size", "inline-size", "layout", "style", "paint"] },
768
- { "property": "content-visibility", "category": "Layout", "type": "enum", "keywords": ["visible", "auto", "hidden"] },
769
- { "property": "contain-intrinsic-size", "category": "Layout", "type": "length", "keywords": ["none", "auto"], "units": ["px", "em", "rem"], "shorthand": true },
770
- { "property": "contain-intrinsic-width", "category": "Layout", "type": "length", "keywords": ["none", "auto"], "units": ["px", "em", "rem"] },
771
- { "property": "contain-intrinsic-height", "category": "Layout", "type": "length", "keywords": ["none", "auto"], "units": ["px", "em", "rem"] },
772
- { "property": "contain-intrinsic-block-size", "category": "Layout", "type": "length", "keywords": ["none", "auto"], "units": ["px", "em", "rem"] },
773
- { "property": "contain-intrinsic-inline-size", "category": "Layout", "type": "length", "keywords": ["none", "auto"], "units": ["px", "em", "rem"] },
774
- { "property": "order", "category": "Layout", "type": "integer" },
775
- { "property": "flex", "category": "Flexbox", "type": "shorthand", "shorthand": true },
776
- { "property": "flex-grow", "category": "Flexbox", "type": "number" },
777
- { "property": "flex-shrink", "category": "Flexbox", "type": "number" },
778
- { "property": "flex-basis", "category": "Flexbox", "type": "length", "keywords": ["auto", "content", "max-content", "min-content", "fit-content"], "units": ["px", "%", "em", "rem", "vh", "vw", "ch"] },
779
- { "property": "flex-direction", "category": "Flexbox", "type": "enum", "keywords": ["row", "row-reverse", "column", "column-reverse"] },
780
- { "property": "flex-wrap", "category": "Flexbox", "type": "enum", "keywords": ["nowrap", "wrap", "wrap-reverse"] },
781
- { "property": "flex-flow", "category": "Flexbox", "type": "shorthand", "keywords": ["row", "row-reverse", "column", "column-reverse", "nowrap", "wrap", "wrap-reverse"], "shorthand": true },
782
- { "property": "justify-content", "category": "Flexbox", "type": "enum", "keywords": ["normal", "flex-start", "flex-end", "center", "space-between", "space-around", "space-evenly", "start", "end", "left", "right", "stretch", "safe", "unsafe"] },
783
- { "property": "align-items", "category": "Flexbox", "type": "enum", "keywords": ["normal", "stretch", "flex-start", "flex-end", "center", "baseline", "first baseline", "last baseline", "start", "end", "self-start", "self-end", "safe", "unsafe", "anchor-center"] },
784
- { "property": "align-content", "category": "Flexbox", "type": "enum", "keywords": ["normal", "flex-start", "flex-end", "center", "space-between", "space-around", "space-evenly", "stretch", "start", "end", "baseline", "first baseline", "last baseline", "safe", "unsafe"] },
785
- { "property": "align-self", "category": "Flexbox", "type": "enum", "keywords": ["auto", "normal", "stretch", "flex-start", "flex-end", "center", "baseline", "first baseline", "last baseline", "start", "end", "self-start", "self-end", "safe", "unsafe", "anchor-center"] },
786
- { "property": "justify-self", "category": "Flexbox", "type": "enum", "keywords": ["auto", "normal", "stretch", "flex-start", "flex-end", "center", "baseline", "first baseline", "last baseline", "start", "end", "self-start", "self-end", "left", "right", "safe", "unsafe", "anchor-center"] },
787
- { "property": "justify-items", "category": "Flexbox", "type": "enum", "keywords": ["normal", "stretch", "flex-start", "flex-end", "center", "baseline", "first baseline", "last baseline", "start", "end", "self-start", "self-end", "left", "right", "legacy", "safe", "unsafe", "anchor-center"] },
788
- { "property": "place-content", "category": "Flexbox", "type": "shorthand", "keywords": ["normal", "stretch", "flex-start", "flex-end", "center", "space-between", "space-around", "space-evenly", "start", "end", "left", "right", "baseline", "first baseline", "last baseline"], "shorthand": true },
789
- { "property": "place-items", "category": "Flexbox", "type": "shorthand", "keywords": ["normal", "stretch", "flex-start", "flex-end", "center", "baseline", "first baseline", "last baseline", "start", "end", "self-start", "self-end", "left", "right", "legacy"], "shorthand": true },
790
- { "property": "place-self", "category": "Flexbox", "type": "shorthand", "keywords": ["auto", "normal", "stretch", "flex-start", "flex-end", "center", "baseline", "first baseline", "last baseline", "start", "end", "self-start", "self-end"], "shorthand": true },
791
- { "property": "gap", "category": "Flexbox", "type": "shorthand", "keywords": ["normal"], "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "shorthand": true },
792
- { "property": "row-gap", "category": "Flexbox", "type": "length", "keywords": ["normal"], "units": ["px", "%", "em", "rem", "vh", "vw", "ch"] },
793
- { "property": "column-gap", "category": "Flexbox", "type": "length", "keywords": ["normal"], "units": ["px", "%", "em", "rem", "vh", "vw", "ch"] },
794
- { "property": "grid", "category": "Grid", "type": "shorthand", "shorthand": true },
795
- { "property": "grid-template", "category": "Grid", "type": "shorthand", "shorthand": true },
796
- { "property": "grid-template-columns", "category": "Grid", "type": "string", "keywords": ["none", "min-content", "max-content", "auto", "subgrid", "masonry"], "units": ["px", "em", "rem", "%", "fr", "vh", "vw", "ch"] },
797
- { "property": "grid-template-rows", "category": "Grid", "type": "string", "keywords": ["none", "min-content", "max-content", "auto", "subgrid", "masonry"], "units": ["px", "em", "rem", "%", "fr", "vh", "vw", "ch"] },
798
- { "property": "grid-template-areas", "category": "Grid", "type": "string", "keywords": ["none"] },
799
- { "property": "grid-auto-columns", "category": "Grid", "type": "length", "keywords": ["auto", "min-content", "max-content"], "units": ["px", "em", "rem", "%", "fr", "vh", "vw", "ch"] },
800
- { "property": "grid-auto-rows", "category": "Grid", "type": "length", "keywords": ["auto", "min-content", "max-content"], "units": ["px", "em", "rem", "%", "fr", "vh", "vw", "ch"] },
801
- { "property": "grid-auto-flow", "category": "Grid", "type": "enum", "keywords": ["row", "column", "dense"] },
802
- { "property": "grid-column", "category": "Grid", "type": "shorthand", "keywords": ["auto", "span"], "shorthand": true },
803
- { "property": "grid-row", "category": "Grid", "type": "shorthand", "keywords": ["auto", "span"], "shorthand": true },
804
- { "property": "grid-column-start", "category": "Grid", "type": "string", "keywords": ["auto", "span"] },
805
- { "property": "grid-column-end", "category": "Grid", "type": "string", "keywords": ["auto", "span"] },
806
- { "property": "grid-row-start", "category": "Grid", "type": "string", "keywords": ["auto", "span"] },
807
- { "property": "grid-row-end", "category": "Grid", "type": "string", "keywords": ["auto", "span"] },
808
- { "property": "grid-area", "category": "Grid", "type": "shorthand", "keywords": ["auto", "span"], "shorthand": true },
809
- { "property": "margin", "category": "Spacing", "type": "shorthand", "keywords": ["auto"], "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "box": "margin", "shorthand": true },
810
- { "property": "margin-top", "category": "Spacing", "type": "length", "keywords": ["auto"], "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "box": "margin" },
811
- { "property": "margin-right", "category": "Spacing", "type": "length", "keywords": ["auto"], "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "box": "margin" },
812
- { "property": "margin-bottom", "category": "Spacing", "type": "length", "keywords": ["auto"], "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "box": "margin" },
813
- { "property": "margin-left", "category": "Spacing", "type": "length", "keywords": ["auto"], "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "box": "margin" },
814
- { "property": "margin-block", "category": "Spacing", "type": "shorthand", "keywords": ["auto"], "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "box": "margin", "shorthand": true },
815
- { "property": "margin-block-start", "category": "Spacing", "type": "length", "keywords": ["auto"], "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "box": "margin" },
816
- { "property": "margin-block-end", "category": "Spacing", "type": "length", "keywords": ["auto"], "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "box": "margin" },
817
- { "property": "margin-inline", "category": "Spacing", "type": "shorthand", "keywords": ["auto"], "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "box": "margin", "shorthand": true },
818
- { "property": "margin-inline-start", "category": "Spacing", "type": "length", "keywords": ["auto"], "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "box": "margin" },
819
- { "property": "margin-inline-end", "category": "Spacing", "type": "length", "keywords": ["auto"], "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "box": "margin" },
820
- { "property": "padding", "category": "Spacing", "type": "shorthand", "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "box": "padding", "shorthand": true },
821
- { "property": "padding-top", "category": "Spacing", "type": "length", "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "box": "padding" },
822
- { "property": "padding-right", "category": "Spacing", "type": "length", "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "box": "padding" },
823
- { "property": "padding-bottom", "category": "Spacing", "type": "length", "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "box": "padding" },
824
- { "property": "padding-left", "category": "Spacing", "type": "length", "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "box": "padding" },
825
- { "property": "padding-block", "category": "Spacing", "type": "shorthand", "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "box": "padding", "shorthand": true },
826
- { "property": "padding-block-start", "category": "Spacing", "type": "length", "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "box": "padding" },
827
- { "property": "padding-block-end", "category": "Spacing", "type": "length", "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "box": "padding" },
828
- { "property": "padding-inline", "category": "Spacing", "type": "shorthand", "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "box": "padding", "shorthand": true },
829
- { "property": "padding-inline-start", "category": "Spacing", "type": "length", "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "box": "padding" },
830
- { "property": "padding-inline-end", "category": "Spacing", "type": "length", "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "box": "padding" },
831
- { "property": "width", "category": "Sizing", "type": "length", "keywords": ["auto", "max-content", "min-content", "fit-content", "stretch"], "units": ["px", "%", "em", "rem", "vh", "vw", "ch"] },
832
- { "property": "height", "category": "Sizing", "type": "length", "keywords": ["auto", "max-content", "min-content", "fit-content", "stretch"], "units": ["px", "%", "em", "rem", "vh", "vw", "ch"] },
833
- { "property": "min-width", "category": "Sizing", "type": "length", "keywords": ["auto", "max-content", "min-content", "fit-content", "stretch"], "units": ["px", "%", "em", "rem", "vh", "vw", "ch"] },
834
- { "property": "max-width", "category": "Sizing", "type": "length", "keywords": ["none", "max-content", "min-content", "fit-content", "stretch"], "units": ["px", "%", "em", "rem", "vh", "vw", "ch"] },
835
- { "property": "min-height", "category": "Sizing", "type": "length", "keywords": ["auto", "max-content", "min-content", "fit-content", "stretch"], "units": ["px", "%", "em", "rem", "vh", "vw", "ch"] },
836
- { "property": "max-height", "category": "Sizing", "type": "length", "keywords": ["none", "max-content", "min-content", "fit-content", "stretch"], "units": ["px", "%", "em", "rem", "vh", "vw", "ch"] },
837
- { "property": "aspect-ratio", "category": "Sizing", "type": "number", "keywords": ["auto"] },
838
- { "property": "block-size", "category": "Sizing", "type": "length", "keywords": ["auto", "max-content", "min-content", "fit-content", "stretch"], "units": ["px", "%", "em", "rem", "vh", "vw", "ch"] },
839
- { "property": "inline-size", "category": "Sizing", "type": "length", "keywords": ["auto", "max-content", "min-content", "fit-content", "stretch"], "units": ["px", "%", "em", "rem", "vh", "vw", "ch"] },
840
- { "property": "min-block-size", "category": "Sizing", "type": "length", "keywords": ["auto", "max-content", "min-content", "fit-content", "stretch"], "units": ["px", "%", "em", "rem", "vh", "vw", "ch"] },
841
- { "property": "max-block-size", "category": "Sizing", "type": "length", "keywords": ["none", "max-content", "min-content", "fit-content", "stretch"], "units": ["px", "%", "em", "rem", "vh", "vw", "ch"] },
842
- { "property": "min-inline-size", "category": "Sizing", "type": "length", "keywords": ["auto", "max-content", "min-content", "fit-content", "stretch"], "units": ["px", "%", "em", "rem", "vh", "vw", "ch"] },
843
- { "property": "max-inline-size", "category": "Sizing", "type": "length", "keywords": ["none", "max-content", "min-content", "fit-content", "stretch"], "units": ["px", "%", "em", "rem", "vh", "vw", "ch"] },
844
- { "property": "object-fit", "category": "Sizing", "type": "enum", "keywords": ["fill", "contain", "cover", "none", "scale-down"] },
845
- { "property": "object-position", "category": "Sizing", "type": "length", "keywords": ["left", "right", "top", "bottom", "center"], "units": ["px", "%", "em", "rem"] },
846
- { "property": "border", "category": "Border", "type": "shorthand", "shorthand": true },
847
- { "property": "border-width", "category": "Border", "type": "shorthand", "shorthand": true },
848
- { "property": "border-style", "category": "Border", "type": "shorthand", "shorthand": true },
849
- { "property": "border-color", "category": "Border", "type": "shorthand", "shorthand": true },
850
- { "property": "border-top", "category": "Border", "type": "shorthand", "shorthand": true },
851
- { "property": "border-right", "category": "Border", "type": "shorthand", "shorthand": true },
852
- { "property": "border-bottom", "category": "Border", "type": "shorthand", "shorthand": true },
853
- { "property": "border-left", "category": "Border", "type": "shorthand", "shorthand": true },
854
- { "property": "border-top-width", "category": "Border", "type": "length", "keywords": ["thin", "medium", "thick"], "units": ["px", "em", "rem", "vh", "vw", "ch"], "box": "border-width" },
855
- { "property": "border-right-width", "category": "Border", "type": "length", "keywords": ["thin", "medium", "thick"], "units": ["px", "em", "rem", "vh", "vw", "ch"], "box": "border-width" },
856
- { "property": "border-bottom-width", "category": "Border", "type": "length", "keywords": ["thin", "medium", "thick"], "units": ["px", "em", "rem", "vh", "vw", "ch"], "box": "border-width" },
857
- { "property": "border-left-width", "category": "Border", "type": "length", "keywords": ["thin", "medium", "thick"], "units": ["px", "em", "rem", "vh", "vw", "ch"], "box": "border-width" },
858
- { "property": "border-top-style", "category": "Border", "type": "enum", "keywords": ["none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset"], "box": "border-style" },
859
- { "property": "border-right-style", "category": "Border", "type": "enum", "keywords": ["none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset"], "box": "border-style" },
860
- { "property": "border-bottom-style", "category": "Border", "type": "enum", "keywords": ["none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset"], "box": "border-style" },
861
- { "property": "border-left-style", "category": "Border", "type": "enum", "keywords": ["none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset"], "box": "border-style" },
862
- { "property": "border-top-color", "category": "Border", "type": "color", "keywords": ["currentcolor", "transparent"], "box": "border-color" },
863
- { "property": "border-right-color", "category": "Border", "type": "color", "keywords": ["currentcolor", "transparent"], "box": "border-color" },
864
- { "property": "border-bottom-color", "category": "Border", "type": "color", "keywords": ["currentcolor", "transparent"], "box": "border-color" },
865
- { "property": "border-left-color", "category": "Border", "type": "color", "keywords": ["currentcolor", "transparent"], "box": "border-color" },
866
- { "property": "border-block", "category": "Border", "type": "shorthand", "shorthand": true },
867
- { "property": "border-block-start", "category": "Border", "type": "shorthand", "shorthand": true },
868
- { "property": "border-block-end", "category": "Border", "type": "shorthand", "shorthand": true },
869
- { "property": "border-inline", "category": "Border", "type": "shorthand", "shorthand": true },
870
- { "property": "border-inline-start", "category": "Border", "type": "shorthand", "shorthand": true },
871
- { "property": "border-inline-end", "category": "Border", "type": "shorthand", "shorthand": true },
872
- { "property": "border-block-width", "category": "Border", "type": "shorthand", "shorthand": true },
873
- { "property": "border-inline-width", "category": "Border", "type": "shorthand", "shorthand": true },
874
- { "property": "border-block-style", "category": "Border", "type": "shorthand", "shorthand": true },
875
- { "property": "border-inline-style", "category": "Border", "type": "shorthand", "shorthand": true },
876
- { "property": "border-block-color", "category": "Border", "type": "shorthand", "shorthand": true },
877
- { "property": "border-inline-color", "category": "Border", "type": "shorthand", "shorthand": true },
878
- { "property": "border-block-start-width", "category": "Border", "type": "length", "keywords": ["thin", "medium", "thick"], "units": ["px", "em", "rem", "vh", "vw", "ch"] },
879
- { "property": "border-block-end-width", "category": "Border", "type": "length", "keywords": ["thin", "medium", "thick"], "units": ["px", "em", "rem", "vh", "vw", "ch"] },
880
- { "property": "border-inline-start-width", "category": "Border", "type": "length", "keywords": ["thin", "medium", "thick"], "units": ["px", "em", "rem", "vh", "vw", "ch"] },
881
- { "property": "border-inline-end-width", "category": "Border", "type": "length", "keywords": ["thin", "medium", "thick"], "units": ["px", "em", "rem", "vh", "vw", "ch"] },
882
- { "property": "border-block-start-style", "category": "Border", "type": "enum", "keywords": ["none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset"] },
883
- { "property": "border-block-end-style", "category": "Border", "type": "enum", "keywords": ["none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset"] },
884
- { "property": "border-inline-start-style", "category": "Border", "type": "enum", "keywords": ["none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset"] },
885
- { "property": "border-inline-end-style", "category": "Border", "type": "enum", "keywords": ["none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset"] },
886
- { "property": "border-block-start-color", "category": "Border", "type": "color", "keywords": ["currentcolor", "transparent"] },
887
- { "property": "border-block-end-color", "category": "Border", "type": "color", "keywords": ["currentcolor", "transparent"] },
888
- { "property": "border-inline-start-color", "category": "Border", "type": "color", "keywords": ["currentcolor", "transparent"] },
889
- { "property": "border-inline-end-color", "category": "Border", "type": "color", "keywords": ["currentcolor", "transparent"] },
890
- { "property": "border-radius", "category": "Border", "type": "shorthand", "shorthand": true },
891
- { "property": "border-top-left-radius", "category": "Border", "type": "length", "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "box": "radius" },
892
- { "property": "border-top-right-radius", "category": "Border", "type": "length", "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "box": "radius" },
893
- { "property": "border-bottom-right-radius", "category": "Border", "type": "length", "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "box": "radius" },
894
- { "property": "border-bottom-left-radius", "category": "Border", "type": "length", "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "box": "radius" },
895
- { "property": "border-start-start-radius", "category": "Border", "type": "length", "units": ["px", "%", "em", "rem", "vh", "vw", "ch"] },
896
- { "property": "border-start-end-radius", "category": "Border", "type": "length", "units": ["px", "%", "em", "rem", "vh", "vw", "ch"] },
897
- { "property": "border-end-start-radius", "category": "Border", "type": "length", "units": ["px", "%", "em", "rem", "vh", "vw", "ch"] },
898
- { "property": "border-end-end-radius", "category": "Border", "type": "length", "units": ["px", "%", "em", "rem", "vh", "vw", "ch"] },
899
- { "property": "border-image", "category": "Border", "type": "shorthand", "shorthand": true },
900
- { "property": "border-image-source", "category": "Border", "type": "image", "keywords": ["none"] },
901
- { "property": "border-image-slice", "category": "Border", "type": "number", "keywords": ["fill"], "units": ["%"] },
902
- { "property": "border-image-width", "category": "Border", "type": "number", "keywords": ["auto"], "units": ["px", "%", "em", "rem"] },
903
- { "property": "border-image-outset", "category": "Border", "type": "number", "units": ["px", "em", "rem"] },
904
- { "property": "border-image-repeat", "category": "Border", "type": "enum", "keywords": ["stretch", "repeat", "round", "space"] },
905
- { "property": "outline", "category": "Border", "type": "shorthand", "shorthand": true },
906
- { "property": "outline-width", "category": "Border", "type": "length", "keywords": ["thin", "medium", "thick"], "units": ["px", "em", "rem", "vh", "vw", "ch"] },
907
- { "property": "outline-style", "category": "Border", "type": "enum", "keywords": ["auto", "none", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset"] },
908
- { "property": "outline-color", "category": "Border", "type": "color", "keywords": ["currentcolor", "invert"] },
909
- { "property": "outline-offset", "category": "Border", "type": "length", "units": ["px", "em", "rem", "vh", "vw", "ch"] },
910
- { "property": "background", "category": "Background", "type": "shorthand", "shorthand": true },
911
- { "property": "background-color", "category": "Background", "type": "color" },
912
- { "property": "background-image", "category": "Background", "type": "image" },
913
- { "property": "background-position", "category": "Background", "type": "shorthand", "keywords": ["top", "right", "bottom", "left", "center"], "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "shorthand": true },
914
- { "property": "background-position-x", "category": "Background", "type": "length", "keywords": ["left", "right", "center"], "units": ["px", "%", "em", "rem", "vh", "vw", "ch"] },
915
- { "property": "background-position-y", "category": "Background", "type": "length", "keywords": ["top", "bottom", "center"], "units": ["px", "%", "em", "rem", "vh", "vw", "ch"] },
916
- { "property": "background-size", "category": "Background", "type": "shorthand", "keywords": ["auto", "cover", "contain"], "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "shorthand": true },
917
- { "property": "background-repeat", "category": "Background", "type": "enum", "keywords": ["repeat", "repeat-x", "repeat-y", "no-repeat", "space", "round"] },
918
- { "property": "background-attachment", "category": "Background", "type": "enum", "keywords": ["scroll", "fixed", "local"] },
919
- { "property": "background-clip", "category": "Background", "type": "enum", "keywords": ["border-box", "padding-box", "content-box", "text"] },
920
- { "property": "background-origin", "category": "Background", "type": "enum", "keywords": ["border-box", "padding-box", "content-box"] },
921
- { "property": "background-blend-mode", "category": "Background", "type": "enum", "keywords": ["normal", "multiply", "screen", "overlay", "darken", "lighten", "color-dodge", "color-burn", "hard-light", "soft-light", "difference", "exclusion", "hue", "saturation", "color", "luminosity"] },
922
- { "property": "color", "category": "Typography", "type": "color", "inherited": true },
923
- { "property": "opacity", "category": "Typography", "type": "number" },
924
- { "property": "font", "category": "Typography", "type": "shorthand", "inherited": true, "shorthand": true },
925
- { "property": "font-family", "category": "Typography", "type": "string", "inherited": true },
926
- { "property": "font-size", "category": "Typography", "type": "length", "keywords": ["xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large", "xxx-large", "larger", "smaller"], "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "inherited": true },
927
- { "property": "font-size-adjust", "category": "Typography", "type": "number", "keywords": ["none", "ex-height", "cap-height", "ch-width", "ic-width", "ic-height", "from-font"], "inherited": true },
928
- { "property": "font-weight", "category": "Typography", "type": "integer", "keywords": ["normal", "bold", "bolder", "lighter"], "inherited": true },
929
- { "property": "font-style", "category": "Typography", "type": "enum", "keywords": ["normal", "italic", "oblique"], "inherited": true },
930
- { "property": "font-variant", "category": "Typography", "type": "shorthand", "keywords": ["normal", "none", "small-caps", "all-small-caps", "petite-caps", "all-petite-caps", "unicase", "titling-caps", "ordinal", "slashed-zero", "lining-nums", "oldstyle-nums", "proportional-nums", "tabular-nums", "diagonal-fractions", "stacked-fractions"], "inherited": true, "shorthand": true },
931
- { "property": "font-variant-caps", "category": "Typography", "type": "enum", "keywords": ["normal", "small-caps", "all-small-caps", "petite-caps", "all-petite-caps", "unicase", "titling-caps"], "inherited": true },
932
- { "property": "font-variant-numeric", "category": "Typography", "type": "enum", "keywords": ["normal", "ordinal", "slashed-zero", "lining-nums", "oldstyle-nums", "proportional-nums", "tabular-nums", "diagonal-fractions", "stacked-fractions"], "inherited": true },
933
- { "property": "font-variant-ligatures", "category": "Typography", "type": "enum", "keywords": ["normal", "none", "common-ligatures", "no-common-ligatures", "discretionary-ligatures", "no-discretionary-ligatures", "historical-ligatures", "no-historical-ligatures", "contextual", "no-contextual"], "inherited": true },
934
- { "property": "font-variant-east-asian", "category": "Typography", "type": "enum", "keywords": ["normal", "ruby", "jis78", "jis83", "jis90", "jis04", "simplified", "traditional", "full-width", "proportional-width"], "inherited": true },
935
- { "property": "font-variant-position", "category": "Typography", "type": "enum", "keywords": ["normal", "sub", "super"], "inherited": true },
936
- { "property": "font-stretch", "category": "Typography", "type": "percentage", "keywords": ["normal", "ultra-condensed", "extra-condensed", "condensed", "semi-condensed", "semi-expanded", "expanded", "extra-expanded", "ultra-expanded"], "units": ["%"], "inherited": true },
937
- { "property": "font-feature-settings", "category": "Typography", "type": "string", "keywords": ["normal"], "inherited": true },
938
- { "property": "font-variation-settings", "category": "Typography", "type": "string", "keywords": ["normal"], "inherited": true },
939
- { "property": "font-kerning", "category": "Typography", "type": "enum", "keywords": ["auto", "normal", "none"], "inherited": true },
940
- { "property": "font-optical-sizing", "category": "Typography", "type": "enum", "keywords": ["auto", "none"], "inherited": true },
941
- { "property": "font-synthesis", "category": "Typography", "type": "enum", "keywords": ["none", "weight", "style", "small-caps", "position"], "inherited": true, "shorthand": true },
942
- { "property": "line-height", "category": "Typography", "type": "number", "keywords": ["normal"], "units": ["px", "%", "em", "rem"], "inherited": true },
943
- { "property": "letter-spacing", "category": "Typography", "type": "length", "keywords": ["normal"], "units": ["px", "em", "rem", "ch"], "inherited": true },
944
- { "property": "word-spacing", "category": "Typography", "type": "length", "keywords": ["normal"], "units": ["px", "%", "em", "rem"], "inherited": true },
945
- { "property": "text-align", "category": "Typography", "type": "enum", "keywords": ["start", "end", "left", "right", "center", "justify", "match-parent", "justify-all"], "inherited": true },
946
- { "property": "text-align-last", "category": "Typography", "type": "enum", "keywords": ["auto", "start", "end", "left", "right", "center", "justify"], "inherited": true },
947
- { "property": "text-justify", "category": "Typography", "type": "enum", "keywords": ["auto", "none", "inter-word", "inter-character"], "inherited": true },
948
- { "property": "text-decoration", "category": "Typography", "type": "shorthand", "shorthand": true },
949
- { "property": "text-decoration-line", "category": "Typography", "type": "enum", "keywords": ["none", "underline", "overline", "line-through", "blink"] },
950
- { "property": "text-decoration-color", "category": "Typography", "type": "color" },
951
- { "property": "text-decoration-style", "category": "Typography", "type": "enum", "keywords": ["solid", "double", "dotted", "dashed", "wavy"] },
952
- { "property": "text-decoration-thickness", "category": "Typography", "type": "length", "keywords": ["auto", "from-font"], "units": ["px", "%", "em", "rem"] },
953
- { "property": "text-decoration-skip-ink", "category": "Typography", "type": "enum", "keywords": ["auto", "none", "all"], "inherited": true },
954
- { "property": "text-underline-offset", "category": "Typography", "type": "length", "keywords": ["auto"], "units": ["px", "%", "em", "rem"], "inherited": true },
955
- { "property": "text-underline-position", "category": "Typography", "type": "enum", "keywords": ["auto", "from-font", "under", "left", "right"], "inherited": true },
956
- { "property": "text-emphasis", "category": "Typography", "type": "shorthand", "inherited": true, "shorthand": true },
957
- { "property": "text-emphasis-style", "category": "Typography", "type": "enum", "keywords": ["none", "filled", "open", "dot", "circle", "double-circle", "triangle", "sesame"], "inherited": true },
958
- { "property": "text-emphasis-color", "category": "Typography", "type": "color", "inherited": true },
959
- { "property": "text-emphasis-position", "category": "Typography", "type": "enum", "keywords": ["over", "under", "left", "right"], "inherited": true },
960
- { "property": "text-transform", "category": "Typography", "type": "enum", "keywords": ["none", "capitalize", "uppercase", "lowercase", "full-width", "full-size-kana"], "inherited": true },
961
- { "property": "text-indent", "category": "Typography", "type": "length", "keywords": ["hanging", "each-line"], "units": ["px", "%", "em", "rem"], "inherited": true },
962
- { "property": "text-overflow", "category": "Typography", "type": "enum", "keywords": ["clip", "ellipsis"] },
963
- { "property": "text-shadow", "category": "Typography", "type": "string", "keywords": ["none"], "inherited": true },
964
- { "property": "white-space", "category": "Typography", "type": "enum", "keywords": ["normal", "nowrap", "pre", "pre-wrap", "pre-line", "break-spaces"], "inherited": true },
965
- { "property": "white-space-collapse", "category": "Typography", "type": "enum", "keywords": ["collapse", "preserve", "preserve-breaks", "preserve-spaces", "break-spaces"], "inherited": true },
966
- { "property": "text-wrap", "category": "Typography", "type": "enum", "keywords": ["wrap", "nowrap", "balance", "pretty", "stable"], "inherited": true },
967
- { "property": "text-wrap-mode", "category": "Typography", "type": "enum", "keywords": ["wrap", "nowrap"], "inherited": true },
968
- { "property": "text-wrap-style", "category": "Typography", "type": "enum", "keywords": ["auto", "balance", "pretty", "stable"], "inherited": true },
969
- { "property": "word-break", "category": "Typography", "type": "enum", "keywords": ["normal", "break-all", "keep-all", "break-word", "auto-phrase"], "inherited": true },
970
- { "property": "line-break", "category": "Typography", "type": "enum", "keywords": ["auto", "loose", "normal", "strict", "anywhere"], "inherited": true },
971
- { "property": "overflow-wrap", "category": "Typography", "type": "enum", "keywords": ["normal", "break-word", "anywhere"], "inherited": true },
972
- { "property": "hyphens", "category": "Typography", "type": "enum", "keywords": ["none", "manual", "auto"], "inherited": true },
973
- { "property": "hyphenate-character", "category": "Typography", "type": "string", "keywords": ["auto"], "inherited": true },
974
- { "property": "direction", "category": "Typography", "type": "enum", "keywords": ["ltr", "rtl"], "inherited": true },
975
- { "property": "unicode-bidi", "category": "Typography", "type": "enum", "keywords": ["normal", "embed", "isolate", "bidi-override", "isolate-override", "plaintext"] },
976
- { "property": "writing-mode", "category": "Typography", "type": "enum", "keywords": ["horizontal-tb", "vertical-rl", "vertical-lr", "sideways-rl", "sideways-lr"], "inherited": true },
977
- { "property": "text-orientation", "category": "Typography", "type": "enum", "keywords": ["mixed", "upright", "sideways"], "inherited": true },
978
- { "property": "text-combine-upright", "category": "Typography", "type": "enum", "keywords": ["none", "all", "digits"], "inherited": true },
979
- { "property": "vertical-align", "category": "Typography", "type": "length", "keywords": ["baseline", "sub", "super", "text-top", "text-bottom", "middle", "top", "bottom"], "units": ["px", "%", "em", "rem"] },
980
- { "property": "tab-size", "category": "Typography", "type": "number", "units": ["px", "em", "rem"], "inherited": true },
981
- { "property": "quotes", "category": "Typography", "type": "string", "keywords": ["none", "auto"], "inherited": true },
982
- { "property": "hanging-punctuation", "category": "Typography", "type": "enum", "keywords": ["none", "first", "last", "force-end", "allow-end"], "inherited": true },
983
- { "property": "text-rendering", "category": "Typography", "type": "enum", "keywords": ["auto", "optimizeSpeed", "optimizeLegibility", "geometricPrecision"], "inherited": true },
984
- { "property": "-webkit-text-stroke", "category": "Typography", "type": "shorthand", "shorthand": true },
985
- { "property": "-webkit-text-stroke-width", "category": "Typography", "type": "length", "units": ["px", "em", "rem"] },
986
- { "property": "-webkit-text-stroke-color", "category": "Typography", "type": "color" },
987
- { "property": "-webkit-text-fill-color", "category": "Typography", "type": "color" },
988
- { "property": "-webkit-line-clamp", "category": "Typography", "type": "integer", "keywords": ["none"] },
989
- { "property": "caret-color", "category": "Typography", "type": "color", "keywords": ["auto"], "inherited": true },
990
- { "property": "box-shadow", "category": "Effects", "type": "string", "keywords": ["none"] },
991
- { "property": "filter", "category": "Effects", "type": "string", "keywords": ["none"] },
992
- { "property": "backdrop-filter", "category": "Effects", "type": "string", "keywords": ["none"] },
993
- { "property": "mix-blend-mode", "category": "Effects", "type": "enum", "keywords": ["normal", "multiply", "screen", "overlay", "darken", "lighten", "color-dodge", "color-burn", "hard-light", "soft-light", "difference", "exclusion", "hue", "saturation", "color", "luminosity", "plus-darker", "plus-lighter"] },
994
- { "property": "clip-path", "category": "Effects", "type": "string", "keywords": ["none", "border-box", "padding-box", "content-box", "margin-box", "fill-box", "stroke-box", "view-box"] },
995
- { "property": "mask", "category": "Effects", "type": "shorthand", "shorthand": true },
996
- { "property": "mask-image", "category": "Effects", "type": "image", "keywords": ["none"] },
997
- { "property": "mask-mode", "category": "Effects", "type": "enum", "keywords": ["alpha", "luminance", "match-source"] },
998
- { "property": "mask-repeat", "category": "Effects", "type": "enum", "keywords": ["repeat", "repeat-x", "repeat-y", "space", "round", "no-repeat"] },
999
- { "property": "mask-position", "category": "Effects", "type": "length", "keywords": ["top", "bottom", "left", "right", "center"], "units": ["px", "%", "em", "rem", "vh", "vw", "ch"] },
1000
- { "property": "mask-clip", "category": "Effects", "type": "enum", "keywords": ["border-box", "padding-box", "content-box", "fill-box", "stroke-box", "view-box", "no-clip"] },
1001
- { "property": "mask-origin", "category": "Effects", "type": "enum", "keywords": ["border-box", "padding-box", "content-box", "fill-box", "stroke-box", "view-box"] },
1002
- { "property": "mask-size", "category": "Effects", "type": "length", "keywords": ["auto", "cover", "contain"], "units": ["px", "%", "em", "rem", "vh", "vw", "ch"] },
1003
- { "property": "mask-composite", "category": "Effects", "type": "enum", "keywords": ["add", "subtract", "intersect", "exclude"] },
1004
- { "property": "mask-type", "category": "Effects", "type": "enum", "keywords": ["luminance", "alpha"] },
1005
- { "property": "cursor", "category": "Effects", "type": "enum", "keywords": ["auto", "default", "none", "context-menu", "help", "pointer", "progress", "wait", "cell", "crosshair", "text", "vertical-text", "alias", "copy", "move", "no-drop", "not-allowed", "grab", "grabbing", "all-scroll", "col-resize", "row-resize", "n-resize", "e-resize", "s-resize", "w-resize", "ne-resize", "nw-resize", "se-resize", "sw-resize", "ew-resize", "ns-resize", "nesw-resize", "nwse-resize", "zoom-in", "zoom-out"], "inherited": true },
1006
- { "property": "accent-color", "category": "Effects", "type": "color", "keywords": ["auto"], "inherited": true },
1007
- { "property": "color-scheme", "category": "Effects", "type": "enum", "keywords": ["normal", "light", "dark", "only"], "inherited": true },
1008
- { "property": "transform", "category": "Transform", "type": "string" },
1009
- { "property": "transform-origin", "category": "Transform", "type": "string" },
1010
- { "property": "transform-style", "category": "Transform", "type": "enum", "keywords": ["flat", "preserve-3d"] },
1011
- { "property": "transform-box", "category": "Transform", "type": "enum", "keywords": ["content-box", "border-box", "fill-box", "stroke-box", "view-box"] },
1012
- { "property": "translate", "category": "Transform", "type": "string" },
1013
- { "property": "rotate", "category": "Transform", "type": "string" },
1014
- { "property": "scale", "category": "Transform", "type": "string" },
1015
- { "property": "perspective", "category": "Transform", "type": "length", "keywords": ["none"], "units": ["px", "em", "rem", "vh", "vw", "ch"] },
1016
- { "property": "perspective-origin", "category": "Transform", "type": "string" },
1017
- { "property": "backface-visibility", "category": "Transform", "type": "enum", "keywords": ["visible", "hidden"] },
1018
- { "property": "transition", "category": "Animation", "type": "shorthand", "shorthand": true },
1019
- { "property": "transition-property", "category": "Animation", "type": "enum", "keywords": ["none", "all"] },
1020
- { "property": "transition-duration", "category": "Animation", "type": "time", "units": ["s", "ms"] },
1021
- { "property": "transition-timing-function", "category": "Animation", "type": "enum", "keywords": ["linear", "ease", "ease-in", "ease-out", "ease-in-out", "step-start", "step-end", "steps", "cubic-bezier"] },
1022
- { "property": "transition-delay", "category": "Animation", "type": "time", "units": ["s", "ms"] },
1023
- { "property": "transition-behavior", "category": "Animation", "type": "enum", "keywords": ["normal", "allow-discrete"] },
1024
- { "property": "animation", "category": "Animation", "type": "shorthand", "shorthand": true },
1025
- { "property": "animation-name", "category": "Animation", "type": "enum", "keywords": ["none"] },
1026
- { "property": "animation-duration", "category": "Animation", "type": "time", "units": ["s", "ms"] },
1027
- { "property": "animation-timing-function", "category": "Animation", "type": "enum", "keywords": ["linear", "ease", "ease-in", "ease-out", "ease-in-out", "step-start", "step-end", "steps", "cubic-bezier"] },
1028
- { "property": "animation-delay", "category": "Animation", "type": "time", "units": ["s", "ms"] },
1029
- { "property": "animation-iteration-count", "category": "Animation", "type": "number", "keywords": ["infinite"] },
1030
- { "property": "animation-direction", "category": "Animation", "type": "enum", "keywords": ["normal", "reverse", "alternate", "alternate-reverse"] },
1031
- { "property": "animation-fill-mode", "category": "Animation", "type": "enum", "keywords": ["none", "forwards", "backwards", "both"] },
1032
- { "property": "animation-play-state", "category": "Animation", "type": "enum", "keywords": ["running", "paused"] },
1033
- { "property": "animation-composition", "category": "Animation", "type": "enum", "keywords": ["replace", "add", "accumulate"] },
1034
- { "property": "will-change", "category": "Animation", "type": "enum", "keywords": ["auto", "scroll-position", "contents"] },
1035
- { "property": "content", "category": "Misc", "type": "string" },
1036
- { "property": "list-style", "category": "Misc", "type": "shorthand", "inherited": true, "shorthand": true },
1037
- { "property": "list-style-type", "category": "Misc", "type": "enum", "keywords": ["disc", "circle", "square", "decimal", "decimal-leading-zero", "lower-roman", "upper-roman", "lower-greek", "lower-latin", "upper-latin", "lower-alpha", "upper-alpha", "armenian", "georgian", "cjk-decimal", "cjk-ideographic", "hebrew", "hiragana", "hiragana-iroha", "katakana", "katakana-iroha", "arabic-indic", "bengali", "cambodian", "khmer", "devanagari", "gujarati", "gurmukhi", "kannada", "lao", "malayalam", "myanmar", "oriya", "persian", "tamil", "telugu", "thai", "tibetan", "japanese-formal", "japanese-informal", "korean-hangul-formal", "korean-hanja-formal", "korean-hanja-informal", "simp-chinese-formal", "simp-chinese-informal", "trad-chinese-formal", "trad-chinese-informal", "disclosure-open", "disclosure-closed", "none"], "inherited": true },
1038
- { "property": "list-style-position", "category": "Misc", "type": "enum", "keywords": ["inside", "outside"], "inherited": true },
1039
- { "property": "list-style-image", "category": "Misc", "type": "image", "inherited": true },
1040
- { "property": "scroll-behavior", "category": "Misc", "type": "enum", "keywords": ["auto", "smooth"] },
1041
- { "property": "scroll-snap-type", "category": "Misc", "type": "enum", "keywords": ["none", "x", "y", "block", "inline", "both", "mandatory", "proximity"] },
1042
- { "property": "scroll-snap-align", "category": "Misc", "type": "enum", "keywords": ["none", "start", "end", "center"] },
1043
- { "property": "scroll-snap-stop", "category": "Misc", "type": "enum", "keywords": ["normal", "always"] },
1044
- { "property": "scroll-margin", "category": "Misc", "type": "length", "units": ["px", "em", "rem", "vh", "vw", "ch"], "shorthand": true },
1045
- { "property": "scroll-margin-top", "category": "Misc", "type": "length", "units": ["px", "em", "rem", "vh", "vw", "ch"], "box": "margin" },
1046
- { "property": "scroll-margin-right", "category": "Misc", "type": "length", "units": ["px", "em", "rem", "vh", "vw", "ch"], "box": "margin" },
1047
- { "property": "scroll-margin-bottom", "category": "Misc", "type": "length", "units": ["px", "em", "rem", "vh", "vw", "ch"], "box": "margin" },
1048
- { "property": "scroll-margin-left", "category": "Misc", "type": "length", "units": ["px", "em", "rem", "vh", "vw", "ch"], "box": "margin" },
1049
- { "property": "scroll-margin-block", "category": "Misc", "type": "length", "units": ["px", "em", "rem", "vh", "vw", "ch"], "shorthand": true },
1050
- { "property": "scroll-margin-inline", "category": "Misc", "type": "length", "units": ["px", "em", "rem", "vh", "vw", "ch"], "shorthand": true },
1051
- { "property": "scroll-margin-block-start", "category": "Misc", "type": "length", "units": ["px", "em", "rem", "vh", "vw", "ch"], "box": "margin" },
1052
- { "property": "scroll-margin-block-end", "category": "Misc", "type": "length", "units": ["px", "em", "rem", "vh", "vw", "ch"], "box": "margin" },
1053
- { "property": "scroll-margin-inline-start", "category": "Misc", "type": "length", "units": ["px", "em", "rem", "vh", "vw", "ch"], "box": "margin" },
1054
- { "property": "scroll-margin-inline-end", "category": "Misc", "type": "length", "units": ["px", "em", "rem", "vh", "vw", "ch"], "box": "margin" },
1055
- { "property": "scroll-padding", "category": "Misc", "type": "length", "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "shorthand": true },
1056
- { "property": "scroll-padding-top", "category": "Misc", "type": "length", "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "box": "padding" },
1057
- { "property": "scroll-padding-right", "category": "Misc", "type": "length", "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "box": "padding" },
1058
- { "property": "scroll-padding-bottom", "category": "Misc", "type": "length", "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "box": "padding" },
1059
- { "property": "scroll-padding-left", "category": "Misc", "type": "length", "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "box": "padding" },
1060
- { "property": "scroll-padding-block", "category": "Misc", "type": "length", "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "shorthand": true },
1061
- { "property": "scroll-padding-inline", "category": "Misc", "type": "length", "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "shorthand": true },
1062
- { "property": "scroll-padding-block-start", "category": "Misc", "type": "length", "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "box": "padding" },
1063
- { "property": "scroll-padding-block-end", "category": "Misc", "type": "length", "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "box": "padding" },
1064
- { "property": "scroll-padding-inline-start", "category": "Misc", "type": "length", "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "box": "padding" },
1065
- { "property": "scroll-padding-inline-end", "category": "Misc", "type": "length", "units": ["px", "%", "em", "rem", "vh", "vw", "ch"], "box": "padding" },
1066
- { "property": "overscroll-behavior", "category": "Misc", "type": "enum", "keywords": ["auto", "contain", "none"], "shorthand": true },
1067
- { "property": "overscroll-behavior-x", "category": "Misc", "type": "enum", "keywords": ["auto", "contain", "none"] },
1068
- { "property": "overscroll-behavior-y", "category": "Misc", "type": "enum", "keywords": ["auto", "contain", "none"] },
1069
- { "property": "overscroll-behavior-block", "category": "Misc", "type": "enum", "keywords": ["auto", "contain", "none"] },
1070
- { "property": "overscroll-behavior-inline", "category": "Misc", "type": "enum", "keywords": ["auto", "contain", "none"] },
1071
- { "property": "user-select", "category": "Misc", "type": "enum", "keywords": ["auto", "text", "none", "all", "contain"] },
1072
- { "property": "pointer-events", "category": "Misc", "type": "enum", "keywords": ["auto", "none", "visiblePainted", "visibleFill", "visibleStroke", "visible", "painted", "fill", "stroke", "all"], "inherited": true },
1073
- { "property": "touch-action", "category": "Misc", "type": "enum", "keywords": ["auto", "none", "pan-x", "pan-left", "pan-right", "pan-y", "pan-up", "pan-down", "pinch-zoom", "manipulation"] },
1074
- { "property": "resize", "category": "Misc", "type": "enum", "keywords": ["none", "both", "horizontal", "vertical", "block", "inline"] },
1075
- { "property": "appearance", "category": "Misc", "type": "enum", "keywords": ["none", "auto", "base-select", "menulist-button", "textfield", "button", "searchfield", "textarea", "checkbox", "radio", "menulist", "listbox", "meter", "progress-bar", "push-button", "slider-horizontal", "square-button"] },
1076
- { "property": "table-layout", "category": "Misc", "type": "enum", "keywords": ["auto", "fixed"] },
1077
- { "property": "border-collapse", "category": "Misc", "type": "enum", "keywords": ["separate", "collapse"], "inherited": true },
1078
- { "property": "border-spacing", "category": "Misc", "type": "length", "units": ["px", "em", "rem"], "inherited": true },
1079
- { "property": "caption-side", "category": "Misc", "type": "enum", "keywords": ["top", "bottom", "block-start", "block-end", "inline-start", "inline-end"], "inherited": true },
1080
- { "property": "empty-cells", "category": "Misc", "type": "enum", "keywords": ["show", "hide"], "inherited": true },
1081
- { "property": "caret", "category": "Misc", "type": "shorthand", "inherited": true, "shorthand": true },
1082
- { "property": "caret-shape", "category": "Misc", "type": "enum", "keywords": ["auto", "bar", "block", "underscore"], "inherited": true },
1083
- { "property": "scrollbar-width", "category": "Misc", "type": "enum", "keywords": ["auto", "thin", "none"] },
1084
- { "property": "scrollbar-color", "category": "Misc", "type": "color", "inherited": true },
1085
- { "property": "scrollbar-gutter", "category": "Misc", "type": "enum", "keywords": ["auto", "stable", "both-edges"] },
1086
- { "property": "image-rendering", "category": "Misc", "type": "enum", "keywords": ["auto", "smooth", "high-quality", "crisp-edges", "pixelated"], "inherited": true },
1087
- { "property": "counter-reset", "category": "Misc", "type": "string" },
1088
- { "property": "counter-increment", "category": "Misc", "type": "string" },
1089
- { "property": "counter-set", "category": "Misc", "type": "string" },
1090
- { "property": "all", "category": "Misc", "type": "enum", "keywords": ["initial", "inherit", "unset", "revert", "revert-layer"], "shorthand": true },
1091
- { "property": "forced-color-adjust", "category": "Misc", "type": "enum", "keywords": ["auto", "none", "preserve-parent-color"], "inherited": true },
1092
- { "property": "print-color-adjust", "category": "Misc", "type": "enum", "keywords": ["economy", "exact"], "inherited": true }
1093
- ];
1094
-
1095
- // src/overlay/cssRegistry.ts
1096
- var COMMON = /* @__PURE__ */ new Set([
1097
- // Layout
1098
- "display",
1099
- "position",
1100
- "top",
1101
- "right",
1102
- "bottom",
1103
- "left",
1104
- "float",
1105
- "clear",
1106
- "z-index",
1107
- "box-sizing",
1108
- "visibility",
1109
- "overflow",
1110
- "overflow-x",
1111
- "overflow-y",
1112
- "opacity",
1113
- // Flexbox
1114
- "flex",
1115
- "flex-direction",
1116
- "flex-wrap",
1117
- "justify-content",
1118
- "align-items",
1119
- "align-content",
1120
- "align-self",
1121
- "justify-self",
1122
- "flex-grow",
1123
- "flex-shrink",
1124
- "flex-basis",
1125
- "order",
1126
- "gap",
1127
- "row-gap",
1128
- "column-gap",
1129
- // Grid
1130
- "grid-template-columns",
1131
- "grid-template-rows",
1132
- "grid-auto-flow",
1133
- "grid-auto-columns",
1134
- "grid-auto-rows",
1135
- "grid-column",
1136
- "grid-row",
1137
- "grid-area",
1138
- "justify-items",
1139
- "place-items",
1140
- // Spacing
1141
- "margin",
1142
- "margin-top",
1143
- "margin-right",
1144
- "margin-bottom",
1145
- "margin-left",
1146
- "padding",
1147
- "padding-top",
1148
- "padding-right",
1149
- "padding-bottom",
1150
- "padding-left",
1151
- // Sizing
1152
- "width",
1153
- "height",
1154
- "min-width",
1155
- "max-width",
1156
- "min-height",
1157
- "max-height",
1158
- "aspect-ratio",
1159
- "object-fit",
1160
- "object-position",
1161
- // Border
1162
- "border",
1163
- "border-width",
1164
- "border-style",
1165
- "border-color",
1166
- "border-top-width",
1167
- "border-right-width",
1168
- "border-bottom-width",
1169
- "border-left-width",
1170
- "border-radius",
1171
- "border-top-left-radius",
1172
- "border-top-right-radius",
1173
- "border-bottom-right-radius",
1174
- "border-bottom-left-radius",
1175
- "outline",
1176
- "outline-width",
1177
- "outline-style",
1178
- "outline-color",
1179
- "outline-offset",
1180
- // Background
1181
- "background",
1182
- "background-color",
1183
- "background-image",
1184
- "background-size",
1185
- "background-position",
1186
- "background-repeat",
1187
- "background-attachment",
1188
- "background-clip",
1189
- // Typography
1190
- "color",
1191
- "font",
1192
- "font-family",
1193
- "font-size",
1194
- "font-weight",
1195
- "font-style",
1196
- "font-variant",
1197
- "line-height",
1198
- "letter-spacing",
1199
- "word-spacing",
1200
- "text-align",
1201
- "text-decoration",
1202
- "text-decoration-line",
1203
- "text-decoration-color",
1204
- "text-transform",
1205
- "text-indent",
1206
- "text-overflow",
1207
- "white-space",
1208
- "text-shadow",
1209
- "direction",
1210
- "vertical-align",
1211
- // Effects
1212
- "box-shadow",
1213
- "filter",
1214
- "backdrop-filter",
1215
- "mix-blend-mode",
1216
- "clip-path",
1217
- "cursor",
1218
- "mask",
1219
- // Transform
1220
- "transform",
1221
- "transform-origin",
1222
- "transform-style",
1223
- "perspective",
1224
- "backface-visibility",
1225
- "translate",
1226
- "rotate",
1227
- "scale",
1228
- // Animation
1229
- "transition",
1230
- "transition-property",
1231
- "transition-duration",
1232
- "transition-timing-function",
1233
- "transition-delay",
1234
- "animation",
1235
- "animation-name",
1236
- "animation-duration",
1237
- "animation-timing-function",
1238
- "animation-delay",
1239
- "animation-iteration-count",
1240
- "animation-direction",
1241
- "animation-fill-mode",
1242
- "will-change",
1243
- // Misc
1244
- "content",
1245
- "list-style",
1246
- "list-style-type",
1247
- "list-style-position",
1248
- "user-select",
1249
- "pointer-events",
1250
- "scroll-behavior",
1251
- "resize",
1252
- "caret-color",
1253
- "accent-color",
1254
- "appearance"
1255
- ]);
1256
- var CATEGORY_ORDER = [
1257
- "Layout",
1258
- "Flexbox",
1259
- "Grid",
1260
- "Spacing",
1261
- "Sizing",
1262
- "Border",
1263
- "Background",
1264
- "Typography",
1265
- "Effects",
1266
- "Transform",
1267
- "Animation",
1268
- "Misc"
1269
- ];
1270
- var DEFAULT_UNITS = ["px", "%", "em", "rem", "vh", "vw", "ch"];
1271
- function categoryFor(p) {
1272
- if (/^grid/.test(p)) return "Grid";
1273
- if (/^(flex|justify|align|order|place)/.test(p)) return "Flexbox";
1274
- if (/^(margin|padding|gap|row-gap|column-gap)/.test(p)) return "Spacing";
1275
- if (/^(width|height|min-|max-|aspect-ratio|inline-size|block-size|object-)/.test(p)) return "Sizing";
1276
- if (/^(border|outline)/.test(p)) return "Border";
1277
- if (/^background/.test(p)) return "Background";
1278
- if (/^(font|text|color$|line-height|letter|word|white-space|writing|direction|vertical-align|tab-size|hyphens|quotes|list-style)/.test(p))
1279
- return "Typography";
1280
- if (/^(transition|animation|will-change)/.test(p)) return "Animation";
1281
- if (/^(transform|translate|rotate|scale|perspective|backface)/.test(p)) return "Transform";
1282
- if (/^(opacity|box-shadow|filter|backdrop|mix-blend|clip-path|mask|cursor)/.test(p)) return "Effects";
1283
- if (/^(display|position|top|right|bottom|left|inset|float|clear|visibility|z-index|box-sizing|overflow|isolation|contain)/.test(p))
1284
- return "Layout";
1285
- return "Misc";
1286
- }
1287
- function typeForValue(p, v) {
1288
- const s = (v || "").trim();
1289
- if (/color/.test(p) || /^(rgb|rgba|hsl|hsla|#|currentcolor|transparent)\b/i.test(s)) return "color";
1290
- if (/^-?\d*\.?\d+(px|em|rem|%|vh|vw|vmin|vmax|ch|ex|cm|mm|in|pt|pc|q)$/i.test(s)) return "length";
1291
- if (/^-?\d*\.?\d+(s|ms)$/i.test(s)) return "time";
1292
- if (/^-?\d*\.?\d+(deg|rad|grad|turn)$/i.test(s)) return "angle";
1293
- if (/^(url\(|linear-gradient|radial-gradient|conic-gradient)/i.test(s)) return "image";
1294
- if (/(^|-)color$/.test(p)) return "color";
1295
- if (/(width|height|size|^inset|margin|padding|gap|^top$|^left$|^right$|^bottom$|spacing|indent|offset|radius|translate|^scroll-padding|^scroll-margin)/.test(p))
1296
- return "length";
1297
- if (/^-?\d+$/.test(s)) return "integer";
1298
- if (/^-?\d*\.?\d+$/.test(s)) return "number";
1299
- return "string";
1300
- }
1301
- var _registry = null;
1302
- function cssRegistry() {
1303
- if (_registry) return _registry;
1304
- const byProp = /* @__PURE__ */ new Map();
1305
- for (const m of CSS_PROPERTY_DATA) {
1306
- byProp.set(m.property, {
1307
- ...m,
1308
- units: m.units && m.units.length ? m.units : m.type === "length" ? DEFAULT_UNITS : void 0,
1309
- common: COMMON.has(m.property)
1310
- });
1311
- }
1312
- try {
1313
- if (typeof document !== "undefined") {
1314
- const cs = getComputedStyle(document.documentElement);
1315
- for (let i = 0; i < cs.length; i++) {
1316
- const p = cs[i];
1317
- if (!p || p.startsWith("--") || byProp.has(p)) continue;
1318
- const type = typeForValue(p, cs.getPropertyValue(p));
1319
- byProp.set(p, { property: p, category: categoryFor(p), type, units: type === "length" ? DEFAULT_UNITS : void 0 });
1320
- }
1321
- }
1322
- } catch {
1323
- }
1324
- const groups = /* @__PURE__ */ new Map();
1325
- for (const [prop, m] of byProp) {
1326
- const cat = m.category || "Misc";
1327
- const arr = groups.get(cat) ?? [];
1328
- arr.push(prop);
1329
- groups.set(cat, arr);
1330
- }
1331
- const orderedNames = [
1332
- ...CATEGORY_ORDER.filter((c) => groups.has(c)),
1333
- ...[...groups.keys()].filter((c) => !CATEGORY_ORDER.includes(c)).sort()
1334
- ];
1335
- const categories = orderedNames.map((name) => ({ name, props: groups.get(name).slice().sort() }));
1336
- _registry = { byProp, categories };
1337
- return _registry;
1338
- }
1339
- function cssMeta(property) {
1340
- return cssRegistry().byProp.get(property);
1341
- }
1342
-
1343
728
  // src/overlay/mechanism.ts
1344
729
  var TW_UTILITY = /^-?(?:p|m|px|py|pt|pr|pb|pl|mx|my|mt|mr|mb|ml|gap|w|h|min-w|max-w|min-h|max-h|text|bg|border|rounded|flex|grid|gap-x|gap-y|items|justify|self|place|font|leading|tracking|space|inline|block|inline-block|hidden|table|absolute|relative|fixed|sticky|static|top|bottom|left|right|inset|z|shadow|opacity|transition|duration|ease|scale|rotate|translate|cursor|overflow|object|aspect|order|col|row|basis|grow|shrink|divide|ring|outline)(?:-|$)/;
1345
730
  var TW_VARIANT = /^(?:sm|md|lg|xl|2xl|hover|focus|focus-visible|focus-within|active|visited|disabled|dark|group|group-hover|peer|first|last|odd|even|motion-safe|motion-reduce|print|rtl|ltr)::?|^(?:sm|md|lg|xl|2xl|hover|focus|active|disabled|dark|group-hover):/;
@@ -1408,6 +793,115 @@ function mk(primaryMechanism, evidence, sourceClassNames) {
1408
793
  return { primaryMechanism, evidence, sourceClassNames };
1409
794
  }
1410
795
 
796
+ // src/overlay/i18n.ts
797
+ var RU = {
798
+ // chrome / buttons
799
+ "Toggle uivisor (Alt+U)": "\u0412\u043A\u043B/\u0432\u044B\u043A\u043B uivisor (Alt+U)",
800
+ "Turn uivisor off (Alt+U)": "\u0412\u044B\u043A\u043B\u044E\u0447\u0438\u0442\u044C uivisor (Alt+U)",
801
+ Close: "\u0417\u0430\u043A\u0440\u044B\u0442\u044C",
802
+ "Drag to resize": "\u041F\u043E\u0442\u044F\u043D\u0438\u0442\u0435, \u0447\u0442\u043E\u0431\u044B \u0438\u0437\u043C\u0435\u043D\u0438\u0442\u044C \u0448\u0438\u0440\u0438\u043D\u0443",
803
+ "Drag to change": "\u041F\u043E\u0442\u044F\u043D\u0438\u0442\u0435, \u0447\u0442\u043E\u0431\u044B \u0438\u0437\u043C\u0435\u043D\u0438\u0442\u044C",
804
+ "Copy prompt for agent": "\u0421\u043A\u043E\u043F\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u043F\u0440\u043E\u043C\u043F\u0442 \u0434\u043B\u044F \u0430\u0433\u0435\u043D\u0442\u0430",
805
+ "Copy JSON": "\u0421\u043A\u043E\u043F\u0438\u0440\u043E\u0432\u0430\u0442\u044C JSON",
806
+ Reset: "\u0421\u0431\u0440\u043E\u0441\u0438\u0442\u044C",
807
+ "Revert tweaks on selected element": "\u041E\u0442\u043A\u0430\u0442\u0438\u0442\u044C \u043F\u0440\u0430\u0432\u043A\u0438 \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u043E\u0433\u043E \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0430",
808
+ Clear: "\u041E\u0447\u0438\u0441\u0442\u0438\u0442\u044C",
809
+ "Clear all": "\u041E\u0447\u0438\u0441\u0442\u0438\u0442\u044C \u0432\u0441\u0451",
810
+ Unit: "\u0415\u0434\u0438\u043D\u0438\u0446\u0430",
811
+ Token: "\u0422\u043E\u043A\u0435\u043D",
812
+ "pick token": "\u0432\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0442\u043E\u043A\u0435\u043D",
813
+ Mixed: "\u0440\u0430\u0437\u043D\u044B\u0435",
814
+ "Edit each side individually": "\u0420\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u043A\u0430\u0436\u0434\u0443\u044E \u0441\u0442\u043E\u0440\u043E\u043D\u0443 \u043E\u0442\u0434\u0435\u043B\u044C\u043D\u043E",
815
+ // apply-changes-to
816
+ "Apply changes to": "\u041F\u0440\u0438\u043C\u0435\u043D\u0438\u0442\u044C \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F \u043A",
817
+ "This element": "\u042D\u0442\u043E\u043C\u0443 \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0443",
818
+ "Only this one": "\u0422\u043E\u043B\u044C\u043A\u043E \u044D\u0442\u043E\u043C\u0443",
819
+ "All {n} like this": "\u0412\u0441\u0435\u043C \u0442\u0430\u043A\u0438\u043C ({n})",
820
+ "New class\u2026": "\u041D\u043E\u0432\u044B\u0439 \u043A\u043B\u0430\u0441\u0441\u2026",
821
+ "new class name": "\u0438\u043C\u044F \u043D\u043E\u0432\u043E\u0433\u043E \u043A\u043B\u0430\u0441\u0441\u0430",
822
+ "Create a new class instead of touching the existing ones": "\u0421\u043E\u0437\u0434\u0430\u0442\u044C \u043D\u043E\u0432\u044B\u0439 \u043A\u043B\u0430\u0441\u0441 \u0432\u043C\u0435\u0441\u0442\u043E \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044E\u0449\u0438\u0445",
823
+ // legend
824
+ file: "\u0438\u0437 \u0444\u0430\u0439\u043B\u0430",
825
+ edited: "\u0438\u0437\u043C\u0435\u043D\u0435\u043D\u043E",
826
+ inherited: "\u043D\u0430\u0441\u043B\u0435\u0434\u0443\u0435\u0442\u0441\u044F",
827
+ auto: "\u0430\u0432\u0442\u043E",
828
+ // empty / hint
829
+ "Click any element in the frame to select it.": "\u041A\u043B\u0438\u043A\u043D\u0438\u0442\u0435 \u043F\u043E \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0443 \u0432\u043E \u0444\u0440\u0435\u0439\u043C\u0435, \u0447\u0442\u043E\u0431\u044B \u0432\u044B\u0431\u0440\u0430\u0442\u044C \u0435\u0433\u043E.",
830
+ "Click any element on the page to select it.": "\u041A\u043B\u0438\u043A\u043D\u0438\u0442\u0435 \u043F\u043E \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0443 \u043D\u0430 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0435, \u0447\u0442\u043E\u0431\u044B \u0432\u044B\u0431\u0440\u0430\u0442\u044C \u0435\u0433\u043E.",
831
+ "Alt+U toggles \xB7 Esc deselects \xB7 \u2318/Ctrl+Z undo, \u21E7 to redo. Tweaks stay in the browser \u2014 nothing is written to your code.": "Alt+U \u2014 \u0432\u043A\u043B/\u0432\u044B\u043A\u043B \xB7 Esc \u2014 \u0441\u043D\u044F\u0442\u044C \u0432\u044B\u0431\u043E\u0440 \xB7 \u2318/Ctrl+Z \u2014 \u043E\u0442\u043C\u0435\u043D\u0438\u0442\u044C, \u21E7 \u2014 \u0432\u0435\u0440\u043D\u0443\u0442\u044C. \u041F\u0440\u0430\u0432\u043A\u0438 \u0436\u0438\u0432\u0443\u0442 \u0442\u043E\u043B\u044C\u043A\u043E \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 \u2014 \u0432 \u043A\u043E\u0434 \u043D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u043F\u0438\u0448\u0435\u0442\u0441\u044F.",
832
+ // floating "all styles" readout
833
+ "all styles": "\u0432\u0441\u0435 \u0441\u0442\u0438\u043B\u0438",
834
+ computed: "\u0432\u044B\u0447\u0438\u0441\u043B\u0435\u043D\u043E",
835
+ // design system
836
+ "Design system": "\u0414\u0438\u0437\u0430\u0439\u043D-\u0441\u0438\u0441\u0442\u0435\u043C\u0430",
837
+ "tokens detected": "\u0442\u043E\u043A\u0435\u043D\u043E\u0432 \u043D\u0430\u0439\u0434\u0435\u043D\u043E",
838
+ // frame readout
839
+ editing: "\u043F\u0440\u0430\u0432\u0438\u043C",
840
+ "No breakpoint \u2014 applies to every size by default": "\u0411\u0435\u0437 \u0431\u0440\u0435\u0439\u043A\u043F\u043E\u0438\u043D\u0442\u0430 \u2014 \u043F\u0440\u0438\u043C\u0435\u043D\u044F\u0435\u0442\u0441\u044F \u043A\u043E \u0432\u0441\u0435\u043C \u0440\u0430\u0437\u043C\u0435\u0440\u0430\u043C",
841
+ // toasts
842
+ "No tweaks recorded yet": "\u041F\u043E\u043A\u0430 \u043D\u0435\u0442 \u043D\u0438 \u043E\u0434\u043D\u043E\u0439 \u043F\u0440\u0430\u0432\u043A\u0438",
843
+ "Prompt copied \u2713": "\u041F\u0440\u043E\u043C\u043F\u0442 \u0441\u043A\u043E\u043F\u0438\u0440\u043E\u0432\u0430\u043D \u2713",
844
+ "JSON copied \u2713": "JSON \u0441\u043A\u043E\u043F\u0438\u0440\u043E\u0432\u0430\u043D \u2713",
845
+ "Nothing to undo": "\u041D\u0435\u0447\u0435\u0433\u043E \u043E\u0442\u043C\u0435\u043D\u044F\u0442\u044C",
846
+ "Undo \u21A9": "\u041E\u0442\u043C\u0435\u043D\u0435\u043D\u043E \u21A9",
847
+ "Nothing to redo": "\u041D\u0435\u0447\u0435\u0433\u043E \u0432\u043E\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044C",
848
+ "Redo \u21AA": "\u0412\u043E\u0437\u0432\u0440\u0430\u0449\u0435\u043D\u043E \u21AA",
849
+ // section titles
850
+ Layout: "\u0420\u0430\u0441\u043A\u043B\u0430\u0434\u043A\u0430",
851
+ Size: "\u0420\u0430\u0437\u043C\u0435\u0440",
852
+ Spacing: "\u041E\u0442\u0441\u0442\u0443\u043F\u044B",
853
+ Border: "\u0413\u0440\u0430\u043D\u0438\u0446\u0430",
854
+ Typography: "\u0422\u0438\u043F\u043E\u0433\u0440\u0430\u0444\u0438\u043A\u0430",
855
+ Fill: "\u0417\u0430\u043B\u0438\u0432\u043A\u0430",
856
+ // control labels
857
+ Display: "\u0422\u0438\u043F",
858
+ Direction: "\u041D\u0430\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435",
859
+ Justify: "\u0420\u0430\u0441\u043F\u0440\u0435\u0434.",
860
+ Align: "\u0412\u044B\u0440\u0430\u0432\u043D\u0438\u0432.",
861
+ Wrap: "\u041F\u0435\u0440\u0435\u043D\u043E\u0441",
862
+ Width: "\u0428\u0438\u0440\u0438\u043D\u0430",
863
+ Height: "\u0412\u044B\u0441\u043E\u0442\u0430",
864
+ "Max W": "\u041C\u0430\u043A\u0441 \u0428",
865
+ "Min H": "\u041C\u0438\u043D \u0412",
866
+ Padding: "\u0412\u043D\u0443\u0442\u0440. \u043E\u0442\u0441\u0442\u0443\u043F",
867
+ Margin: "\u0412\u043D\u0435\u0448\u043D. \u043E\u0442\u0441\u0442\u0443\u043F",
868
+ Gap: "\u041F\u0440\u043E\u043C\u0435\u0436\u0443\u0442\u043E\u043A",
869
+ Radius: "\u0421\u043A\u0440\u0443\u0433\u043B\u0435\u043D\u0438\u0435",
870
+ Weight: "\u041D\u0430\u0441\u044B\u0449\u0435\u043D\u043D\u043E\u0441\u0442\u044C",
871
+ Line: "\u0412\u044B\u0441\u043E\u0442\u0430 \u0441\u0442\u0440\u043E\u043A\u0438",
872
+ Text: "\u0422\u0435\u043A\u0441\u0442",
873
+ Background: "\u0424\u043E\u043D"
874
+ };
875
+ var DICT = { en: {}, ru: RU };
876
+ function detect() {
877
+ try {
878
+ const saved = localStorage.getItem("uiv-lang");
879
+ if (saved === "en" || saved === "ru") return saved;
880
+ } catch {
881
+ }
882
+ try {
883
+ if (typeof navigator !== "undefined" && /^ru\b/i.test(navigator.language || "")) return "ru";
884
+ } catch {
885
+ }
886
+ return "en";
887
+ }
888
+ var lang = detect();
889
+ function getLang() {
890
+ return lang;
891
+ }
892
+ function setLang(next) {
893
+ lang = next;
894
+ try {
895
+ localStorage.setItem("uiv-lang", next);
896
+ } catch {
897
+ }
898
+ }
899
+ function t(key, vars) {
900
+ let out = DICT[lang][key] ?? key;
901
+ if (vars) for (const k of Object.keys(vars)) out = out.replace(`{${k}}`, String(vars[k]));
902
+ return out;
903
+ }
904
+
1411
905
  // src/overlay/prompt.ts
1412
906
  function collapseChanges(changes) {
1413
907
  const byBp = groupByBreakpoint(changes);
@@ -1630,12 +1124,12 @@ var INTERNAL_COMPONENTS = /* @__PURE__ */ new Set([
1630
1124
  function isInternalName(name) {
1631
1125
  return INTERNAL_COMPONENTS.has(name) || /(?:Boundary|Router)$/.test(name) || name.startsWith("_");
1632
1126
  }
1633
- function fiberName(t) {
1634
- if (typeof t === "function") return t.displayName || t.name || null;
1635
- if (t && typeof t === "object") {
1636
- const inner = t.type || t.render;
1637
- if (typeof inner === "function") return t.displayName || inner.displayName || inner.name || null;
1638
- if (typeof t.displayName === "string") return t.displayName;
1127
+ function fiberName(t2) {
1128
+ if (typeof t2 === "function") return t2.displayName || t2.name || null;
1129
+ if (t2 && typeof t2 === "object") {
1130
+ const inner = t2.type || t2.render;
1131
+ if (typeof inner === "function") return t2.displayName || inner.displayName || inner.name || null;
1132
+ if (typeof t2.displayName === "string") return t2.displayName;
1639
1133
  }
1640
1134
  return null;
1641
1135
  }
@@ -1806,22 +1300,23 @@ var CSS = (
1806
1300
  border-bottom: 1px solid #242428; position: sticky; top: 0; z-index: 5; background: #141416;
1807
1301
  }
1808
1302
  .uiv-head b { font-size: 13px; color: #fafafa; letter-spacing: .2px; }
1809
- .uiv-bp { margin-left: auto; font-size: 10px; padding: 2px 8px; border-radius: 999px;
1303
+ .uiv-lang { margin-left: auto; cursor: pointer; font-size: 10px; font-weight: 700; letter-spacing: .4px;
1304
+ padding: 2px 7px; border-radius: 6px; background: #1c1c20; border: 1px solid #313138; color: #a1a1aa; }
1305
+ .uiv-lang:hover { color: #fff; border-color: #4f46e5; background: #26262c; }
1306
+ .uiv-bp { font-size: 10px; padding: 2px 8px; border-radius: 999px;
1810
1307
  background: #312e81; color: #c7d2fe; font-weight: 600; }
1811
1308
  .uiv-x { cursor: pointer; color: #71717a; padding: 2px 4px; }
1812
1309
  .uiv-x:hover { color: #fff; }
1813
1310
 
1814
1311
  .uiv-sec { padding: 11px 13px; border-bottom: 1px solid #1f1f22; }
1815
1312
 
1816
- /* ---- Framer-style top alignment toolbar ---- */
1817
- .uiv-toolbar { display: flex; align-items: center; gap: 8px; padding: 8px 13px;
1818
- border-bottom: 1px solid #1f1f22; }
1819
- .uiv-tgroup { display: flex; gap: 2px; }
1820
- .uiv-tbtn { display: flex; align-items: center; justify-content: center; width: 26px; height: 22px;
1821
- border-radius: 5px; background: transparent; border: 1px solid transparent; color: #8b8b94; cursor: pointer; }
1822
- .uiv-tbtn:hover { background: #1f1f23; color: #e4e4e7; }
1823
- .uiv-tbtn.on { background: #312e81; border-color: #4f46e5; color: #fff; }
1824
- .uiv-tsep { width: 1px; height: 16px; background: #2a2a2e; }
1313
+ /* ---- Framer-style flex/grid alignment buttons (Justify / Align rows) ---- */
1314
+ .uiv-fbtns { display: flex; gap: 5px; }
1315
+ .uiv-fbtn { flex: 1; display: flex; align-items: center; justify-content: center; height: 30px;
1316
+ border-radius: 8px; background: #1c1c20; border: 1px solid #313138; color: #8b8b94;
1317
+ cursor: pointer; transition: background .12s ease, color .12s ease, border-color .12s ease; }
1318
+ .uiv-fbtn:hover { background: #26262c; color: #e4e4e7; border-color: #45454d; }
1319
+ .uiv-fbtn.on { background: #312e81; border-color: #6366f1; color: #fff; box-shadow: 0 0 0 1px #4f46e5 inset; }
1825
1320
  .uiv-empty { color: #71717a; padding: 18px 12px; text-align: center; }
1826
1321
 
1827
1322
  .uiv-meta { line-height: 1.5; }
@@ -1845,14 +1340,20 @@ var CSS = (
1845
1340
  .uiv-chip.on, .uiv-clschip.on { background: #4f46e5; border-color: #6366f1; color: #fff; }
1846
1341
  .uiv-bphint { margin-top: 7px; font-size: 10px; color: #71717a; line-height: 1.4; }
1847
1342
  .uiv-bphint b { color: #c7d2fe; }
1343
+ /* "Apply changes to" dropdown (sits outside .uiv-ctl, so style it directly) */
1344
+ .uiv-targetsel { width: 100%; box-sizing: border-box; cursor: pointer;
1345
+ background: #1c1c20; border: 1px solid #313138; color: #fff;
1346
+ border-radius: 7px; padding: 7px 9px; font-size: 12px; outline: none; }
1347
+ .uiv-targetsel:hover { border-color: #45454d; }
1348
+ .uiv-targetsel:focus { border-color: #6366f1; }
1848
1349
  .uiv-newclass {
1849
- border: 1px dashed #52525b; background: transparent; color: #a1a1aa;
1850
- border-radius: 6px; padding: 3px 8px; font-size: 11px; width: 104px; outline: none;
1350
+ margin-top: 7px; box-sizing: border-box; width: 100%;
1351
+ border: 1px dashed #52525b; background: transparent; color: #e4e4e7;
1352
+ border-radius: 7px; padding: 6px 9px; font-size: 12px; outline: none;
1851
1353
  font-family: ui-monospace, monospace;
1852
1354
  }
1853
1355
  .uiv-newclass::placeholder { color: #71717a; }
1854
1356
  .uiv-newclass:focus { border-style: solid; border-color: #6366f1; color: #fff; }
1855
- .uiv-newclass.on { border-style: solid; border-color: #22d3ee; color: #fff; }
1856
1357
 
1857
1358
  /* ---- design-system indicator + token pickers ---- */
1858
1359
  .uiv-dsbar { padding: 7px 12px; border-bottom: 1px solid #27272a;
@@ -1926,8 +1427,9 @@ var CSS = (
1926
1427
  .uiv-acc:hover .uiv-chev { color: #818cf8; }
1927
1428
  .uiv-acc:not(.collapsed) .uiv-chev { transform: rotate(90deg); }
1928
1429
 
1929
- .uiv-ctl { display: grid; grid-template-columns: 70px 1fr 26px; gap: 8px;
1430
+ .uiv-ctl { display: grid; grid-template-columns: 84px 1fr 26px; gap: 8px;
1930
1431
  align-items: center; margin-bottom: 7px; }
1432
+ .uiv-ctl > .clabel { overflow: hidden; text-overflow: ellipsis; }
1931
1433
  .uiv-ctl:last-child { margin-bottom: 0; }
1932
1434
  .uiv-ctl > .clabel { font-size: 11px; color: #a1a1aa; }
1933
1435
  .uiv-ctl > .cfield { min-width: 0; }
@@ -1988,7 +1490,7 @@ var CSS = (
1988
1490
  .uiv-jchg .bp { color: #818cf8; }
1989
1491
  .uiv-jchg .tok { color: #4ade80; }
1990
1492
 
1991
- .uiv-foot { display: flex; gap: 6px; padding: 10px 12px; position: sticky; bottom: 0;
1493
+ .uiv-foot { display: flex; gap: 6px; padding: 10px 12px; position: sticky; bottom: 0; z-index: 8;
1992
1494
  background: #18181b; border-top: 1px solid #27272a; flex-wrap: wrap; }
1993
1495
  .uiv-btn { flex: 1; cursor: pointer; border: 1px solid #3f3f46; background: #27272a;
1994
1496
  color: #e4e4e7; border-radius: 7px; padding: 7px 8px; font-size: 11px; font-weight: 600;
@@ -1997,10 +1499,11 @@ var CSS = (
1997
1499
  .uiv-btn.primary { background: #4f46e5; border-color: #6366f1; color: #fff; flex-basis: 100%; }
1998
1500
  .uiv-btn.primary:hover { background: #4338ca; }
1999
1501
  .uiv-btn.ghost { flex: 0 0 auto; }
2000
- /* floating read-only "all styles" block, docked bottom-right, left of the panel */
2001
- .uiv-info { position: fixed; right: 384px; bottom: 16px; z-index: 2147483646;
2002
- width: 216px; max-height: 52vh; overflow: auto; display: none;
2003
- background: rgba(24,24,27,0.86); color: #e4e4e7;
1502
+ /* floating read-only "all styles" block \u2014 top-LEFT of the screen, its top edge on
1503
+ the same line as the breakpoint toolbar (which is centred up top). */
1504
+ .uiv-info { position: fixed; left: 14px; top: 8px; z-index: 2147483646;
1505
+ width: 216px; max-height: 84vh; overflow: auto; display: none;
1506
+ background: rgba(24,24,27,0.92); color: #e4e4e7;
2004
1507
  border: 1px solid #3f3f46; border-radius: 10px; padding: 8px 10px;
2005
1508
  font-size: 11px; box-shadow: 0 8px 28px rgba(0,0,0,0.4); }
2006
1509
  .uiv-info.show { display: block; }
@@ -2033,6 +1536,10 @@ var CSS = (
2033
1536
  .uiv-bm-i.st-edited { color: #4ade80; }
2034
1537
  .uiv-bm-i.st-inherit { color: #38bdf8; }
2035
1538
  .uiv-bm-i.st-auto { color: #6b7280; }
1539
+ /* a side bound to a design token \u2014 shown by name, accent-coloured, no spin */
1540
+ .uiv-bm-i.uiv-bm-tok { color: #a5b4fc; font-size: 9px; letter-spacing: -0.2px;
1541
+ border-color: #4338ca; background: #1e1b4b40; text-overflow: ellipsis; }
1542
+ .uiv-bm-i.uiv-bm-tok.st-edited { color: #818cf8; }
2036
1543
  /* spacing-token dropdown \u2014 opens when a side value is focused/clicked */
2037
1544
  .uiv-bm-pop { display: flex; flex-wrap: wrap; gap: 5px; align-items: center;
2038
1545
  margin: -3px 0 8px; padding: 8px; background: #1c1c20; border: 1px solid #34343c;
@@ -2044,39 +1551,6 @@ var CSS = (
2044
1551
  padding: 3px 8px; font-size: 10px; cursor: pointer; font-family: ui-monospace, monospace; }
2045
1552
  .uiv-bm-chip:hover { background: #4f46e5; border-color: #6366f1; color: #fff; }
2046
1553
 
2047
- /* ---- All CSS inspector (search + categories + generic smart inputs) ---- */
2048
- .uiv-csssearch { width: 100%; background: #0f0f12; border: 1px solid #3f3f46; color: #e4e4e7;
2049
- border-radius: 7px; padding: 7px 9px; font-size: 12px; outline: none; font-family: ui-monospace, monospace; }
2050
- .uiv-csssearch:focus { border-color: #6366f1; }
2051
- .uiv-csssearch::placeholder { color: #6b6b73; }
2052
- .uiv-catacc .uiv-catn { color: #52525b; font-weight: 700; margin-left: auto; }
2053
- .uiv-showall { background: none; border: 0; color: #818cf8; cursor: pointer;
2054
- font-size: 10px; padding: 2px 0 4px; font-weight: 600; }
2055
- .uiv-showall:hover { color: #a5b4fc; }
2056
- .uiv-gctl { grid-template-columns: 108px 1fr; gap: 8px; margin-bottom: 5px; }
2057
- .uiv-gplabel { font-family: ui-monospace, monospace; font-size: 10px; color: #a1a1aa;
2058
- overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
2059
- .uiv-gsel { width: 100%; background: #1c1c20; border: 1px solid #313138; color: #fff;
2060
- border-radius: 7px; padding: 5px 6px; font-size: 11px; outline: none; font-family: ui-monospace, monospace; }
2061
- .uiv-gsel:focus { border-color: #6366f1; }
2062
- .uiv-gnum { display: flex; align-items: stretch; background: #1c1c20; border: 1px solid #313138;
2063
- border-radius: 7px; overflow: hidden; }
2064
- .uiv-gnum:focus-within { border-color: #6366f1; }
2065
- .uiv-gtext { flex: 1; min-width: 0; background: #1c1c20; border: 1px solid #313138; color: #fff;
2066
- border-radius: 7px; padding: 5px 7px; font-size: 11px; outline: none; font-family: ui-monospace, monospace; }
2067
- .uiv-gnum .uiv-gtext { border: none; border-radius: 0; background: transparent; padding-left: 2px; }
2068
- .uiv-gtext:focus { border-color: #6366f1; }
2069
- .uiv-gtext::placeholder { color: #6b6b73; }
2070
- .uiv-gcolorwrap { display: flex; gap: 5px; align-items: center; }
2071
- .uiv-gcolor { width: 28px; height: 26px; padding: 2px; flex: 0 0 auto; background: #1c1c20;
2072
- border: 1px solid #313138; border-radius: 7px; cursor: pointer; }
2073
- .uiv-gtextc { flex: 1; }
2074
- .uiv-gctl.st-file .uiv-gtext, .uiv-gctl.st-file .uiv-gsel { color: #e4e4e7; }
2075
- .uiv-gctl.st-edited .uiv-gtext, .uiv-gctl.st-edited .uiv-gsel { color: #4ade80; }
2076
- .uiv-gctl.st-edited .uiv-gnum, .uiv-gctl.st-edited .uiv-gsel { border-color: #4ade80; }
2077
- .uiv-gctl.st-inherit .uiv-gtext, .uiv-gctl.st-inherit .uiv-gsel { color: #38bdf8; }
2078
- .uiv-gctl.st-auto .uiv-gtext, .uiv-gctl.st-auto .uiv-gsel { color: #6b7280; }
2079
-
2080
1554
  .uiv-toast { position: fixed; right: 16px; bottom: 128px; z-index: 2147483647;
2081
1555
  background: #22c55e; color: #052e16; padding: 8px 12px; border-radius: 8px;
2082
1556
  font-size: 12px; font-weight: 600; display: none; }
@@ -2097,38 +1571,6 @@ var INHERITED_PROPS = /* @__PURE__ */ new Set([
2097
1571
  "text-align",
2098
1572
  "font-family"
2099
1573
  ]);
2100
- var BOX_SIDES = {
2101
- inset: [
2102
- { css: "top", label: "T" },
2103
- { css: "right", label: "R" },
2104
- { css: "bottom", label: "B" },
2105
- { css: "left", label: "L" }
2106
- ],
2107
- padding: [
2108
- { css: "padding-top", label: "T" },
2109
- { css: "padding-right", label: "R" },
2110
- { css: "padding-bottom", label: "B" },
2111
- { css: "padding-left", label: "L" }
2112
- ],
2113
- margin: [
2114
- { css: "margin-top", label: "T" },
2115
- { css: "margin-right", label: "R" },
2116
- { css: "margin-bottom", label: "B" },
2117
- { css: "margin-left", label: "L" }
2118
- ],
2119
- radius: [
2120
- { css: "border-top-left-radius", label: "TL" },
2121
- { css: "border-top-right-radius", label: "TR" },
2122
- { css: "border-bottom-right-radius", label: "BR" },
2123
- { css: "border-bottom-left-radius", label: "BL" }
2124
- ],
2125
- "border-width": [
2126
- { css: "border-top-width", label: "T" },
2127
- { css: "border-right-width", label: "R" },
2128
- { css: "border-bottom-width", label: "B" },
2129
- { css: "border-left-width", label: "L" }
2130
- ]
2131
- };
2132
1574
  var Uivisor = class {
2133
1575
  constructor() {
2134
1576
  this.enabled = false;
@@ -2139,10 +1581,6 @@ var Uivisor = class {
2139
1581
  this.collapsedSecs = /* @__PURE__ */ new Set();
2140
1582
  /** Controls manually revealed via "+" (hideWhenAuto controls that are auto). */
2141
1583
  this.revealedCtls = /* @__PURE__ */ new Set();
2142
- /** "All CSS" search query + which property categories are expanded / showing all. */
2143
- this.cssSearch = "";
2144
- this.expandedCats = /* @__PURE__ */ new Set();
2145
- this.showAllCats = /* @__PURE__ */ new Set();
2146
1584
  /** Box-model widget: the last-focused side the token dropdown targets. */
2147
1585
  this.lastBmSide = "padding-top";
2148
1586
  /** Undo / redo stacks of full edit-state snapshots. */
@@ -2162,6 +1600,11 @@ var Uivisor = class {
2162
1600
  // responsive (virtual screen) mode
2163
1601
  this.responsive = false;
2164
1602
  this.frameWidth = 768;
1603
+ /** The breakpoint new edits are scoped to — chosen explicitly via the chips,
1604
+ * NOT derived from the frame's pixel width. Defaults to 'base' so a casual tweak
1605
+ * applies to EVERY size (and never "disappears" when you view another size).
1606
+ * Picking a specific breakpoint chip narrows the scope to that breakpoint. */
1607
+ this.pickedBp = "base";
2165
1608
  // ---- pointer handling ----
2166
1609
  this.onMove = (e) => {
2167
1610
  if (!this.enabled || this.isOurs(e)) {
@@ -2231,12 +1674,6 @@ var Uivisor = class {
2231
1674
  this.selBox.style.display = "none";
2232
1675
  }
2233
1676
  };
2234
- /** Properties to snapshot on selection: the curated set ∪ the whole registry. */
2235
- this._snapProps = null;
2236
- // ---- "All CSS" inspector (registry-driven, curated like Framer/Webflow) ----
2237
- /** Properties already covered by the curated quick-control sections above — so we
2238
- * don't show them again in the All-CSS area. */
2239
- this._curatedProps = null;
2240
1677
  }
2241
1678
  /** Project breakpoints — re-detect until the stylesheets yield a real set. */
2242
1679
  bpSystem() {
@@ -2289,32 +1726,33 @@ var Uivisor = class {
2289
1726
  this.root.innerHTML = `
2290
1727
  <style>${CSS}</style>
2291
1728
  <div class="uiv-framewrap">
2292
- <div class="uiv-framebar"><div class="uiv-framechips uiv-chips"></div><span class="uiv-framew">768px</span><span class="uiv-framex" title="Turn uivisor off (Alt+U)">\u2715</span></div>
1729
+ <div class="uiv-framebar"><div class="uiv-framechips uiv-chips"></div><span class="uiv-framew">768px</span><span class="uiv-framex" title="${escapeAttr(t("Turn uivisor off (Alt+U)"))}">\u2715</span></div>
2293
1730
  <div class="uiv-framestage">
2294
1731
  <div class="uiv-framehost">
2295
1732
  <iframe class="uiv-frame" data-uiv-frame="1"></iframe>
2296
- <div class="uiv-framehandle" title="Drag to resize"></div>
1733
+ <div class="uiv-framehandle" title="${escapeAttr(t("Drag to resize"))}"></div>
2297
1734
  </div>
2298
1735
  </div>
2299
1736
  </div>
2300
1737
  <div class="uiv-box hover"></div>
2301
1738
  <div class="uiv-box sel"></div>
2302
1739
  <div class="uiv-tag"></div>
2303
- <div class="uiv-fab" title="Toggle uivisor (Alt+U)">\u25CE</div>
1740
+ <div class="uiv-fab" title="${escapeAttr(t("Toggle uivisor (Alt+U)"))}">\u25CE</div>
2304
1741
  <div class="uiv-info"></div>
2305
1742
  <div class="uiv-toast"></div>
2306
1743
  <div class="uiv-panel">
2307
1744
  <div class="uiv-head">
2308
1745
  <b>uivisor</b>
1746
+ <button class="uiv-lang" title="Language / \u042F\u0437\u044B\u043A">${getLang().toUpperCase()}</button>
2309
1747
  <span class="uiv-bp">base</span>
2310
- <span class="uiv-x" title="Close">\u2715</span>
1748
+ <span class="uiv-x" title="${escapeAttr(t("Close"))}">\u2715</span>
2311
1749
  </div>
2312
1750
  <div class="uiv-body"></div>
2313
1751
  <div class="uiv-foot">
2314
- <button class="uiv-btn primary copy-prompt">Copy prompt for agent</button>
2315
- <button class="uiv-btn copy-json">Copy JSON</button>
2316
- <button class="uiv-btn ghost reset" title="Revert tweaks on selected element">Reset</button>
2317
- <button class="uiv-btn ghost clear" title="Clear all">Clear</button>
1752
+ <button class="uiv-btn primary copy-prompt">${t("Copy prompt for agent")}</button>
1753
+ <button class="uiv-btn copy-json">${t("Copy JSON")}</button>
1754
+ <button class="uiv-btn ghost reset" title="${escapeAttr(t("Revert tweaks on selected element"))}">${t("Reset")}</button>
1755
+ <button class="uiv-btn ghost clear" title="${escapeAttr(t("Clear all"))}">${t("Clear")}</button>
2318
1756
  </div>
2319
1757
  </div>
2320
1758
  `;
@@ -2329,6 +1767,7 @@ var Uivisor = class {
2329
1767
  this.frame = this.q(".uiv-frame");
2330
1768
  this.fab.addEventListener("click", () => this.toggle());
2331
1769
  this.q(".uiv-x").addEventListener("click", () => this.toggle(false));
1770
+ this.q(".uiv-lang").addEventListener("click", () => this.setLanguage(getLang() === "ru" ? "en" : "ru"));
2332
1771
  this.q(".uiv-framex").addEventListener("click", () => this.toggle(false));
2333
1772
  this.q(".copy-prompt").addEventListener("click", () => this.copyPrompt());
2334
1773
  this.q(".copy-json").addEventListener("click", () => this.copyJSON());
@@ -2367,6 +1806,29 @@ var Uivisor = class {
2367
1806
  isOurs(e) {
2368
1807
  return e.composedPath().includes(this.host);
2369
1808
  }
1809
+ /** Switch the UI language: persist it, refresh the static chrome built once in
1810
+ * mount() (buttons, titles, the toggle label) and re-render the live panel. */
1811
+ setLanguage(next) {
1812
+ setLang(next);
1813
+ this.q(".uiv-lang").textContent = next.toUpperCase();
1814
+ this.q(".uiv-x").setAttribute("title", t("Close"));
1815
+ this.q(".uiv-framex").setAttribute("title", t("Turn uivisor off (Alt+U)"));
1816
+ this.q(".uiv-framehandle").setAttribute("title", t("Drag to resize"));
1817
+ this.fab.setAttribute("title", t("Toggle uivisor (Alt+U)"));
1818
+ this.q(".copy-prompt").textContent = t("Copy prompt for agent");
1819
+ this.q(".copy-json").textContent = t("Copy JSON");
1820
+ const reset = this.q(".reset");
1821
+ reset.textContent = t("Reset");
1822
+ reset.setAttribute("title", t("Revert tweaks on selected element"));
1823
+ const clear = this.q(".clear");
1824
+ clear.textContent = t("Clear");
1825
+ clear.setAttribute("title", t("Clear all"));
1826
+ this.renderBody();
1827
+ if (this.responsive) {
1828
+ this.renderFrameBar();
1829
+ this.setFrameWidth(this.frameWidth);
1830
+ }
1831
+ }
2370
1832
  // ---- enable / disable ----
2371
1833
  toggle(force) {
2372
1834
  this.enabled = force ?? !this.enabled;
@@ -2380,21 +1842,16 @@ var Uivisor = class {
2380
1842
  } else {
2381
1843
  this.scheduleBpRefresh();
2382
1844
  if (!this.responsive) {
2383
- this.frameWidth = this.defaultFrameWidth();
1845
+ this.pickedBp = "base";
1846
+ this.frameWidth = this.baseFrameWidth();
2384
1847
  this.toggleResponsive(true);
2385
1848
  }
2386
1849
  }
2387
1850
  }
2388
- /** Frame width on enable: the real window width (≈ the current breakpoint). */
1851
+ /** The real window width used as the desktop reference for a desktop-first base. */
2389
1852
  defaultFrameWidth() {
2390
1853
  return typeof window !== "undefined" ? window.innerWidth : 1280;
2391
1854
  }
2392
- /** Frame width for the "all"/base chip: a phone-ish width in the base range. */
2393
- baseFrameWidth() {
2394
- const bps = this.bpSystem().breakpoints;
2395
- const firstBp = bps.length ? bps[0].minWidth : 640;
2396
- return this.bpSystem().dir === "min" ? Math.min(390, firstBp - 1) : 390;
2397
- }
2398
1855
  /** Stylesheets (esp. JIT/CDN Tailwind) load async — re-detect breakpoints a few
2399
1856
  * times after enabling and re-render only if the set actually changed. */
2400
1857
  scheduleBpRefresh() {
@@ -2411,6 +1868,21 @@ var Uivisor = class {
2411
1868
  };
2412
1869
  for (const d of [250, 900, 2200]) window.setTimeout(refresh, d);
2413
1870
  }
1871
+ /** Frame width for the "all"/base chip — the screen the project's UNPREFIXED
1872
+ * (base) styles target, which depends on the cascade direction:
1873
+ * • mobile-first (min-width) → base is the SMALLEST view → a phone width;
1874
+ * • desktop-first (max-width) → base is the WIDEST view → a desktop width.
1875
+ * The EDIT SCOPE stays decoupled (a base edit applies at every size regardless). */
1876
+ baseFrameWidth() {
1877
+ const sys = this.bpSystem();
1878
+ const bps = sys.breakpoints;
1879
+ if (sys.dir === "min") {
1880
+ const firstBp = bps.length ? bps[0].minWidth : 640;
1881
+ return Math.min(390, firstBp - 1);
1882
+ }
1883
+ const lastBp = bps.length ? bps[bps.length - 1].minWidth : 1024;
1884
+ return Math.max(this.defaultFrameWidth(), lastBp + 80);
1885
+ }
2414
1886
  // ---- responsive (virtual screen) mode ----
2415
1887
  /** The document the inspector currently targets: the iframe in responsive mode. */
2416
1888
  doc() {
@@ -2489,8 +1961,7 @@ var Uivisor = class {
2489
1961
  this.frameWidth = Math.max(280, Math.min(2400, Math.round(w)));
2490
1962
  const host = this.q(".uiv-framehost");
2491
1963
  host.style.width = `${this.frameWidth}px`;
2492
- const bp = activeBreakpoint(this.frameWidth, this.bpSystem()).name;
2493
- this.q(".uiv-framew").textContent = `${this.frameWidth}px \xB7 ${this.bpLabel(bp)}`;
1964
+ this.q(".uiv-framew").textContent = `${this.frameWidth}px \xB7 ${t("editing")} ${this.bpLabel(this.scopeName())}`;
2494
1965
  this.updateBp();
2495
1966
  this.reposition();
2496
1967
  }
@@ -2550,9 +2021,10 @@ var Uivisor = class {
2550
2021
  this.reposition();
2551
2022
  this.renderBody();
2552
2023
  }
2024
+ /** Properties to snapshot on selection — the curated set the controls can edit,
2025
+ * plus the flex-alignment props handled by the visual button-rows. */
2553
2026
  snapshotProps() {
2554
- if (!this._snapProps) this._snapProps = [.../* @__PURE__ */ new Set([...ALL_CSS, ...cssRegistry().byProp.keys()])];
2555
- return this._snapProps;
2027
+ return [.../* @__PURE__ */ new Set([...ALL_CSS, "justify-content", "align-items"])];
2556
2028
  }
2557
2029
  // ---- value helpers ----
2558
2030
  st() {
@@ -2586,6 +2058,14 @@ var Uivisor = class {
2586
2058
  if (inline && !inline.includes("var(")) return inline;
2587
2059
  return this.computedVal(css) || st.original[css] || "";
2588
2060
  }
2061
+ /** If a design token is the effective value for `css`, its short name (e.g. "lg"
2062
+ * for --space-lg) — so the field shows the token by name, not its resolved px. */
2063
+ tokenNameFor(css) {
2064
+ const ch = this.effectiveChange(css);
2065
+ if (!ch?.after.designToken) return null;
2066
+ const t2 = this.designSystem().tokens.find((x) => x.cssVar === ch.after.designToken);
2067
+ return t2 ? t2.name : ch.after.designToken;
2068
+ }
2589
2069
  liveNum(css) {
2590
2070
  const v = this.liveVal(css).trim();
2591
2071
  const m = /^(-?\d*\.?\d+)px$/.exec(v);
@@ -2687,18 +2167,37 @@ var Uivisor = class {
2687
2167
  }
2688
2168
  this.reposition();
2689
2169
  }
2690
- /** The breakpoint recorded edits are scoped to: manual override, else window. */
2691
- /** The breakpoint edits are scoped to: the virtual screen's width when in
2692
- * responsive mode, otherwise the real window. */
2170
+ /** The breakpoint new edits are scoped to. In responsive mode it's the EXPLICITLY
2171
+ * picked breakpoint (default 'base' = every size), decoupled from the frame's
2172
+ * pixel width so editing at a desktop-sized frame still defaults to "all sizes"
2173
+ * instead of silently scoping to the top breakpoint and vanishing elsewhere. */
2693
2174
  activeScope() {
2694
2175
  const sys = this.bpSystem();
2695
- if (this.responsive) return activeBreakpoint(this.frameWidth, sys);
2696
- return currentBreakpoint(sys);
2697
- }
2698
- /** The width the inspector is scoped to (virtual screen, else real window). */
2176
+ if (!this.responsive) return currentBreakpoint(sys);
2177
+ const name = this.scopeName();
2178
+ const bp = sys.breakpoints.find((b) => b.name === name);
2179
+ return { name, minWidth: bp ? bp.minWidth : 0 };
2180
+ }
2181
+ /** The picked breakpoint, validated against the current system (falls back to
2182
+ * 'base' if a previously-picked breakpoint no longer exists after re-detection). */
2183
+ scopeName() {
2184
+ if (this.pickedBp === "base") return "base";
2185
+ return this.bpSystem().breakpoints.some((b) => b.name === this.pickedBp) ? this.pickedBp : "base";
2186
+ }
2187
+ /** The width the cascade is evaluated at — the representative width of the PICKED
2188
+ * scope, not the frame's visual width. base → a width where only base applies (so
2189
+ * base edits win and show everywhere); a named breakpoint → its threshold. */
2699
2190
  activeWidth() {
2700
- if (this.responsive) return this.frameWidth;
2701
- return typeof window !== "undefined" ? window.innerWidth : 0;
2191
+ if (!this.responsive) return typeof window !== "undefined" ? window.innerWidth : 0;
2192
+ return this.scopeWidth(this.scopeName());
2193
+ }
2194
+ scopeWidth(name) {
2195
+ const sys = this.bpSystem();
2196
+ if (name !== "base") {
2197
+ const bp = sys.breakpoints.find((b) => b.name === name);
2198
+ if (bp) return bp.minWidth;
2199
+ }
2200
+ return sys.dir === "min" ? 0 : 1e6;
2702
2201
  }
2703
2202
  /** The recorded change that wins the breakpoint cascade for `css` at the active
2704
2203
  * width — i.e. the value effective here, set on this breakpoint or inherited. */
@@ -2822,8 +2321,8 @@ var Uivisor = class {
2822
2321
  if (!this.selected) {
2823
2322
  body.innerHTML = `
2824
2323
  ${this.breakpointBarHtml()}
2825
- <div class="uiv-empty">Click any element ${this.responsive ? "in the frame" : "on the page"} to select it.</div>
2826
- <div class="uiv-hint">Alt+U toggles \xB7 Esc deselects \xB7 \u2318/Ctrl+Z undo, \u21E7 to redo. Tweaks stay in the browser \u2014 nothing is written to your code.</div>
2324
+ <div class="uiv-empty">${t(this.responsive ? "Click any element in the frame to select it." : "Click any element on the page to select it.")}</div>
2325
+ <div class="uiv-hint">${t("Alt+U toggles \xB7 Esc deselects \xB7 \u2318/Ctrl+Z undo, \u21E7 to redo. Tweaks stay in the browser \u2014 nothing is written to your code.")}</div>
2827
2326
  ${this.journalHtml()}
2828
2327
  `;
2829
2328
  if (this.responsive) this.renderFrameBar();
@@ -2840,13 +2339,11 @@ var Uivisor = class {
2840
2339
  <div class="uiv-src">${escapeHtml(src)}</div>
2841
2340
  <span class="uiv-mech">${st.record.styling.primaryMechanism}</span>
2842
2341
  </div>
2843
- ${this.alignToolbarHtml()}
2844
2342
  ${this.dsIndicatorHtml()}
2845
2343
  ${this.breakpointBarHtml()}
2846
2344
  ${this.targetHtml(st)}
2847
2345
  ${this.controlsHtml(this.context(this.selected))}
2848
2346
  ${this.journalHtml()}
2849
- ${this.allCssHtml()}
2850
2347
  `;
2851
2348
  if (this.responsive) this.renderFrameBar();
2852
2349
  this.renderInfo();
@@ -2857,7 +2354,7 @@ var Uivisor = class {
2857
2354
  const ds = this.designSystem();
2858
2355
  if (ds.source === "none") return "";
2859
2356
  const cats = Object.keys(ds.byCategory).map((c) => `${ds.byCategory[c].length} ${c}`).join(" \xB7 ");
2860
- return `<div class="uiv-dsbar" title="${escapeAttr(cats)}">\u25C6 Design system \xB7 ${ds.tokens.length} tokens detected</div>`;
2357
+ return `<div class="uiv-dsbar" title="${escapeAttr(cats)}">\u25C6 ${t("Design system")} \xB7 ${ds.tokens.length} ${t("tokens detected")}</div>`;
2861
2358
  }
2862
2359
  /** Longhand properties an authoring rule (or non-uivisor inline) sets on `el`.
2863
2360
  * Reimplements getMatchedCSSRules over same-origin sheets (incl. matching
@@ -2924,7 +2421,7 @@ var Uivisor = class {
2924
2421
  ctlLabel(label, props) {
2925
2422
  const from = this.inheritedFrom(props);
2926
2423
  const badge = from ? ` <span class="uiv-inh" title="inherited from ${escapeAttr(this.bpLabel(from))} \u2014 not set at this breakpoint">\u2923${escapeHtml(this.bpLabel(from))}</span>` : "";
2927
- return `<span class="clabel">${label}${badge}</span>`;
2424
+ return `<span class="clabel">${escapeHtml(t(label))}${badge}</span>`;
2928
2425
  }
2929
2426
  /** Is any of `props` authored in the project CSS? For inherited properties we
2930
2427
  * also walk ancestors (a body/parent font rule still counts as "from the file"). */
@@ -2958,10 +2455,10 @@ var Uivisor = class {
2958
2455
  return /^#|rgb/.test(h) ? `<span class="uiv-sw" style="background:${h}"></span>${h}` : h;
2959
2456
  };
2960
2457
  const sides = (parts) => {
2961
- const [t, r, b, l] = parts.map(g);
2962
- if (t === r && r === b && b === l) return t;
2963
- if (t === b && r === l) return `${t} ${r}`;
2964
- return `${t} ${r} ${b} ${l}`;
2458
+ const [t2, r, b, l] = parts.map(g);
2459
+ if (t2 === r && r === b && b === l) return t2;
2460
+ if (t2 === b && r === l) return `${t2} ${r}`;
2461
+ return `${t2} ${r} ${b} ${l}`;
2965
2462
  };
2966
2463
  const px4 = (pre, suf = "") => [`${pre}-top${suf}`, `${pre}-right${suf}`, `${pre}-bottom${suf}`, `${pre}-left${suf}`];
2967
2464
  const clip = (s, n = 30) => s.length > n ? s.slice(0, n - 1) + "\u2026" : s;
@@ -3064,7 +2561,7 @@ var Uivisor = class {
3064
2561
  info.innerHTML = "";
3065
2562
  return;
3066
2563
  }
3067
- info.innerHTML = `<div class="uiv-info-h">all styles <span class="uiv-info-sub">computed</span></div><div class="uiv-readout">${this.styleRows()}</div>`;
2564
+ info.innerHTML = `<div class="uiv-info-h">${t("all styles")} <span class="uiv-info-sub">${t("computed")}</span></div><div class="uiv-readout">${this.styleRows()}</div>`;
3068
2565
  info.classList.add("show");
3069
2566
  }
3070
2567
  /** Display label for a breakpoint name — the unprefixed "base" scope reads "all"
@@ -3085,11 +2582,10 @@ var Uivisor = class {
3085
2582
  * project breakpoint. Reused by the panel (Live) and the over-frame bar. */
3086
2583
  breakpointChipsHtml() {
3087
2584
  const sys = this.bpSystem();
3088
- const frameBp = this.responsive ? activeBreakpoint(this.frameWidth, sys).name : null;
3089
2585
  const winBp = currentBreakpoint(sys).name;
3090
- const isActive = (n) => this.responsive ? n === frameBp : n === winBp;
2586
+ const isActive = (n) => this.responsive ? n === this.scopeName() : n === winBp;
3091
2587
  const chip = (n, on, title) => `<button class="uiv-chip${on ? " on" : ""}" data-bp="${n}" title="${escapeAttr(title)}">${this.bpIcon(n)}<span>${this.bpLabel(n)}</span></button>`;
3092
- const all = chip("base", isActive("base"), "No breakpoint \u2014 applies to every size by default");
2588
+ const all = chip("base", isActive("base"), t("No breakpoint \u2014 applies to every size by default"));
3093
2589
  const rest = sys.breakpoints.map((b) => chip(b.name, isActive(b.name), sys.dir === "min" ? `\u2265 ${b.minWidth}px` : `\u2264 ${b.minWidth}px`)).join("");
3094
2590
  return all + rest;
3095
2591
  }
@@ -3117,12 +2613,10 @@ var Uivisor = class {
3117
2613
  const isNew = target.startsWith("new:");
3118
2614
  const newName = isNew ? target.slice(4) : "";
3119
2615
  const n = st.record.identity.instanceCount;
3120
- const chip = (val, label, on) => `<button class="uiv-clschip${on ? " on" : ""}" data-target="${escapeAttr(val)}">${escapeHtml(label)}</button>`;
3121
- const allChip = n > 1 ? chip("all", `All ${n} like this`, target === "all") : "";
3122
- const elChip = chip("element", n > 1 ? "Only this one" : "This element", target === "element");
3123
- const classChips = classes.map((c) => chip(c, `.${c}`, target === c)).join("");
3124
- const newInput = `<input class="uiv-newclass${isNew ? " on" : ""}" placeholder="+ new class" value="${escapeAttr(newName)}" title="Create a new class instead of touching the existing ones">`;
3125
- return `<div class="uiv-sec"><div class="uiv-sectitle">Apply changes to</div><div class="uiv-chips">${allChip}${elChip}${classChips}${newInput}</div></div>`;
2616
+ const opt = (val, label) => `<option value="${escapeAttr(val)}"${target === val ? " selected" : ""}>${escapeHtml(label)}</option>`;
2617
+ const opts = (n > 1 ? opt("all", t("All {n} like this", { n })) : "") + opt("element", n > 1 ? t("Only this one") : t("This element")) + classes.map((c) => opt(c, `.${c}`)).join("") + `<option value="__new__"${isNew ? " selected" : ""}>${escapeHtml(`\uFF0B ${t("New class\u2026")}`)}</option>`;
2618
+ const newInput = isNew ? `<input class="uiv-newclass" placeholder="${escapeAttr(t("new class name"))}" value="${escapeAttr(newName)}" title="${escapeAttr(t("Create a new class instead of touching the existing ones"))}" spellcheck="false">` : "";
2619
+ return `<div class="uiv-sec"><div class="uiv-sectitle">${t("Apply changes to")}</div><div class="cfield"><select class="uiv-sel uiv-targetsel">${opts}</select></div>${newInput}</div>`;
3126
2620
  }
3127
2621
  /** Decide which controls are relevant to the selected element. */
3128
2622
  context(el) {
@@ -3144,28 +2638,35 @@ var Uivisor = class {
3144
2638
  }
3145
2639
  /** Framer-style top alignment toolbar — justify (horizontal) + align (vertical)
3146
2640
  * icon buttons. Shown for flex/grid containers (where they apply). */
3147
- alignToolbarHtml() {
2641
+ /** Visual flex/grid alignment controls — bigger Framer-style icon buttons in two
2642
+ * labelled rows (Justify, Align). Injected right below the Display dropdown and
2643
+ * shown only for flex/grid containers; replaces the duplicate Justify/Align
2644
+ * selects entirely. Commits through the engine via the shared `.uiv-fbtn` binding. */
2645
+ flexControlsHtml() {
3148
2646
  const el = this.selected;
3149
2647
  if (!el || !this.context(el).flexGrid) return "";
3150
2648
  const j = this.liveVal("justify-content").trim();
3151
2649
  const a = this.liveVal("align-items").trim();
3152
- const g = (r) => `<svg viewBox="0 0 14 14" width="13" height="13" fill="currentColor">${r}</svg>`;
3153
- const JI = {
3154
- "flex-start": g('<rect x="1" y="3" width="2" height="8"/><rect x="4" y="3" width="2" height="8"/>'),
3155
- center: g('<rect x="4" y="3" width="2" height="8"/><rect x="8" y="3" width="2" height="8"/>'),
3156
- "flex-end": g('<rect x="8" y="3" width="2" height="8"/><rect x="11" y="3" width="2" height="8"/>'),
3157
- "space-between": g('<rect x="1" y="3" width="2" height="8"/><rect x="11" y="3" width="2" height="8"/>')
3158
- };
3159
- const AI = {
3160
- "flex-start": g('<rect x="3" y="1" width="8" height="2"/><rect x="3" y="4" width="8" height="2"/>'),
3161
- center: g('<rect x="3" y="4" width="8" height="2"/><rect x="3" y="8" width="8" height="2"/>'),
3162
- "flex-end": g('<rect x="3" y="8" width="8" height="2"/><rect x="3" y="11" width="8" height="2"/>'),
3163
- stretch: g('<rect x="3" y="1" width="8" height="12"/>')
2650
+ const g = (r) => `<svg viewBox="0 0 18 18" width="17" height="17" fill="currentColor">${r}</svg>`;
2651
+ const JI = [
2652
+ ["flex-start", g('<rect x="2" y="4" width="2.4" height="10" rx="1"/><rect x="5.6" y="4" width="2.4" height="10" rx="1"/>')],
2653
+ ["center", g('<rect x="5" y="4" width="2.4" height="10" rx="1"/><rect x="10.6" y="4" width="2.4" height="10" rx="1"/>')],
2654
+ ["flex-end", g('<rect x="10" y="4" width="2.4" height="10" rx="1"/><rect x="13.6" y="4" width="2.4" height="10" rx="1"/>')],
2655
+ ["space-between", g('<rect x="2" y="4" width="2.4" height="10" rx="1"/><rect x="13.6" y="4" width="2.4" height="10" rx="1"/>')]
2656
+ ];
2657
+ const AI = [
2658
+ ["flex-start", g('<rect x="4" y="2" width="10" height="2.4" rx="1"/><rect x="4" y="5.6" width="10" height="2.4" rx="1"/>')],
2659
+ ["center", g('<rect x="4" y="5" width="10" height="2.4" rx="1"/><rect x="4" y="10.6" width="10" height="2.4" rx="1"/>')],
2660
+ ["flex-end", g('<rect x="4" y="10" width="10" height="2.4" rx="1"/><rect x="4" y="13.6" width="10" height="2.4" rx="1"/>')],
2661
+ ["stretch", g('<rect x="4" y="2" width="10" height="14" rx="1"/>')]
2662
+ ];
2663
+ const row = (label, prop, cur, entries) => {
2664
+ const btns = entries.map(
2665
+ ([v, ic]) => `<button class="uiv-fbtn${cur === v ? " on" : ""}" data-prop="${prop}" data-val="${v}" title="${prop}: ${v}">${ic}</button>`
2666
+ ).join("");
2667
+ return `<div class="uiv-ctl${this.controlStateClass([prop])}">${this.ctlLabel(label, [prop])}<div class="cfield uiv-fbtns">${btns}</div><span></span></div>`;
3164
2668
  };
3165
- const btn = (prop, val, icon, cur) => `<button class="uiv-tbtn${cur === val ? " on" : ""}" data-prop="${prop}" data-val="${val}" title="${prop}: ${val}">${icon}</button>`;
3166
- const jb = Object.entries(JI).map(([v, ic]) => btn("justify-content", v, ic, j)).join("");
3167
- const ab = Object.entries(AI).map(([v, ic]) => btn("align-items", v, ic, a)).join("");
3168
- return `<div class="uiv-toolbar"><div class="uiv-tgroup">${jb}</div><div class="uiv-tsep"></div><div class="uiv-tgroup">${ab}</div></div>`;
2669
+ return row("Justify", "justify-content", j, JI) + row("Align", "align-items", a, AI);
3169
2670
  }
3170
2671
  /** Figma/Framer-style nested box-model widget: MARGIN ring around a PADDING ring,
3171
2672
  * with an editable number on each of the 8 sides. Commits via the engine. */
@@ -3174,13 +2675,18 @@ var Uivisor = class {
3174
2675
  const n = this.liveNum(css);
3175
2676
  return n == null ? "0" : String(round2(n));
3176
2677
  };
3177
- const side = (css, pos) => `<input class="uiv-bm-i ${pos}${this.controlStateClass([css])}" data-css="${css}" value="${escapeAttr(num(css))}" title="${css}" inputmode="decimal" spellcheck="false">`;
2678
+ const side = (css, pos) => {
2679
+ const tok = this.tokenNameFor(css);
2680
+ const val = tok ?? num(css);
2681
+ const title = tok ? `${css}: ${tok}` : css;
2682
+ return `<input class="uiv-bm-i ${pos}${this.controlStateClass([css])}${tok ? " uiv-bm-tok" : ""}" data-css="${css}" value="${escapeAttr(val)}" title="${escapeAttr(title)}" inputmode="decimal" spellcheck="false">`;
2683
+ };
3178
2684
  const spaceTokens = this.designSystem().byCategory["spacing"] ?? [];
3179
- const pop = spaceTokens.length ? `<div class="uiv-bm-pop" hidden><span class="uiv-bm-poplabel">Token</span>` + spaceTokens.map((t) => `<button class="uiv-bm-chip" data-var="${escapeAttr(t.cssVar)}" title="${escapeAttr(t.value)}">${escapeHtml(t.name)} \xB7 ${escapeHtml(t.value)}</button>`).join("") + `</div>` : "";
2685
+ const pop = spaceTokens.length ? `<div class="uiv-bm-pop" hidden><span class="uiv-bm-poplabel">${t("Token")}</span>` + spaceTokens.map((tok) => `<button class="uiv-bm-chip" data-var="${escapeAttr(tok.cssVar)}" title="${escapeAttr(tok.value)}">${escapeHtml(tok.name)} \xB7 ${escapeHtml(tok.value)}</button>`).join("") + `</div>` : "";
3180
2686
  return `<div class="uiv-bm"><span class="uiv-bm-tag">MARGIN</span>` + side("margin-top", "bm-top") + side("margin-right", "bm-right") + side("margin-bottom", "bm-bottom") + side("margin-left", "bm-left") + `<div class="uiv-bm-pad"><span class="uiv-bm-tag">PADDING</span>` + side("padding-top", "bm-top") + side("padding-right", "bm-right") + side("padding-bottom", "bm-bottom") + side("padding-left", "bm-left") + `<div class="uiv-bm-content"></div></div></div>` + pop;
3181
2687
  }
3182
2688
  controlsHtml(ctx) {
3183
- const legend = `<div class="uiv-leg"><span class="uiv-lg">file</span><span class="uiv-lg edit">edited</span><span class="uiv-lg inh">inherited</span><span class="uiv-lg auto">auto</span></div>`;
2689
+ const legend = `<div class="uiv-leg"><span class="uiv-lg">${t("file")}</span><span class="uiv-lg edit">${t("edited")}</span><span class="uiv-lg inh">${t("inherited")}</span><span class="uiv-lg auto">${t("auto")}</span></div>`;
3184
2690
  const secs = SECTIONS.map((sec) => {
3185
2691
  const controls = sec.controls.filter((c) => this.relevant(c, ctx));
3186
2692
  if (!controls.length) return "";
@@ -3193,9 +2699,10 @@ var Uivisor = class {
3193
2699
  if (isSpacing && c.kind === "box" && (c.key === "padding" || c.key === "margin")) continue;
3194
2700
  const css = c.css;
3195
2701
  if (c.kind === "len" && c.hideWhenAuto && css && !this.revealedCtls.has(css) && this.controlState([css]) === "auto") {
3196
- adds.push(`<button class="uiv-addctl" data-css="${css}">+ ${escapeHtml(c.label)}</button>`);
2702
+ adds.push(`<button class="uiv-addctl" data-css="${css}">+ ${escapeHtml(t(c.label))}</button>`);
3197
2703
  } else {
3198
2704
  rows.push(this.controlRow(c));
2705
+ if (css === "display") rows.push(this.flexControlsHtml());
3199
2706
  }
3200
2707
  }
3201
2708
  const addRow = adds.length ? `<div class="uiv-adds">${adds.join("")}</div>` : "";
@@ -3206,10 +2713,10 @@ var Uivisor = class {
3206
2713
  /** A collapsible section header. Clicking it hides/shows the section's controls. */
3207
2714
  accordionTitle(title) {
3208
2715
  const collapsed = this.collapsedSecs.has(title);
3209
- return `<button class="uiv-sectitle uiv-acc${collapsed ? " collapsed" : ""}" data-sec="${escapeAttr(title)}"><span class="uiv-chev">${ICONS.chevron}</span>${title}</button>`;
2716
+ return `<button class="uiv-sectitle uiv-acc${collapsed ? " collapsed" : ""}" data-sec="${escapeAttr(title)}"><span class="uiv-chev">${ICONS.chevron}</span>${escapeHtml(t(title))}</button>`;
3210
2717
  }
3211
2718
  numField(cssAttr, value, handle, changed, isSide, placeholder) {
3212
- return `<div class="uiv-num${changed ? " changed" : ""}" data-css="${cssAttr}"><span class="uiv-scrub${isSide ? " txt" : ""}" title="Drag to change">${handle}</span><input type="number" value="${escapeAttr(value)}" placeholder="${escapeAttr(placeholder)}"></div>`;
2719
+ return `<div class="uiv-num${changed ? " changed" : ""}" data-css="${cssAttr}"><span class="uiv-scrub${isSide ? " txt" : ""}" title="${escapeAttr(t("Drag to change"))}">${handle}</span><input type="number" value="${escapeAttr(value)}" placeholder="${escapeAttr(placeholder)}"></div>`;
3213
2720
  }
3214
2721
  fontSizePx() {
3215
2722
  const el = this.selected;
@@ -3264,10 +2771,24 @@ var Uivisor = class {
3264
2771
  if (unit === "%") return px2 / fs * 100;
3265
2772
  return px2;
3266
2773
  }
2774
+ /** A dim value's own number + unit ('' = unitless, e.g. line-height: 1.5). */
2775
+ parseDim(v) {
2776
+ const m = /^(-?\d*\.?\d+)(px|em|rem|%)?$/.exec(v.trim());
2777
+ return m ? { num: parseFloat(m[1]), unit: m[2] ?? "" } : null;
2778
+ }
3267
2779
  dimDisplay(c) {
3268
2780
  const st = this.st();
3269
- const computed = this.liveVal(c.css);
3270
- const unit = st.dimUnit[c.css] ?? c.defaultUnit;
2781
+ const computed = this.liveVal(c.css).trim();
2782
+ const native = this.parseDim(computed);
2783
+ const picked = st.dimUnit[c.css];
2784
+ if (picked != null) {
2785
+ const px3 = this.currentPx(c.css);
2786
+ if (px3 != null) return { num: String(round2(this.pxToUnit(px3, picked))), unit: picked, placeholder: computed || "\u2014" };
2787
+ }
2788
+ if (native && c.units.includes(native.unit)) {
2789
+ return { num: String(round2(native.num)), unit: native.unit, placeholder: computed || "\u2014" };
2790
+ }
2791
+ const unit = picked ?? c.defaultUnit;
3271
2792
  const px2 = this.currentPx(c.css);
3272
2793
  if (px2 == null) return { num: "", unit, placeholder: computed || "normal" };
3273
2794
  return { num: String(round2(this.pxToUnit(px2, unit))), unit, placeholder: computed || "\u2014" };
@@ -3276,7 +2797,7 @@ var Uivisor = class {
3276
2797
  const d = this.dimDisplay(c);
3277
2798
  const changed = this.isChanged([c.css]);
3278
2799
  const units = c.units.map((u) => `<option value="${u}"${u === d.unit ? " selected" : ""}>${UNIT_LABELS[u] ?? u}</option>`).join("");
3279
- return `<div class="uiv-ctl${this.controlStateClass([c.css])}">${this.ctlLabel(c.label, [c.css])}<div class="cfield"><div class="uiv-num uiv-dim${changed ? " changed" : ""}" data-css="${c.css}"><span class="uiv-scrub" title="Drag to change">${c.icon}</span><input type="number" step="any" value="${escapeAttr(d.num)}" placeholder="${escapeAttr(d.placeholder)}"><select class="uiv-unit" title="Unit">${units}</select></div></div><span></span></div>`;
2800
+ return `<div class="uiv-ctl${this.controlStateClass([c.css])}">${this.ctlLabel(c.label, [c.css])}<div class="cfield"><div class="uiv-num uiv-dim${changed ? " changed" : ""}" data-css="${c.css}"><span class="uiv-scrub" title="${escapeAttr(t("Drag to change"))}">${c.icon}</span><input type="number" step="any" value="${escapeAttr(d.num)}" placeholder="${escapeAttr(d.placeholder)}"><select class="uiv-unit" title="${escapeAttr(t("Unit"))}">${units}</select></div></div><span></span></div>`;
3280
2801
  }
3281
2802
  /** A design-token picker row for a property, shown only when the project exposes
3282
2803
  * tokens for that category. Picking a token applies its value + tags the prompt. */
@@ -3292,17 +2813,17 @@ var Uivisor = class {
3292
2813
  (c) => c.property === css && c.after.designToken
3293
2814
  );
3294
2815
  if (cat === "color") {
3295
- const swatches = list.map((t) => {
3296
- const on = near?.exact && near.token.cssVar === t.cssVar;
3297
- return `<button class="uiv-swatch${on ? " on" : ""}" data-css="${css}" data-var="${escapeAttr(t.cssVar)}" title="${escapeAttr(`${t.name} \xB7 ${t.value}`)}" style="background:${escapeAttr(t.value)}"></button>`;
2816
+ const swatches = list.map((tok) => {
2817
+ const on = near?.exact && near.token.cssVar === tok.cssVar;
2818
+ return `<button class="uiv-swatch${on ? " on" : ""}" data-css="${css}" data-var="${escapeAttr(tok.cssVar)}" title="${escapeAttr(`${tok.name} \xB7 ${tok.value}`)}" style="background:${escapeAttr(tok.value)}"></button>`;
3298
2819
  }).join("");
3299
- return `<div class="uiv-ctl"><span class="clabel uiv-tlabel">${label}</span><div class="cfield uiv-swatches">${swatches}</div><span></span></div>`;
2820
+ return `<div class="uiv-ctl"><span class="clabel uiv-tlabel">${escapeHtml(t(label))}</span><div class="cfield uiv-swatches">${swatches}</div><span></span></div>`;
3300
2821
  }
3301
- const head = `<option value="">${near && !near.exact ? `\u2248 ${escapeHtml(near.token.name)} \xB7 pick token` : "\u2014 pick token \u2014"}</option>`;
2822
+ const head = `<option value="">${near && !near.exact ? `\u2248 ${escapeHtml(near.token.name)} \xB7 ${t("pick token")}` : `\u2014 ${t("pick token")} \u2014`}</option>`;
3302
2823
  const opts = list.map(
3303
- (t) => `<option value="${escapeAttr(t.cssVar)}"${near?.exact && near.token.cssVar === t.cssVar ? " selected" : ""}>${escapeHtml(`${t.name} \xB7 ${t.value}`)}</option>`
2824
+ (tok) => `<option value="${escapeAttr(tok.cssVar)}"${near?.exact && near.token.cssVar === tok.cssVar ? " selected" : ""}>${escapeHtml(`${tok.name} \xB7 ${tok.value}`)}</option>`
3304
2825
  ).join("");
3305
- return `<div class="uiv-ctl"><span class="clabel uiv-tlabel">${label}</span><div class="cfield"><select class="uiv-sel uiv-tokensel${edited ? " changed" : ""}" data-css="${css}">${head}${opts}</select></div><span></span></div>`;
2826
+ return `<div class="uiv-ctl"><span class="clabel uiv-tlabel">${escapeHtml(t(label))}</span><div class="cfield"><select class="uiv-sel uiv-tokensel${edited ? " changed" : ""}" data-css="${css}">${head}${opts}</select></div><span></span></div>`;
3306
2827
  }
3307
2828
  controlRow(c) {
3308
2829
  if (c.kind === "box") {
@@ -3310,7 +2831,7 @@ var Uivisor = class {
3310
2831
  const info = this.numInfo(cssList);
3311
2832
  const changed = this.isChanged(cssList);
3312
2833
  const open = this.expanded.has(c.key);
3313
- let html = `<div class="uiv-ctl${this.controlStateClass(cssList)}">` + this.ctlLabel(c.label, cssList) + `<div class="cfield">${this.numField(cssList.join(","), info.mixed ? "" : info.value, c.icon, changed, false, info.mixed ? "Mixed" : "\u2014")}</div><button class="uiv-expand${open ? " on" : ""}" data-key="${c.key}" title="Edit each side individually">${open ? ICONS.collapse : ICONS.expand}</button></div>`;
2834
+ let html = `<div class="uiv-ctl${this.controlStateClass(cssList)}">` + this.ctlLabel(c.label, cssList) + `<div class="cfield">${this.numField(cssList.join(","), info.mixed ? "" : info.value, c.icon, changed, false, info.mixed ? t("Mixed") : "\u2014")}</div><button class="uiv-expand${open ? " on" : ""}" data-key="${c.key}" title="${escapeAttr(t("Edit each side individually"))}">${open ? ICONS.collapse : ICONS.expand}</button></div>`;
3314
2835
  if (open) {
3315
2836
  html += `<div class="uiv-sides">` + c.sides.map((s) => {
3316
2837
  const v = this.liveNum(s.css);
@@ -3345,214 +2866,9 @@ var Uivisor = class {
3345
2866
  const val = toHexInput(this.liveVal(c.css));
3346
2867
  return `<div class="uiv-ctl${this.controlStateClass([c.css])}">${this.ctlLabel(c.label, [c.css])}<div class="cfield"><input type="color" class="uiv-color${this.isChanged([c.css]) ? " changed" : ""}" data-css="${c.css}" value="${val}"></div><span></span></div>` + this.tokenRowHtml(c.css, "Token");
3347
2868
  }
3348
- curatedCssProps() {
3349
- if (this._curatedProps) return this._curatedProps;
3350
- const set = /* @__PURE__ */ new Set();
3351
- for (const sec of SECTIONS)
3352
- for (const c of sec.controls) {
3353
- if (c.kind === "box") c.sides.forEach((s) => set.add(s.css));
3354
- else set.add(c.css || "");
3355
- }
3356
- set.delete("");
3357
- this._curatedProps = set;
3358
- return set;
3359
- }
3360
- /**
3361
- * Search box + categorised accordions. By default each category shows only the
3362
- * COMMON properties (Framer/Webflow-style — no logical/vendor/rare noise), box
3363
- * groups as a 4-sided editor; "+ N more" reveals the long tail and search reaches
3364
- * literally everything. Additive: the curated sections above are untouched.
3365
- */
3366
- allCssHtml() {
3367
- const reg = cssRegistry();
3368
- const curated = this.curatedCssProps();
3369
- const q = this.cssSearch.trim().toLowerCase();
3370
- const search = `<div class="uiv-sec"><div class="uiv-sectitle">All CSS</div><input class="uiv-csssearch" placeholder="Search any of ${reg.byProp.size} properties\u2026" value="${escapeAttr(this.cssSearch)}" spellcheck="false"></div>`;
3371
- if (q) {
3372
- const hits = [...reg.byProp.values()].filter((m) => m.property.includes(q)).sort((a, b) => a.property.localeCompare(b.property));
3373
- const rows = hits.slice(0, 60).map((m) => this.genericRow(m)).join("");
3374
- const more = hits.length > 60 ? `<div class="uiv-bphint">+${hits.length - 60} more \u2014 refine the search</div>` : "";
3375
- return search + `<div class="uiv-sec"><div class="uiv-sectitle">Results (${hits.length})</div>` + (rows || '<div class="uiv-empty">No property matches.</div>') + more + `</div>`;
3376
- }
3377
- const cats = reg.categories.map((c) => {
3378
- const avail = c.props.filter((p) => !curated.has(p));
3379
- if (!avail.length) return "";
3380
- const common = avail.filter((p) => reg.byProp.get(p).common);
3381
- const open = this.expandedCats.has(c.name);
3382
- const head = `<button class="uiv-sectitle uiv-catacc${open ? "" : " collapsed"}" data-cat="${escapeAttr(c.name)}"><span class="uiv-chev">${ICONS.chevron}</span>${c.name} <span class="uiv-catn">${common.length}</span></button>`;
3383
- let body = "";
3384
- if (open) {
3385
- const showAll = this.showAllCats.has(c.name);
3386
- body = this.renderCommonControls(showAll ? avail : common);
3387
- if (!showAll && avail.length > common.length)
3388
- body += `<button class="uiv-showall" data-cat="${escapeAttr(c.name)}">+ ${avail.length - common.length} more</button>`;
3389
- }
3390
- return `<div class="uiv-sec">${head}${body}</div>`;
3391
- }).filter(Boolean).join("");
3392
- return search + cats;
3393
- }
3394
- /** Render a property list: box-groups (inset etc.) as a 4-sided editor, the rest
3395
- * as smart inputs. Reuses the tested box control + the generic field. */
3396
- renderCommonControls(props) {
3397
- const reg = cssRegistry();
3398
- const boxGroups = {};
3399
- const singles = [];
3400
- for (const p of props) {
3401
- const m = reg.byProp.get(p);
3402
- if (m.box && BOX_SIDES[m.box] && !m.shorthand) boxGroups[m.box] = true;
3403
- else singles.push(p);
3404
- }
3405
- let html = "";
3406
- for (const g of Object.keys(boxGroups)) html += this.boxGroupControl(g);
3407
- for (const p of singles) html += this.genericRow(reg.byProp.get(p));
3408
- return html;
3409
- }
3410
- /** A 4-sided box editor for a box group (inset/padding/…), via the curated control. */
3411
- boxGroupControl(group) {
3412
- const sides = BOX_SIDES[group];
3413
- if (!sides) return "";
3414
- const icon = group === "radius" ? ICONS.radius : group === "border-width" ? ICONS.border : group === "margin" ? ICONS.margin : group === "inset" ? ICONS.margin : ICONS.padding;
3415
- const label = { inset: "Inset", padding: "Padding", margin: "Margin", radius: "Radius", "border-width": "Border" }[group] || group;
3416
- return this.controlRow({ kind: "box", key: `g-${group}`, label, icon, sides });
3417
- }
3418
- genericRow(m) {
3419
- const prop = m.property;
3420
- return `<div class="uiv-ctl uiv-gctl${this.controlStateClass([prop])}"><span class="clabel uiv-gplabel" title="${escapeAttr(prop)}">${escapeHtml(prop)}</span><div class="cfield">${this.genericField(m)}</div></div>`;
3421
- }
3422
- /** Smart input for one property, by its registry type. Commits via the engine. */
3423
- genericField(m) {
3424
- const prop = m.property;
3425
- const cur = this.liveVal(prop);
3426
- const da = `data-gprop="${escapeAttr(prop)}"`;
3427
- if (m.type === "enum" && m.keywords && m.keywords.length) {
3428
- const c = cur.trim();
3429
- const list = c && !m.keywords.includes(c) ? [c, ...m.keywords] : m.keywords;
3430
- const opts = list.map((k) => `<option value="${escapeAttr(k)}"${k === c ? " selected" : ""}>${escapeHtml(k)}</option>`).join("");
3431
- return `<select class="uiv-gsel" ${da}>${opts}</select>`;
3432
- }
3433
- if (m.type === "color") {
3434
- return `<div class="uiv-gcolorwrap"><input type="color" class="uiv-gcolor" ${da} value="${toHexInput(cur)}"><input type="text" class="uiv-gtext uiv-gtextc" ${da} value="${escapeAttr(cur)}" placeholder="\u2014" spellcheck="false"></div>`;
3435
- }
3436
- const complex = (m.type === "shorthand" || m.shorthand || /^grid-template/.test(prop)) && !this.isChanged([prop]);
3437
- const val = complex ? "" : cur;
3438
- const ph = complex && cur ? escapeAttr(cur) : "\u2014";
3439
- const numeric = m.type === "length" || m.type === "number" || m.type === "integer" || m.type === "percentage" || m.type === "time" || m.type === "angle";
3440
- if (numeric) {
3441
- return `<div class="uiv-gnum"><span class="uiv-scrub uiv-gscrub" ${da} title="Drag to change">${ICONS.size}</span><input type="text" class="uiv-gtext" ${da} value="${escapeAttr(val)}" placeholder="${ph}" spellcheck="false"></div>`;
3442
- }
3443
- return `<input type="text" class="uiv-gtext uiv-gtextonly" ${da} value="${escapeAttr(val)}" placeholder="${ph}" spellcheck="false">`;
3444
- }
3445
- /** Bind the "All CSS" search, category toggles and generic inputs. */
3446
- bindGeneric() {
3447
- const root = this.root;
3448
- const search = root.querySelector(".uiv-csssearch");
3449
- if (search) {
3450
- search.addEventListener("input", () => {
3451
- const pos = search.selectionStart ?? search.value.length;
3452
- this.cssSearch = search.value;
3453
- this.renderBody();
3454
- const s2 = this.root.querySelector(".uiv-csssearch");
3455
- if (s2) {
3456
- s2.focus();
3457
- s2.setSelectionRange(pos, pos);
3458
- }
3459
- });
3460
- }
3461
- root.querySelectorAll(".uiv-catacc").forEach((node) => {
3462
- const btn = node;
3463
- const cat = btn.getAttribute("data-cat");
3464
- btn.addEventListener("click", () => {
3465
- if (this.expandedCats.has(cat)) this.expandedCats.delete(cat);
3466
- else this.expandedCats.add(cat);
3467
- this.renderBody();
3468
- });
3469
- });
3470
- root.querySelectorAll(".uiv-showall").forEach((node) => {
3471
- const btn = node;
3472
- const cat = btn.getAttribute("data-cat");
3473
- btn.addEventListener("click", () => {
3474
- this.showAllCats.add(cat);
3475
- this.renderBody();
3476
- });
3477
- });
3478
- const commit = (prop, value) => {
3479
- this.pushHistory();
3480
- this.commitValue([prop], value, true);
3481
- };
3482
- root.querySelectorAll(".uiv-gsel").forEach((node) => {
3483
- const sel = node;
3484
- sel.addEventListener("change", () => commit(sel.getAttribute("data-gprop"), sel.value));
3485
- });
3486
- root.querySelectorAll(".uiv-gcolor").forEach((node) => {
3487
- const inp = node;
3488
- const prop = inp.getAttribute("data-gprop");
3489
- inp.addEventListener("change", () => {
3490
- if (inp.value.toLowerCase() === toHexInput(this.liveVal(prop)).toLowerCase()) return;
3491
- commit(prop, inp.value);
3492
- });
3493
- });
3494
- root.querySelectorAll(".uiv-gtext").forEach((node) => {
3495
- const inp = node;
3496
- inp.addEventListener("change", () => commit(inp.getAttribute("data-gprop"), inp.value));
3497
- inp.addEventListener("keydown", (e) => {
3498
- if (e.key === "Enter") inp.blur();
3499
- });
3500
- });
3501
- root.querySelectorAll(".uiv-gscrub").forEach((node) => {
3502
- const handle = node;
3503
- const prop = handle.getAttribute("data-gprop");
3504
- const input = handle.parentElement.querySelector("input");
3505
- this.bindGenericScrub(handle, input, prop);
3506
- });
3507
- }
3508
- /** Default unit for a numeric property when the current value carries none —
3509
- * from the registry type, so a unitless number never gets a bogus "px". */
3510
- defaultUnit(prop) {
3511
- const t = cssMeta(prop)?.type;
3512
- if (t === "number" || t === "integer") return "";
3513
- if (t === "time") return "s";
3514
- if (t === "angle") return "deg";
3515
- if (t === "percentage") return "%";
3516
- return "px";
3517
- }
3518
- bindGenericScrub(handle, input, prop) {
3519
- handle.addEventListener("pointerdown", (e) => {
3520
- e.preventDefault();
3521
- const startX = e.clientX;
3522
- const m = /^(-?\d*\.?\d+)(\D*)$/.exec(input.value.trim());
3523
- const start2 = m ? parseFloat(m[1]) : 0;
3524
- const unit = m && m[2] ? m[2] : this.defaultUnit(prop);
3525
- const unitless = unit === "";
3526
- const step = unitless ? cssMeta(prop)?.type === "integer" ? 1 : 0.01 : 1;
3527
- let pushed = false;
3528
- try {
3529
- handle.setPointerCapture(e.pointerId);
3530
- } catch {
3531
- }
3532
- const move = (ev) => {
3533
- if (!pushed) {
3534
- this.pushHistory();
3535
- pushed = true;
3536
- }
3537
- let nv = start2 + Math.round(ev.clientX - startX) * step;
3538
- if (ev.shiftKey) nv = Math.round(nv / (10 * step)) * 10 * step;
3539
- nv = +nv.toFixed(unitless && step < 1 ? 2 : 0);
3540
- input.value = `${nv}${unit}`;
3541
- this.liveSet([prop], input.value);
3542
- };
3543
- const up = () => {
3544
- handle.removeEventListener("pointermove", move);
3545
- handle.removeEventListener("pointerup", up);
3546
- this.recordProps([prop]);
3547
- };
3548
- handle.addEventListener("pointermove", move);
3549
- handle.addEventListener("pointerup", up);
3550
- });
3551
- }
3552
2869
  bindControls() {
3553
2870
  const root = this.root;
3554
- this.bindGeneric();
3555
- root.querySelectorAll(".uiv-tbtn").forEach((node) => {
2871
+ root.querySelectorAll(".uiv-fbtn").forEach((node) => {
3556
2872
  const btn = node;
3557
2873
  const prop = btn.getAttribute("data-prop");
3558
2874
  const val = btn.getAttribute("data-val");
@@ -3620,7 +2936,7 @@ var Uivisor = class {
3620
2936
  const cssVar = btn.getAttribute("data-var");
3621
2937
  btn.addEventListener("mousedown", (e) => {
3622
2938
  e.preventDefault();
3623
- const token = this.designSystem().tokens.find((t) => t.cssVar === cssVar);
2939
+ const token = this.designSystem().tokens.find((t2) => t2.cssVar === cssVar);
3624
2940
  if (token) this.applyToken(this.lastBmSide, token);
3625
2941
  });
3626
2942
  });
@@ -3676,7 +2992,7 @@ var Uivisor = class {
3676
2992
  const css = sel.getAttribute("data-css");
3677
2993
  sel.addEventListener("change", () => {
3678
2994
  if (!sel.value) return;
3679
- const token = this.designSystem().tokens.find((t) => t.cssVar === sel.value);
2995
+ const token = this.designSystem().tokens.find((t2) => t2.cssVar === sel.value);
3680
2996
  if (token) this.applyToken(css, token);
3681
2997
  });
3682
2998
  });
@@ -3685,7 +3001,7 @@ var Uivisor = class {
3685
3001
  const css = btn.getAttribute("data-css");
3686
3002
  const cssVar = btn.getAttribute("data-var");
3687
3003
  btn.addEventListener("click", () => {
3688
- const token = this.designSystem().tokens.find((t) => t.cssVar === cssVar);
3004
+ const token = this.designSystem().tokens.find((t2) => t2.cssVar === cssVar);
3689
3005
  if (token) this.applyToken(css, token);
3690
3006
  });
3691
3007
  });
@@ -3719,23 +3035,25 @@ var Uivisor = class {
3719
3035
  const btn = node;
3720
3036
  const bp = btn.getAttribute("data-bp");
3721
3037
  btn.addEventListener("click", () => {
3722
- const w = bp === "base" ? this.baseFrameWidth() : this.bpSystem().breakpoints.find((b) => b.name === bp)?.minWidth ?? 768;
3723
- this.setFrameWidth(w);
3038
+ this.pickedBp = bp;
3039
+ this.setFrameWidth(bp === "base" ? this.baseFrameWidth() : this.scopeWidth(bp));
3724
3040
  this.reapplyScope();
3725
3041
  this.renderBody();
3726
3042
  });
3727
3043
  });
3728
- root.querySelectorAll(".uiv-clschip").forEach((node) => {
3729
- const btn = node;
3730
- const target = btn.getAttribute("data-target");
3731
- btn.addEventListener("click", () => {
3044
+ const targetSel = root.querySelector(".uiv-targetsel");
3045
+ if (targetSel) {
3046
+ targetSel.addEventListener("change", () => {
3732
3047
  const st = this.st();
3733
- if (st && st.record.target !== target) this.pushHistory();
3734
- if (st) st.record.target = target;
3048
+ if (!st) return;
3049
+ const next = targetSel.value === "__new__" ? st.record.target.startsWith("new:") ? st.record.target : "new:" : targetSel.value;
3050
+ if (st.record.target !== next) this.pushHistory();
3051
+ st.record.target = next;
3735
3052
  this.reapplyForTarget();
3736
3053
  this.renderBody();
3054
+ if (next === "new:") this.root.querySelector(".uiv-newclass")?.focus();
3737
3055
  });
3738
- });
3056
+ }
3739
3057
  root.querySelectorAll(".uiv-newclass").forEach((node) => {
3740
3058
  const input = node;
3741
3059
  input.addEventListener("change", () => {
@@ -3891,13 +3209,13 @@ var Uivisor = class {
3891
3209
  }
3892
3210
  async copyPrompt() {
3893
3211
  const recs = this.records();
3894
- if (!recs.length) return this.showToast("No tweaks recorded yet");
3212
+ if (!recs.length) return this.showToast(t("No tweaks recorded yet"));
3895
3213
  await this.copy(renderPrompt(recs));
3896
- this.showToast("Prompt copied \u2713");
3214
+ this.showToast(t("Prompt copied \u2713"));
3897
3215
  }
3898
3216
  async copyJSON() {
3899
3217
  const recs = this.records();
3900
- if (!recs.length) return this.showToast("No tweaks recorded yet");
3218
+ if (!recs.length) return this.showToast(t("No tweaks recorded yet"));
3901
3219
  const spec = renderSpec(recs, {
3902
3220
  url: location.href,
3903
3221
  width: window.innerWidth,
@@ -3906,7 +3224,7 @@ var Uivisor = class {
3906
3224
  now: (/* @__PURE__ */ new Date()).toISOString()
3907
3225
  });
3908
3226
  await this.copy(JSON.stringify(spec, null, 2));
3909
- this.showToast("JSON copied \u2713");
3227
+ this.showToast(t("JSON copied \u2713"));
3910
3228
  }
3911
3229
  resetSelected() {
3912
3230
  const el = this.selected;
@@ -3970,16 +3288,16 @@ var Uivisor = class {
3970
3288
  this.renderBody();
3971
3289
  }
3972
3290
  undo() {
3973
- if (!this.undoStack.length) return this.showToast("Nothing to undo");
3291
+ if (!this.undoStack.length) return this.showToast(t("Nothing to undo"));
3974
3292
  this.redoStack.push(this.cloneSnap());
3975
3293
  this.applySnap(this.undoStack.pop());
3976
- this.showToast("Undo \u21A9");
3294
+ this.showToast(t("Undo \u21A9"));
3977
3295
  }
3978
3296
  redo() {
3979
- if (!this.redoStack.length) return this.showToast("Nothing to redo");
3297
+ if (!this.redoStack.length) return this.showToast(t("Nothing to redo"));
3980
3298
  this.undoStack.push(this.cloneSnap());
3981
3299
  this.applySnap(this.redoStack.pop());
3982
- this.showToast("Redo \u21AA");
3300
+ this.showToast(t("Redo \u21AA"));
3983
3301
  }
3984
3302
  async copy(text) {
3985
3303
  try {