@takazudo/zdtp 0.1.0-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/CHANGELOG.md +107 -0
  2. package/LICENSE +21 -0
  3. package/README.md +1044 -0
  4. package/dist/apply/apply-token-overrides.d.ts +81 -0
  5. package/dist/apply/apply-token-overrides.d.ts.map +1 -0
  6. package/dist/apply/build-apply-overrides.d.ts +71 -0
  7. package/dist/apply/build-apply-overrides.d.ts.map +1 -0
  8. package/dist/apply/route-tokens-to-files.d.ts +65 -0
  9. package/dist/apply/route-tokens-to-files.d.ts.map +1 -0
  10. package/dist/apply/tier-resolver.d.ts +75 -0
  11. package/dist/apply/tier-resolver.d.ts.map +1 -0
  12. package/dist/apply-modal.d.ts +49 -0
  13. package/dist/apply-modal.d.ts.map +1 -0
  14. package/dist/astro/DesignTokenPanelHost.astro +76 -0
  15. package/dist/astro/host-adapter.d.ts +47 -0
  16. package/dist/astro/host-adapter.d.ts.map +1 -0
  17. package/dist/astro/host-adapter.js +81 -0
  18. package/dist/astro/index.d.ts +30 -0
  19. package/dist/astro/index.d.ts.map +1 -0
  20. package/dist/astro/index.js +54 -0
  21. package/dist/bin/cors.d.ts +24 -0
  22. package/dist/bin/cors.d.ts.map +1 -0
  23. package/dist/bin/parse-args.d.ts +38 -0
  24. package/dist/bin/parse-args.d.ts.map +1 -0
  25. package/dist/bin/server.d.ts +23 -0
  26. package/dist/bin/server.d.ts.map +1 -0
  27. package/dist/bin/server.js +283 -0
  28. package/dist/color-schemes-CgzOBqGO.js +85 -0
  29. package/dist/components/color-picker/color-picker.d.ts +64 -0
  30. package/dist/components/color-picker/color-picker.d.ts.map +1 -0
  31. package/dist/components/color-picker/custom-slider.d.ts +25 -0
  32. package/dist/components/color-picker/custom-slider.d.ts.map +1 -0
  33. package/dist/components/color-picker/index.d.ts +3 -0
  34. package/dist/components/color-picker/index.d.ts.map +1 -0
  35. package/dist/config/cluster-config.d.ts +135 -0
  36. package/dist/config/cluster-config.d.ts.map +1 -0
  37. package/dist/config/color-scheme-utils.d.ts +105 -0
  38. package/dist/config/color-scheme-utils.d.ts.map +1 -0
  39. package/dist/config/color-schemes.d.ts +83 -0
  40. package/dist/config/color-schemes.d.ts.map +1 -0
  41. package/dist/config/panel-config.d.ts +258 -0
  42. package/dist/config/panel-config.d.ts.map +1 -0
  43. package/dist/controls/pill-slider-row.d.ts +37 -0
  44. package/dist/controls/pill-slider-row.d.ts.map +1 -0
  45. package/dist/controls/role-button.d.ts +18 -0
  46. package/dist/controls/role-button.d.ts.map +1 -0
  47. package/dist/controls/sanitize-css-value.d.ts +22 -0
  48. package/dist/controls/sanitize-css-value.d.ts.map +1 -0
  49. package/dist/controls/select-row.d.ts +26 -0
  50. package/dist/controls/select-row.d.ts.map +1 -0
  51. package/dist/controls/slider-row.d.ts +34 -0
  52. package/dist/controls/slider-row.d.ts.map +1 -0
  53. package/dist/controls/text-row.d.ts +28 -0
  54. package/dist/controls/text-row.d.ts.map +1 -0
  55. package/dist/controls/tier-ref-selector.d.ts +33 -0
  56. package/dist/controls/tier-ref-selector.d.ts.map +1 -0
  57. package/dist/controls/tooltip.d.ts +44 -0
  58. package/dist/controls/tooltip.d.ts.map +1 -0
  59. package/dist/export-modal.d.ts +33 -0
  60. package/dist/export-modal.d.ts.map +1 -0
  61. package/dist/highlight/find-elements.d.ts +113 -0
  62. package/dist/highlight/find-elements.d.ts.map +1 -0
  63. package/dist/highlight/highlight-orchestrator.d.ts +24 -0
  64. package/dist/highlight/highlight-orchestrator.d.ts.map +1 -0
  65. package/dist/highlight/highlight-overlay.d.ts +43 -0
  66. package/dist/highlight/highlight-overlay.d.ts.map +1 -0
  67. package/dist/highlight/highlight-settings-popover.d.ts +25 -0
  68. package/dist/highlight/highlight-settings-popover.d.ts.map +1 -0
  69. package/dist/highlight/highlight-state.d.ts +87 -0
  70. package/dist/highlight/highlight-state.d.ts.map +1 -0
  71. package/dist/highlight/highlight-toggle-button.d.ts +34 -0
  72. package/dist/highlight/highlight-toggle-button.d.ts.map +1 -0
  73. package/dist/import-modal.d.ts +33 -0
  74. package/dist/import-modal.d.ts.map +1 -0
  75. package/dist/index.d.ts +105 -0
  76. package/dist/index.d.ts.map +1 -0
  77. package/dist/index.js +5480 -0
  78. package/dist/load-routing-XyKgftpe.js +353 -0
  79. package/dist/manifest-DCReQE0k.js +24 -0
  80. package/dist/panel-config-DP2_P7dD.js +332 -0
  81. package/dist/panel.d.ts +3 -0
  82. package/dist/panel.d.ts.map +1 -0
  83. package/dist/route-tokens-to-files-1DvmWBdj.js +41 -0
  84. package/dist/server/create-apply-handler.d.ts +48 -0
  85. package/dist/server/create-apply-handler.d.ts.map +1 -0
  86. package/dist/server/index.d.ts +24 -0
  87. package/dist/server/index.d.ts.map +1 -0
  88. package/dist/server/index.js +10 -0
  89. package/dist/server/load-routing.d.ts +39 -0
  90. package/dist/server/load-routing.d.ts.map +1 -0
  91. package/dist/server/path-safety.d.ts +36 -0
  92. package/dist/server/path-safety.d.ts.map +1 -0
  93. package/dist/server/serialize-write.d.ts +7 -0
  94. package/dist/server/serialize-write.d.ts.map +1 -0
  95. package/dist/state/persist.d.ts +39 -0
  96. package/dist/state/persist.d.ts.map +1 -0
  97. package/dist/state/tweak-state.d.ts +344 -0
  98. package/dist/state/tweak-state.d.ts.map +1 -0
  99. package/dist/tabs/_generic-item-editor.d.ts +23 -0
  100. package/dist/tabs/_generic-item-editor.d.ts.map +1 -0
  101. package/dist/tabs/color-tab.d.ts +55 -0
  102. package/dist/tabs/color-tab.d.ts.map +1 -0
  103. package/dist/tabs/font-tab.d.ts +22 -0
  104. package/dist/tabs/font-tab.d.ts.map +1 -0
  105. package/dist/tabs/generic-tab.d.ts +43 -0
  106. package/dist/tabs/generic-tab.d.ts.map +1 -0
  107. package/dist/tabs/size-tab.d.ts +20 -0
  108. package/dist/tabs/size-tab.d.ts.map +1 -0
  109. package/dist/tabs/spacing-tab.d.ts +23 -0
  110. package/dist/tabs/spacing-tab.d.ts.map +1 -0
  111. package/dist/testing.d.ts +81 -0
  112. package/dist/testing.d.ts.map +1 -0
  113. package/dist/testing.js +23 -0
  114. package/dist/tokens/manifest.d.ts +148 -0
  115. package/dist/tokens/manifest.d.ts.map +1 -0
  116. package/dist/tokens/tier-model.d.ts +89 -0
  117. package/dist/tokens/tier-model.d.ts.map +1 -0
  118. package/dist/tweak-state-DSJa5csL.js +624 -0
  119. package/dist/utils/color-convert.d.ts +7 -0
  120. package/dist/utils/color-convert.d.ts.map +1 -0
  121. package/dist/utils/color-hsla.d.ts +9 -0
  122. package/dist/utils/color-hsla.d.ts.map +1 -0
  123. package/dist/utils/color-oklch.d.ts +51 -0
  124. package/dist/utils/color-oklch.d.ts.map +1 -0
  125. package/dist/utils/design-token-serde.d.ts +193 -0
  126. package/dist/utils/design-token-serde.d.ts.map +1 -0
  127. package/dist/utils/structural-equal.d.ts +22 -0
  128. package/dist/utils/structural-equal.d.ts.map +1 -0
  129. package/dist/zdtp.css +1 -0
  130. package/package.json +102 -0
