@wix/web5-core 1.63.38 → 1.63.39

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.
@@ -8,7 +8,12 @@
8
8
  /* Color tokens — HSL triplets */
9
9
  --background: 0 0% 100%;
10
10
  --foreground: 0 0% 3.9%;
11
- --card: 0 0% 100%;
11
+ /* A card must not dissolve into the page it sits on. Until the seed's
12
+ * migration to `bg-card` this separation was drawn the other way round —
13
+ * section bands were `bg-muted` and cards were the pure `--background` — so
14
+ * the tint moves onto the card and `--background` goes back to meaning what
15
+ * it says: the page. Same two greys, opposite surfaces. */
16
+ --card: 0 0% 96.1%;
12
17
  --card-foreground: 0 0% 3.9%;
13
18
  --popover: 0 0% 100%;
14
19
  --popover-foreground: 0 0% 3.9%;
@@ -113,7 +118,7 @@
113
118
  .dark {
114
119
  --background: 0 0% 3.9%;
115
120
  --foreground: 0 0% 98%;
116
- --card: 0 0% 3.9%;
121
+ --card: 0 0% 14.9%;
117
122
  --card-foreground: 0 0% 98%;
118
123
  --popover: 0 0% 3.9%;
119
124
  --popover-foreground: 0 0% 98%;
@@ -71,11 +71,19 @@ exports.hostAliasFor = hostAliasFor;
71
71
  * with no name, and a label on a token nobody may set is a promise the panel
72
72
  * cannot keep. One argument, one decision.
73
73
  *
74
- * Labels are the merchant's words rather than the token's — "Buttons & links",
75
- * not "primary". Someone choosing their shop's colours is not reading a design
74
+ * Labels are the merchant's words rather than the token's — "Card background",
75
+ * not "card". Someone choosing their shop's colours is not reading a design
76
76
  * system, and `--primary-foreground` is not a colour anyone picks: it is
77
77
  * whatever stays legible ON primary, which the theme derives. Exposing the
78
78
  * derived half is how a panel produces white text on a white button.
79
+ *
80
+ * Only FOUR carry a label (product request, 2026-09-09): the page's surface and
81
+ * text, and a card's. They are the four a shop owner can point at on the page
82
+ * and name without being taught the vocabulary, and — unlike `--secondary`,
83
+ * `--accent` or `--muted`, which the importer MIXES from the anchors — they are
84
+ * independent of each other, so setting one cannot contradict the arithmetic
85
+ * that produced another. Everything else stays import-only: the store still
86
+ * fills it, the panel just does not offer it.
79
87
  */
80
88
  const brandColor = label => ({
81
89
  bucket: 'brand',
@@ -97,21 +105,21 @@ const brandColor = label => ({
97
105
  */
98
106
  const THEME_TOKEN_CONTRACT = exports.THEME_TOKEN_CONTRACT = Object.freeze({
99
107
  // ── brand · colour roles (18) ────────────────────────────────────────────
100
- '--background': brandColor('Page background'),
101
- '--foreground': brandColor('Text'),
102
- '--card': brandColor(),
103
- '--card-foreground': brandColor(),
108
+ '--background': brandColor('Background color'),
109
+ '--foreground': brandColor('Text color'),
110
+ '--card': brandColor('Card background'),
111
+ '--card-foreground': brandColor('Card text'),
104
112
  '--popover': brandColor(),
105
113
  '--popover-foreground': brandColor(),
106
- '--primary': brandColor('Buttons & links'),
114
+ '--primary': brandColor(),
107
115
  '--primary-foreground': brandColor(),
108
116
  '--secondary': brandColor(),
109
117
  '--secondary-foreground': brandColor(),
110
118
  '--muted': brandColor(),
111
119
  '--muted-foreground': brandColor(),
112
- '--accent': brandColor('Highlights'),
120
+ '--accent': brandColor(),
113
121
  '--accent-foreground': brandColor(),
114
- '--border': brandColor('Lines & borders'),
122
+ '--border': brandColor(),
115
123
  '--input': brandColor(),
116
124
  '--ring': brandColor(),
117
125
  /**
@@ -121,7 +129,7 @@ const THEME_TOKEN_CONTRACT = exports.THEME_TOKEN_CONTRACT = Object.freeze({
121
129
  * emits the other twenty. A store that states a distinct heading colour has
122
130
  * somewhere for it to go the moment an adapter learns to read one.
123
131
  */
124
- '--heading': brandColor('Headings'),
132
+ '--heading': brandColor(),
125
133
  // ── brand · type (2) ─────────────────────────────────────────────────────
126
134
  '--font-sans': {
127
135
  bucket: 'brand',
@@ -136,14 +144,15 @@ const THEME_TOKEN_CONTRACT = exports.THEME_TOKEN_CONTRACT = Object.freeze({
136
144
  // ── host · shape (1) ─────────────────────────────────────────────────────
137
145
  /**
138
146
  * The one token whose bucket changed, and the reason this contract exists.
139
- * Editable because it is the one value a store and a template are known to
140
- * disagree about in a way a merchant can see and wants to settle.
147
+ * A store's imported radius still reaches the page as `--web5-host-radius`
148
+ * and a template still beats it; what changed is that the OWNER no longer
149
+ * gets a control for it — the panel is four colours now, and shape is not
150
+ * one of them.
141
151
  */
142
152
  '--radius': {
143
153
  bucket: 'host',
144
154
  type: 'length',
145
- editable: true,
146
- label: 'Corner rounding'
155
+ editable: false
147
156
  }
148
157
  });
149
158
 
@@ -169,8 +178,9 @@ const TOKEN_NAME_PATTERN = exports.TOKEN_NAME_PATTERN = /^--[a-z0-9-]+$/;
169
178
  * Derived from the contract rather than listed again beside it, so a token
170
179
  * cannot be editable in one place and absent from the other. The order is the
171
180
  * declaration order above, which reads outside-in — the page, then its text,
172
- * then the things drawn on it — and is a better first impression than
173
- * alphabetical or than the order the tokens happen to be defined for CSS.
181
+ * then the card drawn on it, then the card's text — and is a better first
182
+ * impression than alphabetical or than the order the tokens happen to be
183
+ * defined for CSS.
174
184
  */
175
185
  const EDITABLE_TOKENS = exports.EDITABLE_TOKENS = Object.freeze(Object.entries(THEME_TOKEN_CONTRACT).filter(([, entry]) => entry.editable));
176
186
 
@@ -1 +1 @@
1
- {"version":3,"names":["brandColor","label","bucket","type","editable","undefined","THEME_TOKEN_CONTRACT","exports","Object","freeze","BRAND_TOKENS","Set","entries","filter","entry","map","token","TOKEN_NAME_PATTERN","EDITABLE_TOKENS","hostAliasFor","slice","bucketOf","_THEME_TOKEN_CONTRACT"],"sources":["../../../src/theme/tokenContract.ts"],"sourcesContent":["/**\n * The theme-token contract (DL #193).\n *\n * One home for the answer to \"who is allowed to set this token, and who wins\n * when more than one of them does\". Three things need that answer and must not\n * each keep their own copy:\n *\n * - **`applyThemeOverrides`** decides, per key, whether to write the real\n * token or its `--web5-host-*` alias.\n * - **the seed's `validate-templates`** fails a template that sets a brand\n * token.\n * - **the shop owner's panel** renders a control per `editable` entry.\n *\n * A leaf module beside `hostScope.ts`, and for the same reason: both are data\n * that several packages must agree on, and both have to be readable from plain\n * Node tooling. Requiring this package's ENTRY from Node fails — the CSS import\n * in it is a syntax error to the CJS loader, which is what `scope-css.ts`\n * documents — but a deep import of a leaf like this one works, so the seed's\n * validator can read it without loading a component library.\n *\n * It was briefly its own package. That was justified by `embed-loader` needing\n * the list without taking core's eleven dependencies — and the loader turned\n * out not to need it at all, because `applyThemeOverrides` has owned runtime\n * token injection here since DL #131.\n *\n * ## The two buckets\n *\n * The split is about who WINS, not about what may be imported. A platform\n * adapter is free to read anything the store states; the bucket decides what\n * happens when a template has an opinion about the same token.\n *\n * - `brand` — the store's identity: colour roles and font families. The\n * imported value is written as the real token, last, so it wins\n * unconditionally. A template is not permitted to set these.\n * - `host` — the store's shape: corner radius today. The imported value is\n * written as `--web5-host-<name>` and consumed by core as a `var()`\n * fallback, so a template stating the real token beats it and a template\n * that stays silent inherits the store's.\n *\n * A token absent from this map is treated as `host`. That is deliberate and\n * safe: an alias nothing consumes renders nothing, so an adapter that learns\n * to read a token core has never heard of cannot override a template by\n * accident. The wiring line in core is the real gate for a host token, not the\n * entry here.\n *\n * ## Why all but one are brand\n *\n * This is not a new taxonomy. Twenty of these are the set\n * `web50-shopify-adapter` already emits, with a bucket attached; the\n * twenty-first, `--heading`, has been in core's catalogue since DL #131 and is\n * consumed by the seed, but no adapter fills it yet. Exactly one token changes\n * hands relative to the behaviour before DL #193 — `--radius`, which used to\n * win against the template that had chosen a different one. That single\n * misfiling is the whole of the bug this contract exists to fix.\n */\n\n/** How a value is spelled, which is what makes validation possible. */\nexport type TokenType =\n /** An HSL triplet with no `hsl()` wrapper — `0 0% 9%`. The core bridge wraps it. */\n | 'color-hsl'\n /** A CSS font stack — `'Poppins', ui-sans-serif, sans-serif`. */\n | 'font-stack'\n /** A CSS length. MUST carry a unit: a bare `0` turns `calc(var(--radius) - 4px)`\n * into a type error and takes the derived radius scale out entirely. */\n | 'length';\n\n/** Which layer wins when both a store and a template state this token. */\nexport type TokenBucket = 'brand' | 'host';\n\nexport interface TokenContractEntry {\n bucket: TokenBucket;\n type: TokenType;\n /** May the shop owner set this from the panel? */\n editable: boolean;\n /** Shown in the owner's panel. Absent for entries that are not editable. */\n label?: string;\n}\n\n/**\n * A colour role. Giving one a label is what puts it in the owner's panel.\n *\n * The two travel together on purpose: `editable` without a label is a control\n * with no name, and a label on a token nobody may set is a promise the panel\n * cannot keep. One argument, one decision.\n *\n * Labels are the merchant's words rather than the token's — \"Buttons & links\",\n * not \"primary\". Someone choosing their shop's colours is not reading a design\n * system, and `--primary-foreground` is not a colour anyone picks: it is\n * whatever stays legible ON primary, which the theme derives. Exposing the\n * derived half is how a panel produces white text on a white button.\n */\nconst brandColor = (label?: string): TokenContractEntry => ({\n bucket: 'brand',\n type: 'color-hsl',\n editable: label !== undefined,\n ...(label === undefined ? {} : { label }),\n});\n\n/**\n * Every token a platform adapter may meaningfully emit today.\n *\n * Growth is adapter-driven on purpose: a token joins when an adapter can\n * actually read it, not on spec. `theme_overrides` is capped at 32 entries by\n * its proto, so there are twelve slots left and no reason to spend them on\n * speculation. `--spacing` is the tempting next one and should be resisted —\n * it scales every `p-*`, `m-*` and `gap-*` in the bundle from one number.\n */\nexport const THEME_TOKEN_CONTRACT: Readonly<Record<string, TokenContractEntry>> =\n Object.freeze({\n // ── brand · colour roles (18) ────────────────────────────────────────────\n '--background': brandColor('Page background'),\n '--foreground': brandColor('Text'),\n '--card': brandColor(),\n '--card-foreground': brandColor(),\n '--popover': brandColor(),\n '--popover-foreground': brandColor(),\n '--primary': brandColor('Buttons & links'),\n '--primary-foreground': brandColor(),\n '--secondary': brandColor(),\n '--secondary-foreground': brandColor(),\n '--muted': brandColor(),\n '--muted-foreground': brandColor(),\n '--accent': brandColor('Highlights'),\n '--accent-foreground': brandColor(),\n '--border': brandColor('Lines & borders'),\n '--input': brandColor(),\n '--ring': brandColor(),\n\n /**\n * Brand-shaped and supported end to end, but no adapter fills it yet: the\n * seed consumes it (`--color-heading-fg: hsl(var(--heading, var(--foreground)))`)\n * and core has catalogued it since DL #131, while `web50-shopify-adapter`\n * emits the other twenty. A store that states a distinct heading colour has\n * somewhere for it to go the moment an adapter learns to read one.\n */\n '--heading': brandColor('Headings'),\n\n // ── brand · type (2) ─────────────────────────────────────────────────────\n '--font-sans': { bucket: 'brand', type: 'font-stack', editable: false },\n '--font-display': { bucket: 'brand', type: 'font-stack', editable: false },\n\n // ── host · shape (1) ─────────────────────────────────────────────────────\n /**\n * The one token whose bucket changed, and the reason this contract exists.\n * Editable because it is the one value a store and a template are known to\n * disagree about in a way a merchant can see and wants to settle.\n */\n '--radius': {\n bucket: 'host',\n type: 'length',\n editable: true,\n label: 'Corner rounding',\n },\n });\n\n/**\n * The tokens written directly, which is the only question the loader has to\n * answer per key — everything else takes the alias path.\n */\nexport const BRAND_TOKENS: ReadonlySet<string> = Object.freeze(\n new Set(\n Object.entries(THEME_TOKEN_CONTRACT)\n .filter(([, entry]) => entry.bucket === 'brand')\n .map(([token]) => token),\n ),\n) as ReadonlySet<string>;\n\n/**\n * A token name we are willing to compose into a CSS declaration.\n *\n * The keys reaching the loader came out of a backend map, which came out of an\n * adapter reading a merchant's theme file. A key carrying `:` or `;` would\n * write arbitrary declarations onto the mount, so the shape is checked where\n * the declaration is built rather than trusted from the source.\n */\nexport const TOKEN_NAME_PATTERN = /^--[a-z0-9-]+$/;\n\n/**\n * What the owner's panel offers, in the order it offers it.\n *\n * Derived from the contract rather than listed again beside it, so a token\n * cannot be editable in one place and absent from the other. The order is the\n * declaration order above, which reads outside-in — the page, then its text,\n * then the things drawn on it — and is a better first impression than\n * alphabetical or than the order the tokens happen to be defined for CSS.\n */\nexport const EDITABLE_TOKENS: readonly (readonly [\n token: string,\n entry: TokenContractEntry,\n])[] = Object.freeze(\n Object.entries(THEME_TOKEN_CONTRACT).filter(([, entry]) => entry.editable),\n) as readonly (readonly [string, TokenContractEntry])[];\n\n/** `--radius` → `--web5-host-radius`. Derived, never stored: one fewer thing to get wrong. */\nexport function hostAliasFor(token: string): string {\n return `--web5-host-${token.slice(2)}`;\n}\n\n/** Whether this token is written directly (brand) or as an alias (host, and anything unknown). */\nexport function bucketOf(token: string): TokenBucket {\n return THEME_TOKEN_CONTRACT[token]?.bucket ?? 'host';\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["brandColor","label","bucket","type","editable","undefined","THEME_TOKEN_CONTRACT","exports","Object","freeze","BRAND_TOKENS","Set","entries","filter","entry","map","token","TOKEN_NAME_PATTERN","EDITABLE_TOKENS","hostAliasFor","slice","bucketOf","_THEME_TOKEN_CONTRACT"],"sources":["../../../src/theme/tokenContract.ts"],"sourcesContent":["/**\n * The theme-token contract (DL #193).\n *\n * One home for the answer to \"who is allowed to set this token, and who wins\n * when more than one of them does\". Three things need that answer and must not\n * each keep their own copy:\n *\n * - **`applyThemeOverrides`** decides, per key, whether to write the real\n * token or its `--web5-host-*` alias.\n * - **the seed's `validate-templates`** fails a template that sets a brand\n * token.\n * - **the shop owner's panel** renders a control per `editable` entry.\n *\n * A leaf module beside `hostScope.ts`, and for the same reason: both are data\n * that several packages must agree on, and both have to be readable from plain\n * Node tooling. Requiring this package's ENTRY from Node fails — the CSS import\n * in it is a syntax error to the CJS loader, which is what `scope-css.ts`\n * documents — but a deep import of a leaf like this one works, so the seed's\n * validator can read it without loading a component library.\n *\n * It was briefly its own package. That was justified by `embed-loader` needing\n * the list without taking core's eleven dependencies — and the loader turned\n * out not to need it at all, because `applyThemeOverrides` has owned runtime\n * token injection here since DL #131.\n *\n * ## The two buckets\n *\n * The split is about who WINS, not about what may be imported. A platform\n * adapter is free to read anything the store states; the bucket decides what\n * happens when a template has an opinion about the same token.\n *\n * - `brand` — the store's identity: colour roles and font families. The\n * imported value is written as the real token, last, so it wins\n * unconditionally. A template is not permitted to set these.\n * - `host` — the store's shape: corner radius today. The imported value is\n * written as `--web5-host-<name>` and consumed by core as a `var()`\n * fallback, so a template stating the real token beats it and a template\n * that stays silent inherits the store's.\n *\n * A token absent from this map is treated as `host`. That is deliberate and\n * safe: an alias nothing consumes renders nothing, so an adapter that learns\n * to read a token core has never heard of cannot override a template by\n * accident. The wiring line in core is the real gate for a host token, not the\n * entry here.\n *\n * ## Why all but one are brand\n *\n * This is not a new taxonomy. Twenty of these are the set\n * `web50-shopify-adapter` already emits, with a bucket attached; the\n * twenty-first, `--heading`, has been in core's catalogue since DL #131 and is\n * consumed by the seed, but no adapter fills it yet. Exactly one token changes\n * hands relative to the behaviour before DL #193 — `--radius`, which used to\n * win against the template that had chosen a different one. That single\n * misfiling is the whole of the bug this contract exists to fix.\n */\n\n/** How a value is spelled, which is what makes validation possible. */\nexport type TokenType =\n /** An HSL triplet with no `hsl()` wrapper — `0 0% 9%`. The core bridge wraps it. */\n | 'color-hsl'\n /** A CSS font stack — `'Poppins', ui-sans-serif, sans-serif`. */\n | 'font-stack'\n /** A CSS length. MUST carry a unit: a bare `0` turns `calc(var(--radius) - 4px)`\n * into a type error and takes the derived radius scale out entirely. */\n | 'length';\n\n/** Which layer wins when both a store and a template state this token. */\nexport type TokenBucket = 'brand' | 'host';\n\nexport interface TokenContractEntry {\n bucket: TokenBucket;\n type: TokenType;\n /** May the shop owner set this from the panel? */\n editable: boolean;\n /** Shown in the owner's panel. Absent for entries that are not editable. */\n label?: string;\n}\n\n/**\n * A colour role. Giving one a label is what puts it in the owner's panel.\n *\n * The two travel together on purpose: `editable` without a label is a control\n * with no name, and a label on a token nobody may set is a promise the panel\n * cannot keep. One argument, one decision.\n *\n * Labels are the merchant's words rather than the token's — \"Card background\",\n * not \"card\". Someone choosing their shop's colours is not reading a design\n * system, and `--primary-foreground` is not a colour anyone picks: it is\n * whatever stays legible ON primary, which the theme derives. Exposing the\n * derived half is how a panel produces white text on a white button.\n *\n * Only FOUR carry a label (product request, 2026-09-09): the page's surface and\n * text, and a card's. They are the four a shop owner can point at on the page\n * and name without being taught the vocabulary, and — unlike `--secondary`,\n * `--accent` or `--muted`, which the importer MIXES from the anchors — they are\n * independent of each other, so setting one cannot contradict the arithmetic\n * that produced another. Everything else stays import-only: the store still\n * fills it, the panel just does not offer it.\n */\nconst brandColor = (label?: string): TokenContractEntry => ({\n bucket: 'brand',\n type: 'color-hsl',\n editable: label !== undefined,\n ...(label === undefined ? {} : { label }),\n});\n\n/**\n * Every token a platform adapter may meaningfully emit today.\n *\n * Growth is adapter-driven on purpose: a token joins when an adapter can\n * actually read it, not on spec. `theme_overrides` is capped at 32 entries by\n * its proto, so there are twelve slots left and no reason to spend them on\n * speculation. `--spacing` is the tempting next one and should be resisted —\n * it scales every `p-*`, `m-*` and `gap-*` in the bundle from one number.\n */\nexport const THEME_TOKEN_CONTRACT: Readonly<Record<string, TokenContractEntry>> =\n Object.freeze({\n // ── brand · colour roles (18) ────────────────────────────────────────────\n '--background': brandColor('Background color'),\n '--foreground': brandColor('Text color'),\n '--card': brandColor('Card background'),\n '--card-foreground': brandColor('Card text'),\n '--popover': brandColor(),\n '--popover-foreground': brandColor(),\n '--primary': brandColor(),\n '--primary-foreground': brandColor(),\n '--secondary': brandColor(),\n '--secondary-foreground': brandColor(),\n '--muted': brandColor(),\n '--muted-foreground': brandColor(),\n '--accent': brandColor(),\n '--accent-foreground': brandColor(),\n '--border': brandColor(),\n '--input': brandColor(),\n '--ring': brandColor(),\n\n /**\n * Brand-shaped and supported end to end, but no adapter fills it yet: the\n * seed consumes it (`--color-heading-fg: hsl(var(--heading, var(--foreground)))`)\n * and core has catalogued it since DL #131, while `web50-shopify-adapter`\n * emits the other twenty. A store that states a distinct heading colour has\n * somewhere for it to go the moment an adapter learns to read one.\n */\n '--heading': brandColor(),\n\n // ── brand · type (2) ─────────────────────────────────────────────────────\n '--font-sans': { bucket: 'brand', type: 'font-stack', editable: false },\n '--font-display': { bucket: 'brand', type: 'font-stack', editable: false },\n\n // ── host · shape (1) ─────────────────────────────────────────────────────\n /**\n * The one token whose bucket changed, and the reason this contract exists.\n * A store's imported radius still reaches the page as `--web5-host-radius`\n * and a template still beats it; what changed is that the OWNER no longer\n * gets a control for it — the panel is four colours now, and shape is not\n * one of them.\n */\n '--radius': {\n bucket: 'host',\n type: 'length',\n editable: false,\n },\n });\n\n/**\n * The tokens written directly, which is the only question the loader has to\n * answer per key — everything else takes the alias path.\n */\nexport const BRAND_TOKENS: ReadonlySet<string> = Object.freeze(\n new Set(\n Object.entries(THEME_TOKEN_CONTRACT)\n .filter(([, entry]) => entry.bucket === 'brand')\n .map(([token]) => token),\n ),\n) as ReadonlySet<string>;\n\n/**\n * A token name we are willing to compose into a CSS declaration.\n *\n * The keys reaching the loader came out of a backend map, which came out of an\n * adapter reading a merchant's theme file. A key carrying `:` or `;` would\n * write arbitrary declarations onto the mount, so the shape is checked where\n * the declaration is built rather than trusted from the source.\n */\nexport const TOKEN_NAME_PATTERN = /^--[a-z0-9-]+$/;\n\n/**\n * What the owner's panel offers, in the order it offers it.\n *\n * Derived from the contract rather than listed again beside it, so a token\n * cannot be editable in one place and absent from the other. The order is the\n * declaration order above, which reads outside-in — the page, then its text,\n * then the card drawn on it, then the card's text — and is a better first\n * impression than alphabetical or than the order the tokens happen to be\n * defined for CSS.\n */\nexport const EDITABLE_TOKENS: readonly (readonly [\n token: string,\n entry: TokenContractEntry,\n])[] = Object.freeze(\n Object.entries(THEME_TOKEN_CONTRACT).filter(([, entry]) => entry.editable),\n) as readonly (readonly [string, TokenContractEntry])[];\n\n/** `--radius` → `--web5-host-radius`. Derived, never stored: one fewer thing to get wrong. */\nexport function hostAliasFor(token: string): string {\n return `--web5-host-${token.slice(2)}`;\n}\n\n/** Whether this token is written directly (brand) or as an alias (host, and anything unknown). */\nexport function bucketOf(token: string): TokenBucket {\n return THEME_TOKEN_CONTRACT[token]?.bucket ?? 'host';\n}\n"],"mappings":"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","ignoreList":[]}
@@ -8,7 +8,12 @@
8
8
  /* Color tokens — HSL triplets */
9
9
  --background: 0 0% 100%;
10
10
  --foreground: 0 0% 3.9%;
11
- --card: 0 0% 100%;
11
+ /* A card must not dissolve into the page it sits on. Until the seed's
12
+ * migration to `bg-card` this separation was drawn the other way round —
13
+ * section bands were `bg-muted` and cards were the pure `--background` — so
14
+ * the tint moves onto the card and `--background` goes back to meaning what
15
+ * it says: the page. Same two greys, opposite surfaces. */
16
+ --card: 0 0% 96.1%;
12
17
  --card-foreground: 0 0% 3.9%;
13
18
  --popover: 0 0% 100%;
14
19
  --popover-foreground: 0 0% 3.9%;
@@ -113,7 +118,7 @@
113
118
  .dark {
114
119
  --background: 0 0% 3.9%;
115
120
  --foreground: 0 0% 98%;
116
- --card: 0 0% 3.9%;
121
+ --card: 0 0% 14.9%;
117
122
  --card-foreground: 0 0% 98%;
118
123
  --popover: 0 0% 3.9%;
119
124
  --popover-foreground: 0 0% 98%;
@@ -65,11 +65,19 @@
65
65
  * with no name, and a label on a token nobody may set is a promise the panel
66
66
  * cannot keep. One argument, one decision.
67
67
  *
68
- * Labels are the merchant's words rather than the token's — "Buttons & links",
69
- * not "primary". Someone choosing their shop's colours is not reading a design
68
+ * Labels are the merchant's words rather than the token's — "Card background",
69
+ * not "card". Someone choosing their shop's colours is not reading a design
70
70
  * system, and `--primary-foreground` is not a colour anyone picks: it is
71
71
  * whatever stays legible ON primary, which the theme derives. Exposing the
72
72
  * derived half is how a panel produces white text on a white button.
73
+ *
74
+ * Only FOUR carry a label (product request, 2026-09-09): the page's surface and
75
+ * text, and a card's. They are the four a shop owner can point at on the page
76
+ * and name without being taught the vocabulary, and — unlike `--secondary`,
77
+ * `--accent` or `--muted`, which the importer MIXES from the anchors — they are
78
+ * independent of each other, so setting one cannot contradict the arithmetic
79
+ * that produced another. Everything else stays import-only: the store still
80
+ * fills it, the panel just does not offer it.
73
81
  */
74
82
  const brandColor = label => ({
75
83
  bucket: 'brand',
@@ -91,21 +99,21 @@ const brandColor = label => ({
91
99
  */
92
100
  export const THEME_TOKEN_CONTRACT = Object.freeze({
93
101
  // ── brand · colour roles (18) ────────────────────────────────────────────
94
- '--background': brandColor('Page background'),
95
- '--foreground': brandColor('Text'),
96
- '--card': brandColor(),
97
- '--card-foreground': brandColor(),
102
+ '--background': brandColor('Background color'),
103
+ '--foreground': brandColor('Text color'),
104
+ '--card': brandColor('Card background'),
105
+ '--card-foreground': brandColor('Card text'),
98
106
  '--popover': brandColor(),
99
107
  '--popover-foreground': brandColor(),
100
- '--primary': brandColor('Buttons & links'),
108
+ '--primary': brandColor(),
101
109
  '--primary-foreground': brandColor(),
102
110
  '--secondary': brandColor(),
103
111
  '--secondary-foreground': brandColor(),
104
112
  '--muted': brandColor(),
105
113
  '--muted-foreground': brandColor(),
106
- '--accent': brandColor('Highlights'),
114
+ '--accent': brandColor(),
107
115
  '--accent-foreground': brandColor(),
108
- '--border': brandColor('Lines & borders'),
116
+ '--border': brandColor(),
109
117
  '--input': brandColor(),
110
118
  '--ring': brandColor(),
111
119
  /**
@@ -115,7 +123,7 @@ export const THEME_TOKEN_CONTRACT = Object.freeze({
115
123
  * emits the other twenty. A store that states a distinct heading colour has
116
124
  * somewhere for it to go the moment an adapter learns to read one.
117
125
  */
118
- '--heading': brandColor('Headings'),
126
+ '--heading': brandColor(),
119
127
  // ── brand · type (2) ─────────────────────────────────────────────────────
120
128
  '--font-sans': {
121
129
  bucket: 'brand',
@@ -130,14 +138,15 @@ export const THEME_TOKEN_CONTRACT = Object.freeze({
130
138
  // ── host · shape (1) ─────────────────────────────────────────────────────
131
139
  /**
132
140
  * The one token whose bucket changed, and the reason this contract exists.
133
- * Editable because it is the one value a store and a template are known to
134
- * disagree about in a way a merchant can see and wants to settle.
141
+ * A store's imported radius still reaches the page as `--web5-host-radius`
142
+ * and a template still beats it; what changed is that the OWNER no longer
143
+ * gets a control for it — the panel is four colours now, and shape is not
144
+ * one of them.
135
145
  */
136
146
  '--radius': {
137
147
  bucket: 'host',
138
148
  type: 'length',
139
- editable: true,
140
- label: 'Corner rounding'
149
+ editable: false
141
150
  }
142
151
  });
143
152
 
@@ -169,8 +178,9 @@ export const TOKEN_NAME_PATTERN = /^--[a-z0-9-]+$/;
169
178
  * Derived from the contract rather than listed again beside it, so a token
170
179
  * cannot be editable in one place and absent from the other. The order is the
171
180
  * declaration order above, which reads outside-in — the page, then its text,
172
- * then the things drawn on it — and is a better first impression than
173
- * alphabetical or than the order the tokens happen to be defined for CSS.
181
+ * then the card drawn on it, then the card's text — and is a better first
182
+ * impression than alphabetical or than the order the tokens happen to be
183
+ * defined for CSS.
174
184
  */
175
185
  export const EDITABLE_TOKENS = Object.freeze(Object.entries(THEME_TOKEN_CONTRACT).filter(_ref3 => {
176
186
  let [, entry] = _ref3;
@@ -1 +1 @@
1
- {"version":3,"names":["brandColor","label","bucket","type","editable","undefined","THEME_TOKEN_CONTRACT","Object","freeze","BRAND_TOKENS","Set","entries","filter","_ref","entry","map","_ref2","token","TOKEN_NAME_PATTERN","EDITABLE_TOKENS","_ref3","hostAliasFor","slice","bucketOf","_THEME_TOKEN_CONTRACT"],"sources":["../../../src/theme/tokenContract.ts"],"sourcesContent":["/**\n * The theme-token contract (DL #193).\n *\n * One home for the answer to \"who is allowed to set this token, and who wins\n * when more than one of them does\". Three things need that answer and must not\n * each keep their own copy:\n *\n * - **`applyThemeOverrides`** decides, per key, whether to write the real\n * token or its `--web5-host-*` alias.\n * - **the seed's `validate-templates`** fails a template that sets a brand\n * token.\n * - **the shop owner's panel** renders a control per `editable` entry.\n *\n * A leaf module beside `hostScope.ts`, and for the same reason: both are data\n * that several packages must agree on, and both have to be readable from plain\n * Node tooling. Requiring this package's ENTRY from Node fails — the CSS import\n * in it is a syntax error to the CJS loader, which is what `scope-css.ts`\n * documents — but a deep import of a leaf like this one works, so the seed's\n * validator can read it without loading a component library.\n *\n * It was briefly its own package. That was justified by `embed-loader` needing\n * the list without taking core's eleven dependencies — and the loader turned\n * out not to need it at all, because `applyThemeOverrides` has owned runtime\n * token injection here since DL #131.\n *\n * ## The two buckets\n *\n * The split is about who WINS, not about what may be imported. A platform\n * adapter is free to read anything the store states; the bucket decides what\n * happens when a template has an opinion about the same token.\n *\n * - `brand` — the store's identity: colour roles and font families. The\n * imported value is written as the real token, last, so it wins\n * unconditionally. A template is not permitted to set these.\n * - `host` — the store's shape: corner radius today. The imported value is\n * written as `--web5-host-<name>` and consumed by core as a `var()`\n * fallback, so a template stating the real token beats it and a template\n * that stays silent inherits the store's.\n *\n * A token absent from this map is treated as `host`. That is deliberate and\n * safe: an alias nothing consumes renders nothing, so an adapter that learns\n * to read a token core has never heard of cannot override a template by\n * accident. The wiring line in core is the real gate for a host token, not the\n * entry here.\n *\n * ## Why all but one are brand\n *\n * This is not a new taxonomy. Twenty of these are the set\n * `web50-shopify-adapter` already emits, with a bucket attached; the\n * twenty-first, `--heading`, has been in core's catalogue since DL #131 and is\n * consumed by the seed, but no adapter fills it yet. Exactly one token changes\n * hands relative to the behaviour before DL #193 — `--radius`, which used to\n * win against the template that had chosen a different one. That single\n * misfiling is the whole of the bug this contract exists to fix.\n */\n\n/** How a value is spelled, which is what makes validation possible. */\nexport type TokenType =\n /** An HSL triplet with no `hsl()` wrapper — `0 0% 9%`. The core bridge wraps it. */\n | 'color-hsl'\n /** A CSS font stack — `'Poppins', ui-sans-serif, sans-serif`. */\n | 'font-stack'\n /** A CSS length. MUST carry a unit: a bare `0` turns `calc(var(--radius) - 4px)`\n * into a type error and takes the derived radius scale out entirely. */\n | 'length';\n\n/** Which layer wins when both a store and a template state this token. */\nexport type TokenBucket = 'brand' | 'host';\n\nexport interface TokenContractEntry {\n bucket: TokenBucket;\n type: TokenType;\n /** May the shop owner set this from the panel? */\n editable: boolean;\n /** Shown in the owner's panel. Absent for entries that are not editable. */\n label?: string;\n}\n\n/**\n * A colour role. Giving one a label is what puts it in the owner's panel.\n *\n * The two travel together on purpose: `editable` without a label is a control\n * with no name, and a label on a token nobody may set is a promise the panel\n * cannot keep. One argument, one decision.\n *\n * Labels are the merchant's words rather than the token's — \"Buttons & links\",\n * not \"primary\". Someone choosing their shop's colours is not reading a design\n * system, and `--primary-foreground` is not a colour anyone picks: it is\n * whatever stays legible ON primary, which the theme derives. Exposing the\n * derived half is how a panel produces white text on a white button.\n */\nconst brandColor = (label?: string): TokenContractEntry => ({\n bucket: 'brand',\n type: 'color-hsl',\n editable: label !== undefined,\n ...(label === undefined ? {} : { label }),\n});\n\n/**\n * Every token a platform adapter may meaningfully emit today.\n *\n * Growth is adapter-driven on purpose: a token joins when an adapter can\n * actually read it, not on spec. `theme_overrides` is capped at 32 entries by\n * its proto, so there are twelve slots left and no reason to spend them on\n * speculation. `--spacing` is the tempting next one and should be resisted —\n * it scales every `p-*`, `m-*` and `gap-*` in the bundle from one number.\n */\nexport const THEME_TOKEN_CONTRACT: Readonly<Record<string, TokenContractEntry>> =\n Object.freeze({\n // ── brand · colour roles (18) ────────────────────────────────────────────\n '--background': brandColor('Page background'),\n '--foreground': brandColor('Text'),\n '--card': brandColor(),\n '--card-foreground': brandColor(),\n '--popover': brandColor(),\n '--popover-foreground': brandColor(),\n '--primary': brandColor('Buttons & links'),\n '--primary-foreground': brandColor(),\n '--secondary': brandColor(),\n '--secondary-foreground': brandColor(),\n '--muted': brandColor(),\n '--muted-foreground': brandColor(),\n '--accent': brandColor('Highlights'),\n '--accent-foreground': brandColor(),\n '--border': brandColor('Lines & borders'),\n '--input': brandColor(),\n '--ring': brandColor(),\n\n /**\n * Brand-shaped and supported end to end, but no adapter fills it yet: the\n * seed consumes it (`--color-heading-fg: hsl(var(--heading, var(--foreground)))`)\n * and core has catalogued it since DL #131, while `web50-shopify-adapter`\n * emits the other twenty. A store that states a distinct heading colour has\n * somewhere for it to go the moment an adapter learns to read one.\n */\n '--heading': brandColor('Headings'),\n\n // ── brand · type (2) ─────────────────────────────────────────────────────\n '--font-sans': { bucket: 'brand', type: 'font-stack', editable: false },\n '--font-display': { bucket: 'brand', type: 'font-stack', editable: false },\n\n // ── host · shape (1) ─────────────────────────────────────────────────────\n /**\n * The one token whose bucket changed, and the reason this contract exists.\n * Editable because it is the one value a store and a template are known to\n * disagree about in a way a merchant can see and wants to settle.\n */\n '--radius': {\n bucket: 'host',\n type: 'length',\n editable: true,\n label: 'Corner rounding',\n },\n });\n\n/**\n * The tokens written directly, which is the only question the loader has to\n * answer per key — everything else takes the alias path.\n */\nexport const BRAND_TOKENS: ReadonlySet<string> = Object.freeze(\n new Set(\n Object.entries(THEME_TOKEN_CONTRACT)\n .filter(([, entry]) => entry.bucket === 'brand')\n .map(([token]) => token),\n ),\n) as ReadonlySet<string>;\n\n/**\n * A token name we are willing to compose into a CSS declaration.\n *\n * The keys reaching the loader came out of a backend map, which came out of an\n * adapter reading a merchant's theme file. A key carrying `:` or `;` would\n * write arbitrary declarations onto the mount, so the shape is checked where\n * the declaration is built rather than trusted from the source.\n */\nexport const TOKEN_NAME_PATTERN = /^--[a-z0-9-]+$/;\n\n/**\n * What the owner's panel offers, in the order it offers it.\n *\n * Derived from the contract rather than listed again beside it, so a token\n * cannot be editable in one place and absent from the other. The order is the\n * declaration order above, which reads outside-in — the page, then its text,\n * then the things drawn on it — and is a better first impression than\n * alphabetical or than the order the tokens happen to be defined for CSS.\n */\nexport const EDITABLE_TOKENS: readonly (readonly [\n token: string,\n entry: TokenContractEntry,\n])[] = Object.freeze(\n Object.entries(THEME_TOKEN_CONTRACT).filter(([, entry]) => entry.editable),\n) as readonly (readonly [string, TokenContractEntry])[];\n\n/** `--radius` → `--web5-host-radius`. Derived, never stored: one fewer thing to get wrong. */\nexport function hostAliasFor(token: string): string {\n return `--web5-host-${token.slice(2)}`;\n}\n\n/** Whether this token is written directly (brand) or as an alias (host, and anything unknown). */\nexport function bucketOf(token: string): TokenBucket {\n return THEME_TOKEN_CONTRACT[token]?.bucket ?? 'host';\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["brandColor","label","bucket","type","editable","undefined","THEME_TOKEN_CONTRACT","Object","freeze","BRAND_TOKENS","Set","entries","filter","_ref","entry","map","_ref2","token","TOKEN_NAME_PATTERN","EDITABLE_TOKENS","_ref3","hostAliasFor","slice","bucketOf","_THEME_TOKEN_CONTRACT"],"sources":["../../../src/theme/tokenContract.ts"],"sourcesContent":["/**\n * The theme-token contract (DL #193).\n *\n * One home for the answer to \"who is allowed to set this token, and who wins\n * when more than one of them does\". Three things need that answer and must not\n * each keep their own copy:\n *\n * - **`applyThemeOverrides`** decides, per key, whether to write the real\n * token or its `--web5-host-*` alias.\n * - **the seed's `validate-templates`** fails a template that sets a brand\n * token.\n * - **the shop owner's panel** renders a control per `editable` entry.\n *\n * A leaf module beside `hostScope.ts`, and for the same reason: both are data\n * that several packages must agree on, and both have to be readable from plain\n * Node tooling. Requiring this package's ENTRY from Node fails — the CSS import\n * in it is a syntax error to the CJS loader, which is what `scope-css.ts`\n * documents — but a deep import of a leaf like this one works, so the seed's\n * validator can read it without loading a component library.\n *\n * It was briefly its own package. That was justified by `embed-loader` needing\n * the list without taking core's eleven dependencies — and the loader turned\n * out not to need it at all, because `applyThemeOverrides` has owned runtime\n * token injection here since DL #131.\n *\n * ## The two buckets\n *\n * The split is about who WINS, not about what may be imported. A platform\n * adapter is free to read anything the store states; the bucket decides what\n * happens when a template has an opinion about the same token.\n *\n * - `brand` — the store's identity: colour roles and font families. The\n * imported value is written as the real token, last, so it wins\n * unconditionally. A template is not permitted to set these.\n * - `host` — the store's shape: corner radius today. The imported value is\n * written as `--web5-host-<name>` and consumed by core as a `var()`\n * fallback, so a template stating the real token beats it and a template\n * that stays silent inherits the store's.\n *\n * A token absent from this map is treated as `host`. That is deliberate and\n * safe: an alias nothing consumes renders nothing, so an adapter that learns\n * to read a token core has never heard of cannot override a template by\n * accident. The wiring line in core is the real gate for a host token, not the\n * entry here.\n *\n * ## Why all but one are brand\n *\n * This is not a new taxonomy. Twenty of these are the set\n * `web50-shopify-adapter` already emits, with a bucket attached; the\n * twenty-first, `--heading`, has been in core's catalogue since DL #131 and is\n * consumed by the seed, but no adapter fills it yet. Exactly one token changes\n * hands relative to the behaviour before DL #193 — `--radius`, which used to\n * win against the template that had chosen a different one. That single\n * misfiling is the whole of the bug this contract exists to fix.\n */\n\n/** How a value is spelled, which is what makes validation possible. */\nexport type TokenType =\n /** An HSL triplet with no `hsl()` wrapper — `0 0% 9%`. The core bridge wraps it. */\n | 'color-hsl'\n /** A CSS font stack — `'Poppins', ui-sans-serif, sans-serif`. */\n | 'font-stack'\n /** A CSS length. MUST carry a unit: a bare `0` turns `calc(var(--radius) - 4px)`\n * into a type error and takes the derived radius scale out entirely. */\n | 'length';\n\n/** Which layer wins when both a store and a template state this token. */\nexport type TokenBucket = 'brand' | 'host';\n\nexport interface TokenContractEntry {\n bucket: TokenBucket;\n type: TokenType;\n /** May the shop owner set this from the panel? */\n editable: boolean;\n /** Shown in the owner's panel. Absent for entries that are not editable. */\n label?: string;\n}\n\n/**\n * A colour role. Giving one a label is what puts it in the owner's panel.\n *\n * The two travel together on purpose: `editable` without a label is a control\n * with no name, and a label on a token nobody may set is a promise the panel\n * cannot keep. One argument, one decision.\n *\n * Labels are the merchant's words rather than the token's — \"Card background\",\n * not \"card\". Someone choosing their shop's colours is not reading a design\n * system, and `--primary-foreground` is not a colour anyone picks: it is\n * whatever stays legible ON primary, which the theme derives. Exposing the\n * derived half is how a panel produces white text on a white button.\n *\n * Only FOUR carry a label (product request, 2026-09-09): the page's surface and\n * text, and a card's. They are the four a shop owner can point at on the page\n * and name without being taught the vocabulary, and — unlike `--secondary`,\n * `--accent` or `--muted`, which the importer MIXES from the anchors — they are\n * independent of each other, so setting one cannot contradict the arithmetic\n * that produced another. Everything else stays import-only: the store still\n * fills it, the panel just does not offer it.\n */\nconst brandColor = (label?: string): TokenContractEntry => ({\n bucket: 'brand',\n type: 'color-hsl',\n editable: label !== undefined,\n ...(label === undefined ? {} : { label }),\n});\n\n/**\n * Every token a platform adapter may meaningfully emit today.\n *\n * Growth is adapter-driven on purpose: a token joins when an adapter can\n * actually read it, not on spec. `theme_overrides` is capped at 32 entries by\n * its proto, so there are twelve slots left and no reason to spend them on\n * speculation. `--spacing` is the tempting next one and should be resisted —\n * it scales every `p-*`, `m-*` and `gap-*` in the bundle from one number.\n */\nexport const THEME_TOKEN_CONTRACT: Readonly<Record<string, TokenContractEntry>> =\n Object.freeze({\n // ── brand · colour roles (18) ────────────────────────────────────────────\n '--background': brandColor('Background color'),\n '--foreground': brandColor('Text color'),\n '--card': brandColor('Card background'),\n '--card-foreground': brandColor('Card text'),\n '--popover': brandColor(),\n '--popover-foreground': brandColor(),\n '--primary': brandColor(),\n '--primary-foreground': brandColor(),\n '--secondary': brandColor(),\n '--secondary-foreground': brandColor(),\n '--muted': brandColor(),\n '--muted-foreground': brandColor(),\n '--accent': brandColor(),\n '--accent-foreground': brandColor(),\n '--border': brandColor(),\n '--input': brandColor(),\n '--ring': brandColor(),\n\n /**\n * Brand-shaped and supported end to end, but no adapter fills it yet: the\n * seed consumes it (`--color-heading-fg: hsl(var(--heading, var(--foreground)))`)\n * and core has catalogued it since DL #131, while `web50-shopify-adapter`\n * emits the other twenty. A store that states a distinct heading colour has\n * somewhere for it to go the moment an adapter learns to read one.\n */\n '--heading': brandColor(),\n\n // ── brand · type (2) ─────────────────────────────────────────────────────\n '--font-sans': { bucket: 'brand', type: 'font-stack', editable: false },\n '--font-display': { bucket: 'brand', type: 'font-stack', editable: false },\n\n // ── host · shape (1) ─────────────────────────────────────────────────────\n /**\n * The one token whose bucket changed, and the reason this contract exists.\n * A store's imported radius still reaches the page as `--web5-host-radius`\n * and a template still beats it; what changed is that the OWNER no longer\n * gets a control for it — the panel is four colours now, and shape is not\n * one of them.\n */\n '--radius': {\n bucket: 'host',\n type: 'length',\n editable: false,\n },\n });\n\n/**\n * The tokens written directly, which is the only question the loader has to\n * answer per key — everything else takes the alias path.\n */\nexport const BRAND_TOKENS: ReadonlySet<string> = Object.freeze(\n new Set(\n Object.entries(THEME_TOKEN_CONTRACT)\n .filter(([, entry]) => entry.bucket === 'brand')\n .map(([token]) => token),\n ),\n) as ReadonlySet<string>;\n\n/**\n * A token name we are willing to compose into a CSS declaration.\n *\n * The keys reaching the loader came out of a backend map, which came out of an\n * adapter reading a merchant's theme file. A key carrying `:` or `;` would\n * write arbitrary declarations onto the mount, so the shape is checked where\n * the declaration is built rather than trusted from the source.\n */\nexport const TOKEN_NAME_PATTERN = /^--[a-z0-9-]+$/;\n\n/**\n * What the owner's panel offers, in the order it offers it.\n *\n * Derived from the contract rather than listed again beside it, so a token\n * cannot be editable in one place and absent from the other. The order is the\n * declaration order above, which reads outside-in — the page, then its text,\n * then the card drawn on it, then the card's text — and is a better first\n * impression than alphabetical or than the order the tokens happen to be\n * defined for CSS.\n */\nexport const EDITABLE_TOKENS: readonly (readonly [\n token: string,\n entry: TokenContractEntry,\n])[] = Object.freeze(\n Object.entries(THEME_TOKEN_CONTRACT).filter(([, entry]) => entry.editable),\n) as readonly (readonly [string, TokenContractEntry])[];\n\n/** `--radius` → `--web5-host-radius`. Derived, never stored: one fewer thing to get wrong. */\nexport function hostAliasFor(token: string): string {\n return `--web5-host-${token.slice(2)}`;\n}\n\n/** Whether this token is written directly (brand) or as an alias (host, and anything unknown). */\nexport function bucketOf(token: string): TokenBucket {\n return THEME_TOKEN_CONTRACT[token]?.bucket ?? 'host';\n}\n"],"mappings":"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","ignoreList":[]}
@@ -102,8 +102,9 @@ export declare const TOKEN_NAME_PATTERN: RegExp;
102
102
  * Derived from the contract rather than listed again beside it, so a token
103
103
  * cannot be editable in one place and absent from the other. The order is the
104
104
  * declaration order above, which reads outside-in — the page, then its text,
105
- * then the things drawn on it — and is a better first impression than
106
- * alphabetical or than the order the tokens happen to be defined for CSS.
105
+ * then the card drawn on it, then the card's text — and is a better first
106
+ * impression than alphabetical or than the order the tokens happen to be
107
+ * defined for CSS.
107
108
  */
108
109
  export declare const EDITABLE_TOKENS: readonly (readonly [
109
110
  token: string,
@@ -1 +1 @@
1
- {"version":3,"file":"tokenContract.d.ts","sourceRoot":"","sources":["../../../src/theme/tokenContract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AAEH,uEAAuE;AACvE,MAAM,MAAM,SAAS;AACnB,oFAAoF;AAClF,WAAW;AACb,iEAAiE;GAC/D,YAAY;AACd;yEACyE;GACvE,QAAQ,CAAC;AAEb,0EAA0E;AAC1E,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,CAAC;AAE3C,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,kDAAkD;IAClD,QAAQ,EAAE,OAAO,CAAC;IAClB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAsBD;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CA8C1E,CAAC;AAEL;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,WAAW,CAAC,MAAM,CAMrB,CAAC;AAEzB;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,QAAmB,CAAC;AAEnD;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,EAAE,SAAS,CAAC,SAAS;IAC/C,KAAK,EAAE,MAAM;IACb,KAAK,EAAE,kBAAkB;CAC1B,CAAC,EAEqD,CAAC;AAExD,8FAA8F;AAC9F,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,kGAAkG;AAClG,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAEnD"}
1
+ {"version":3,"file":"tokenContract.d.ts","sourceRoot":"","sources":["../../../src/theme/tokenContract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AAEH,uEAAuE;AACvE,MAAM,MAAM,SAAS;AACnB,oFAAoF;AAClF,WAAW;AACb,iEAAiE;GAC/D,YAAY;AACd;yEACyE;GACvE,QAAQ,CAAC;AAEb,0EAA0E;AAC1E,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,CAAC;AAE3C,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,kDAAkD;IAClD,QAAQ,EAAE,OAAO,CAAC;IAClB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA8BD;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CA+C1E,CAAC;AAEL;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,WAAW,CAAC,MAAM,CAMrB,CAAC;AAEzB;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,QAAmB,CAAC;AAEnD;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe,EAAE,SAAS,CAAC,SAAS;IAC/C,KAAK,EAAE,MAAM;IACb,KAAK,EAAE,kBAAkB;CAC1B,CAAC,EAEqD,CAAC;AAExD,8FAA8F;AAC9F,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,kGAAkG;AAClG,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAEnD"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@wix/web5-core",
3
3
  "license": "MIT",
4
- "version": "1.63.38",
4
+ "version": "1.63.39",
5
5
  "author": {
6
6
  "name": "tsachis",
7
7
  "email": "tsachis@wix.com"
@@ -100,5 +100,5 @@
100
100
  "wallaby": {
101
101
  "autoDetect": true
102
102
  },
103
- "falconPackageHash": "527f52ff447d5d61666f8af72e2f79ab513eea188fe4f1a640a38cb2"
103
+ "falconPackageHash": "8a098816a1c8a9fd6d700dbc9c9cf3383fa9b48cc496e76ecd2e0bf0"
104
104
  }
@@ -8,7 +8,12 @@
8
8
  /* Color tokens — HSL triplets */
9
9
  --background: 0 0% 100%;
10
10
  --foreground: 0 0% 3.9%;
11
- --card: 0 0% 100%;
11
+ /* A card must not dissolve into the page it sits on. Until the seed's
12
+ * migration to `bg-card` this separation was drawn the other way round —
13
+ * section bands were `bg-muted` and cards were the pure `--background` — so
14
+ * the tint moves onto the card and `--background` goes back to meaning what
15
+ * it says: the page. Same two greys, opposite surfaces. */
16
+ --card: 0 0% 96.1%;
12
17
  --card-foreground: 0 0% 3.9%;
13
18
  --popover: 0 0% 100%;
14
19
  --popover-foreground: 0 0% 3.9%;
@@ -113,7 +118,7 @@
113
118
  .dark {
114
119
  --background: 0 0% 3.9%;
115
120
  --foreground: 0 0% 98%;
116
- --card: 0 0% 3.9%;
121
+ --card: 0 0% 14.9%;
117
122
  --card-foreground: 0 0% 98%;
118
123
  --popover: 0 0% 3.9%;
119
124
  --popover-foreground: 0 0% 98%;