@civitai/theme 0.3.2 → 0.5.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.
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  Framework-agnostic **design tokens**, derived at build time from civitai's real
4
4
  Mantine theme. Ships three forms of the same `--civitai-*` token contract:
5
5
 
6
- - `dist/tokens.css` — a `:root` + `[data-theme='light'|'dark']` stylesheet
6
+ - `dist/tokens.css` — a `:root` + `[data-theme='light'|'dark']` + OS-preference stylesheet
7
7
  (`--civitai-*` custom properties; `<color>` tokens registered via `@property`).
8
8
  - typed JS — `import { tokens, darkTokens, tokenVars, tokensCss } from '@civitai/theme'`.
9
9
  - `dist/tokens.dtcg.json` — a W3C **Design Tokens Community Group** export
@@ -18,8 +18,9 @@ resolution → re-namespaced `--civitai-*`. This is the same primitive civitai
18
18
  uses in `mantine-css-variables.ts`. `--mantine-*` is fully resolved away, so the
19
19
  `--civitai-*` contract is self-contained.
20
20
 
21
- The one exception is the **breakpoint scale**, which deliberately bypasses the
22
- Mantine pipeline — see below.
21
+ Two kinds of token depart from that. The **breakpoint scale** bypasses the
22
+ Mantine pipeline entirely (see below), and a few tokens declare an explicit
23
+ **light/dark pair** — see next section.
23
24
 
24
25
  Four guards keep it honest (`pnpm --filter @civitai/theme test`):
25
26
 
@@ -33,6 +34,22 @@ Four guards keep it honest (`pnpm --filter @civitai/theme test`):
33
34
  - **px-not-em guard** — self-contained; pins the breakpoint tokens to the px
34
35
  scale and asserts the em values are absent.
35
36
 
37
+ ## Scheme-paired tokens
38
+
39
+ A custom property inherits across a shadow boundary; an ancestor selector does
40
+ not cross one. So a component that wanted "gray in light, surface in dark" could
41
+ only say it as `[data-theme='dark'] <descendant>` in `@civitai/components`, which
42
+ a shadow root can never match (`:host-context()` has never shipped in Firefox).
43
+
44
+ Those decisions are tokens now — `--civitai-card-border-width`,
45
+ `--civitai-color-track`, `--civitai-color-segmented-bg` and
46
+ `--civitai-color-media-placeholder`. Mantine has no variable that carries either
47
+ side of these pairs, so `TokenSpec.source` and `.literal` each accept a
48
+ `{ light, dark }` pair, resolved against its own scheme's variable map.
49
+
50
+ `--civitai-card-border-width` is a **width**, not a color: dark drops the default
51
+ hairline's box, and a transparent color would still occupy 1px on every card.
52
+
36
53
  ## Breakpoints — 🔴 the px scale, not Mantine's em scale
37
54
 
38
55
  civitai has **two** breakpoint scales and they agree on exactly one key:
@@ -83,6 +100,27 @@ tokens.colorPrimary; // "#228BE6"
83
100
 
84
101
  Theme by setting `data-theme="light" | "dark"` on any ancestor.
85
102
 
103
+ **Dark is the base, and nothing here consults the OS.** `:root` carries the dark
104
+ palette plus `color-scheme: dark`, so an element with no `data-theme` above it is
105
+ dark — on any machine, under any OS preference. `[data-theme='light']` is a full
106
+ mirror of the light palette and is the only thing that puts light back;
107
+ `[data-theme='dark']` restores dark inside a light subtree. The attribute is the
108
+ override and it wins wherever it sits, because a nearer ancestor's tokens inherit
109
+ over a farther one's.
110
+
111
+ There is deliberately **no** `@media (prefers-color-scheme: …)` block, in either
112
+ direction. The browser must not decide a Civitai surface's theme: civitai.com is
113
+ dark, and an App Block boots dark and takes light only from its host. ⚠️ Until
114
+ `0.5.0` the opposite was true — `:root` was light and dark arrived via
115
+ `@media (prefers-color-scheme: dark) { :root:not([data-theme]) { … } }` — so every
116
+ surface that must not follow the OS had to set `data-theme` explicitly just to
117
+ defeat it. If you added such an attribute for that reason alone, you can drop it.
118
+
119
+ Note on the JS exports, which did **not** change: `tokens` is still the LIGHT
120
+ map and `darkTokens` the dark one. So `tokens` no longer describes what `:root`
121
+ emits — read it as "the `[data-theme='light']` values". That naming is kept
122
+ deliberately, so this release breaks one thing (the CSS default) rather than two.
123
+
86
124
  ## Build
87
125
 
88
126
  `pnpm --filter @civitai/theme build` regenerates `src/tokens.generated.ts`,
@@ -20,25 +20,34 @@
20
20
  * (`scripts/build-tokens.ts`) and the generation-parity test consume it.
21
21
  */
22
22
  import { type MantineThemeOverride } from '@mantine/core';
23
+ /**
24
+ * A light/dark pair, for the tokens whose two sides come from different places —
25
+ * something a single Mantine variable cannot express.
26
+ */
27
+ type SchemePair = {
28
+ light: string;
29
+ dark: string;
30
+ };
23
31
  /** A single public token, mapped to the Mantine variable it derives from. */