@@ -0,0 +1,193 @@
1
+ /**
2
+ * Design-token SerDe — unified JSON export / import for the design-token panel.
3
+ *
4
+ * Supersedes the legacy flat-cssVar-map v1 serde. The JSON format is a single
5
+ * document covering all token categories (color, spacing, typography/font, size)
6
+ * so an AI assistant can consume or emit a whole design-token tweak in one
7
+ * round-trip.
8
+ *
9
+ * ## Schema versioning
10
+ *
11
+ * | `$schema` value | Status | Structure |
12
+ * |----------------------------|----------|------------------------------------------|
13
+ * | `zudo-design-tokens/v1` | Legacy | Flat top-level `color`/`spacing`/`typography`/`size` keys |
14
+ * | `zudo-design-tokens/v2` | Current | `tabs` wrapper keyed by tab id; cssVar-keyed leaves |
15
+ *
16
+ * `serialize()` always emits v2. `deserialize()` accepts both v1 and v2 and
17
+ * normalises to an internal `TweakState` regardless of which schema was in the
18
+ * payload. Hosts that export v1 docs (custom `schemaId`) get a `schema-mismatch`
19
+ * error on import unless they have opted into the dual-accept path (see below).
20
+ *
21
+ * ## v2 format
22
+ *
23
+ * ```jsonc
24
+ * {
25
+ * "$schema": "zudo-design-tokens/v2",
26
+ * "exportedAt": "...",
27
+ * "tabs": {
28
+ * "spacing": {
29
+ * "raw": { "--zfb-spacing-md": "1.25rem" }
30
+ * },
31
+ * "font": {
32
+ * "raw": { "--zfb-scale-base": "1rem" },
33
+ * "semantic": { "--zfb-text-base": "var(--zfb-scale-base)" }
34
+ * },
35
+ * "color": {
36
+ * "palette": { "--zfb-palette-1": "#2d6cdf" },
37
+ * "semantic": { "--zfb-color-primary": 1 } // palette-index integer
38
+ * }
39
+ * }
40
+ * }
41
+ * ```
42
+ *
43
+ * Key decisions (issue #74):
44
+ * - cssVar-keyed leaves for portability across host id renames.
45
+ * - Tier-2 ref values are stored as the literal `var(--tier1-cssvar)` CSS
46
+ * string (no discriminated union — keeps the format flat and hand-editable).
47
+ * - Color `semantic` values are palette-index integers (preserved from v1 so
48
+ * the swatch UI can render the resolved color).
49
+ *
50
+ * ## Diff-only by default
51
+ *
52
+ * `serialize()` only emits tokens the user has actually changed relative to the
53
+ * provided `colorDefaults` (for the color block) and the manifest defaults (for
54
+ * spacing / typography / size). Pass `includeDefaults: true` to dump the full
55
+ * state instead. A tab key is omitted entirely when nothing in it differs.
56
+ *
57
+ * ## cssVar keys
58
+ *
59
+ * Spacing / typography / size overrides use CSS variable names
60
+ * (`"--zd-spacing-hgap-md"`) — the external schema — rather than the internal
61
+ * token id (`"hsp-md"`). This keeps the file human-readable and agnostic of our
62
+ * internal manifest. `deserialize()` maps them back; unknown CSS vars are
63
+ * reported via `unknownTokens` so the UI can surface them.
64
+ *
65
+ * Read-only manifest tokens are skipped in both directions.
66
+ */
67
+ import type { ColorTweakState, TweakState } from '../state/tweak-state';
68
+ /** The canonical v2 schema identifier emitted by serialize(). */
69
+ export declare const SCHEMA_V2 = "zudo-design-tokens/v2";
70
+ /** The legacy v1 schema identifier accepted by deserialize() for back-compat. */
71
+ export declare const SCHEMA_V1 = "zudo-design-tokens/v1";
72
+ /**
73
+ * Read the active design-token schema id at call time.
74
+ *
75
+ * Returns the host-configured schema id from `panelConfig.schemaId`. Used as
76
+ * the `$schema` value in legacy v1 exports (for hosts that have not upgraded
77
+ * their config to v2). The canonical v2 serialize path always emits `SCHEMA_V2`.
78
+ */
79
+ export declare function getDesignTokenSchema(): string;
80
+ /** External JSON value for a base-color / semantic-color entry (v1). */
81
+ type ColorSlotValue = number | 'bg' | 'fg';
82
+ export interface DesignTokenJsonColorBase {
83
+ bg?: number;
84
+ fg?: number;
85
+ cursor?: number;
86
+ /** Dashed keys mirror the external docs; they are quoted in source. */
87
+ 'sel-bg'?: number;
88
+ 'sel-fg'?: number;
89
+ }
90
+ export interface DesignTokenJsonColor {
91
+ palette?: string[];
92
+ base?: DesignTokenJsonColorBase;
93
+ /** Palette-index (or "bg"/"fg") mappings, same keys as `SEMANTIC_DEFAULTS`. */
94
+ semantic?: Record<string, ColorSlotValue>;
95
+ shikiTheme?: string;
96
+ }
97
+ /** External token map keyed by CSS var name. */
98
+ export type DesignTokenJsonOverrides = Record<string, string>;
99
+ /** Legacy v1 external JSON document shape. */
100
+ export interface DesignTokenJson {
101
+ $schema: string;
102
+ exportedAt: string;
103
+ color?: DesignTokenJsonColor;
104
+ spacing?: DesignTokenJsonOverrides;
105
+ typography?: DesignTokenJsonOverrides;
106
+ size?: DesignTokenJsonOverrides;
107
+ }
108
+ /**
109
+ * A single tier's cssVar-keyed overrides.
110
+ *
111
+ * For token tiers (spacing/font/size raw): values are CSS length/value strings.
112
+ * For reference tiers (font semantic, etc.): values are `var(--tier1-cssvar)` strings.
113
+ * For color palette: values are hex color strings.
114
+ * For color semantic: values are palette-index integers.
115
+ */
116
+ export type V2TierMap = Record<string, string | number>;
117
+ /** Per-tab overrides in v2 format. Key is tier id. */
118
+ export type V2TabEntry = Record<string, V2TierMap>;
119
+ /** v2 external JSON document shape. */
120
+ export interface DesignTokenJsonV2 {
121
+ $schema: string;
122
+ exportedAt: string;
123
+ tabs?: Record<string, V2TabEntry>;
124
+ }
125
+ export interface SerializeOptions {
126
+ /** When true, dump full state (all palette entries, all token manifest
127
+ * defaults merged in). Default: diff-only. */
128
+ includeDefaults?: boolean;
129
+ /** Color baseline to diff against — typically the current scheme's initial
130
+ * state. Required for meaningful color-diff output; callers that don't have
131
+ * it available (e.g. tests without DOM) can omit it and we'll treat the
132
+ * whole color block as changed. */
133
+ colorDefaults?: ColorTweakState;
134
+ /** Override the `exportedAt` stamp (test-only). */
135
+ now?: () => Date;
136
+ }
137
+ export interface DeserializeResult {
138
+ /** The reconstructed tweak state, with unknown-token values dropped. */
139
+ state: TweakState;
140
+ /** CSS var names present in the payload that don't match any known token. */
141
+ unknownTokens: string[];
142
+ /** Human-readable errors that did not prevent a state from being produced
143
+ * (e.g. "semantic mapping dropped because value isn't a number"). */
144
+ warnings: string[];
145
+ }
146
+ export interface DeserializeOptions {
147
+ /** Color baseline used to fill in fields absent from the payload (diff-only
148
+ * exports are missing most fields by design). Typically the current
149
+ * scheme's initial state. */
150
+ colorDefaults?: ColorTweakState;
151
+ }
152
+ /**
153
+ * Thrown when the payload is not a v1 or v2 schema object. The error `.reason`
154
+ * helps the UI render a precise inline message.
155
+ *
156
+ * Note: `schema-mismatch` is thrown only when the schema is present but does
157
+ * not match either the v1 or v2 schema. v1 schemas are silently accepted and
158
+ * lifted to v2 internally.
159
+ */
160
+ export declare class DesignTokenSchemaError extends Error {
161
+ readonly reason: 'not-object' | 'schema-missing' | 'schema-mismatch';
162
+ readonly actualSchema?: unknown;
163
+ constructor(reason: 'not-object' | 'schema-missing' | 'schema-mismatch', message: string, actualSchema?: unknown);
164
+ }
165
+ /**
166
+ * Produce the external JSON document (v2 format) for a given tweak state.
167
+ *
168
+ * By default this is diff-only against `opts.colorDefaults` + manifest
169
+ * defaults; set `opts.includeDefaults = true` to dump everything.
170
+ *
171
+ * The output `$schema` is always `SCHEMA_V2` ("zudo-design-tokens/v2").
172
+ */
173
+ export declare function serialize(state: TweakState, opts?: SerializeOptions): DesignTokenJsonV2;
174
+ /**
175
+ * Parse a design-token JSON document and lift it back into a tweak state.
176
+ *
177
+ * Accepted schema values:
178
+ * - `SCHEMA_V2` ("zudo-design-tokens/v2") — parsed directly.
179
+ * - `SCHEMA_V1` ("zudo-design-tokens/v1") — lifted to equivalent internal
180
+ * state (one-way migration; v1 is no longer a valid OUTPUT format).
181
+ * - Any other value (including custom host schema ids) — throws
182
+ * `DesignTokenSchemaError` with reason `schema-mismatch`.
183
+ *
184
+ * Throws `DesignTokenSchemaError` on schema mismatch / non-object input. Any
185
+ * CSS var name that doesn't match a known manifest entry is collected into
186
+ * `unknownTokens` (the caller can surface these as a warning).
187
+ *
188
+ * Missing fields fall back to `opts.colorDefaults` (or, absent that, a
189
+ * minimal neutral default) so the result is always a valid `TweakState`.
190
+ */
191
+ export declare function deserialize(input: unknown, opts?: DeserializeOptions): DeserializeResult;
192
+ export {};
193
+ //# sourceMappingURL=design-token-serde.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"design-token-serde.d.ts","sourceRoot":"","sources":["../../src/utils/design-token-serde.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiEG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAkB,UAAU,EAAE,MAAM,sBAAsB,CAAC;AA4BxF,iEAAiE;AACjE,eAAO,MAAM,SAAS,0BAA0B,CAAC;AAEjD,iFAAiF;AACjF,eAAO,MAAM,SAAS,0BAA0B,CAAC;AAWjD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAMD,wEAAwE;AACxE,KAAK,cAAc,GAAG,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;AAE3C,MAAM,WAAW,wBAAwB;IACvC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uEAAuE;IACvE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,IAAI,CAAC,EAAE,wBAAwB,CAAC;IAChC,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,gDAAgD;AAChD,MAAM,MAAM,wBAAwB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE9D,8CAA8C;AAC9C,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,oBAAoB,CAAC;IAC7B,OAAO,CAAC,EAAE,wBAAwB,CAAC;IACnC,UAAU,CAAC,EAAE,wBAAwB,CAAC;IACtC,IAAI,CAAC,EAAE,wBAAwB,CAAC;CACjC;AAMD;;;;;;;GAOG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;AAExD,sDAAsD;AACtD,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAEnD,uCAAuC;AACvC,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CACnC;AAMD,MAAM,WAAW,gBAAgB;IAC/B;mDAC+C;IAC/C,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;wCAGoC;IACpC,aAAa,CAAC,EAAE,eAAe,CAAC;IAChC,mDAAmD;IACnD,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,wEAAwE;IACxE,KAAK,EAAE,UAAU,CAAC;IAClB,6EAA6E;IAC7E,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB;0EACsE;IACtE,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC;;kCAE8B;IAC9B,aAAa,CAAC,EAAE,eAAe,CAAC;CACjC;AAED;;;;;;;GAOG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,QAAQ,CAAC,MAAM,EAAE,YAAY,GAAG,gBAAgB,GAAG,iBAAiB,CAAC;IACrE,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;gBAE9B,MAAM,EAAE,YAAY,GAAG,gBAAgB,GAAG,iBAAiB,EAC3D,OAAO,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,OAAO;CAUzB;AAMD;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,GAAE,gBAAqB,GAAG,iBAAiB,CA8B3F;AAyGD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,GAAE,kBAAuB,GAAG,iBAAiB,CA4B5F"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Structural deep-equality for plain JSON-shaped values.
3
+ *
4
+ * Used by `configurePanel`'s re-init guard so a
5
+ * second `configurePanel(parsedConfig)` call from Astro view-transition reruns
6
+ * — which produces a freshly-parsed object that is byte-for-byte identical to
7
+ * the previous one but referentially distinct — does not throw.
8
+ *
9
+ * Scope:
10
+ * - Primitives compared with `Object.is` (so `NaN === NaN` and `+0 !== -0`,
11
+ * matching the JSON serialization round-trip behaviour we care about).
12
+ * - Arrays compared element-wise (length-first short-circuit).
13
+ * - Plain objects compared key-set-then-value (own enumerable string keys).
14
+ * - Functions, class instances, Maps, Sets, Symbols are NOT supported. The
15
+ * panel config contract (PORTABLE-CONTRACT.md §1, §4.2) bans these from
16
+ * `PanelConfig`, so a structural compare that bails on them is fine.
17
+ *
18
+ * Returns `false` for any value that is `null` vs. non-null or whose typeof
19
+ * differs (string vs. number etc.).
20
+ */
21
+ export declare function structuralEqual(a: unknown, b: unknown): boolean;
22
+ //# sourceMappingURL=structural-equal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structural-equal.d.ts","sourceRoot":"","sources":["../../src/utils/structural-equal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAG,OAAO,CA6B/D"}
package/dist/zdtp.css ADDED
@@ -0,0 +1 @@
1
+ :where(.tokenpanel-shell,[data-design-token-panel-modal],.tokenpanel-highlight-settings-popover,.tokenpanel-color-picker){--tokentweak-color-fg: #b8b8b8;--tokentweak-color-bg: #181818;--tokentweak-color-muted: #888888;--tokentweak-color-surface: #1c1c1c;--tokentweak-color-accent: #d69a66;--tokentweak-color-accent-hover: #a7c0e3;--tokentweak-color-code-bg: #383838;--tokentweak-color-code-fg: #e0e0e0;--tokentweak-color-success: #93bb77;--tokentweak-color-danger: #da6871;--tokentweak-color-warning: #dfbb77;--tokentweak-font-mono: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--tokentweak-pad-2xs: .125rem;--tokentweak-pad-xs: .375rem;--tokentweak-pad-sm: .5rem;--tokentweak-pad-md: .75rem;--tokentweak-pad-lg: 1rem;--tokentweak-pad-xl: 1.5rem;--tokentweak-pad-2xl: 2rem;--tokentweak-gap-2xs: .4375rem;--tokentweak-gap-xs: .875rem;--tokentweak-gap-sm: 1.25rem;--tokentweak-gap-md: 1.5rem;--tokentweak-gap-lg: 1.75rem;--tokentweak-gap-xl: 2.5rem;--tokentweak-gap-2xl: 3.5rem;--tokentweak-text-micro: .75rem;--tokentweak-text-caption: .875rem;--tokentweak-text-small: 1rem;--tokentweak-text-body: 1.2rem;--tokentweak-text-subheading: 1.4rem;--tokentweak-text-heading: 3rem;--tokentweak-text-display: 3.75rem;--radius-tokentweak: .25rem}.tokenpanel-color-picker{position:fixed;width:320px;padding:var(--tokentweak-pad-md);background:var(--tokentweak-color-surface);border:1px solid var(--tokentweak-color-muted);border-radius:var(--radius-tokentweak);box-shadow:0 8px 24px #0006;display:flex;flex-direction:column;gap:var(--tokentweak-gap-2xs);z-index:70;color:var(--tokentweak-color-fg);font-size:var(--tokentweak-text-caption)}.tokenpanel-color-picker[data-mode-shell=expanded]{width:520px;padding:var(--tokentweak-pad-lg);gap:var(--tokentweak-gap-xs)}.tokenpanel-color-picker-header{display:flex;align-items:center;gap:var(--tokentweak-gap-2xs)}.tokenpanel-color-picker-drag-handle{flex-shrink:0;cursor:grab;color:var(--tokentweak-color-muted);font-size:var(--tokentweak-text-caption);line-height:1;padding:var(--tokentweak-pad-2xs);border-radius:var(--radius-tokentweak);-webkit-user-select:none;user-select:none;touch-action:none}.tokenpanel-color-picker-drag-handle:hover{color:var(--tokentweak-color-fg)}.tokenpanel-color-picker-drag-handle:active{cursor:grabbing}.tokenpanel-color-picker-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--tokentweak-color-fg);font-family:var(--tokentweak-font-mono);font-size:var(--tokentweak-text-caption)}.tokenpanel-color-picker-mode-toggle{display:flex;align-items:center;gap:2px;background:var(--tokentweak-color-bg);border:1px solid var(--tokentweak-color-muted);border-radius:999px;padding:2px;flex-shrink:0}.tokenpanel-color-picker-mode-btn{border-radius:999px;padding-inline:var(--tokentweak-pad-xs);padding-block:var(--tokentweak-pad-2xs);font-size:var(--tokentweak-text-micro);color:var(--tokentweak-color-muted);cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .12s ease,color .12s ease;white-space:nowrap}.tokenpanel-color-picker-mode-btn:hover{color:var(--tokentweak-color-fg)}.tokenpanel-color-picker-mode-btn[aria-pressed=true]{background-color:var(--tokentweak-color-accent);color:var(--tokentweak-color-fg)}.tokenpanel-color-picker-mode-btn:focus-visible{outline:2px solid var(--tokentweak-color-accent);outline-offset:2px}.tokenpanel-color-picker-expand-btn{flex-shrink:0;color:var(--tokentweak-color-muted);cursor:pointer;-webkit-user-select:none;user-select:none;padding:var(--tokentweak-pad-2xs);border-radius:var(--radius-tokentweak);transition:color .12s ease}.tokenpanel-color-picker-expand-btn:hover{color:var(--tokentweak-color-fg)}.tokenpanel-color-picker-expand-btn:focus-visible{outline:2px solid var(--tokentweak-color-accent);outline-offset:2px}.tokenpanel-color-picker-top-row{display:flex;align-items:center;gap:var(--tokentweak-gap-2xs)}.tokenpanel-color-picker-preview{position:relative;flex-shrink:0;width:3rem;height:3rem;border-radius:var(--radius-tokentweak);border:1px solid var(--tokentweak-color-muted);overflow:hidden}.tokenpanel-color-picker-preview-checkerboard{position:absolute;inset:0;background-image:repeating-conic-gradient(gray 0% 25%,silver 0% 50%);background-size:10px 10px}.tokenpanel-color-picker-preview-color{position:absolute;inset:0}.tokenpanel-color-picker-hex-input{flex:1;min-width:0;font-family:var(--tokentweak-font-mono);font-size:var(--tokentweak-text-caption);background:var(--tokentweak-color-bg);color:var(--tokentweak-color-fg);border:1px solid var(--tokentweak-color-muted);border-radius:var(--radius-tokentweak);padding:var(--tokentweak-pad-2xs) var(--tokentweak-pad-xs);transition:border-color .12s ease}.tokenpanel-color-picker-hex-input:hover{border-color:var(--tokentweak-color-fg)}.tokenpanel-color-picker-hex-input:focus{border-color:var(--tokentweak-color-accent);outline:none}.tokenpanel-color-picker-grid{display:grid;grid-template-columns:repeat(6,1fr);gap:2px}.tokenpanel-color-picker-grid>[role=row]{display:contents}.tokenpanel-color-picker[data-mode-shell=expanded] .tokenpanel-color-picker-grid{grid-template-columns:repeat(12,1fr)}.tokenpanel-color-picker-grid-cell{position:relative;aspect-ratio:1;border-radius:var(--radius-tokentweak);cursor:pointer;transition:box-shadow .12s ease}.tokenpanel-color-picker-grid-cell:hover{box-shadow:0 0 0 2px var(--tokentweak-color-fg)}.tokenpanel-color-picker-grid-cell[aria-selected=true]{box-shadow:0 0 0 2px var(--tokentweak-color-accent)}.tokenpanel-color-picker-grid-cell:focus-visible{outline:2px solid var(--tokentweak-color-accent);outline-offset:2px}.tokenpanel-color-picker-grid-cell[data-oog=true]:after{content:"";position:absolute;inset:1px;border:1px dashed oklch(98% 0 0 / .4);border-radius:var(--radius-tokentweak);pointer-events:none}.tokenpanel-color-picker-sliders{display:flex;flex-direction:column;gap:var(--tokentweak-gap-2xs)}.tokenpanel-color-picker-slider-row{display:flex;align-items:center;gap:var(--tokentweak-gap-2xs)}.tokenpanel-color-picker-slider-label{flex-shrink:0;width:1.25rem;font-size:var(--tokentweak-text-micro);color:var(--tokentweak-color-muted);-webkit-user-select:none;user-select:none}.tokenpanel-color-picker-slider{flex:1;position:relative;height:18px;display:flex;align-items:center;cursor:pointer;-webkit-user-select:none;user-select:none;touch-action:none}.tokenpanel-color-picker-slider:focus-visible{outline:2px solid var(--tokentweak-color-accent);outline-offset:2px;border-radius:var(--radius-tokentweak)}.tokenpanel-color-picker-slider-track{width:100%;height:18px;border-radius:9px;overflow:hidden;border:1px solid var(--tokentweak-color-muted)}.tokenpanel-color-picker-slider-thumb{position:absolute;top:50%;transform:translate(-50%,-50%);width:14px;height:14px;border-radius:50%;background:var(--tokentweak-color-fg);border:2px solid var(--tokentweak-color-bg);box-shadow:0 0 0 1px var(--tokentweak-color-muted);pointer-events:none}.tokenpanel-color-picker-slider-value{flex-shrink:0;width:3rem;text-align:right;font-family:var(--tokentweak-font-mono);font-size:var(--tokentweak-text-micro);color:var(--tokentweak-color-fg)}.tokenpanel-color-picker-readout{display:none;font-family:var(--tokentweak-font-mono);font-size:var(--tokentweak-text-micro);color:var(--tokentweak-color-muted);padding-top:var(--tokentweak-pad-2xs);border-top:1px solid var(--tokentweak-color-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.tokenpanel-color-picker[data-mode-shell=expanded] .tokenpanel-color-picker-readout{display:block}.tokenpanel-shell{z-index:50;display:flex;flex-direction:column;border:1px solid var(--tokentweak-color-muted);background-color:var(--tokentweak-color-surface);border-radius:var(--radius-tokentweak);box-shadow:0 4px 24px #00000040}.tokenpanel-resize-handle{position:absolute;right:2px;bottom:2px;width:16px;height:16px;cursor:nwse-resize;-webkit-user-select:none;user-select:none;background-image:repeating-linear-gradient(-45deg,transparent 0,transparent 2px,var(--tokentweak-color-muted) 2px,var(--tokentweak-color-muted) 3px);-webkit-mask-image:linear-gradient(135deg,transparent 50%,#000 50%);mask-image:linear-gradient(135deg,transparent 50%,#000 50%);border-bottom-right-radius:var(--radius-tokentweak);transition:opacity .15s ease;opacity:.7}.tokenpanel-resize-handle:hover,.tokenpanel-resize-handle:focus-visible{opacity:1}.tokenpanel-header{display:flex;align-items:center;gap:var(--tokentweak-pad-md);padding-inline:var(--tokentweak-pad-xl);padding-block:var(--tokentweak-gap-xs);border-bottom:1px solid var(--tokentweak-color-muted);flex-shrink:0}.tokenpanel-title{color:var(--tokentweak-color-fg);font-weight:600;font-size:.875rem;flex-shrink:0}.tokenpanel-action-link{color:var(--tokentweak-color-accent);font-size:.75rem;background:none;border:none;padding:0;cursor:pointer;transition:color .15s ease}.tokenpanel-action-link:hover{color:var(--tokentweak-color-accent-hover)}.tokenpanel-spacer{flex:1}.tokenpanel-close-btn{color:var(--tokentweak-color-muted);background:none;border:none;padding:0;cursor:pointer;flex-shrink:0;transition:color .15s ease;display:inline-flex;align-items:center;justify-content:center}.tokenpanel-close-btn:hover{color:var(--tokentweak-color-fg)}.tokenpanel-tabbar{display:flex;align-items:center;border-bottom:1px solid var(--tokentweak-color-muted);padding-inline:var(--tokentweak-pad-xl);flex-shrink:0;gap:var(--tokentweak-pad-md)}.tokenpanel-tabbar-tabs{display:flex;align-items:center;gap:2px;flex:1;min-width:0}.tokenpanel-tab-button{border:none;background:none;padding-inline:var(--tokentweak-pad-md);padding-block:var(--tokentweak-gap-xs);font-size:.875rem;cursor:pointer;border-bottom:2px solid transparent;color:var(--tokentweak-color-muted);transition:color .15s ease,border-color .15s ease}.tokenpanel-tab-button:hover,.tokenpanel-tab-button:focus-visible{color:var(--tokentweak-color-fg);text-decoration:underline}.tokenpanel-tab-button.is-active{color:var(--tokentweak-color-fg);border-bottom-color:var(--tokentweak-color-accent);text-decoration:none}.tokenpanel-density{display:flex;align-items:center;gap:var(--tokentweak-pad-sm);flex-shrink:0}.tokenpanel-density-label{color:var(--tokentweak-color-muted);font-size:.6875rem;text-transform:uppercase;letter-spacing:.05em;-webkit-user-select:none;user-select:none;cursor:pointer}.tokenpanel-density-slider{width:5rem;accent-color:var(--tokentweak-color-accent);cursor:pointer}.tokenpanel-body{flex:1;min-height:0;overflow-y:auto;padding-inline:var(--tokentweak-pad-xl);padding-block:var(--tokentweak-gap-sm)}.tokenpanel-empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;min-height:12rem;padding-block:var(--tokentweak-gap-md);padding-inline:var(--tokentweak-pad-xl)}.tokenpanel-empty-state-text{color:var(--tokentweak-color-muted, #a8a8a8);font-size:.8125rem;line-height:1.5;max-width:32rem;margin:0}.tokenpanel-empty-state-text code{font-family:var(--tokentweak-font-mono, Menlo, Monaco, Consolas, monospace);font-size:.8125rem;color:var(--tokentweak-color-fg)}.tokenpanel-empty-state-link{color:var(--tokentweak-color-accent);text-decoration:underline;transition:color .15s ease}.tokenpanel-empty-state-link:hover,.tokenpanel-empty-state-link:focus-visible{color:var(--tokentweak-color-accent-hover)}.tokenpanel-tab-content{display:flex;flex-direction:column;gap:var(--tokentweak-gap-sm)}.tokenpanel-tab-actions{display:flex;align-items:center;gap:var(--tokentweak-pad-md)}.tokenpanel-tab-section{position:relative;flex-shrink:0;border:1px solid var(--tokentweak-color-muted);border-radius:.5rem;padding:18px 14px 14px}.tokenpanel-tab-section-heading{position:absolute;top:-.625rem;left:12px;background:var(--tokentweak-color-surface);padding:0 8px;margin:0;color:var(--tokentweak-color-fg);font-family:inherit;font-weight:600;font-size:.8125rem;line-height:1.25rem;text-transform:none;letter-spacing:normal}.tokenpanel-tab-section-heading--color{font-size:.875rem}.tokenpanel-tab-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(var(--tokenpanel-grid-min, 18rem),1fr));gap:var(--tokentweak-gap-xs)}.tokenpanel-color-preset-select{background-color:var(--tokentweak-color-surface);color:var(--tokentweak-color-fg);border:1px solid var(--tokentweak-color-muted);padding-inline:var(--tokentweak-pad-sm);padding-block:2px;font-size:.75rem;border-radius:var(--radius-tokentweak);max-width:14rem;cursor:pointer;transition:border-color .15s ease}.tokenpanel-color-preset-select:hover{border-color:var(--tokentweak-color-fg)}.tokenpanel-color-palette-grid,.tokenpanel-color-palette-grid--secondary{display:grid;grid-template-columns:repeat(auto-fit,minmax(var(--tokenpanel-grid-min, 3.5rem),1fr));gap:var(--tokentweak-pad-sm)}.tokenpanel-color-base-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(var(--tokenpanel-grid-min, 11rem),1fr));gap:6px}.tokenpanel-color-swatch-wrap{display:flex;flex-direction:column;align-items:center;gap:4px;min-width:0;width:100%}.tokenpanel-color-swatch-button{display:block;border:1px solid var(--tokentweak-color-muted);cursor:pointer;width:3.5rem;height:3.5rem;border-radius:var(--radius-tokentweak);background:none;padding:0;transition:border-color .15s ease}.tokenpanel-color-swatch-button:hover{border-color:var(--tokentweak-color-fg)}.tokenpanel-color-swatch-button:focus-visible{outline:2px solid var(--tokentweak-color-accent);outline-offset:2px}.tokenpanel-color-swatch-label-row{display:flex;align-items:center;gap:4px;min-width:0;max-width:100%}.tokenpanel-color-swatch-label{color:var(--tokentweak-color-muted);font-family:var(--tokentweak-font-mono);-webkit-user-select:none;user-select:none;font-size:.6875rem;line-height:1.1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tokenpanel-tooltip{position:fixed;z-index:9999;pointer-events:none;background:var(--tokentweak-color-surface);color:var(--tokentweak-color-fg);border:1px solid var(--tokentweak-color-muted);border-radius:4px;padding:4px 8px;font-family:var(--tokentweak-font-mono);font-size:11px;line-height:1.3;white-space:nowrap;box-shadow:0 4px 12px #00000080;opacity:0;transform:translateY(2px);transition:opacity 90ms ease,transform 90ms ease}.tokenpanel-tooltip[data-show=true]{opacity:1;transform:translateY(0)}.tokenpanel-popover{border:1px solid var(--tokentweak-color-muted);background-color:var(--tokentweak-color-surface);padding:12px;border-radius:var(--radius-tokentweak);box-shadow:0 4px 12px #0000004d}.tokenpanel-palette-selector{position:relative;width:100%;display:flex;align-items:center;gap:6px}.tokenpanel-palette-trigger{display:flex;align-items:center;gap:4px;flex:1;min-width:0;border:1px solid var(--tokentweak-color-muted);background-color:var(--tokentweak-color-surface);padding-inline:6px;padding-block:4px;font-size:.75rem;border-radius:var(--radius-tokentweak);cursor:pointer;transition:border-color .15s ease}.tokenpanel-palette-trigger:hover{border-color:var(--tokentweak-color-fg)}.tokenpanel-palette-trigger:focus-visible{outline:2px solid var(--tokentweak-color-accent);outline-offset:2px}.tokenpanel-palette-trigger-label{flex:1;min-width:0;text-align:left;color:var(--tokentweak-color-fg);font-family:var(--tokentweak-font-mono);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tokenpanel-palette-trigger-color{flex-shrink:0;border:1px solid var(--tokentweak-color-muted);width:14px;height:14px;border-radius:2px}.tokenpanel-palette-trigger-value{flex-shrink:0;color:var(--tokentweak-color-muted);font-family:var(--tokentweak-font-mono);width:2.5em}.tokenpanel-palette-trigger-icon{color:var(--tokentweak-color-muted);flex-shrink:0}.tokenpanel-palette-options{border:1px solid var(--tokentweak-color-muted);background-color:var(--tokentweak-color-surface);padding:10px;border-radius:var(--radius-tokentweak);box-shadow:0 4px 12px #0000004d}.tokenpanel-palette-options-extras{display:flex;gap:6px;margin-bottom:8px;padding-bottom:8px;border-bottom:1px solid var(--tokentweak-color-muted)}.tokenpanel-palette-extra-option{display:flex;align-items:center;gap:6px;padding-inline:8px;padding-block:4px;border-radius:4px;font-size:1rem;background:none;border:none;cursor:pointer;transition:background-color .15s ease}.tokenpanel-palette-extra-option:hover{background-color:rgb(from var(--tokentweak-color-fg) r g b / .1)}.tokenpanel-palette-extra-option.is-selected{background-color:rgb(from var(--tokentweak-color-accent) r g b / .2)}.tokenpanel-palette-extra-color{width:1.75rem;height:1.75rem;border-radius:3px;border:1px solid var(--tokentweak-color-muted)}.tokenpanel-palette-extra-label{color:var(--tokentweak-color-fg)}.tokenpanel-palette-options-grid{display:grid;grid-template-columns:repeat(8,minmax(0,1fr));gap:5px}.tokenpanel-palette-option-button{width:3rem;height:3rem;border-radius:3px;border:1px solid var(--tokentweak-color-muted);cursor:pointer;padding:0;transition:box-shadow .15s ease}.tokenpanel-palette-option-button:hover{box-shadow:0 0 0 2px var(--tokentweak-color-fg)}.tokenpanel-palette-option-button.is-selected{box-shadow:0 0 0 2px var(--tokentweak-color-accent)}.tokenpanel-row{display:flex;align-items:center;gap:var(--tokentweak-pad-sm)}.tokenpanel-row--stacked{display:flex;flex-direction:column;gap:2px}.tokenpanel-row--column{display:flex;flex-direction:column;gap:4px}.tokenpanel-row-head{display:flex;align-items:center;gap:var(--tokentweak-pad-sm)}.tokenpanel-row-label{color:var(--tokentweak-color-fg);font-family:var(--tokentweak-font-mono);flex:1;min-width:0;font-size:.8125rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tokenpanel-row-input-group{display:flex;align-items:center;gap:4px;flex-shrink:0}.tokenpanel-row-number-input{background-color:var(--tokentweak-color-surface);color:var(--tokentweak-color-fg);border:1px solid var(--tokentweak-color-muted);padding-inline:6px;padding-block:2px;font-family:var(--tokentweak-font-mono);text-align:right;font-size:.75rem;width:5rem;border-radius:var(--radius-tokentweak)}.tokenpanel-row-number-input:disabled{opacity:.6}.tokenpanel-row-unit{color:var(--tokentweak-color-muted);font-family:var(--tokentweak-font-mono);-webkit-user-select:none;user-select:none;font-size:.75rem;width:2rem}.tokenpanel-row-select{background-color:var(--tokentweak-color-surface);color:var(--tokentweak-color-fg);border:1px solid var(--tokentweak-color-muted);padding-inline:6px;padding-block:2px;font-family:var(--tokentweak-font-mono);font-size:.75rem;width:7rem;border-radius:var(--radius-tokentweak)}.tokenpanel-row-select:disabled{opacity:.6}.tokenpanel-row-text-input{background-color:var(--tokentweak-color-surface);color:var(--tokentweak-color-fg);border:1px solid var(--tokentweak-color-muted);padding-inline:6px;padding-block:2px;font-family:var(--tokentweak-font-mono);font-size:.75rem;flex:1;min-width:0;border-radius:var(--radius-tokentweak)}.tokenpanel-row-text-input:disabled{opacity:.6}.tokenpanel-pill-toggle{display:flex;align-items:center;gap:var(--tokentweak-pad-xs);flex-shrink:0;cursor:pointer}.tokenpanel-pill-toggle-checkbox{accent-color:var(--tokentweak-color-accent)}.tokenpanel-pill-toggle-text{color:var(--tokentweak-color-muted);font-family:var(--tokentweak-font-mono);font-size:.75rem}[data-design-token-panel-modal]{margin-inline:auto;width:100%;max-width:46rem;max-height:80vh;overflow-y:auto;border:1px solid var(--tokentweak-color-muted);background-color:var(--tokentweak-color-surface);color:var(--tokentweak-color-fg);padding:var(--tokentweak-pad-xl);position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);-webkit-user-select:text;user-select:text}[data-design-token-panel-modal]::backdrop{background-color:rgb(from var(--tokentweak-color-bg) r g b / .8)}[data-design-token-panel-modal] [class*=__header]{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--tokentweak-pad-md);margin-bottom:var(--tokentweak-gap-sm)}[data-design-token-panel-modal] [class*=__title]{font-size:var(--tokentweak-text-subheading);font-weight:700;color:var(--tokentweak-color-fg)}[data-design-token-panel-modal] [class*=__hint]{font-size:var(--tokentweak-text-small);color:var(--tokentweak-color-muted);margin-bottom:var(--tokentweak-gap-xs)}[data-design-token-panel-modal] [class*=__section-heading]{font-size:var(--tokentweak-text-small);font-weight:700;color:var(--tokentweak-color-fg);margin-top:var(--tokentweak-gap-sm);margin-bottom:var(--tokentweak-gap-2xs)}[data-design-token-panel-modal] [class*=__list]:not([class*=__list-item]){overflow-x:auto;border:1px solid var(--tokentweak-color-muted);background-color:var(--tokentweak-color-code-bg);color:var(--tokentweak-color-code-fg);padding:var(--tokentweak-pad-sm);font-size:var(--tokentweak-text-small);margin-bottom:var(--tokentweak-gap-xs)}[data-design-token-panel-modal] [class*=__list-item]{font-family:var(--tokentweak-font-mono)}[data-design-token-panel-modal] [class*=__actions]{display:flex;align-items:center;gap:var(--tokentweak-pad-md);margin-top:var(--tokentweak-gap-md)}[data-design-token-panel-modal] [class*=__toggle]{display:inline-flex;align-items:center;gap:var(--tokentweak-pad-xs);font-size:var(--tokentweak-text-small);color:var(--tokentweak-color-fg);cursor:pointer;margin-bottom:var(--tokentweak-gap-xs)}[data-design-token-panel-modal] [class*=__textarea]{width:100%;min-height:12rem;border:1px solid var(--tokentweak-color-muted);background-color:var(--tokentweak-color-code-bg);color:var(--tokentweak-color-code-fg);padding:var(--tokentweak-pad-sm);font-family:var(--tokentweak-font-mono);font-size:var(--tokentweak-text-small);resize:vertical;margin-bottom:var(--tokentweak-gap-xs)}[data-design-token-panel-modal] [class*=__json]{overflow-x:auto;border:1px solid var(--tokentweak-color-muted);background-color:var(--tokentweak-color-code-bg);color:var(--tokentweak-color-code-fg);padding:var(--tokentweak-pad-sm);font-size:var(--tokentweak-text-small);white-space:pre;font-family:var(--tokentweak-font-mono)}[data-design-token-panel-modal] [class*=__status]{font-size:var(--tokentweak-text-small);margin-bottom:var(--tokentweak-gap-xs)}[data-design-token-panel-modal] [class*=__status--info]{color:var(--tokentweak-color-success)}[data-design-token-panel-modal] [class*=__status--error]{color:var(--tokentweak-color-danger)}[data-design-token-panel-modal] [class*=__status--warning]{color:var(--tokentweak-color-warning)}[data-design-token-panel-modal] [class*=__status--success]{color:var(--tokentweak-color-success)}[data-design-token-panel-modal] [class*=__applying]{display:flex;align-items:center;gap:var(--tokentweak-pad-sm);border:1px solid var(--tokentweak-color-muted);background-color:var(--tokentweak-color-code-bg);color:var(--tokentweak-color-muted);padding:var(--tokentweak-pad-sm);font-size:var(--tokentweak-text-small)}[data-design-token-panel-modal] [class*=__spinner]{display:inline-block;width:1rem;height:1rem;border:2px solid var(--tokentweak-color-muted);border-top-color:var(--tokentweak-color-fg);border-radius:50%;animation:design-token-panel-modal-spin .75s linear infinite}@keyframes design-token-panel-modal-spin{to{transform:rotate(360deg)}}[data-design-token-panel-modal] [class*=__revert-hint]{font-size:var(--tokentweak-text-small);font-style:italic;color:var(--tokentweak-color-muted);margin-top:var(--tokentweak-gap-sm);margin-bottom:var(--tokentweak-gap-2xs)}[data-design-token-panel-modal] [class*=__button]{border:1px solid var(--tokentweak-color-muted);background-color:var(--tokentweak-color-surface);color:var(--tokentweak-color-muted);padding-inline:var(--tokentweak-pad-lg);padding-block:var(--tokentweak-gap-2xs);font-size:var(--tokentweak-text-small);cursor:pointer;transition:color .15s ease,border-color .15s ease,background-color .15s ease}[data-design-token-panel-modal] [class*=__button]:hover,[data-design-token-panel-modal] [class*=__button]:focus-visible{color:var(--tokentweak-color-fg);border-color:var(--tokentweak-color-fg)}[data-design-token-panel-modal] [class*=__button]:disabled{cursor:not-allowed;opacity:.5}[data-design-token-panel-modal] [class*=__button--primary]{border-color:var(--tokentweak-color-accent);background-color:var(--tokentweak-color-accent);color:var(--tokentweak-color-bg)}[data-design-token-panel-modal] [class*=__button--primary]:hover,[data-design-token-panel-modal] [class*=__button--primary]:focus-visible{border-color:var(--tokentweak-color-accent-hover);background-color:var(--tokentweak-color-accent-hover);color:var(--tokentweak-color-bg)}[data-design-token-panel-modal] [class*=__close-button]{border:1px solid var(--tokentweak-color-muted);background-color:var(--tokentweak-color-surface);color:var(--tokentweak-color-muted);padding-inline:var(--tokentweak-pad-sm);padding-block:var(--tokentweak-gap-2xs);font-size:var(--tokentweak-text-small);cursor:pointer;transition:color .15s ease,border-color .15s ease}[data-design-token-panel-modal] [class*=__close-button]:hover,[data-design-token-panel-modal] [class*=__close-button]:focus-visible{color:var(--tokentweak-color-fg);border-color:var(--tokentweak-color-fg)}.tokenpanel-tier-ref-selector{position:relative;flex:1;min-width:0}.tokenpanel-tier-ref-trigger{display:flex;align-items:center;gap:6px;width:100%;background-color:var(--tokentweak-color-surface);color:var(--tokentweak-color-fg);border:1px solid var(--tokentweak-color-muted);border-radius:var(--radius-tokentweak);padding-inline:var(--tokentweak-pad-sm);padding-block:4px;font-family:var(--tokentweak-font-mono);font-size:.75rem;text-align:left;cursor:pointer;transition:border-color .15s ease,box-shadow .15s ease}.tokenpanel-tier-ref-trigger:hover{border-color:var(--tokentweak-color-fg)}.tokenpanel-tier-ref-trigger[aria-expanded=true]{border-color:var(--tokentweak-color-accent);box-shadow:0 0 0 2px rgb(from var(--tokentweak-color-accent) r g b / .16)}.tokenpanel-tier-ref-trigger-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tokenpanel-tier-ref-trigger-arrow{color:var(--tokentweak-color-muted);font-size:9px;flex-shrink:0}.tokenpanel-tier-ref-listbox{position:absolute;top:calc(100% + 10px);left:0;right:0;z-index:60;margin:0;padding:4px;list-style:none;background-color:var(--tokentweak-color-surface);border:1px solid var(--tokentweak-color-muted);border-radius:var(--radius-tokentweak);box-shadow:0 12px 28px #00000080;outline:none}.tokenpanel-tier-ref-listbox:before{content:"";position:absolute;top:-7px;left:22px;width:12px;height:12px;background-color:var(--tokentweak-color-surface);border-left:1px solid var(--tokentweak-color-muted);border-top:1px solid var(--tokentweak-color-muted);transform:rotate(45deg)}.tokenpanel-tier-ref-option{display:grid;grid-template-columns:14px 1fr auto;gap:6px;align-items:center;padding:5px 8px;border-radius:3px;cursor:pointer;font-family:var(--tokentweak-font-mono);font-size:.8125rem;color:var(--tokentweak-color-fg);list-style:none}.tokenpanel-tier-ref-option:before{content:"✓";font-size:11px;color:transparent;line-height:1}.tokenpanel-tier-ref-option[aria-selected=true]:before{color:var(--tokentweak-color-accent)}.tokenpanel-tier-ref-option-label{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tokenpanel-tier-ref-option-preview{font-size:.6875rem;color:var(--tokentweak-color-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:10rem}.tokenpanel-tier-ref-option--focused{background-color:rgb(from var(--tokentweak-color-accent) r g b / .16)}.tokenpanel-tier-ref-option--literal{font-style:italic;color:var(--tokentweak-color-muted);border-top:1px solid var(--tokentweak-color-muted);margin-top:4px;padding-top:8px}.tokenpanel-row-label-sub{display:block;font-size:var(--tokentweak-text-micro, .6875rem);color:var(--tokentweak-color-muted);font-family:var(--tokentweak-font-mono);line-height:1.2}.tokenpanel-tab-section [role=heading]{display:block}.tokenpanel-code{font-family:var(--tokentweak-font-mono);font-size:inherit;background:none;color:inherit;padding:0;border:none;border-radius:0;white-space:pre-wrap}[data-design-token-panel-modal] [class*=__button][aria-disabled=true]{cursor:not-allowed;opacity:.5;pointer-events:none}[data-design-token-panel-modal] [role=button]:focus-visible{outline:2px solid var(--tokentweak-color-accent);outline-offset:2px}.tokenpanel-action-link:focus-visible{outline:2px solid var(--tokentweak-color-accent);outline-offset:2px;border-radius:2px}.tokenpanel-close-btn:focus-visible{outline:2px solid var(--tokentweak-color-accent);outline-offset:2px;border-radius:2px}.tokenpanel-tier-ref-trigger:focus-visible{outline:2px solid var(--tokentweak-color-accent);outline-offset:2px}.tokenpanel-tier-ref-listbox[role=listbox]{list-style:none}.tokenpanel-tab-button:focus-visible{outline:2px solid var(--tokentweak-color-accent);outline-offset:2px;border-radius:2px}.tokenpanel-highlight-overlay{margin:0;padding:0;border:0;background:transparent;display:block}.tokenpanel-highlight-toggle{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:16px;height:16px;color:var(--tokentweak-color-muted);cursor:pointer;vertical-align:middle;border-radius:2px;transition:background-color .15s ease,color .15s ease}.tokenpanel-highlight-toggle:hover{color:var(--tokentweak-color-fg);background-color:rgb(from var(--tokentweak-color-fg) r g b / .1)}.tokenpanel-highlight-toggle:focus-visible{outline:2px solid var(--tokentweak-color-accent);outline-offset:2px;border-radius:2px}.tokenpanel-highlight-toggle.is-active{opacity:1}:where(.tokenpanel-shell) svg{fill:currentColor;pointer-events:none;display:inline-block;overflow:visible}:where(.tokenpanel-shell) .tokenpanel-highlight-toggle svg{fill:none;stroke:currentColor}.tokenpanel-highlight-settings-popover{width:370px;background:var(--tokentweak-color-surface);border:1px solid var(--tokentweak-color-muted);border-radius:6px;box-shadow:0 8px 32px #00000080}.tokenpanel-highlight-settings-header{padding:10px 16px;border-bottom:1px solid var(--tokentweak-color-muted);font-weight:600;font-size:.8125rem;color:var(--tokentweak-color-fg);display:flex;align-items:center;justify-content:space-between;gap:12px}.tokenpanel-highlight-settings-header-label{flex:1;min-width:0}.tokenpanel-highlight-settings-outline-control{display:flex;align-items:center;gap:4px;flex-shrink:0}.tokenpanel-highlight-settings-outline-input{width:44px;background:#222;border:1px solid var(--tokentweak-color-muted);border-radius:3px;color:var(--tokentweak-color-fg);font-size:12px;font-variant-numeric:tabular-nums;padding:3px 6px;text-align:right}.tokenpanel-highlight-settings-outline-px{color:var(--tokentweak-color-muted);font-size:12px;font-weight:400}.tokenpanel-highlight-settings-list{padding:4px 0;display:grid;grid-template-columns:1fr 1fr}.tokenpanel-highlight-settings-row{display:grid;grid-template-columns:22px 32px 1fr;gap:8px;align-items:center;padding:8px 12px}.tokenpanel-highlight-settings-row:hover{background:#ffffff08}.tokenpanel-highlight-settings-num{color:var(--tokentweak-color-muted);font-variant-numeric:tabular-nums;text-align:right;font-size:11px}.tokenpanel-highlight-settings-ring{width:28px;height:28px;border-radius:3px;background:transparent;box-sizing:border-box;cursor:pointer;flex-shrink:0}.tokenpanel-highlight-settings-ring:focus-visible{outline:2px solid var(--tokentweak-color-accent);outline-offset:2px}.tokenpanel-highlight-settings-name{font-family:var(--tokentweak-font-mono);font-size:12px;color:var(--tokentweak-color-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tokenpanel-highlight-settings-name.is-active{color:var(--tokentweak-color-fg)}.tokenpanel-highlight-settings-footer{padding:12px 16px;border-top:1px solid var(--tokentweak-color-muted);display:flex;justify-content:flex-end;gap:var(--tokentweak-pad-sm)}.tokenpanel-highlight-settings-reset-btn{padding:6px 12px;background:#333;border:1px solid var(--tokentweak-color-muted);border-radius:3px;cursor:pointer;font-size:12px;color:var(--tokentweak-color-fg);transition:background .15s ease}.tokenpanel-highlight-settings-reset-btn:hover{background:#404040}.tokenpanel-highlight-settings-reset-btn:focus-visible{outline:2px solid var(--tokentweak-color-accent);outline-offset:2px;border-radius:3px}.tokenpanel-gear-btn{color:var(--tokentweak-color-muted);background:none;border:none;padding:0;cursor:pointer;flex-shrink:0;transition:color .15s ease;display:inline-flex;align-items:center;justify-content:center}.tokenpanel-gear-btn:hover{color:var(--tokentweak-color-fg)}.tokenpanel-gear-btn:focus-visible{outline:2px solid var(--tokentweak-color-accent);outline-offset:2px;border-radius:2px}
package/package.json ADDED
@@ -0,0 +1,102 @@
1
+ {
2
+ "name": "@takazudo/zdtp",
3
+ "version": "0.1.0-next.0",
4
+ "description": "Dynamic design-token tweak panel — host-config-driven, framework-agnostic Preact UI.",
5
+ "private": false,
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "author": "Takeshi Takatsudo <takazudo@gmail.com> (https://github.com/Takazudo)",
9
+ "keywords": [
10
+ "design-tokens",
11
+ "design-token",
12
+ "design-system",
13
+ "theming",
14
+ "tweak-panel",
15
+ "preact",
16
+ "react",
17
+ "css-variables",
18
+ "framework-agnostic"
19
+ ],
20
+ "publishConfig": {
21
+ "access": "public"
22
+ },
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "git+https://github.com/Takazudo/zudo-design-token-panel.git",
26
+ "directory": "packages/zdtp"
27
+ },
28
+ "homepage": "https://takazudomodular.com/pj/zudo-design-token-panel/",
29
+ "bugs": {
30
+ "url": "https://github.com/Takazudo/zudo-design-token-panel/issues"
31
+ },
32
+ "main": "./dist/index.js",
33
+ "types": "./dist/index.d.ts",
34
+ "bin": {
35
+ "zdtp-server": "./dist/bin/server.js"
36
+ },
37
+ "sideEffects": [
38
+ "**/*.css",
39
+ "./dist/astro/host-adapter.js",
40
+ "**/host-adapter.js"
41
+ ],
42
+ "exports": {
43
+ ".": {
44
+ "types": "./dist/index.d.ts",
45
+ "import": "./dist/index.js"
46
+ },
47
+ "./astro": {
48
+ "types": "./dist/astro/index.d.ts",
49
+ "import": "./dist/astro/index.js"
50
+ },
51
+ "./astro/host-adapter": {
52
+ "types": "./dist/astro/host-adapter.d.ts",
53
+ "import": "./dist/astro/host-adapter.js"
54
+ },
55
+ "./astro/DesignTokenPanelHost.astro": "./dist/astro/DesignTokenPanelHost.astro",
56
+ "./server": {
57
+ "types": "./dist/server/index.d.ts",
58
+ "import": "./dist/server/index.js"
59
+ },
60
+ "./testing": {
61
+ "types": "./dist/testing.d.ts",
62
+ "import": "./dist/testing.js"
63
+ },
64
+ "./styles": "./dist/zdtp.css",
65
+ "./styles.css": "./dist/zdtp.css"
66
+ },
67
+ "files": [
68
+ "dist",
69
+ "README.md",
70
+ "CHANGELOG.md",
71
+ "LICENSE"
72
+ ],
73
+ "engines": {
74
+ "node": ">=22.0.0",
75
+ "pnpm": ">=10.0.0"
76
+ },
77
+ "peerDependencies": {
78
+ "preact": "^10.29.1"
79
+ },
80
+ "dependencies": {
81
+ "culori": "^4.0.2"
82
+ },
83
+ "devDependencies": {
84
+ "@playwright/test": "^1.60.0",
85
+ "@types/culori": "^4.0.1",
86
+ "@types/node": "^22.0.0",
87
+ "@vitest/browser-playwright": "4.1.5",
88
+ "jsdom": "^25.0.0",
89
+ "playwright": "^1.60.0",
90
+ "preact": "^10.29.1",
91
+ "typescript": "^5.6.0",
92
+ "vite": "^7.3.2",
93
+ "vitest": "^4.1.4"
94
+ },
95
+ "scripts": {
96
+ "build": "vite build && tsc -p tsconfig.build.json && node scripts/copy-astro-assets.mjs && chmod +x dist/bin/server.js",
97
+ "// prepublishOnly": "build-only gate. The full test suite needs Playwright Chromium (browser tests) and is run upstream in ci.yml / pr-checks.yml on every PR, not at publish time.",
98
+ "test": "vitest run",
99
+ "test:watch": "vitest",
100
+ "typecheck": "tsc --noEmit"
101
+ }
102
+ }