24
32
  interface TokenSpec {
25
33
  /** Public name WITHOUT the `--civitai-` prefix, e.g. `color-primary`. */
26
34
  name: string;
27
35
  /**
28
- * Source Mantine variable name (with `--mantine-` prefix). Mutually exclusive
29
- * with `literal` — exactly one of the two must be set.
36
+ * Source Mantine variable name (with `--mantine-` prefix), or one per scheme.
37
+ * Mutually exclusive with `literal` — exactly one of the two must be set.
30
38
  */
31
- source?: string;
39
+ source?: string | SchemePair;
32
40
  /**
33
41
  * Concrete literal value for a token that deliberately does NOT derive from
34
- * Mantine. Only the breakpoint scale uses this, and the reason is load-bearing:
42
+ * Mantine. The breakpoint scale uses this, and the reason is load-bearing:
35
43
  * civitai's px breakpoints are NOT part of its Mantine theme, and Mantine's own
36
44
  * stock EM scale disagrees with them on four of five keys (see
37
45
  * `breakpoints.source.ts`). Routing them through `mergeMantineTheme` would
38
46
  * silently resolve any un-overridden key to the wrong number, so they bypass
39
- * the Mantine pipeline entirely. Scheme-independent by construction.
47
+ * the Mantine pipeline entirely. A single string is scheme-independent by
48
+ * construction.
40
49
  */
41
- literal?: string;
50
+ literal?: string | SchemePair;
42
51
  /** Typed-syntax category — drives `@property` registration + DTCG `$type`. */
43
52
  type: 'color' | 'length' | 'font';
44
53
  description: string;
package/dist/generate.js CHANGED
@@ -22,6 +22,7 @@
22
22
  import { DEFAULT_THEME, defaultCssVariablesResolver, mergeMantineTheme, } from '@mantine/core';
23
23
  import { BREAKPOINT_KEYS, civitaiBreakpointsSource } from './breakpoints.source.js';
24
24
  import { civitaiThemeSource } from './theme.source.js';
25
+ const forScheme = (value, scheme) => typeof value === 'string' ? value : value[scheme];
25
26
  /**
26
27
  * The curated public token contract. ORDER is significant (drives deterministic
27
28
  * CSS/JSON output). Each token derives from a real resolved Mantine variable —
@@ -68,9 +69,12 @@ const TOKEN_SPEC = [
68
69
  },
69
70
  {
70
71
  name: 'color-surface',
71
- source: '--mantine-color-body',
72
+ // Dark parts company with the page: measured against civitai.com, a raised
73
+ // surface is #25262B where the page is darker. Sharing one value made every
74
+ // card, menu, modal and input invisible except for its border.
75
+ source: { light: '--mantine-color-body', dark: '--mantine-color-default' },
72
76
  type: 'color',
73
- description: 'Primary surface / page background.',
77
+ description: 'Raised surface — cards, menus, dialogs, inputs.',
74
78
  },
75
79
  {
76
80
  name: 'color-surface-2',
@@ -164,6 +168,33 @@ const TOKEN_SPEC = [
164
168
  description: `Responsive breakpoint \`${key}\` from civitai's px scale ` +
165
169
  `(src/utils/breakpoints.json) — NOT Mantine's em scale.`,
166
170
  })),
171
+ // Scheme-paired: a shadow root cannot see a `[data-theme='dark']` ancestor,
172
+ // so these carry the decision as an inherited property. Appended last.
173
+ {
174
+ name: 'card-border-width',
175
+ // A width, not a color: a transparent hairline still occupies 1px of box.
176
+ literal: { light: '1px', dark: '0' },
177
+ type: 'length',
178
+ description: 'Default card hairline width. Light needs it (surface == body); dark already separates them, so it collapses to 0.',
179
+ },
180
+ {
181
+ name: 'color-track',
182
+ source: { light: '--mantine-color-gray-2', dark: '--mantine-color-default' },
183
+ type: 'color',
184
+ description: 'Groove behind a slider thumb.',
185
+ },
186
+ {
187
+ name: 'color-segmented-bg',
188
+ source: { light: '--mantine-color-gray-1', dark: '--mantine-color-default' },
189
+ type: 'color',
190
+ description: 'Trough a segmented control\'s segments sit in.',
191
+ },
192
+ {
193
+ name: 'color-media-placeholder',
194
+ source: { light: '--mantine-color-gray-2', dark: '--mantine-color-default' },
195
+ type: 'color',
196
+ description: 'Backdrop shown while an image loads or after it fails.',
197
+ },
167
198
  ];
168
199
  const VAR_RE = /var\(\s*(--[a-zA-Z0-9-]+)\s*(?:,\s*([^)]*))?\)/;
169
200
  /**
@@ -215,10 +246,14 @@ export function resolveTokens(themeOverride = civitaiThemeSource) {
215
246
  if ((spec.source == null) === (spec.literal == null)) {
216
247
  throw new Error(`Token ${varName}: exactly one of \`source\` (Mantine-derived) or \`literal\` must be set.`);
217
248
  }
218
- // A `literal` spec is scheme-independent by construction and NEVER touches the
219
- // Mantine dicts — that bypass is the whole point for the breakpoint scale.
220
- const lightVal = spec.literal ?? resolveValue(`var(${spec.source})`, lightDict);
221
- const darkVal = spec.literal ?? resolveValue(`var(${spec.source})`, darkDict);
249
+ // A `literal` spec NEVER touches the Mantine dicts — that bypass is the
250
+ // whole point for the breakpoint scale.
251
+ const lightVal = spec.literal != null
252
+ ? forScheme(spec.literal, 'light')
253
+ : resolveValue(`var(${forScheme(spec.source, 'light')})`, lightDict);
254
+ const darkVal = spec.literal != null
255
+ ? forScheme(spec.literal, 'dark')
256
+ : resolveValue(`var(${forScheme(spec.source, 'dark')})`, darkDict);
222
257
  root[varName] = lightVal;
223
258
  if (darkVal !== lightVal || spec.alwaysDark)
224
259
  dark[varName] = darkVal;
@@ -245,26 +280,61 @@ export function buildArtifacts(themeOverride = civitaiThemeSource) {
245
280
  // @property initial-value, so registering them would make the browser drop
246
281
  // the whole rule — we skip them and rely on the plain custom-property
247
282
  // declaration (which applies identically). `font` is untyped.
283
+ // 🔴 DARK IS THE BASE. `baseValue` is the single place that decides what an
284
+ // UNTHEMED element gets, and it answers DARK wherever a dark value exists.
285
+ // Before this, `:root` carried the light palette and the dark one arrived via
286
+ // `@media (prefers-color-scheme: dark) { :root:not([data-theme]) }` — i.e. an
287
+ // element with no `data-theme` above it followed the OS. That is the opposite
288
+ // of what every Civitai surface wants: civitai.com is dark, App Blocks boot
289
+ // dark and take light only from the host, and the OS preference is not a
290
+ // signal either of them should consult. Under the old shape every surface
291
+ // spanning the two had to set `data-theme` EXPLICITLY just to stop the OS
292
+ // deciding; that workaround is what this flip removes.
293
+ const baseValue = (varName) => dark[varName] ?? root[varName];
248
294
  const propertyRules = meta
249
295
  .filter((m) => m.type === 'color')
250
296
  .map((m) => {
251
- const initial = root[m.varName];
297
+ // The @property fallback is the no-information case, so it is dark too.
298
+ // ⚠️ CONSISTENCY WITH `:root`, NOT AN INDEPENDENTLY OBSERVABLE BEHAVIOUR —
299
+ // an earlier draft of this comment claimed it "matters for a shadow root
300
+ // that cannot see any ancestor's declaration", and nothing demonstrates
301
+ // that: @property rules are emitted for `type === 'color'` only, and the
302
+ // one shadow-root test case asserts `--civitai-card-border-width`, which
303
+ // has no @property rule at all and resolves by ordinary inheritance of the
304
+ // `:root` declaration. Leaving the initials light against a dark `:root`
305
+ // would be a real inconsistency; that is the reason, and it is the only
306
+ // one claimed here.
307
+ const initial = baseValue(m.varName);
252
308
  return `@property ${m.varName} {\n syntax: '<color>';\n inherits: true;\n initial-value: ${initial};\n}`;
253
309
  })
254
310
  .join('\n');
255
- const rootBlock = meta.map((m) => ` ${m.varName}: ${root[m.varName]};`).join('\n');
256
- // Explicit light block mirrors the :root defaults so `[data-theme='light']`
257
- // (used by @civitai/components) always wins over an ambient dark ancestor.
311
+ const rootBlock = meta.map((m) => ` ${m.varName}: ${baseValue(m.varName)};`).join('\n');
312
+ // The light block must be a FULL mirror, not a diff: it is the only thing that
313
+ // can put a light value back once `:root` carries dark, and it has to win over
314
+ // an ambient dark ancestor (`@civitai/components` relies on that).
258
315
  const lightBlock = meta.map((m) => ` ${m.varName}: ${root[m.varName]};`).join('\n');
259
- const darkBlock = meta
316
+ // Still emitted, and still a diff against the shared values. It is NOT
317
+ // redundant now that `:root` is dark: it is what restores dark for a subtree
318
+ // nested inside a `[data-theme='light']` one.
319
+ const darkDecls = meta
260
320
  .filter((m) => m.varName in dark)
261
- .map((m) => ` ${m.varName}: ${dark[m.varName]};`)
262
- .join('\n');
321
+ .map((m) => `${m.varName}: ${dark[m.varName]};`);
322
+ const darkBlock = darkDecls.map((d) => ` ${d}`).join('\n');
323
+ // Not a token: it tells the UA which scheme to paint NATIVE controls in.
324
+ // Without it a number input's spinner, a select's caret and a scrollbar stay
325
+ // light against a dark surface. It inherits, so it reaches shadow roots too.
326
+ const scheme = (value) => ` color-scheme: ${value};`;
327
+ // 🔴 NO `@media (prefers-color-scheme: …)` BLOCK — deliberately, and do not
328
+ // add one in either direction. The stylesheet has exactly two answers now:
329
+ // the dark base, and whatever `[data-theme]` an ancestor declares. An OS-light
330
+ // block would reintroduce the behaviour this flip removed, and an OS-dark one
331
+ // is already the base. Pinned by `test/generation-parity.test.ts` and by the
332
+ // dark-base contract tests in `@civitai/components`.
263
333
  const tokensCss = `${AUTOGEN_BANNER}\n` +
264
334
  `${propertyRules}\n\n` +
265
- `:root {\n${rootBlock}\n}\n\n` +
266
- `[data-theme='light'] {\n${lightBlock}\n}\n\n` +
267
- `[data-theme='dark'] {\n${darkBlock}\n}\n`;
335
+ `:root {\n${scheme('dark')}\n${rootBlock}\n}\n\n` +
336
+ `[data-theme='light'] {\n${scheme('light')}\n${lightBlock}\n}\n\n` +
337
+ `[data-theme='dark'] {\n${scheme('dark')}\n${darkBlock}\n}\n`;
268
338
  // ---- tokens.dtcg.json (W3C DTCG 2025.10) ----
269
339
  const dtcg = {};
270
340
  for (const m of meta) {
package/dist/tokens.css CHANGED
@@ -3,42 +3,42 @@
3
3
  @property --civitai-color-text {
4
4
  syntax: '<color>';
5
5
  inherits: true;
6
- initial-value: #222;
6
+ initial-value: #C1C2C5;
7
7
  }
8
8
  @property --civitai-color-text-dimmed {
9
9
  syntax: '<color>';
10
10
  inherits: true;
11
- initial-value: #868e96;
11
+ initial-value: #8c8fa3;
12
12
  }
13
13
  @property --civitai-color-body {
14
14
  syntax: '<color>';
15
15
  inherits: true;
16
- initial-value: #fefefe;
16
+ initial-value: #1A1B1E;
17
17
  }
18
18
  @property --civitai-color-surface {
19
19
  syntax: '<color>';
20
20
  inherits: true;
21
- initial-value: #fefefe;
21
+ initial-value: #25262B;
22
22
  }
23
23
  @property --civitai-color-surface-2 {
24
24
  syntax: '<color>';
25
25
  inherits: true;
26
- initial-value: #fefefe;
26
+ initial-value: #25262B;
27
27
  }
28
28
  @property --civitai-color-border {
29
29
  syntax: '<color>';
30
30
  inherits: true;
31
- initial-value: #ced4da;
31
+ initial-value: #373A40;
32
32
  }
33
33
  @property --civitai-color-primary {
34
34
  syntax: '<color>';
35
35
  inherits: true;
36
- initial-value: #228BE6;
36
+ initial-value: #1971C2;
37
37
  }
38
38
  @property --civitai-color-primary-hover {
39
39
  syntax: '<color>';
40
40
  inherits: true;
41
- initial-value: #1C7ED6;
41
+ initial-value: #1864AB;
42
42
  }
43
43
  @property --civitai-color-primary-fg {
44
44
  syntax: '<color>';
@@ -48,27 +48,27 @@
48
48
  @property --civitai-color-primary-light {
49
49
  syntax: '<color>';
50
50
  inherits: true;
51
- initial-value: rgba(34, 139, 230, 0.1);
51
+ initial-value: rgba(34, 139, 230, 0.15);
52
52
  }
53
53
  @property --civitai-color-error {
54
54
  syntax: '<color>';
55
55
  inherits: true;
56
- initial-value: #fa5252;
56
+ initial-value: #e03131;
57
57
  }
58
58
  @property --civitai-color-success {
59
59
  syntax: '<color>';
60
60
  inherits: true;
61
- initial-value: #299C7A;
61
+ initial-value: #326D5C;
62
62
  }
63
63
  @property --civitai-color-warning {
64
64
  syntax: '<color>';
65
65
  inherits: true;
66
- initial-value: #fd7e14;
66
+ initial-value: #e8590c;
67
67
  }
68
68
  @property --civitai-color-info {
69
69
  syntax: '<color>';
70
70
  inherits: true;
71
- initial-value: #228BE6;
71
+ initial-value: #1971C2;
72
72
  }
73
73
  @property --civitai-color-gray-0 {
74
74
  syntax: '<color>';
@@ -120,25 +120,41 @@
120
120
  inherits: true;
121
121
  initial-value: #212529;
122
122
  }
123
+ @property --civitai-color-track {
124
+ syntax: '<color>';
125
+ inherits: true;
126
+ initial-value: #25262B;
127
+ }
128
+ @property --civitai-color-segmented-bg {
129
+ syntax: '<color>';
130
+ inherits: true;
131
+ initial-value: #25262B;
132
+ }
133
+ @property --civitai-color-media-placeholder {
134
+ syntax: '<color>';
135
+ inherits: true;
136
+ initial-value: #25262B;
137
+ }
123
138
 
124
139
  :root {
140
+ color-scheme: dark;
125
141
  --civitai-font: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji;
126
142
  --civitai-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace;
127
143
  --civitai-radius: 0.25rem;
128
- --civitai-color-text: #222;
129
- --civitai-color-text-dimmed: #868e96;
130
- --civitai-color-body: #fefefe;
131
- --civitai-color-surface: #fefefe;
132
- --civitai-color-surface-2: #fefefe;
133
- --civitai-color-border: #ced4da;
134
- --civitai-color-primary: #228BE6;
135
- --civitai-color-primary-hover: #1C7ED6;
144
+ --civitai-color-text: #C1C2C5;
145
+ --civitai-color-text-dimmed: #8c8fa3;
146
+ --civitai-color-body: #1A1B1E;
147
+ --civitai-color-surface: #25262B;
148
+ --civitai-color-surface-2: #25262B;
149
+ --civitai-color-border: #373A40;
150
+ --civitai-color-primary: #1971C2;
151
+ --civitai-color-primary-hover: #1864AB;
136
152
  --civitai-color-primary-fg: #fefefe;
137
- --civitai-color-primary-light: rgba(34, 139, 230, 0.1);
138
- --civitai-color-error: #fa5252;
139
- --civitai-color-success: #299C7A;
140
- --civitai-color-warning: #fd7e14;
141
- --civitai-color-info: #228BE6;
153
+ --civitai-color-primary-light: rgba(34, 139, 230, 0.15);
154
+ --civitai-color-error: #e03131;
155
+ --civitai-color-success: #326D5C;
156
+ --civitai-color-warning: #e8590c;
157
+ --civitai-color-info: #1971C2;
142
158
  --civitai-color-gray-0: #f8f9fa;
143
159
  --civitai-color-gray-1: #f1f3f5;
144
160
  --civitai-color-gray-2: #e9ecef;
@@ -154,9 +170,14 @@
154
170
  --civitai-bp-md: 1024px;
155
171
  --civitai-bp-lg: 1184px;
156
172
  --civitai-bp-xl: 1440px;
173
+ --civitai-card-border-width: 0;
174
+ --civitai-color-track: #25262B;
175
+ --civitai-color-segmented-bg: #25262B;
176
+ --civitai-color-media-placeholder: #25262B;
157
177
  }
158
178
 
159
179
  [data-theme='light'] {
180
+ color-scheme: light;
160
181
  --civitai-font: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji;
161
182
  --civitai-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace;
162
183
  --civitai-radius: 0.25rem;
@@ -189,13 +210,18 @@
189
210
  --civitai-bp-md: 1024px;
190
211
  --civitai-bp-lg: 1184px;
191
212
  --civitai-bp-xl: 1440px;
213
+ --civitai-card-border-width: 1px;
214
+ --civitai-color-track: #e9ecef;
215
+ --civitai-color-segmented-bg: #f1f3f5;
216
+ --civitai-color-media-placeholder: #e9ecef;
192
217
  }
193
218
 
194
219
  [data-theme='dark'] {
220
+ color-scheme: dark;
195
221
  --civitai-color-text: #C1C2C5;
196
222
  --civitai-color-text-dimmed: #8c8fa3;
197
223
  --civitai-color-body: #1A1B1E;
198
- --civitai-color-surface: #1A1B1E;
224
+ --civitai-color-surface: #25262B;
199
225
  --civitai-color-surface-2: #25262B;
200
226
  --civitai-color-border: #373A40;
201
227
  --civitai-color-primary: #1971C2;
@@ -206,4 +232,8 @@
206
232
  --civitai-color-success: #326D5C;
207
233
  --civitai-color-warning: #e8590c;
208
234
  --civitai-color-info: #1971C2;
235
+ --civitai-card-border-width: 0;
236
+ --civitai-color-track: #25262B;
237
+ --civitai-color-segmented-bg: #25262B;
238
+ --civitai-color-media-placeholder: #25262B;
209
239
  }
@@ -55,10 +55,10 @@
55
55
  "surface": {
56
56
  "$type": "color",
57
57
  "$value": "#fefefe",
58
- "$description": "Primary surface / page background.",
58
+ "$description": "Raised surface — cards, menus, dialogs, inputs.",
59
59
  "$extensions": {
60
60
  "com.civitai.theme": {
61
- "dark": "#1A1B1E"
61
+ "dark": "#25262B"
62
62
  }
63
63
  }
64
64
  },
@@ -211,6 +211,36 @@
211
211
  "$type": "color",
212
212
  "$value": "#212529",
213
213
  "$description": "Neutral ramp step 9 (Mantine gray[9]); 0 = lightest … 9 = darkest."
214
+ },
215
+ "track": {
216
+ "$type": "color",
217
+ "$value": "#e9ecef",
218
+ "$description": "Groove behind a slider thumb.",
219
+ "$extensions": {
220
+ "com.civitai.theme": {
221
+ "dark": "#25262B"
222
+ }
223
+ }
224
+ },
225
+ "segmentedBg": {
226
+ "$type": "color",
227
+ "$value": "#f1f3f5",
228
+ "$description": "Trough a segmented control's segments sit in.",
229
+ "$extensions": {
230
+ "com.civitai.theme": {
231
+ "dark": "#25262B"
232
+ }
233
+ }
234
+ },
235
+ "mediaPlaceholder": {
236
+ "$type": "color",
237
+ "$value": "#e9ecef",
238
+ "$description": "Backdrop shown while an image loads or after it fails.",
239
+ "$extensions": {
240
+ "com.civitai.theme": {
241
+ "dark": "#25262B"
242
+ }
243
+ }
214
244
  }
215
245
  },
216
246
  "bp": {
@@ -254,5 +284,20 @@
254
284
  },
255
285
  "$description": "Responsive breakpoint `xl` from civitai's px scale (src/utils/breakpoints.json) — NOT Mantine's em scale."
256
286
  }
287
+ },
288
+ "card": {
289
+ "borderWidth": {
290
+ "$type": "dimension",
291
+ "$value": {
292
+ "value": 1,
293
+ "unit": "px"
294
+ },
295
+ "$description": "Default card hairline width. Light needs it (surface == body); dark already separates them, so it collapses to 0.",
296
+ "$extensions": {
297
+ "com.civitai.theme": {
298
+ "dark": "0"
299
+ }
300
+ }
301
+ }
257
302
  }
258
303
  }
@@ -32,13 +32,17 @@ export declare const tokens: {
32
32
  readonly bpMd: "1024px";
33
33
  readonly bpLg: "1184px";
34
34
  readonly bpXl: "1440px";
35
+ readonly cardBorderWidth: "1px";
36
+ readonly colorTrack: "#e9ecef";
37
+ readonly colorSegmentedBg: "#f1f3f5";
38
+ readonly colorMediaPlaceholder: "#e9ecef";
35
39
  };
36
40
  /** Dark-scheme overrides (only tokens that differ from light). */
37
41
  export declare const darkTokens: {
38
42
  readonly colorText: "#C1C2C5";
39
43
  readonly colorTextDimmed: "#8c8fa3";
40
44
  readonly colorBody: "#1A1B1E";
41
- readonly colorSurface: "#1A1B1E";
45
+ readonly colorSurface: "#25262B";
42
46
  readonly colorSurface2: "#25262B";
43
47
  readonly colorBorder: "#373A40";
44
48
  readonly colorPrimary: "#1971C2";
@@ -49,6 +53,10 @@ export declare const darkTokens: {
49
53
  readonly colorSuccess: "#326D5C";
50
54
  readonly colorWarning: "#e8590c";
51
55
  readonly colorInfo: "#1971C2";
56
+ readonly cardBorderWidth: "0";
57
+ readonly colorTrack: "#25262B";
58
+ readonly colorSegmentedBg: "#25262B";
59
+ readonly colorMediaPlaceholder: "#25262B";
52
60
  };
53
61
  /** `var(--civitai-*)` reference strings for inline JS styling. */
54
62
  export declare const tokenVars: {
@@ -84,8 +92,12 @@ export declare const tokenVars: {
84
92
  readonly bpMd: "var(--civitai-bp-md)";
85
93
  readonly bpLg: "var(--civitai-bp-lg)";
86
94
  readonly bpXl: "var(--civitai-bp-xl)";
95
+ readonly cardBorderWidth: "var(--civitai-card-border-width)";
96
+ readonly colorTrack: "var(--civitai-color-track)";
97
+ readonly colorSegmentedBg: "var(--civitai-color-segmented-bg)";
98
+ readonly colorMediaPlaceholder: "var(--civitai-color-media-placeholder)";
87
99
  };
88
100
  /** The full `--civitai-*` stylesheet (`:root` + light/dark). Also emitted to dist/tokens.css. */
89
- export declare const tokensCss = "/* AUTOGENERATED by @civitai/theme (scripts/build-tokens.ts). DO NOT EDIT.\n Regenerate: pnpm --filter @civitai/theme build. Guarded by generation-parity test. */\n@property --civitai-color-text {\n syntax: '<color>';\n inherits: true;\n initial-value: #222;\n}\n@property --civitai-color-text-dimmed {\n syntax: '<color>';\n inherits: true;\n initial-value: #868e96;\n}\n@property --civitai-color-body {\n syntax: '<color>';\n inherits: true;\n initial-value: #fefefe;\n}\n@property --civitai-color-surface {\n syntax: '<color>';\n inherits: true;\n initial-value: #fefefe;\n}\n@property --civitai-color-surface-2 {\n syntax: '<color>';\n inherits: true;\n initial-value: #fefefe;\n}\n@property --civitai-color-border {\n syntax: '<color>';\n inherits: true;\n initial-value: #ced4da;\n}\n@property --civitai-color-primary {\n syntax: '<color>';\n inherits: true;\n initial-value: #228BE6;\n}\n@property --civitai-color-primary-hover {\n syntax: '<color>';\n inherits: true;\n initial-value: #1C7ED6;\n}\n@property --civitai-color-primary-fg {\n syntax: '<color>';\n inherits: true;\n initial-value: #fefefe;\n}\n@property --civitai-color-primary-light {\n syntax: '<color>';\n inherits: true;\n initial-value: rgba(34, 139, 230, 0.1);\n}\n@property --civitai-color-error {\n syntax: '<color>';\n inherits: true;\n initial-value: #fa5252;\n}\n@property --civitai-color-success {\n syntax: '<color>';\n inherits: true;\n initial-value: #299C7A;\n}\n@property --civitai-color-warning {\n syntax: '<color>';\n inherits: true;\n initial-value: #fd7e14;\n}\n@property --civitai-color-info {\n syntax: '<color>';\n inherits: true;\n initial-value: #228BE6;\n}\n@property --civitai-color-gray-0 {\n syntax: '<color>';\n inherits: true;\n initial-value: #f8f9fa;\n}\n@property --civitai-color-gray-1 {\n syntax: '<color>';\n inherits: true;\n initial-value: #f1f3f5;\n}\n@property --civitai-color-gray-2 {\n syntax: '<color>';\n inherits: true;\n initial-value: #e9ecef;\n}\n@property --civitai-color-gray-3 {\n syntax: '<color>';\n inherits: true;\n initial-value: #dee2e6;\n}\n@property --civitai-color-gray-4 {\n syntax: '<color>';\n inherits: true;\n initial-value: #ced4da;\n}\n@property --civitai-color-gray-5 {\n syntax: '<color>';\n inherits: true;\n initial-value: #adb5bd;\n}\n@property --civitai-color-gray-6 {\n syntax: '<color>';\n inherits: true;\n initial-value: #868e96;\n}\n@property --civitai-color-gray-7 {\n syntax: '<color>';\n inherits: true;\n initial-value: #495057;\n}\n@property --civitai-color-gray-8 {\n syntax: '<color>';\n inherits: true;\n initial-value: #343a40;\n}\n@property --civitai-color-gray-9 {\n syntax: '<color>';\n inherits: true;\n initial-value: #212529;\n}\n\n:root {\n --civitai-font: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji;\n --civitai-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace;\n --civitai-radius: 0.25rem;\n --civitai-color-text: #222;\n --civitai-color-text-dimmed: #868e96;\n --civitai-color-body: #fefefe;\n --civitai-color-surface: #fefefe;\n --civitai-color-surface-2: #fefefe;\n --civitai-color-border: #ced4da;\n --civitai-color-primary: #228BE6;\n --civitai-color-primary-hover: #1C7ED6;\n --civitai-color-primary-fg: #fefefe;\n --civitai-color-primary-light: rgba(34, 139, 230, 0.1);\n --civitai-color-error: #fa5252;\n --civitai-color-success: #299C7A;\n --civitai-color-warning: #fd7e14;\n --civitai-color-info: #228BE6;\n --civitai-color-gray-0: #f8f9fa;\n --civitai-color-gray-1: #f1f3f5;\n --civitai-color-gray-2: #e9ecef;\n --civitai-color-gray-3: #dee2e6;\n --civitai-color-gray-4: #ced4da;\n --civitai-color-gray-5: #adb5bd;\n --civitai-color-gray-6: #868e96;\n --civitai-color-gray-7: #495057;\n --civitai-color-gray-8: #343a40;\n --civitai-color-gray-9: #212529;\n --civitai-bp-xs: 480px;\n --civitai-bp-sm: 768px;\n --civitai-bp-md: 1024px;\n --civitai-bp-lg: 1184px;\n --civitai-bp-xl: 1440px;\n}\n\n[data-theme='light'] {\n --civitai-font: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji;\n --civitai-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace;\n --civitai-radius: 0.25rem;\n --civitai-color-text: #222;\n --civitai-color-text-dimmed: #868e96;\n --civitai-color-body: #fefefe;\n --civitai-color-surface: #fefefe;\n --civitai-color-surface-2: #fefefe;\n --civitai-color-border: #ced4da;\n --civitai-color-primary: #228BE6;\n --civitai-color-primary-hover: #1C7ED6;\n --civitai-color-primary-fg: #fefefe;\n --civitai-color-primary-light: rgba(34, 139, 230, 0.1);\n --civitai-color-error: #fa5252;\n --civitai-color-success: #299C7A;\n --civitai-color-warning: #fd7e14;\n --civitai-color-info: #228BE6;\n --civitai-color-gray-0: #f8f9fa;\n --civitai-color-gray-1: #f1f3f5;\n --civitai-color-gray-2: #e9ecef;\n --civitai-color-gray-3: #dee2e6;\n --civitai-color-gray-4: #ced4da;\n --civitai-color-gray-5: #adb5bd;\n --civitai-color-gray-6: #868e96;\n --civitai-color-gray-7: #495057;\n --civitai-color-gray-8: #343a40;\n --civitai-color-gray-9: #212529;\n --civitai-bp-xs: 480px;\n --civitai-bp-sm: 768px;\n --civitai-bp-md: 1024px;\n --civitai-bp-lg: 1184px;\n --civitai-bp-xl: 1440px;\n}\n\n[data-theme='dark'] {\n --civitai-color-text: #C1C2C5;\n --civitai-color-text-dimmed: #8c8fa3;\n --civitai-color-body: #1A1B1E;\n --civitai-color-surface: #1A1B1E;\n --civitai-color-surface-2: #25262B;\n --civitai-color-border: #373A40;\n --civitai-color-primary: #1971C2;\n --civitai-color-primary-hover: #1864AB;\n --civitai-color-primary-fg: #fefefe;\n --civitai-color-primary-light: rgba(34, 139, 230, 0.15);\n --civitai-color-error: #e03131;\n --civitai-color-success: #326D5C;\n --civitai-color-warning: #e8590c;\n --civitai-color-info: #1971C2;\n}\n";
101
+ export declare const tokensCss = "/* AUTOGENERATED by @civitai/theme (scripts/build-tokens.ts). DO NOT EDIT.\n Regenerate: pnpm --filter @civitai/theme build. Guarded by generation-parity test. */\n@property --civitai-color-text {\n syntax: '<color>';\n inherits: true;\n initial-value: #C1C2C5;\n}\n@property --civitai-color-text-dimmed {\n syntax: '<color>';\n inherits: true;\n initial-value: #8c8fa3;\n}\n@property --civitai-color-body {\n syntax: '<color>';\n inherits: true;\n initial-value: #1A1B1E;\n}\n@property --civitai-color-surface {\n syntax: '<color>';\n inherits: true;\n initial-value: #25262B;\n}\n@property --civitai-color-surface-2 {\n syntax: '<color>';\n inherits: true;\n initial-value: #25262B;\n}\n@property --civitai-color-border {\n syntax: '<color>';\n inherits: true;\n initial-value: #373A40;\n}\n@property --civitai-color-primary {\n syntax: '<color>';\n inherits: true;\n initial-value: #1971C2;\n}\n@property --civitai-color-primary-hover {\n syntax: '<color>';\n inherits: true;\n initial-value: #1864AB;\n}\n@property --civitai-color-primary-fg {\n syntax: '<color>';\n inherits: true;\n initial-value: #fefefe;\n}\n@property --civitai-color-primary-light {\n syntax: '<color>';\n inherits: true;\n initial-value: rgba(34, 139, 230, 0.15);\n}\n@property --civitai-color-error {\n syntax: '<color>';\n inherits: true;\n initial-value: #e03131;\n}\n@property --civitai-color-success {\n syntax: '<color>';\n inherits: true;\n initial-value: #326D5C;\n}\n@property --civitai-color-warning {\n syntax: '<color>';\n inherits: true;\n initial-value: #e8590c;\n}\n@property --civitai-color-info {\n syntax: '<color>';\n inherits: true;\n initial-value: #1971C2;\n}\n@property --civitai-color-gray-0 {\n syntax: '<color>';\n inherits: true;\n initial-value: #f8f9fa;\n}\n@property --civitai-color-gray-1 {\n syntax: '<color>';\n inherits: true;\n initial-value: #f1f3f5;\n}\n@property --civitai-color-gray-2 {\n syntax: '<color>';\n inherits: true;\n initial-value: #e9ecef;\n}\n@property --civitai-color-gray-3 {\n syntax: '<color>';\n inherits: true;\n initial-value: #dee2e6;\n}\n@property --civitai-color-gray-4 {\n syntax: '<color>';\n inherits: true;\n initial-value: #ced4da;\n}\n@property --civitai-color-gray-5 {\n syntax: '<color>';\n inherits: true;\n initial-value: #adb5bd;\n}\n@property --civitai-color-gray-6 {\n syntax: '<color>';\n inherits: true;\n initial-value: #868e96;\n}\n@property --civitai-color-gray-7 {\n syntax: '<color>';\n inherits: true;\n initial-value: #495057;\n}\n@property --civitai-color-gray-8 {\n syntax: '<color>';\n inherits: true;\n initial-value: #343a40;\n}\n@property --civitai-color-gray-9 {\n syntax: '<color>';\n inherits: true;\n initial-value: #212529;\n}\n@property --civitai-color-track {\n syntax: '<color>';\n inherits: true;\n initial-value: #25262B;\n}\n@property --civitai-color-segmented-bg {\n syntax: '<color>';\n inherits: true;\n initial-value: #25262B;\n}\n@property --civitai-color-media-placeholder {\n syntax: '<color>';\n inherits: true;\n initial-value: #25262B;\n}\n\n:root {\n color-scheme: dark;\n --civitai-font: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji;\n --civitai-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace;\n --civitai-radius: 0.25rem;\n --civitai-color-text: #C1C2C5;\n --civitai-color-text-dimmed: #8c8fa3;\n --civitai-color-body: #1A1B1E;\n --civitai-color-surface: #25262B;\n --civitai-color-surface-2: #25262B;\n --civitai-color-border: #373A40;\n --civitai-color-primary: #1971C2;\n --civitai-color-primary-hover: #1864AB;\n --civitai-color-primary-fg: #fefefe;\n --civitai-color-primary-light: rgba(34, 139, 230, 0.15);\n --civitai-color-error: #e03131;\n --civitai-color-success: #326D5C;\n --civitai-color-warning: #e8590c;\n --civitai-color-info: #1971C2;\n --civitai-color-gray-0: #f8f9fa;\n --civitai-color-gray-1: #f1f3f5;\n --civitai-color-gray-2: #e9ecef;\n --civitai-color-gray-3: #dee2e6;\n --civitai-color-gray-4: #ced4da;\n --civitai-color-gray-5: #adb5bd;\n --civitai-color-gray-6: #868e96;\n --civitai-color-gray-7: #495057;\n --civitai-color-gray-8: #343a40;\n --civitai-color-gray-9: #212529;\n --civitai-bp-xs: 480px;\n --civitai-bp-sm: 768px;\n --civitai-bp-md: 1024px;\n --civitai-bp-lg: 1184px;\n --civitai-bp-xl: 1440px;\n --civitai-card-border-width: 0;\n --civitai-color-track: #25262B;\n --civitai-color-segmented-bg: #25262B;\n --civitai-color-media-placeholder: #25262B;\n}\n\n[data-theme='light'] {\n color-scheme: light;\n --civitai-font: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji;\n --civitai-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace;\n --civitai-radius: 0.25rem;\n --civitai-color-text: #222;\n --civitai-color-text-dimmed: #868e96;\n --civitai-color-body: #fefefe;\n --civitai-color-surface: #fefefe;\n --civitai-color-surface-2: #fefefe;\n --civitai-color-border: #ced4da;\n --civitai-color-primary: #228BE6;\n --civitai-color-primary-hover: #1C7ED6;\n --civitai-color-primary-fg: #fefefe;\n --civitai-color-primary-light: rgba(34, 139, 230, 0.1);\n --civitai-color-error: #fa5252;\n --civitai-color-success: #299C7A;\n --civitai-color-warning: #fd7e14;\n --civitai-color-info: #228BE6;\n --civitai-color-gray-0: #f8f9fa;\n --civitai-color-gray-1: #f1f3f5;\n --civitai-color-gray-2: #e9ecef;\n --civitai-color-gray-3: #dee2e6;\n --civitai-color-gray-4: #ced4da;\n --civitai-color-gray-5: #adb5bd;\n --civitai-color-gray-6: #868e96;\n --civitai-color-gray-7: #495057;\n --civitai-color-gray-8: #343a40;\n --civitai-color-gray-9: #212529;\n --civitai-bp-xs: 480px;\n --civitai-bp-sm: 768px;\n --civitai-bp-md: 1024px;\n --civitai-bp-lg: 1184px;\n --civitai-bp-xl: 1440px;\n --civitai-card-border-width: 1px;\n --civitai-color-track: #e9ecef;\n --civitai-color-segmented-bg: #f1f3f5;\n --civitai-color-media-placeholder: #e9ecef;\n}\n\n[data-theme='dark'] {\n color-scheme: dark;\n --civitai-color-text: #C1C2C5;\n --civitai-color-text-dimmed: #8c8fa3;\n --civitai-color-body: #1A1B1E;\n --civitai-color-surface: #25262B;\n --civitai-color-surface-2: #25262B;\n --civitai-color-border: #373A40;\n --civitai-color-primary: #1971C2;\n --civitai-color-primary-hover: #1864AB;\n --civitai-color-primary-fg: #fefefe;\n --civitai-color-primary-light: rgba(34, 139, 230, 0.15);\n --civitai-color-error: #e03131;\n --civitai-color-success: #326D5C;\n --civitai-color-warning: #e8590c;\n --civitai-color-info: #1971C2;\n --civitai-card-border-width: 0;\n --civitai-color-track: #25262B;\n --civitai-color-segmented-bg: #25262B;\n --civitai-color-media-placeholder: #25262B;\n}\n";
90
102
  export type TokenName = keyof typeof tokens;
91
103
  //# sourceMappingURL=tokens.generated.d.ts.map
@@ -33,14 +33,18 @@ export const tokens = {
33
33
  "bpSm": "768px",
34
34
  "bpMd": "1024px",
35
35
  "bpLg": "1184px",
36
- "bpXl": "1440px"
36
+ "bpXl": "1440px",
37
+ "cardBorderWidth": "1px",
38
+ "colorTrack": "#e9ecef",
39
+ "colorSegmentedBg": "#f1f3f5",
40
+ "colorMediaPlaceholder": "#e9ecef"
37
41
  };
38
42
  /** Dark-scheme overrides (only tokens that differ from light). */
39
43
  export const darkTokens = {
40
44
  "colorText": "#C1C2C5",
41
45
  "colorTextDimmed": "#8c8fa3",
42
46
  "colorBody": "#1A1B1E",
43
- "colorSurface": "#1A1B1E",
47
+ "colorSurface": "#25262B",
44
48
  "colorSurface2": "#25262B",
45
49
  "colorBorder": "#373A40",
46
50
  "colorPrimary": "#1971C2",
@@ -50,7 +54,11 @@ export const darkTokens = {
50
54
  "colorError": "#e03131",
51
55
  "colorSuccess": "#326D5C",
52
56
  "colorWarning": "#e8590c",
53
- "colorInfo": "#1971C2"
57
+ "colorInfo": "#1971C2",
58
+ "cardBorderWidth": "0",
59
+ "colorTrack": "#25262B",
60
+ "colorSegmentedBg": "#25262B",
61
+ "colorMediaPlaceholder": "#25262B"
54
62
  };
55
63
  /** `var(--civitai-*)` reference strings for inline JS styling. */
56
64
  export const tokenVars = {
@@ -85,8 +93,12 @@ export const tokenVars = {
85
93
  "bpSm": "var(--civitai-bp-sm)",
86
94
  "bpMd": "var(--civitai-bp-md)",
87
95
  "bpLg": "var(--civitai-bp-lg)",
88
- "bpXl": "var(--civitai-bp-xl)"
96
+ "bpXl": "var(--civitai-bp-xl)",
97
+ "cardBorderWidth": "var(--civitai-card-border-width)",
98
+ "colorTrack": "var(--civitai-color-track)",
99
+ "colorSegmentedBg": "var(--civitai-color-segmented-bg)",
100
+ "colorMediaPlaceholder": "var(--civitai-color-media-placeholder)"
89
101
  };
90
102
  /** The full `--civitai-*` stylesheet (`:root` + light/dark). Also emitted to dist/tokens.css. */
91
- export const tokensCss = "/* AUTOGENERATED by @civitai/theme (scripts/build-tokens.ts). DO NOT EDIT.\n Regenerate: pnpm --filter @civitai/theme build. Guarded by generation-parity test. */\n@property --civitai-color-text {\n syntax: '<color>';\n inherits: true;\n initial-value: #222;\n}\n@property --civitai-color-text-dimmed {\n syntax: '<color>';\n inherits: true;\n initial-value: #868e96;\n}\n@property --civitai-color-body {\n syntax: '<color>';\n inherits: true;\n initial-value: #fefefe;\n}\n@property --civitai-color-surface {\n syntax: '<color>';\n inherits: true;\n initial-value: #fefefe;\n}\n@property --civitai-color-surface-2 {\n syntax: '<color>';\n inherits: true;\n initial-value: #fefefe;\n}\n@property --civitai-color-border {\n syntax: '<color>';\n inherits: true;\n initial-value: #ced4da;\n}\n@property --civitai-color-primary {\n syntax: '<color>';\n inherits: true;\n initial-value: #228BE6;\n}\n@property --civitai-color-primary-hover {\n syntax: '<color>';\n inherits: true;\n initial-value: #1C7ED6;\n}\n@property --civitai-color-primary-fg {\n syntax: '<color>';\n inherits: true;\n initial-value: #fefefe;\n}\n@property --civitai-color-primary-light {\n syntax: '<color>';\n inherits: true;\n initial-value: rgba(34, 139, 230, 0.1);\n}\n@property --civitai-color-error {\n syntax: '<color>';\n inherits: true;\n initial-value: #fa5252;\n}\n@property --civitai-color-success {\n syntax: '<color>';\n inherits: true;\n initial-value: #299C7A;\n}\n@property --civitai-color-warning {\n syntax: '<color>';\n inherits: true;\n initial-value: #fd7e14;\n}\n@property --civitai-color-info {\n syntax: '<color>';\n inherits: true;\n initial-value: #228BE6;\n}\n@property --civitai-color-gray-0 {\n syntax: '<color>';\n inherits: true;\n initial-value: #f8f9fa;\n}\n@property --civitai-color-gray-1 {\n syntax: '<color>';\n inherits: true;\n initial-value: #f1f3f5;\n}\n@property --civitai-color-gray-2 {\n syntax: '<color>';\n inherits: true;\n initial-value: #e9ecef;\n}\n@property --civitai-color-gray-3 {\n syntax: '<color>';\n inherits: true;\n initial-value: #dee2e6;\n}\n@property --civitai-color-gray-4 {\n syntax: '<color>';\n inherits: true;\n initial-value: #ced4da;\n}\n@property --civitai-color-gray-5 {\n syntax: '<color>';\n inherits: true;\n initial-value: #adb5bd;\n}\n@property --civitai-color-gray-6 {\n syntax: '<color>';\n inherits: true;\n initial-value: #868e96;\n}\n@property --civitai-color-gray-7 {\n syntax: '<color>';\n inherits: true;\n initial-value: #495057;\n}\n@property --civitai-color-gray-8 {\n syntax: '<color>';\n inherits: true;\n initial-value: #343a40;\n}\n@property --civitai-color-gray-9 {\n syntax: '<color>';\n inherits: true;\n initial-value: #212529;\n}\n\n:root {\n --civitai-font: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji;\n --civitai-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace;\n --civitai-radius: 0.25rem;\n --civitai-color-text: #222;\n --civitai-color-text-dimmed: #868e96;\n --civitai-color-body: #fefefe;\n --civitai-color-surface: #fefefe;\n --civitai-color-surface-2: #fefefe;\n --civitai-color-border: #ced4da;\n --civitai-color-primary: #228BE6;\n --civitai-color-primary-hover: #1C7ED6;\n --civitai-color-primary-fg: #fefefe;\n --civitai-color-primary-light: rgba(34, 139, 230, 0.1);\n --civitai-color-error: #fa5252;\n --civitai-color-success: #299C7A;\n --civitai-color-warning: #fd7e14;\n --civitai-color-info: #228BE6;\n --civitai-color-gray-0: #f8f9fa;\n --civitai-color-gray-1: #f1f3f5;\n --civitai-color-gray-2: #e9ecef;\n --civitai-color-gray-3: #dee2e6;\n --civitai-color-gray-4: #ced4da;\n --civitai-color-gray-5: #adb5bd;\n --civitai-color-gray-6: #868e96;\n --civitai-color-gray-7: #495057;\n --civitai-color-gray-8: #343a40;\n --civitai-color-gray-9: #212529;\n --civitai-bp-xs: 480px;\n --civitai-bp-sm: 768px;\n --civitai-bp-md: 1024px;\n --civitai-bp-lg: 1184px;\n --civitai-bp-xl: 1440px;\n}\n\n[data-theme='light'] {\n --civitai-font: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji;\n --civitai-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace;\n --civitai-radius: 0.25rem;\n --civitai-color-text: #222;\n --civitai-color-text-dimmed: #868e96;\n --civitai-color-body: #fefefe;\n --civitai-color-surface: #fefefe;\n --civitai-color-surface-2: #fefefe;\n --civitai-color-border: #ced4da;\n --civitai-color-primary: #228BE6;\n --civitai-color-primary-hover: #1C7ED6;\n --civitai-color-primary-fg: #fefefe;\n --civitai-color-primary-light: rgba(34, 139, 230, 0.1);\n --civitai-color-error: #fa5252;\n --civitai-color-success: #299C7A;\n --civitai-color-warning: #fd7e14;\n --civitai-color-info: #228BE6;\n --civitai-color-gray-0: #f8f9fa;\n --civitai-color-gray-1: #f1f3f5;\n --civitai-color-gray-2: #e9ecef;\n --civitai-color-gray-3: #dee2e6;\n --civitai-color-gray-4: #ced4da;\n --civitai-color-gray-5: #adb5bd;\n --civitai-color-gray-6: #868e96;\n --civitai-color-gray-7: #495057;\n --civitai-color-gray-8: #343a40;\n --civitai-color-gray-9: #212529;\n --civitai-bp-xs: 480px;\n --civitai-bp-sm: 768px;\n --civitai-bp-md: 1024px;\n --civitai-bp-lg: 1184px;\n --civitai-bp-xl: 1440px;\n}\n\n[data-theme='dark'] {\n --civitai-color-text: #C1C2C5;\n --civitai-color-text-dimmed: #8c8fa3;\n --civitai-color-body: #1A1B1E;\n --civitai-color-surface: #1A1B1E;\n --civitai-color-surface-2: #25262B;\n --civitai-color-border: #373A40;\n --civitai-color-primary: #1971C2;\n --civitai-color-primary-hover: #1864AB;\n --civitai-color-primary-fg: #fefefe;\n --civitai-color-primary-light: rgba(34, 139, 230, 0.15);\n --civitai-color-error: #e03131;\n --civitai-color-success: #326D5C;\n --civitai-color-warning: #e8590c;\n --civitai-color-info: #1971C2;\n}\n";
103
+ export const tokensCss = "/* AUTOGENERATED by @civitai/theme (scripts/build-tokens.ts). DO NOT EDIT.\n Regenerate: pnpm --filter @civitai/theme build. Guarded by generation-parity test. */\n@property --civitai-color-text {\n syntax: '<color>';\n inherits: true;\n initial-value: #C1C2C5;\n}\n@property --civitai-color-text-dimmed {\n syntax: '<color>';\n inherits: true;\n initial-value: #8c8fa3;\n}\n@property --civitai-color-body {\n syntax: '<color>';\n inherits: true;\n initial-value: #1A1B1E;\n}\n@property --civitai-color-surface {\n syntax: '<color>';\n inherits: true;\n initial-value: #25262B;\n}\n@property --civitai-color-surface-2 {\n syntax: '<color>';\n inherits: true;\n initial-value: #25262B;\n}\n@property --civitai-color-border {\n syntax: '<color>';\n inherits: true;\n initial-value: #373A40;\n}\n@property --civitai-color-primary {\n syntax: '<color>';\n inherits: true;\n initial-value: #1971C2;\n}\n@property --civitai-color-primary-hover {\n syntax: '<color>';\n inherits: true;\n initial-value: #1864AB;\n}\n@property --civitai-color-primary-fg {\n syntax: '<color>';\n inherits: true;\n initial-value: #fefefe;\n}\n@property --civitai-color-primary-light {\n syntax: '<color>';\n inherits: true;\n initial-value: rgba(34, 139, 230, 0.15);\n}\n@property --civitai-color-error {\n syntax: '<color>';\n inherits: true;\n initial-value: #e03131;\n}\n@property --civitai-color-success {\n syntax: '<color>';\n inherits: true;\n initial-value: #326D5C;\n}\n@property --civitai-color-warning {\n syntax: '<color>';\n inherits: true;\n initial-value: #e8590c;\n}\n@property --civitai-color-info {\n syntax: '<color>';\n inherits: true;\n initial-value: #1971C2;\n}\n@property --civitai-color-gray-0 {\n syntax: '<color>';\n inherits: true;\n initial-value: #f8f9fa;\n}\n@property --civitai-color-gray-1 {\n syntax: '<color>';\n inherits: true;\n initial-value: #f1f3f5;\n}\n@property --civitai-color-gray-2 {\n syntax: '<color>';\n inherits: true;\n initial-value: #e9ecef;\n}\n@property --civitai-color-gray-3 {\n syntax: '<color>';\n inherits: true;\n initial-value: #dee2e6;\n}\n@property --civitai-color-gray-4 {\n syntax: '<color>';\n inherits: true;\n initial-value: #ced4da;\n}\n@property --civitai-color-gray-5 {\n syntax: '<color>';\n inherits: true;\n initial-value: #adb5bd;\n}\n@property --civitai-color-gray-6 {\n syntax: '<color>';\n inherits: true;\n initial-value: #868e96;\n}\n@property --civitai-color-gray-7 {\n syntax: '<color>';\n inherits: true;\n initial-value: #495057;\n}\n@property --civitai-color-gray-8 {\n syntax: '<color>';\n inherits: true;\n initial-value: #343a40;\n}\n@property --civitai-color-gray-9 {\n syntax: '<color>';\n inherits: true;\n initial-value: #212529;\n}\n@property --civitai-color-track {\n syntax: '<color>';\n inherits: true;\n initial-value: #25262B;\n}\n@property --civitai-color-segmented-bg {\n syntax: '<color>';\n inherits: true;\n initial-value: #25262B;\n}\n@property --civitai-color-media-placeholder {\n syntax: '<color>';\n inherits: true;\n initial-value: #25262B;\n}\n\n:root {\n color-scheme: dark;\n --civitai-font: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji;\n --civitai-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace;\n --civitai-radius: 0.25rem;\n --civitai-color-text: #C1C2C5;\n --civitai-color-text-dimmed: #8c8fa3;\n --civitai-color-body: #1A1B1E;\n --civitai-color-surface: #25262B;\n --civitai-color-surface-2: #25262B;\n --civitai-color-border: #373A40;\n --civitai-color-primary: #1971C2;\n --civitai-color-primary-hover: #1864AB;\n --civitai-color-primary-fg: #fefefe;\n --civitai-color-primary-light: rgba(34, 139, 230, 0.15);\n --civitai-color-error: #e03131;\n --civitai-color-success: #326D5C;\n --civitai-color-warning: #e8590c;\n --civitai-color-info: #1971C2;\n --civitai-color-gray-0: #f8f9fa;\n --civitai-color-gray-1: #f1f3f5;\n --civitai-color-gray-2: #e9ecef;\n --civitai-color-gray-3: #dee2e6;\n --civitai-color-gray-4: #ced4da;\n --civitai-color-gray-5: #adb5bd;\n --civitai-color-gray-6: #868e96;\n --civitai-color-gray-7: #495057;\n --civitai-color-gray-8: #343a40;\n --civitai-color-gray-9: #212529;\n --civitai-bp-xs: 480px;\n --civitai-bp-sm: 768px;\n --civitai-bp-md: 1024px;\n --civitai-bp-lg: 1184px;\n --civitai-bp-xl: 1440px;\n --civitai-card-border-width: 0;\n --civitai-color-track: #25262B;\n --civitai-color-segmented-bg: #25262B;\n --civitai-color-media-placeholder: #25262B;\n}\n\n[data-theme='light'] {\n color-scheme: light;\n --civitai-font: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji;\n --civitai-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace;\n --civitai-radius: 0.25rem;\n --civitai-color-text: #222;\n --civitai-color-text-dimmed: #868e96;\n --civitai-color-body: #fefefe;\n --civitai-color-surface: #fefefe;\n --civitai-color-surface-2: #fefefe;\n --civitai-color-border: #ced4da;\n --civitai-color-primary: #228BE6;\n --civitai-color-primary-hover: #1C7ED6;\n --civitai-color-primary-fg: #fefefe;\n --civitai-color-primary-light: rgba(34, 139, 230, 0.1);\n --civitai-color-error: #fa5252;\n --civitai-color-success: #299C7A;\n --civitai-color-warning: #fd7e14;\n --civitai-color-info: #228BE6;\n --civitai-color-gray-0: #f8f9fa;\n --civitai-color-gray-1: #f1f3f5;\n --civitai-color-gray-2: #e9ecef;\n --civitai-color-gray-3: #dee2e6;\n --civitai-color-gray-4: #ced4da;\n --civitai-color-gray-5: #adb5bd;\n --civitai-color-gray-6: #868e96;\n --civitai-color-gray-7: #495057;\n --civitai-color-gray-8: #343a40;\n --civitai-color-gray-9: #212529;\n --civitai-bp-xs: 480px;\n --civitai-bp-sm: 768px;\n --civitai-bp-md: 1024px;\n --civitai-bp-lg: 1184px;\n --civitai-bp-xl: 1440px;\n --civitai-card-border-width: 1px;\n --civitai-color-track: #e9ecef;\n --civitai-color-segmented-bg: #f1f3f5;\n --civitai-color-media-placeholder: #e9ecef;\n}\n\n[data-theme='dark'] {\n color-scheme: dark;\n --civitai-color-text: #C1C2C5;\n --civitai-color-text-dimmed: #8c8fa3;\n --civitai-color-body: #1A1B1E;\n --civitai-color-surface: #25262B;\n --civitai-color-surface-2: #25262B;\n --civitai-color-border: #373A40;\n --civitai-color-primary: #1971C2;\n --civitai-color-primary-hover: #1864AB;\n --civitai-color-primary-fg: #fefefe;\n --civitai-color-primary-light: rgba(34, 139, 230, 0.15);\n --civitai-color-error: #e03131;\n --civitai-color-success: #326D5C;\n --civitai-color-warning: #e8590c;\n --civitai-color-info: #1971C2;\n --civitai-card-border-width: 0;\n --civitai-color-track: #25262B;\n --civitai-color-segmented-bg: #25262B;\n --civitai-color-media-placeholder: #25262B;\n}\n";
92
104
  //# sourceMappingURL=tokens.generated.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@civitai/theme",
3
- "version": "0.3.2",
3
+ "version": "0.5.0",
4
4
  "description": "Framework-agnostic --civitai-* design tokens, derived build-time from civitai's real Mantine theme. CSS + typed JS + W3C DTCG.",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/styles.css CHANGED
@@ -3,42 +3,42 @@
3
3
  @property --civitai-color-text {
4
4
  syntax: '<color>';
5
5
  inherits: true;
6
- initial-value: #222;
6
+ initial-value: #C1C2C5;
7
7
  }
8
8
  @property --civitai-color-text-dimmed {
9
9
  syntax: '<color>';
10
10
  inherits: true;
11
- initial-value: #868e96;
11
+ initial-value: #8c8fa3;
12
12
  }
13
13
  @property --civitai-color-body {
14
14
  syntax: '<color>';
15
15
  inherits: true;
16
- initial-value: #fefefe;
16
+ initial-value: #1A1B1E;
17
17
  }
18
18
  @property --civitai-color-surface {
19
19
  syntax: '<color>';
20
20
  inherits: true;
21
- initial-value: #fefefe;
21
+ initial-value: #25262B;
22
22
  }
23
23
  @property --civitai-color-surface-2 {
24
24
  syntax: '<color>';
25
25
  inherits: true;
26
- initial-value: #fefefe;
26
+ initial-value: #25262B;
27
27
  }
28
28
  @property --civitai-color-border {
29
29
  syntax: '<color>';
30
30
  inherits: true;
31
- initial-value: #ced4da;
31
+ initial-value: #373A40;
32
32
  }
33
33
  @property --civitai-color-primary {
34
34
  syntax: '<color>';
35
35
  inherits: true;
36
- initial-value: #228BE6;
36
+ initial-value: #1971C2;
37
37
  }
38
38
  @property --civitai-color-primary-hover {
39
39
  syntax: '<color>';
40
40
  inherits: true;
41
- initial-value: #1C7ED6;
41
+ initial-value: #1864AB;
42
42
  }
43
43
  @property --civitai-color-primary-fg {
44
44
  syntax: '<color>';
@@ -48,27 +48,27 @@
48
48
  @property --civitai-color-primary-light {
49
49
  syntax: '<color>';
50
50
  inherits: true;
51
- initial-value: rgba(34, 139, 230, 0.1);
51
+ initial-value: rgba(34, 139, 230, 0.15);
52
52
  }
53
53
  @property --civitai-color-error {
54
54
  syntax: '<color>';
55
55
  inherits: true;
56
- initial-value: #fa5252;
56
+ initial-value: #e03131;
57
57
  }
58
58
  @property --civitai-color-success {
59
59
  syntax: '<color>';
60
60
  inherits: true;
61
- initial-value: #299C7A;
61
+ initial-value: #326D5C;
62
62
  }
63
63
  @property --civitai-color-warning {
64
64
  syntax: '<color>';
65
65
  inherits: true;
66
- initial-value: #fd7e14;
66
+ initial-value: #e8590c;
67
67
  }
68
68
  @property --civitai-color-info {
69
69
  syntax: '<color>';
70
70
  inherits: true;
71
- initial-value: #228BE6;
71
+ initial-value: #1971C2;
72
72
  }
73
73
  @property --civitai-color-gray-0 {
74
74
  syntax: '<color>';
@@ -120,25 +120,41 @@
120
120
  inherits: true;
121
121
  initial-value: #212529;
122
122
  }
123
+ @property --civitai-color-track {
124
+ syntax: '<color>';
125
+ inherits: true;
126
+ initial-value: #25262B;
127
+ }
128
+ @property --civitai-color-segmented-bg {
129
+ syntax: '<color>';
130
+ inherits: true;
131
+ initial-value: #25262B;
132
+ }
133
+ @property --civitai-color-media-placeholder {
134
+ syntax: '<color>';
135
+ inherits: true;
136
+ initial-value: #25262B;
137
+ }
123
138
 
124
139
  :root {
140
+ color-scheme: dark;
125
141
  --civitai-font: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji;
126
142
  --civitai-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace;
127
143
  --civitai-radius: 0.25rem;
128
- --civitai-color-text: #222;
129
- --civitai-color-text-dimmed: #868e96;
130
- --civitai-color-body: #fefefe;
131
- --civitai-color-surface: #fefefe;
132
- --civitai-color-surface-2: #fefefe;
133
- --civitai-color-border: #ced4da;
134
- --civitai-color-primary: #228BE6;
135
- --civitai-color-primary-hover: #1C7ED6;
144
+ --civitai-color-text: #C1C2C5;
145
+ --civitai-color-text-dimmed: #8c8fa3;
146
+ --civitai-color-body: #1A1B1E;
147
+ --civitai-color-surface: #25262B;
148
+ --civitai-color-surface-2: #25262B;
149
+ --civitai-color-border: #373A40;
150
+ --civitai-color-primary: #1971C2;
151
+ --civitai-color-primary-hover: #1864AB;
136
152
  --civitai-color-primary-fg: #fefefe;
137
- --civitai-color-primary-light: rgba(34, 139, 230, 0.1);
138
- --civitai-color-error: #fa5252;
139
- --civitai-color-success: #299C7A;
140
- --civitai-color-warning: #fd7e14;
141
- --civitai-color-info: #228BE6;
153
+ --civitai-color-primary-light: rgba(34, 139, 230, 0.15);
154
+ --civitai-color-error: #e03131;
155
+ --civitai-color-success: #326D5C;
156
+ --civitai-color-warning: #e8590c;
157
+ --civitai-color-info: #1971C2;
142
158
  --civitai-color-gray-0: #f8f9fa;
143
159
  --civitai-color-gray-1: #f1f3f5;
144
160
  --civitai-color-gray-2: #e9ecef;
@@ -154,9 +170,14 @@
154
170
  --civitai-bp-md: 1024px;
155
171
  --civitai-bp-lg: 1184px;
156
172
  --civitai-bp-xl: 1440px;
173
+ --civitai-card-border-width: 0;
174
+ --civitai-color-track: #25262B;
175
+ --civitai-color-segmented-bg: #25262B;
176
+ --civitai-color-media-placeholder: #25262B;
157
177
  }
158
178
 
159
179
  [data-theme='light'] {
180
+ color-scheme: light;
160
181
  --civitai-font: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji;
161
182
  --civitai-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace;
162
183
  --civitai-radius: 0.25rem;
@@ -189,13 +210,18 @@
189
210
  --civitai-bp-md: 1024px;
190
211
  --civitai-bp-lg: 1184px;
191
212
  --civitai-bp-xl: 1440px;
213
+ --civitai-card-border-width: 1px;
214
+ --civitai-color-track: #e9ecef;
215
+ --civitai-color-segmented-bg: #f1f3f5;
216
+ --civitai-color-media-placeholder: #e9ecef;
192
217
  }
193
218
 
194
219
  [data-theme='dark'] {
220
+ color-scheme: dark;
195
221
  --civitai-color-text: #C1C2C5;
196
222
  --civitai-color-text-dimmed: #8c8fa3;
197
223
  --civitai-color-body: #1A1B1E;
198
- --civitai-color-surface: #1A1B1E;
224
+ --civitai-color-surface: #25262B;
199
225
  --civitai-color-surface-2: #25262B;
200
226
  --civitai-color-border: #373A40;
201
227
  --civitai-color-primary: #1971C2;
@@ -206,4 +232,8 @@
206
232
  --civitai-color-success: #326D5C;
207
233
  --civitai-color-warning: #e8590c;
208
234
  --civitai-color-info: #1971C2;
235
+ --civitai-card-border-width: 0;
236
+ --civitai-color-track: #25262B;
237
+ --civitai-color-segmented-bg: #25262B;
238
+ --civitai-color-media-placeholder: #25262B;
209
239
  }